diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/di_builder.rs b/compiler/rustc_codegen_llvm/src/debuginfo/di_builder.rs new file mode 100644 index 0000000000000..ef8259091ef66 --- /dev/null +++ b/compiler/rustc_codegen_llvm/src/debuginfo/di_builder.rs @@ -0,0 +1,115 @@ +//! Safe wrappers for [`DIBuilder`] FFI functions. + +use libc::c_uint; +use rustc_abi::{Align, Size}; + +use crate::llvm::debuginfo::{DIBuilder, DIFlags}; +use crate::llvm::{self, Metadata}; + +impl<'ll> DIBuilder<'ll> { + pub(crate) fn create_subroutine_type( + &self, + parameter_types: &[Option<&'ll Metadata>], + flags: DIFlags, + ) -> &'ll Metadata { + unsafe { + llvm::LLVMDIBuilderCreateSubroutineType( + self, + None, // ("File"; unused) + parameter_types.as_ptr(), + parameter_types.len() as c_uint, + flags, + ) + } + } + + pub(crate) fn create_union_type( + &self, + scope: Option<&'ll Metadata>, + name: &str, + file_metadata: &'ll Metadata, + line_number: c_uint, + size: Size, + align: Align, + flags: DIFlags, + elements: &[&'ll Metadata], + unique_id: &str, + ) -> &'ll Metadata { + unsafe { + llvm::LLVMDIBuilderCreateUnionType( + self, + scope, + name.as_ptr(), + name.len(), + file_metadata, + line_number, + size.bits(), + align.bits() as u32, + flags, + elements.as_ptr(), + elements.len() as c_uint, + 0, // ("Objective-C runtime version"; default is 0) + unique_id.as_ptr(), + unique_id.len(), + ) + } + } + + pub(crate) fn create_array_type( + &self, + size: Size, + align: Align, + element_type: &'ll Metadata, + subscripts: &[&'ll Metadata], + ) -> &'ll Metadata { + unsafe { + llvm::LLVMDIBuilderCreateArrayType( + self, + size.bits(), + align.bits() as u32, + element_type, + subscripts.as_ptr(), + subscripts.len() as c_uint, + ) + } + } + + pub(crate) fn create_basic_type( + &self, + name: &str, + size: Size, + dwarf_type_encoding: u32, + flags: DIFlags, + ) -> &'ll Metadata { + unsafe { + llvm::LLVMDIBuilderCreateBasicType( + self, + name.as_ptr(), + name.len(), + size.bits(), + dwarf_type_encoding, + flags, + ) + } + } + + pub(crate) fn create_pointer_type( + &self, + pointee_type: &'ll Metadata, + size: Size, + align: Align, + name: &str, + ) -> &'ll Metadata { + unsafe { + llvm::LLVMDIBuilderCreatePointerType( + self, + pointee_type, + size.bits(), + align.bits() as u32, + 0, // ("DWARF address space"; default is 0) + name.as_ptr(), + name.len(), + ) + } + } +} diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 98d59f5a8ae06..f530095c36a05 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -29,9 +29,7 @@ use self::type_map::{DINodeCreationResult, Stub, UniqueTypeId}; use super::CodegenUnitDebugContext; use super::namespace::mangled_name_of_instance; use super::type_names::{compute_debuginfo_type_name, compute_debuginfo_vtable_name}; -use super::utils::{ - DIB, create_DIArray, debug_context, get_namespace_for_item, is_node_local_to_unit, -}; +use super::utils::{DIB, debug_context, get_namespace_for_item, is_node_local_to_unit}; use crate::common::{AsCCharPtr, CodegenCx}; use crate::debuginfo::dwarf_const; use crate::debuginfo::metadata::type_map::build_type_with_children; @@ -114,19 +112,9 @@ fn build_fixed_size_array_di_node<'ll, 'tcx>( .try_to_target_usize(cx.tcx) .expect("expected monomorphic const in codegen") as c_longlong; - let subrange = - unsafe { Some(llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound)) }; + let subrange = unsafe { llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound) }; - let subscripts = create_DIArray(DIB(cx), &[subrange]); - let di_node = unsafe { - llvm::LLVMRustDIBuilderCreateArrayType( - DIB(cx), - size.bits(), - align.bits() as u32, - element_type_di_node, - subscripts, - ) - }; + let di_node = DIB(cx).create_array_type(size, align, element_type_di_node, &[subrange]); DINodeCreationResult::new(di_node, false) } @@ -168,17 +156,12 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>( "ptr_type={ptr_type}, pointee_type={pointee_type}", ); - let di_node = unsafe { - llvm::LLVMRustDIBuilderCreatePointerType( - DIB(cx), - pointee_type_di_node, - data_layout.pointer_size.bits(), - data_layout.pointer_align.abi.bits() as u32, - 0, // Ignore DWARF address space. - ptr_type_debuginfo_name.as_c_char_ptr(), - ptr_type_debuginfo_name.len(), - ) - }; + let di_node = DIB(cx).create_pointer_type( + pointee_type_di_node, + data_layout.pointer_size, + data_layout.pointer_align.abi, + &ptr_type_debuginfo_name, + ); DINodeCreationResult { di_node, already_stored_in_typemap: false } } @@ -226,17 +209,12 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>( // The data pointer type is a regular, thin pointer, regardless of whether this // is a slice or a trait object. - let data_ptr_type_di_node = unsafe { - llvm::LLVMRustDIBuilderCreatePointerType( - DIB(cx), - pointee_type_di_node, - addr_field.size.bits(), - addr_field.align.abi.bits() as u32, - 0, // Ignore DWARF address space. - std::ptr::null(), - 0, - ) - }; + let data_ptr_type_di_node = DIB(cx).create_pointer_type( + pointee_type_di_node, + addr_field.size, + addr_field.align.abi, + "", + ); smallvec![ build_field_di_node( @@ -311,12 +289,7 @@ fn build_subroutine_type_di_node<'ll, 'tcx>( debug_context(cx).type_map.unique_id_to_di_node.borrow_mut().remove(&unique_type_id); - let fn_di_node = unsafe { - llvm::LLVMRustDIBuilderCreateSubroutineType( - DIB(cx), - create_DIArray(DIB(cx), &signature_di_nodes[..]), - ) - }; + let fn_di_node = DIB(cx).create_subroutine_type(&signature_di_nodes, DIFlags::FlagZero); // This is actually a function pointer, so wrap it in pointer DI. let name = compute_debuginfo_type_name(cx.tcx, fn_ty, false); @@ -325,17 +298,7 @@ fn build_subroutine_type_di_node<'ll, 'tcx>( ty::FnPtr(..) => (cx.tcx.data_layout.pointer_size, cx.tcx.data_layout.pointer_align.abi), _ => unreachable!(), }; - let di_node = unsafe { - llvm::LLVMRustDIBuilderCreatePointerType( - DIB(cx), - fn_di_node, - size.bits(), - align.bits() as u32, - 0, // Ignore DWARF address space. - name.as_c_char_ptr(), - name.len(), - ) - }; + let di_node = DIB(cx).create_pointer_type(fn_di_node, size, align, &name); DINodeCreationResult::new(di_node, false) } @@ -487,26 +450,22 @@ pub(crate) fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> // FIXME(mw): Cache this via a regular UniqueTypeId instead of an extra field in the debug context. fn recursion_marker_type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) -> &'ll DIType { *debug_context(cx).recursion_marker_type.get_or_init(move || { - unsafe { - // The choice of type here is pretty arbitrary - - // anything reading the debuginfo for a recursive - // type is going to see *something* weird - the only - // question is what exactly it will see. - // - // FIXME: the name `` does not fit the naming scheme - // of other types. - // - // FIXME: it might make sense to use an actual pointer type here - // so that debuggers can show the address. - let name = ""; - llvm::LLVMRustDIBuilderCreateBasicType( - DIB(cx), - name.as_c_char_ptr(), - name.len(), - cx.tcx.data_layout.pointer_size.bits(), - dwarf_const::DW_ATE_unsigned, - ) - } + // The choice of type here is pretty arbitrary - + // anything reading the debuginfo for a recursive + // type is going to see *something* weird - the only + // question is what exactly it will see. + // + // FIXME: the name `` does not fit the naming scheme + // of other types. + // + // FIXME: it might make sense to use an actual pointer type here + // so that debuggers can show the address. + DIB(cx).create_basic_type( + "", + cx.tcx.data_layout.pointer_size, + dwarf_const::DW_ATE_unsigned, + DIFlags::FlagZero, + ) }) } @@ -788,15 +747,7 @@ fn build_basic_type_di_node<'ll, 'tcx>( _ => bug!("debuginfo::build_basic_type_di_node - `t` is invalid type"), }; - let ty_di_node = unsafe { - llvm::LLVMRustDIBuilderCreateBasicType( - DIB(cx), - name.as_c_char_ptr(), - name.len(), - cx.size_of(t).bits(), - encoding, - ) - }; + let ty_di_node = DIB(cx).create_basic_type(name, cx.size_of(t), encoding, DIFlags::FlagZero); if !cpp_like_debuginfo { return DINodeCreationResult::new(ty_di_node, false); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs index af1d503ad6a43..785b16a3e7c38 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs @@ -226,23 +226,17 @@ pub(super) fn stub<'ll, 'tcx>( ) } } - Stub::Union => unsafe { - llvm::LLVMRustDIBuilderCreateUnionType( - DIB(cx), - containing_scope, - name.as_c_char_ptr(), - name.len(), - file_metadata, - line_number, - size.bits(), - align.bits() as u32, - flags, - Some(empty_array), - 0, - unique_type_id_str.as_c_char_ptr(), - unique_type_id_str.len(), - ) - }, + Stub::Union => DIB(cx).create_union_type( + containing_scope, + name, + file_metadata, + line_number, + size, + align, + flags, + &[], + &unique_type_id_str, + ), }; StubInfo { metadata, unique_type_id } } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 10819a53b1df8..127f9e4f63d02 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -40,6 +40,7 @@ use crate::llvm::debuginfo::{ use crate::value::Value; mod create_scope_map; +mod di_builder; mod dwarf_const; mod gdb; pub(crate) mod metadata; @@ -325,9 +326,9 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { let loc = self.lookup_debug_loc(span.lo()); let file_metadata = file_metadata(self, &loc.file); - let function_type_metadata = unsafe { + let function_type_metadata = { let fn_signature = get_function_signature(self, fn_abi); - llvm::LLVMRustDIBuilderCreateSubroutineType(DIB(self), fn_signature) + DIB(self).create_subroutine_type(&fn_signature, DIFlags::FlagZero) }; let mut name = String::with_capacity(64); @@ -420,9 +421,9 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn get_function_signature<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, - ) -> &'ll DIArray { + ) -> Vec> { if cx.sess().opts.debuginfo != DebugInfo::Full { - return create_DIArray(DIB(cx), &[]); + return vec![]; } let mut signature = Vec::with_capacity(fn_abi.args.len() + 1); @@ -463,7 +464,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { .extend(fn_abi.args.iter().map(|arg| Some(type_di_node(cx, arg.layout.ty)))); } - create_DIArray(DIB(cx), &signature[..]) + signature } fn get_template_parameters<'ll, 'tcx>( diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 3b0187b9d37b1..0681d68e558c2 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1772,6 +1772,59 @@ unsafe extern "C" { Scope: &'ll Metadata, InlinedAt: Option<&'ll Metadata>, ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateSubroutineType<'ll>( + Builder: &DIBuilder<'ll>, + File: Option<&'ll Metadata>, // (unused) + ParameterTypes: *const Option<&'ll Metadata>, + NumParameterTypes: c_uint, + Flags: DIFlags, // (optional; default is `DIFlags::FlagZero`) + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateUnionType<'ll>( + Builder: &DIBuilder<'ll>, + Scope: Option<&'ll Metadata>, + Name: *const c_uchar, + NameLen: size_t, + File: &'ll Metadata, + LineNumber: c_uint, + SizeInBits: u64, + AlignInBits: u32, + Flags: DIFlags, + Elements: *const &'ll Metadata, + NumElements: c_uint, + RunTimeLang: c_uint, // ("Objective-C runtime version"; default is 0) + UniqueId: *const c_uchar, + UniqueIdLen: size_t, + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateArrayType<'ll>( + Builder: &DIBuilder<'ll>, + Size: u64, + AlignInBits: u32, + Ty: &'ll Metadata, + Subscripts: *const &'ll Metadata, + NumSubscripts: c_uint, + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateBasicType<'ll>( + Builder: &DIBuilder<'ll>, + Name: *const c_uchar, + NameLen: size_t, + SizeInBits: u64, + Encoding: c_uint, // `LLVMDWARFTypeEncoding` + Flags: DIFlags, // (optional; default is `DIFlags::FlagZero`) + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreatePointerType<'ll>( + Builder: &DIBuilder<'ll>, + PointeeTy: &'ll Metadata, + SizeInBits: u64, + AlignInBits: u32, + AddressSpace: c_uint, + Name: *const c_uchar, + NameLen: size_t, + ) -> &'ll Metadata; } #[link(name = "llvm-wrapper", kind = "static")] @@ -2085,11 +2138,6 @@ unsafe extern "C" { SourceLen: size_t, ) -> &'a DIFile; - pub(crate) fn LLVMRustDIBuilderCreateSubroutineType<'a>( - Builder: &DIBuilder<'a>, - ParameterTypes: &'a DIArray, - ) -> &'a DICompositeType; - pub(crate) fn LLVMRustDIBuilderCreateFunction<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIDescriptor, @@ -2123,14 +2171,6 @@ unsafe extern "C" { TParam: &'a DIArray, ) -> &'a DISubprogram; - pub(crate) fn LLVMRustDIBuilderCreateBasicType<'a>( - Builder: &DIBuilder<'a>, - Name: *const c_char, - NameLen: size_t, - SizeInBits: u64, - Encoding: c_uint, - ) -> &'a DIBasicType; - pub(crate) fn LLVMRustDIBuilderCreateTypedef<'a>( Builder: &DIBuilder<'a>, Type: &'a DIBasicType, @@ -2141,16 +2181,6 @@ unsafe extern "C" { Scope: Option<&'a DIScope>, ) -> &'a DIDerivedType; - pub(crate) fn LLVMRustDIBuilderCreatePointerType<'a>( - Builder: &DIBuilder<'a>, - PointeeTy: &'a DIType, - SizeInBits: u64, - AlignInBits: u32, - AddressSpace: c_uint, - Name: *const c_char, - NameLen: size_t, - ) -> &'a DIDerivedType; - pub(crate) fn LLVMRustDIBuilderCreateStructType<'a>( Builder: &DIBuilder<'a>, Scope: Option<&'a DIDescriptor>, @@ -2248,14 +2278,6 @@ unsafe extern "C" { AlignInBits: u32, ) -> &'a DIVariable; - pub(crate) fn LLVMRustDIBuilderCreateArrayType<'a>( - Builder: &DIBuilder<'a>, - Size: u64, - AlignInBits: u32, - Ty: &'a DIType, - Subscripts: &'a DIArray, - ) -> &'a DIType; - pub(crate) fn LLVMRustDIBuilderGetOrCreateSubrange<'a>( Builder: &DIBuilder<'a>, Lo: i64, @@ -2301,22 +2323,6 @@ unsafe extern "C" { IsScoped: bool, ) -> &'a DIType; - pub(crate) fn LLVMRustDIBuilderCreateUnionType<'a>( - Builder: &DIBuilder<'a>, - Scope: Option<&'a DIScope>, - Name: *const c_char, - NameLen: size_t, - File: &'a DIFile, - LineNumber: c_uint, - SizeInBits: u64, - AlignInBits: u32, - Flags: DIFlags, - Elements: Option<&'a DIArray>, - RunTimeLang: c_uint, - UniqueId: *const c_char, - UniqueIdLen: size_t, - ) -> &'a DIType; - pub(crate) fn LLVMRustDIBuilderCreateVariantPart<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIScope, diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index b8cef6a7e250e..8610ff3454809 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1009,13 +1009,6 @@ LLVMRustDIBuilderCreateFile(LLVMDIBuilderRef Builder, const char *Filename, CSInfo, oSource)); } -extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateSubroutineType(LLVMDIBuilderRef Builder, - LLVMMetadataRef ParameterTypes) { - return wrap(unwrap(Builder)->createSubroutineType( - DITypeRefArray(unwrap(ParameterTypes)))); -} - extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, const char *LinkageName, size_t LinkageNameLen, @@ -1054,14 +1047,6 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMethod( return wrap(Sub); } -extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateBasicType(LLVMDIBuilderRef Builder, const char *Name, - size_t NameLen, uint64_t SizeInBits, - unsigned Encoding) { - return wrap(unwrap(Builder)->createBasicType(StringRef(Name, NameLen), - SizeInBits, Encoding)); -} - extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTypedef(LLVMDIBuilderRef Builder, LLVMMetadataRef Type, const char *Name, size_t NameLen, @@ -1072,15 +1057,6 @@ LLVMRustDIBuilderCreateTypedef(LLVMDIBuilderRef Builder, LLVMMetadataRef Type, LineNo, unwrapDIPtr(Scope))); } -extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType( - LLVMDIBuilderRef Builder, LLVMMetadataRef PointeeTy, uint64_t SizeInBits, - uint32_t AlignInBits, unsigned AddressSpace, const char *Name, - size_t NameLen) { - return wrap(unwrap(Builder)->createPointerType( - unwrapDI(PointeeTy), SizeInBits, AlignInBits, AddressSpace, - StringRef(Name, NameLen))); -} - extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, @@ -1201,15 +1177,6 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable( } } -extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateArrayType(LLVMDIBuilderRef Builder, uint64_t Size, - uint32_t AlignInBits, LLVMMetadataRef Ty, - LLVMMetadataRef Subscripts) { - return wrap(unwrap(Builder)->createArrayType( - Size, AlignInBits, unwrapDI(Ty), - DINodeArray(unwrapDI(Subscripts)))); -} - extern "C" LLVMMetadataRef LLVMRustDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef Builder, int64_t Lo, int64_t Count) { @@ -1258,19 +1225,6 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType( /* RunTimeLang */ 0, "", IsScoped)); } -extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType( - LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, - size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, - uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags, - LLVMMetadataRef Elements, unsigned RunTimeLang, const char *UniqueId, - size_t UniqueIdLen) { - return wrap(unwrap(Builder)->createUnionType( - unwrapDI(Scope), StringRef(Name, NameLen), - unwrapDI(File), LineNumber, SizeInBits, AlignInBits, - fromRust(Flags), DINodeArray(unwrapDI(Elements)), RunTimeLang, - StringRef(UniqueId, UniqueIdLen))); -} - extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef Ty) {