diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs index 07bd0f4d1c171..59a807e3879ad 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs @@ -135,7 +135,7 @@ fn make_mir_scope<'ll, 'tcx>( }) } None => unsafe { - llvm::LLVMRustDIBuilderCreateLexicalBlock( + llvm::LLVMDIBuilderCreateLexicalBlock( DIB(cx), parent_scope.dbg_scope, file_metadata, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 592752540224f..54416fa9f9157 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -4,7 +4,7 @@ use std::hash::{Hash, Hasher}; use std::path::{Path, PathBuf}; use std::{iter, ptr}; -use libc::{c_char, c_longlong, c_uint}; +use libc::{c_char, c_uint}; use rustc_abi::{Align, Size}; use rustc_codegen_ssa::debuginfo::type_names::{VTableNameKind, cpp_like_debuginfo}; use rustc_codegen_ssa::traits::*; @@ -27,9 +27,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::metadata::type_map::build_type_with_children; use crate::debuginfo::utils::{WidePtrKind, wide_pointer_kind}; @@ -123,21 +121,26 @@ fn build_fixed_size_array_di_node<'ll, 'tcx>( let (size, align) = cx.size_and_align_of(array_type); - let upper_bound = len - .try_to_target_usize(cx.tcx) - .expect("expected monomorphic const in codegen") as c_longlong; + let upper_bound = + len.try_to_target_usize(cx.tcx).expect("expected monomorphic const in codegen"); - let subrange = - unsafe { Some(llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound)) }; + let subrange = unsafe { + llvm::LLVMDIBuilderGetOrCreateSubrange( + DIB(cx), + /* LowerBound */ 0i64, + /* Count */ upper_bound as i64, + ) + }; - let subscripts = create_DIArray(DIB(cx), &[subrange]); + let subscripts = &[subrange]; let di_node = unsafe { - llvm::LLVMRustDIBuilderCreateArrayType( + llvm::LLVMDIBuilderCreateArrayType( DIB(cx), size.bits(), align.bits() as u32, element_type_di_node, - subscripts, + subscripts.as_ptr(), + subscripts.len() as c_uint, ) }; @@ -182,13 +185,13 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>( ); let di_node = unsafe { - llvm::LLVMRustDIBuilderCreatePointerType( + llvm::LLVMDIBuilderCreatePointerType( 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.as_ptr(), ptr_type_debuginfo_name.len(), ) }; @@ -240,7 +243,7 @@ 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( + llvm::LLVMDIBuilderCreatePointerType( DIB(cx), pointee_type_di_node, addr_field.size.bits(), @@ -325,9 +328,12 @@ 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( + llvm::LLVMDIBuilderCreateSubroutineType( DIB(cx), - create_DIArray(DIB(cx), &signature_di_nodes[..]), + /* File (unused) */ None, + signature_di_nodes.as_ptr(), + signature_di_nodes.len() as c_uint, + DIFlags::FlagZero, ) }; @@ -342,13 +348,13 @@ fn build_subroutine_type_di_node<'ll, 'tcx>( _ => unreachable!(), }; let di_node = unsafe { - llvm::LLVMRustDIBuilderCreatePointerType( + llvm::LLVMDIBuilderCreatePointerType( DIB(cx), fn_di_node, size, align, 0, // Ignore DWARF address space. - name.as_c_char_ptr(), + name.as_ptr(), name.len(), ) }; @@ -515,12 +521,13 @@ fn recursion_marker_type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) -> &'ll D // FIXME: it might make sense to use an actual pointer type here // so that debuggers can show the address. let name = ""; - llvm::LLVMRustDIBuilderCreateBasicType( + llvm::LLVMDIBuilderCreateBasicType( DIB(cx), - name.as_c_char_ptr(), + name.as_ptr(), name.len(), cx.tcx.data_layout.pointer_size.bits(), DW_ATE_unsigned, + DIFlags::FlagZero, ) } }) @@ -803,12 +810,13 @@ fn build_basic_type_di_node<'ll, 'tcx>( }; let ty_di_node = unsafe { - llvm::LLVMRustDIBuilderCreateBasicType( + llvm::LLVMDIBuilderCreateBasicType( DIB(cx), - name.as_c_char_ptr(), + name.as_ptr(), name.len(), cx.size_of(t).bits(), encoding, + DIFlags::FlagZero, ) }; @@ -824,14 +832,15 @@ fn build_basic_type_di_node<'ll, 'tcx>( }; let typedef_di_node = unsafe { - llvm::LLVMRustDIBuilderCreateTypedef( + llvm::LLVMDIBuilderCreateTypedef( DIB(cx), ty_di_node, - typedef_name.as_c_char_ptr(), + typedef_name.as_ptr(), typedef_name.len(), unknown_file_metadata(cx), - 0, - None, + /* LineNo */ 0u32, + /* Scope */ None, + /* AlignInBits (optional) */ 0u32, ) }; @@ -945,7 +954,7 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>( unsafe { let compile_unit_file = llvm::LLVMRustDIBuilderCreateFile( - debug_context.builder, + debug_context.builder.as_ref(), name_in_debuginfo.as_c_char_ptr(), name_in_debuginfo.len(), work_dir.as_c_char_ptr(), @@ -958,7 +967,7 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>( ); let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit( - debug_context.builder, + debug_context.builder.as_ref(), DW_LANG_RUST, compile_unit_file, producer.as_c_char_ptr(), @@ -999,10 +1008,10 @@ fn build_field_di_node<'ll, 'tcx>( (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER) }; unsafe { - llvm::LLVMRustDIBuilderCreateMemberType( + llvm::LLVMDIBuilderCreateMemberType( DIB(cx), owner, - name.as_c_char_ptr(), + name.as_ptr(), name.len(), file_metadata, line_number, @@ -1630,7 +1639,14 @@ pub(crate) fn extend_scope_to_file<'ll>( file: &SourceFile, ) -> &'ll DILexicalBlock { let file_metadata = file_metadata(cx, file); - unsafe { llvm::LLVMRustDIBuilderCreateLexicalBlockFile(DIB(cx), scope_metadata, file_metadata) } + unsafe { + llvm::LLVMDIBuilderCreateLexicalBlockFile( + DIB(cx), + scope_metadata, + file_metadata, + /* Discriminator (default) */ 0u32, + ) + } } fn tuple_field_name(field_index: usize) -> Cow<'static, str> { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs index d374767f187d8..970dcd1d24237 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, AdtDef, CoroutineArgs, CoroutineArgsExt, Ty}; use smallvec::smallvec; -use crate::common::{AsCCharPtr, CodegenCx}; +use crate::common::CodegenCx; use crate::debuginfo::metadata::enums::DiscrResult; use crate::debuginfo::metadata::type_map::{self, Stub, UniqueTypeId}; use crate::debuginfo::metadata::{ @@ -381,10 +381,10 @@ fn build_single_variant_union_fields<'ll, 'tcx>( None, ), unsafe { - llvm::LLVMRustDIBuilderCreateStaticMemberType( + llvm::LLVMDIBuilderCreateStaticMemberType( DIB(cx), enum_type_di_node, - TAG_FIELD_NAME.as_c_char_ptr(), + TAG_FIELD_NAME.as_ptr(), TAG_FIELD_NAME.len(), unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, @@ -571,10 +571,10 @@ fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>( let build_assoc_const = |name: &str, type_di_node: &'ll DIType, value: u64, align: Align| unsafe { - llvm::LLVMRustDIBuilderCreateStaticMemberType( + llvm::LLVMDIBuilderCreateStaticMemberType( DIB(cx), wrapper_struct_type_di_node, - name.as_c_char_ptr(), + name.as_ptr(), name.len(), unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, @@ -829,10 +829,10 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>( // the build_field_di_node() function does not support specifying a source location, // which is something that we don't do anywhere else. unsafe { - llvm::LLVMRustDIBuilderCreateMemberType( + llvm::LLVMDIBuilderCreateMemberType( DIB(cx), enum_type_di_node, - field_name.as_c_char_ptr(), + field_name.as_ptr(), field_name.len(), file_di_node, line_number, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs index 241bf167a81a0..58cbc241f24f4 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs @@ -366,10 +366,10 @@ fn build_discr_member_di_node<'ll, 'tcx>( let (size, align) = cx.size_and_align_of(tag_base_type); unsafe { - Some(llvm::LLVMRustDIBuilderCreateMemberType( + Some(llvm::LLVMDIBuilderCreateMemberType( DIB(cx), containing_scope, - tag_name.as_c_char_ptr(), + tag_name.as_ptr(), tag_name.len(), unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, 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 a37e719d43f2b..703f05a2668a0 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs @@ -9,7 +9,7 @@ use rustc_middle::bug; use rustc_middle::ty::{self, PolyExistentialTraitRef, Ty, TyCtxt}; use super::{DefinitionLocation, SmallVec, UNKNOWN_LINE_NUMBER, unknown_file_metadata}; -use crate::common::{AsCCharPtr, CodegenCx}; +use crate::common::CodegenCx; use crate::debuginfo::utils::{DIB, create_DIArray, debug_context}; use crate::llvm::debuginfo::{DIFlags, DIScope, DIType}; use crate::llvm::{self}; @@ -191,7 +191,6 @@ pub(super) fn stub<'ll, 'tcx>( containing_scope: Option<&'ll DIScope>, flags: DIFlags, ) -> StubInfo<'ll, 'tcx> { - let empty_array = create_DIArray(DIB(cx), &[]); let unique_type_id_str = unique_type_id.generate_unique_id_string(cx.tcx); let (file_metadata, line_number) = if let Some(def_location) = def_location { @@ -207,39 +206,41 @@ pub(super) fn stub<'ll, 'tcx>( _ => None, }; unsafe { - llvm::LLVMRustDIBuilderCreateStructType( + llvm::LLVMDIBuilderCreateStructType( DIB(cx), containing_scope, - name.as_c_char_ptr(), + name.as_ptr(), name.len(), file_metadata, line_number, size.bits(), align.bits() as u32, flags, - None, - empty_array, - 0, + /* DerivedFrom */ None, + /* Elements */ (&[]).as_ptr(), + /* NumElements */ 0u32, + /* RunTimeLang */ 0u32, vtable_holder, - unique_type_id_str.as_c_char_ptr(), + unique_type_id_str.as_ptr(), unique_type_id_str.len(), ) } } Stub::Union => unsafe { - llvm::LLVMRustDIBuilderCreateUnionType( + llvm::LLVMDIBuilderCreateUnionType( DIB(cx), containing_scope, - name.as_c_char_ptr(), + name.as_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(), + /* Elements */ (&[]).as_ptr(), + /* NumElements */ 0u32, + /* RunTimeLang */ 0u32, + unique_type_id_str.as_ptr(), unique_type_id_str.len(), ) }, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index a8fdfbed59244..f9053811bb161 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -34,7 +34,7 @@ use crate::builder::Builder; use crate::common::{AsCCharPtr, CodegenCx}; use crate::llvm; use crate::llvm::debuginfo::{ - DIArray, DIBuilder, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope, DIType, + DIArray, DIBuilderBox, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope, DIType, DIVariable, }; use crate::value::Value; @@ -53,10 +53,20 @@ const DW_TAG_auto_variable: c_uint = 0x100; #[allow(non_upper_case_globals)] const DW_TAG_arg_variable: c_uint = 0x101; +// `DW_OP_*` values taken from: +// - `llvm/include/llvm/BinaryFormat/Dwarf.def` +// - `llvm/include/llvm/BinaryFormat/Dwarf.h` +#[allow(non_upper_case_globals)] +const DW_OP_deref: u64 = 0x06; +#[allow(non_upper_case_globals)] +const DW_OP_plus_uconst: u64 = 0x23; +#[allow(non_upper_case_globals)] +const DW_OP_LLVM_fragment: u64 = 0x1000; + /// A context object for maintaining all state needed by the debuginfo module. pub(crate) struct CodegenUnitDebugContext<'ll, 'tcx> { llmod: &'ll llvm::Module, - builder: &'ll mut DIBuilder<'ll>, + builder: DIBuilderBox<'ll>, created_files: RefCell, &'ll DIFile>>, type_map: metadata::TypeMap<'ll, 'tcx>, @@ -64,18 +74,10 @@ pub(crate) struct CodegenUnitDebugContext<'ll, 'tcx> { recursion_marker_type: OnceCell<&'ll DIType>, } -impl Drop for CodegenUnitDebugContext<'_, '_> { - fn drop(&mut self) { - unsafe { - llvm::LLVMRustDIBuilderDispose(&mut *(self.builder as *mut _)); - } - } -} - impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> { pub(crate) fn new(llmod: &'ll llvm::Module) -> Self { debug!("CodegenUnitDebugContext::new"); - let builder = unsafe { llvm::LLVMRustDIBuilderCreate(llmod) }; + let builder = DIBuilderBox::new(llmod); // DIBuilder inherits context from the module, so we'd better use the same one CodegenUnitDebugContext { llmod, @@ -88,7 +90,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> { } pub(crate) fn finalize(&self, sess: &Session) { - unsafe { llvm::LLVMRustDIBuilderFinalize(self.builder) }; + unsafe { llvm::LLVMDIBuilderFinalize(self.builder.as_ref()) }; if !sess.target.is_like_msvc { // Debuginfo generation in LLVM by default uses a higher // version of dwarf than macOS currently understands. We can @@ -154,40 +156,38 @@ impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> { fragment: Option>, ) { // Convert the direct and indirect offsets and fragment byte range to address ops. - // FIXME(eddyb) use `const`s instead of getting the values via FFI, - // the values should match the ones in the DWARF standard anyway. - let op_deref = || unsafe { llvm::LLVMRustDIBuilderCreateOpDeref() }; - let op_plus_uconst = || unsafe { llvm::LLVMRustDIBuilderCreateOpPlusUconst() }; - let op_llvm_fragment = || unsafe { llvm::LLVMRustDIBuilderCreateOpLLVMFragment() }; let mut addr_ops = SmallVec::<[u64; 8]>::new(); if direct_offset.bytes() > 0 { - addr_ops.push(op_plus_uconst()); + addr_ops.push(DW_OP_plus_uconst); addr_ops.push(direct_offset.bytes() as u64); } for &offset in indirect_offsets { - addr_ops.push(op_deref()); + addr_ops.push(DW_OP_deref); if offset.bytes() > 0 { - addr_ops.push(op_plus_uconst()); + addr_ops.push(DW_OP_plus_uconst); addr_ops.push(offset.bytes() as u64); } } if let Some(fragment) = fragment { // `DW_OP_LLVM_fragment` takes as arguments the fragment's // offset and size, both of them in bits. - addr_ops.push(op_llvm_fragment()); + addr_ops.push(DW_OP_LLVM_fragment); addr_ops.push(fragment.start.bits() as u64); addr_ops.push((fragment.end - fragment.start).bits() as u64); } + let expr = unsafe { + llvm::LLVMDIBuilderCreateExpression(DIB(self.cx()), addr_ops.as_ptr(), addr_ops.len()) + }; + unsafe { // FIXME(eddyb) replace `llvm.dbg.declare` with `llvm.dbg.addr`. - llvm::LLVMRustDIBuilderInsertDeclareAtEnd( + llvm::LLVMRustDIBuilderInsertDeclareRecordAtEnd( DIB(self.cx()), variable_alloca, dbg_var, - addr_ops.as_ptr(), - addr_ops.len() as c_uint, + expr, dbg_loc, self.llbb(), ); @@ -327,7 +327,13 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { let function_type_metadata = unsafe { let fn_signature = get_function_signature(self, fn_abi); - llvm::LLVMRustDIBuilderCreateSubroutineType(DIB(self), fn_signature) + llvm::LLVMDIBuilderCreateSubroutineType( + DIB(self), + /* File (unused) */ None, + fn_signature.as_ptr(), + fn_signature.len() as c_uint, + DIFlags::FlagZero, + ) }; let mut name = String::with_capacity(64); @@ -420,9 +426,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 +469,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>( @@ -578,7 +584,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { (line, col) }; - unsafe { llvm::LLVMRustDIBuilderCreateDebugLocation(line, col, scope, inlined_at) } + unsafe { llvm::LLVMDIBuilderCreateDebugLocation(self.llcx, line, col, scope, inlined_at) } } fn create_vtable_debuginfo( diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs b/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs index 33d9bc238903e..b4d639368b005 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs @@ -5,7 +5,7 @@ use rustc_hir::def_id::DefId; use rustc_middle::ty::{self, Instance}; use super::utils::{DIB, debug_context}; -use crate::common::{AsCCharPtr, CodegenCx}; +use crate::common::CodegenCx; use crate::llvm; use crate::llvm::debuginfo::DIScope; @@ -33,12 +33,12 @@ pub(crate) fn item_namespace<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'l }; let scope = unsafe { - llvm::LLVMRustDIBuilderCreateNameSpace( + llvm::LLVMDIBuilderCreateNameSpace( DIB(cx), parent_scope, - namespace_name_string.as_c_char_ptr(), + namespace_name_string.as_ptr(), namespace_name_string.len(), - false, // ExportSymbols (only relevant for C++ anonymous namespaces) + llvm::False, // ExportSymbols (only relevant for C++ anonymous namespaces) ) }; diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs index 6e84129347787..7e1e49310f61c 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs @@ -28,7 +28,7 @@ pub(crate) fn create_DIArray<'ll>( builder: &DIBuilder<'ll>, arr: &[Option<&'ll DIDescriptor>], ) -> &'ll DIArray { - unsafe { llvm::LLVMRustDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32) } + unsafe { llvm::LLVMDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len()) } } #[inline] @@ -41,7 +41,7 @@ pub(crate) fn debug_context<'a, 'll, 'tcx>( #[inline] #[allow(non_snake_case)] pub(crate) fn DIB<'a, 'll>(cx: &'a CodegenCx<'ll, '_>) -> &'a DIBuilder<'ll> { - cx.dbg_cx.as_ref().unwrap().builder + cx.dbg_cx.as_ref().unwrap().builder.as_ref() } pub(crate) fn get_namespace_for_item<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope { diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 8b4523bd252b3..7aa8ea17e855f 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1,3 +1,15 @@ +//! Bindings to the LLVM-C API (`LLVM*`), and to our own `extern "C"` wrapper +//! functions around the unstable LLVM C++ API (`LLVMRust*`). +//! +//! ## Passing pointer/length strings as `*const c_uchar` +//! +//! Normally it's a good idea for Rust-side bindings to match the corresponding +//! C-side function declarations as closely as possible. But when passing `&str` +//! or `&[u8]` data as a pointer/length pair, it's more convenient to declare +//! the Rust-side pointer as `*const c_uchar` instead of `*const c_char`. +//! Both pointer types have the same ABI, and using `*const c_uchar` avoids +//! the need for an extra cast from `*const u8` on the Rust side. + #![allow(non_camel_case_types)] #![allow(non_upper_case_globals)] @@ -5,17 +17,17 @@ use std::fmt::Debug; use std::marker::PhantomData; use std::ptr; -use libc::{c_char, c_int, c_uint, c_ulonglong, c_void, size_t}; +use libc::{c_char, c_int, c_uchar, c_uint, c_ulonglong, c_void, size_t}; use rustc_macros::TryFromU32; use rustc_target::spec::SymbolVisibility; use super::RustString; use super::debuginfo::{ - DIArray, DIBasicType, DIBuilder, DICompositeType, DIDerivedType, DIDescriptor, DIEnumerator, - DIFile, DIFlags, DIGlobalVariableExpression, DILexicalBlock, DILocation, DINameSpace, - DISPFlags, DIScope, DISubprogram, DISubrange, DITemplateTypeParameter, DIType, DIVariable, - DebugEmissionKind, DebugNameTableKind, + DIArray, DIBuilder, DIDerivedType, DIDescriptor, DIEnumerator, DIFile, DIFlags, + DIGlobalVariableExpression, DILocation, DISPFlags, DIScope, DISubprogram, + DITemplateTypeParameter, DIType, DIVariable, DebugEmissionKind, DebugNameTableKind, }; +use crate::llvm; pub type Bool = c_uint; @@ -723,13 +735,40 @@ pub type DiagnosticHandlerTy = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void pub type InlineAsmDiagHandlerTy = unsafe extern "C" fn(&SMDiagnostic, *const c_void, c_uint); pub mod debuginfo { + use std::ptr; + use bitflags::bitflags; use super::{InvariantOpaque, Metadata}; + use crate::llvm::{self, Module}; #[repr(C)] pub struct DIBuilder<'a>(InvariantOpaque<'a>); + pub(crate) struct DIBuilderBox<'ll> { + raw: ptr::NonNull>, + } + + impl<'ll> DIBuilderBox<'ll> { + pub(crate) fn new(llmod: &'ll Module) -> Self { + let raw = unsafe { llvm::LLVMCreateDIBuilder(llmod) }; + let raw = ptr::NonNull::new(raw).unwrap(); + Self { raw } + } + + pub(crate) fn as_ref(&self) -> &DIBuilder<'ll> { + // SAFETY: This is an owning pointer, so `&DIBuilder` is valid + // for as long as `&self` is. + unsafe { self.raw.as_ref() } + } + } + + impl<'ll> Drop for DIBuilderBox<'ll> { + fn drop(&mut self) { + unsafe { llvm::LLVMDisposeDIBuilder(self.raw) }; + } + } + pub type DIDescriptor = Metadata; pub type DILocation = Metadata; pub type DIScope = DIDescriptor; @@ -748,8 +787,8 @@ pub mod debuginfo { pub type DIEnumerator = DIDescriptor; pub type DITemplateTypeParameter = DIDescriptor; - // These values **must** match with LLVMRustDIFlags!! bitflags! { + /// Must match the layout of `LLVMDIFlags` in the LLVM-C API. #[repr(transparent)] #[derive(Clone, Copy, Default)] pub struct DIFlags: u32 { @@ -759,7 +798,7 @@ pub mod debuginfo { const FlagPublic = 3; const FlagFwdDecl = (1 << 2); const FlagAppleBlock = (1 << 3); - const FlagBlockByrefStruct = (1 << 4); + const FlagReservedBit4 = (1 << 4); const FlagVirtual = (1 << 5); const FlagArtificial = (1 << 6); const FlagExplicit = (1 << 7); @@ -770,10 +809,20 @@ pub mod debuginfo { const FlagStaticMember = (1 << 12); const FlagLValueReference = (1 << 13); const FlagRValueReference = (1 << 14); - const FlagExternalTypeRef = (1 << 15); + const FlagReserved = (1 << 15); + const FlagSingleInheritance = (1 << 16); + const FlagMultipleInheritance = (2 << 16); + const FlagVirtualInheritance = (3 << 16); const FlagIntroducedVirtual = (1 << 18); const FlagBitField = (1 << 19); const FlagNoReturn = (1 << 20); + const FlagTypePassByValue = (1 << 22); + const FlagTypePassByReference = (1 << 23); + const FlagEnumClass = (1 << 24); + const FlagThunk = (1 << 25); + const FlagNonTrivial = (1 << 26); + const FlagBigEndian = (1 << 27); + const FlagLittleEndian = (1 << 28); } } @@ -1587,6 +1636,178 @@ unsafe extern "C" { ) -> &'a Value; } +// FFI bindings for `DIBuilder` functions in the LLVM-C API. +// Try to keep these in the same order as in `llvm/include/llvm-c/DebugInfo.h`. +// +// FIXME(#134001): Audit all `Option` parameters, especially in lists, to check +// that they really are nullable on the C/C++ side. LLVM doesn't appear to +// actually document which ones are nullable. +unsafe extern "C" { + pub(crate) fn LLVMCreateDIBuilder<'ll>(M: &'ll Module) -> *mut DIBuilder<'ll>; + pub(crate) fn LLVMDisposeDIBuilder<'ll>(Builder: ptr::NonNull>); + + pub(crate) fn LLVMDIBuilderFinalize<'ll>(Builder: &DIBuilder<'ll>); + + pub(crate) fn LLVMDIBuilderCreateNameSpace<'ll>( + Builder: &DIBuilder<'ll>, + ParentScope: Option<&'ll Metadata>, + Name: *const c_uchar, + NameLen: size_t, + ExportSymbols: llvm::Bool, + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateLexicalBlock<'ll>( + Builder: &DIBuilder<'ll>, + Scope: &'ll Metadata, + File: &'ll Metadata, + Line: c_uint, + Column: c_uint, + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateLexicalBlockFile<'ll>( + Builder: &DIBuilder<'ll>, + Scope: &'ll Metadata, + File: &'ll Metadata, + Discriminator: c_uint, // (optional "DWARF path discriminator"; default is 0) + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateDebugLocation<'ll>( + Ctx: &'ll Context, + Line: c_uint, + Column: c_uint, + 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, // (optional; 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; + + pub(crate) fn LLVMDIBuilderCreateStructType<'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, + DerivedFrom: Option<&'ll Metadata>, + Elements: *const &'ll Metadata, + NumElements: c_uint, + RunTimeLang: c_uint, + VTableHolder: Option<&'ll Metadata>, + UniqueId: *const c_uchar, + UniqueIdLen: size_t, + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateMemberType<'ll>( + Builder: &DIBuilder<'ll>, + Scope: &'ll Metadata, + Name: *const c_uchar, + NameLen: size_t, + File: &'ll Metadata, + LineNo: c_uint, + SizeInBits: u64, + AlignInBits: u32, + OffsetInBits: u64, + Flags: DIFlags, + Ty: &'ll Metadata, + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateStaticMemberType<'ll>( + Builder: &DIBuilder<'ll>, + Scope: &'ll Metadata, + Name: *const c_uchar, + NameLen: size_t, + File: &'ll Metadata, + LineNumber: c_uint, + Type: &'ll Metadata, + Flags: DIFlags, + ConstantVal: Option<&'ll Value>, + AlignInBits: u32, + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateTypedef<'ll>( + Builder: &DIBuilder<'ll>, + Type: &'ll Metadata, + Name: *const c_uchar, + NameLen: size_t, + File: &'ll Metadata, + LineNo: c_uint, + Scope: Option<&'ll Metadata>, + AlignInBits: u32, // (optional; default is 0) + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderGetOrCreateSubrange<'ll>( + Builder: &DIBuilder<'ll>, + LowerBound: i64, + Count: i64, + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderGetOrCreateArray<'ll>( + Builder: &DIBuilder<'ll>, + Data: *const Option<&'ll Metadata>, + NumElements: size_t, + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateExpression<'ll>( + Builder: &DIBuilder<'ll>, + Addr: *const u64, + Length: size_t, + ) -> &'ll Metadata; +} + #[link(name = "llvm-wrapper", kind = "static")] unsafe extern "C" { pub fn LLVMRustInstallErrorHandlers(); @@ -1854,12 +2075,9 @@ unsafe extern "C" { ValueLen: size_t, ); - pub fn LLVMRustDIBuilderCreate(M: &Module) -> &mut DIBuilder<'_>; - - pub fn LLVMRustDIBuilderDispose<'a>(Builder: &'a mut DIBuilder<'a>); - - pub fn LLVMRustDIBuilderFinalize(Builder: &DIBuilder<'_>); - + /// As of LLVM 18/19, the corresponding LLVM-C function is hard-coded to + /// assume `DebugNameTableKind = Default`, but we sometimes want to pass + /// `None`. pub fn LLVMRustDIBuilderCreateCompileUnit<'a>( Builder: &DIBuilder<'a>, Lang: c_uint, @@ -1877,6 +2095,8 @@ unsafe extern "C" { DebugNameTableKind: DebugNameTableKind, ) -> &'a DIDescriptor; + /// As of LLVM 18/19, the corresponding LLVM-C function is hard-coded to + /// assume that there is no optional checksum or optional source text. pub fn LLVMRustDIBuilderCreateFile<'a>( Builder: &DIBuilder<'a>, Filename: *const c_char, @@ -1890,11 +2110,8 @@ unsafe extern "C" { SourceLen: size_t, ) -> &'a DIFile; - pub fn LLVMRustDIBuilderCreateSubroutineType<'a>( - Builder: &DIBuilder<'a>, - ParameterTypes: &'a DIArray, - ) -> &'a DICompositeType; - + /// As of LLVM 18/19, the corresponding LLVM-C function only supports a + /// subset of `DISPFlags`. pub fn LLVMRustDIBuilderCreateFunction<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIDescriptor, @@ -1913,6 +2130,7 @@ unsafe extern "C" { Decl: Option<&'a DIDescriptor>, ) -> &'a DISubprogram; + /// As of LLVM 18/19, there is no corresponding LLVM-C function. pub fn LLVMRustDIBuilderCreateMethod<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIDescriptor, @@ -1928,66 +2146,7 @@ unsafe extern "C" { TParam: &'a DIArray, ) -> &'a DISubprogram; - pub fn LLVMRustDIBuilderCreateBasicType<'a>( - Builder: &DIBuilder<'a>, - Name: *const c_char, - NameLen: size_t, - SizeInBits: u64, - Encoding: c_uint, - ) -> &'a DIBasicType; - - pub fn LLVMRustDIBuilderCreateTypedef<'a>( - Builder: &DIBuilder<'a>, - Type: &'a DIBasicType, - Name: *const c_char, - NameLen: size_t, - File: &'a DIFile, - LineNo: c_uint, - Scope: Option<&'a DIScope>, - ) -> &'a DIDerivedType; - - pub 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 fn LLVMRustDIBuilderCreateStructType<'a>( - Builder: &DIBuilder<'a>, - Scope: Option<&'a DIDescriptor>, - Name: *const c_char, - NameLen: size_t, - File: &'a DIFile, - LineNumber: c_uint, - SizeInBits: u64, - AlignInBits: u32, - Flags: DIFlags, - DerivedFrom: Option<&'a DIType>, - Elements: &'a DIArray, - RunTimeLang: c_uint, - VTableHolder: Option<&'a DIType>, - UniqueId: *const c_char, - UniqueIdLen: size_t, - ) -> &'a DICompositeType; - - pub fn LLVMRustDIBuilderCreateMemberType<'a>( - Builder: &DIBuilder<'a>, - Scope: &'a DIDescriptor, - Name: *const c_char, - NameLen: size_t, - File: &'a DIFile, - LineNo: c_uint, - SizeInBits: u64, - AlignInBits: u32, - OffsetInBits: u64, - Flags: DIFlags, - Ty: &'a DIType, - ) -> &'a DIDerivedType; - + /// As of LLVM 18/19, there is no corresponding LLVM-C function. pub fn LLVMRustDIBuilderCreateVariantMemberType<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIScope, @@ -2003,33 +2162,7 @@ unsafe extern "C" { Ty: &'a DIType, ) -> &'a DIType; - pub fn LLVMRustDIBuilderCreateStaticMemberType<'a>( - Builder: &DIBuilder<'a>, - Scope: &'a DIDescriptor, - Name: *const c_char, - NameLen: size_t, - File: &'a DIFile, - LineNo: c_uint, - Ty: &'a DIType, - Flags: DIFlags, - val: Option<&'a Value>, - AlignInBits: u32, - ) -> &'a DIDerivedType; - - pub fn LLVMRustDIBuilderCreateLexicalBlock<'a>( - Builder: &DIBuilder<'a>, - Scope: &'a DIScope, - File: &'a DIFile, - Line: c_uint, - Col: c_uint, - ) -> &'a DILexicalBlock; - - pub fn LLVMRustDIBuilderCreateLexicalBlockFile<'a>( - Builder: &DIBuilder<'a>, - Scope: &'a DIScope, - File: &'a DIFile, - ) -> &'a DILexicalBlock; - + /// FIXME(#134001): This doesn't map cleanly to any single LLVM-C function. pub fn LLVMRustDIBuilderCreateStaticVariable<'a>( Builder: &DIBuilder<'a>, Context: Option<&'a DIScope>, @@ -2046,6 +2179,7 @@ unsafe extern "C" { AlignInBits: u32, ) -> &'a DIGlobalVariableExpression; + /// FIXME(#134001): This doesn't map cleanly to any single LLVM-C function. pub fn LLVMRustDIBuilderCreateVariable<'a>( Builder: &DIBuilder<'a>, Tag: c_uint, @@ -2061,36 +2195,19 @@ unsafe extern "C" { AlignInBits: u32, ) -> &'a DIVariable; - pub fn LLVMRustDIBuilderCreateArrayType<'a>( - Builder: &DIBuilder<'a>, - Size: u64, - AlignInBits: u32, - Ty: &'a DIType, - Subscripts: &'a DIArray, - ) -> &'a DIType; - - pub fn LLVMRustDIBuilderGetOrCreateSubrange<'a>( - Builder: &DIBuilder<'a>, - Lo: i64, - Count: i64, - ) -> &'a DISubrange; - - pub fn LLVMRustDIBuilderGetOrCreateArray<'a>( - Builder: &DIBuilder<'a>, - Ptr: *const Option<&'a DIDescriptor>, - Count: c_uint, - ) -> &'a DIArray; - - pub fn LLVMRustDIBuilderInsertDeclareAtEnd<'a>( - Builder: &DIBuilder<'a>, - Val: &'a Value, - VarInfo: &'a DIVariable, - AddrOps: *const u64, - AddrOpsCount: c_uint, - DL: &'a DILocation, - InsertAtEnd: &'a BasicBlock, + /// Mostly equivalent to `LLVMDIBuilderInsertDeclareRecordAtEnd` in LLVM 19, + /// except that this works on LLVM 18 and also doesn't return a value. + pub(crate) fn LLVMRustDIBuilderInsertDeclareRecordAtEnd<'ll>( + Builder: &DIBuilder<'ll>, + Storage: &'ll Value, + VarInfo: &'ll Metadata, + Expr: &'ll Metadata, + DebugLoc: &'ll Metadata, + Block: &'ll BasicBlock, ); + /// As of LLVM 18/19, the corresponding LLVM-C function is hard-coded to + /// assume a 64-bit value. pub fn LLVMRustDIBuilderCreateEnumerator<'a>( Builder: &DIBuilder<'a>, Name: *const c_char, @@ -2100,6 +2217,8 @@ unsafe extern "C" { IsUnsigned: bool, ) -> &'a DIEnumerator; + /// As of LLVM 18/19, the corresponding LLVM-C function is hard-coded to + /// assume `IsScoped = false`, but we want to pass `true`. pub fn LLVMRustDIBuilderCreateEnumerationType<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIScope, @@ -2114,22 +2233,7 @@ unsafe extern "C" { IsScoped: bool, ) -> &'a DIType; - pub 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; - + /// As of LLVM 18/19, there is no corresponding LLVM-C function. pub fn LLVMRustDIBuilderCreateVariantPart<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIScope, @@ -2146,6 +2250,7 @@ unsafe extern "C" { UniqueIdLen: size_t, ) -> &'a DIDerivedType; + /// As of LLVM 18/19, there is no corresponding LLVM-C function. pub fn LLVMRustDIBuilderCreateTemplateTypeParameter<'a>( Builder: &DIBuilder<'a>, Scope: Option<&'a DIScope>, @@ -2154,14 +2259,7 @@ unsafe extern "C" { Ty: &'a DIType, ) -> &'a DITemplateTypeParameter; - pub fn LLVMRustDIBuilderCreateNameSpace<'a>( - Builder: &DIBuilder<'a>, - Scope: Option<&'a DIScope>, - Name: *const c_char, - NameLen: size_t, - ExportSymbols: bool, - ) -> &'a DINameSpace; - + /// As of LLVM 18/19, there is no corresponding LLVM-C function. pub fn LLVMRustDICompositeTypeReplaceArrays<'a>( Builder: &DIBuilder<'a>, CompositeType: &'a DIType, @@ -2169,19 +2267,11 @@ unsafe extern "C" { Params: Option<&'a DIArray>, ); - pub fn LLVMRustDIBuilderCreateDebugLocation<'a>( - Line: c_uint, - Column: c_uint, - Scope: &'a DIScope, - InlinedAt: Option<&'a DILocation>, - ) -> &'a DILocation; + /// As of LLVM 18/19, there is no corresponding LLVM-C function. pub fn LLVMRustDILocationCloneWithBaseDiscriminator<'a>( Location: &'a DILocation, BD: c_uint, ) -> Option<&'a DILocation>; - pub fn LLVMRustDIBuilderCreateOpDeref() -> u64; - pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> u64; - pub fn LLVMRustDIBuilderCreateOpLLVMFragment() -> u64; pub fn LLVMRustWriteTypeToString(Type: &Type, s: &RustString); pub fn LLVMRustWriteValueToString(value_ref: &Value, s: &RustString); diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index b79205ff946d3..e405a2d64a0b9 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1,6 +1,7 @@ #include "LLVMWrapper.h" #include "llvm-c/Core.h" +#include "llvm-c/DebugInfo.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" @@ -626,8 +627,6 @@ extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints, unwrap(Ty), StringRef(Constraints, ConstraintsLen))); } -typedef DIBuilder *LLVMRustDIBuilderRef; - template DIT *unwrapDIPtr(LLVMMetadataRef Ref) { return (DIT *)(Ref ? unwrap(Ref) : nullptr); } @@ -636,117 +635,63 @@ template DIT *unwrapDIPtr(LLVMMetadataRef Ref) { #define DIArray DINodeArray #define unwrapDI unwrapDIPtr -// These values **must** match debuginfo::DIFlags! They also *happen* -// to match LLVM, but that isn't required as we do giant sets of -// matching below. The value shouldn't be directly passed to LLVM. -enum class LLVMRustDIFlags : uint32_t { - FlagZero = 0, - FlagPrivate = 1, - FlagProtected = 2, - FlagPublic = 3, - FlagFwdDecl = (1 << 2), - FlagAppleBlock = (1 << 3), - FlagBlockByrefStruct = (1 << 4), - FlagVirtual = (1 << 5), - FlagArtificial = (1 << 6), - FlagExplicit = (1 << 7), - FlagPrototyped = (1 << 8), - FlagObjcClassComplete = (1 << 9), - FlagObjectPointer = (1 << 10), - FlagVector = (1 << 11), - FlagStaticMember = (1 << 12), - FlagLValueReference = (1 << 13), - FlagRValueReference = (1 << 14), - FlagExternalTypeRef = (1 << 15), - FlagIntroducedVirtual = (1 << 18), - FlagBitField = (1 << 19), - FlagNoReturn = (1 << 20), - // Do not add values that are not supported by the minimum LLVM - // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def -}; - -inline LLVMRustDIFlags operator&(LLVMRustDIFlags A, LLVMRustDIFlags B) { - return static_cast(static_cast(A) & - static_cast(B)); -} - -inline LLVMRustDIFlags operator|(LLVMRustDIFlags A, LLVMRustDIFlags B) { - return static_cast(static_cast(A) | - static_cast(B)); -} - -inline LLVMRustDIFlags &operator|=(LLVMRustDIFlags &A, LLVMRustDIFlags B) { - return A = A | B; -} - -inline bool isSet(LLVMRustDIFlags F) { return F != LLVMRustDIFlags::FlagZero; } - -inline LLVMRustDIFlags visibility(LLVMRustDIFlags F) { - return static_cast(static_cast(F) & 0x3); -} - -static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) { - DINode::DIFlags Result = DINode::DIFlags::FlagZero; - - switch (visibility(Flags)) { - case LLVMRustDIFlags::FlagPrivate: - Result |= DINode::DIFlags::FlagPrivate; +static DINode::DIFlags fromRust(LLVMDIFlags Flags) { + using DIFlags = DINode::DIFlags; + + // Internally, LLVM does this conversion with a simple integer cast, but we + // can't rely on that always being the case so we write this the long way. + auto Result = DIFlags::FlagZero; + + // clang-format off + if (Flags & LLVMDIFlagFwdDecl) Result |= DIFlags::FlagFwdDecl; + if (Flags & LLVMDIFlagAppleBlock) Result |= DIFlags::FlagAppleBlock; + if (Flags & LLVMDIFlagReservedBit4) Result |= DIFlags::FlagReservedBit4; + if (Flags & LLVMDIFlagVirtual) Result |= DIFlags::FlagVirtual; + if (Flags & LLVMDIFlagArtificial) Result |= DIFlags::FlagArtificial; + if (Flags & LLVMDIFlagExplicit) Result |= DIFlags::FlagExplicit; + if (Flags & LLVMDIFlagPrototyped) Result |= DIFlags::FlagPrototyped; + if (Flags & LLVMDIFlagObjcClassComplete) Result |= DIFlags::FlagObjcClassComplete; + if (Flags & LLVMDIFlagObjectPointer) Result |= DIFlags::FlagObjectPointer; + if (Flags & LLVMDIFlagVector) Result |= DIFlags::FlagVector; + if (Flags & LLVMDIFlagStaticMember) Result |= DIFlags::FlagStaticMember; + if (Flags & LLVMDIFlagLValueReference) Result |= DIFlags::FlagLValueReference; + if (Flags & LLVMDIFlagRValueReference) Result |= DIFlags::FlagRValueReference; + // This flag has been recycled, but the value in the C API hasn't been renamed yet. + if (Flags & LLVMDIFlagReserved) Result |= DIFlags::FlagExportSymbols; + if (Flags & LLVMDIFlagSingleInheritance) Result |= DIFlags::FlagSingleInheritance; + if (Flags & LLVMDIFlagMultipleInheritance) Result |= DIFlags::FlagMultipleInheritance; + if (Flags & LLVMDIFlagVirtualInheritance) Result |= DIFlags::FlagVirtualInheritance; + if (Flags & LLVMDIFlagIntroducedVirtual) Result |= DIFlags::FlagIntroducedVirtual; + if (Flags & LLVMDIFlagBitField) Result |= DIFlags::FlagBitField; + if (Flags & LLVMDIFlagNoReturn) Result |= DIFlags::FlagNoReturn; + if (Flags & LLVMDIFlagTypePassByValue) Result |= DIFlags::FlagTypePassByValue; + if (Flags & LLVMDIFlagTypePassByReference) Result |= DIFlags::FlagTypePassByReference; + if (Flags & LLVMDIFlagEnumClass) Result |= DIFlags::FlagEnumClass; + if (Flags & LLVMDIFlagThunk) Result |= DIFlags::FlagThunk; + if (Flags & LLVMDIFlagNonTrivial) Result |= DIFlags::FlagNonTrivial; + if (Flags & LLVMDIFlagBigEndian) Result |= DIFlags::FlagLittleEndian; + if (Flags & LLVMDIFlagLittleEndian) Result |= DIFlags::FlagLittleEndian; + // clang-format on + + // The private/protected/public values overlap, so processing them separately + // (after other flags) seems to be easier for compilers to optimize. + switch (Flags & LLVMDIFlagAccessibility) { + case LLVMDIFlagPrivate: + Result |= DIFlags::FlagPrivate; break; - case LLVMRustDIFlags::FlagProtected: - Result |= DINode::DIFlags::FlagProtected; + case LLVMDIFlagProtected: + Result |= DIFlags::FlagProtected; break; - case LLVMRustDIFlags::FlagPublic: - Result |= DINode::DIFlags::FlagPublic; + case LLVMDIFlagPublic: + Result |= DIFlags::FlagPublic; break; default: - // The rest are handled below break; } - if (isSet(Flags & LLVMRustDIFlags::FlagFwdDecl)) { - Result |= DINode::DIFlags::FlagFwdDecl; - } - if (isSet(Flags & LLVMRustDIFlags::FlagAppleBlock)) { - Result |= DINode::DIFlags::FlagAppleBlock; - } - if (isSet(Flags & LLVMRustDIFlags::FlagVirtual)) { - Result |= DINode::DIFlags::FlagVirtual; - } - if (isSet(Flags & LLVMRustDIFlags::FlagArtificial)) { - Result |= DINode::DIFlags::FlagArtificial; - } - if (isSet(Flags & LLVMRustDIFlags::FlagExplicit)) { - Result |= DINode::DIFlags::FlagExplicit; - } - if (isSet(Flags & LLVMRustDIFlags::FlagPrototyped)) { - Result |= DINode::DIFlags::FlagPrototyped; - } - if (isSet(Flags & LLVMRustDIFlags::FlagObjcClassComplete)) { - Result |= DINode::DIFlags::FlagObjcClassComplete; - } - if (isSet(Flags & LLVMRustDIFlags::FlagObjectPointer)) { - Result |= DINode::DIFlags::FlagObjectPointer; - } - if (isSet(Flags & LLVMRustDIFlags::FlagVector)) { - Result |= DINode::DIFlags::FlagVector; - } - if (isSet(Flags & LLVMRustDIFlags::FlagStaticMember)) { - Result |= DINode::DIFlags::FlagStaticMember; - } - if (isSet(Flags & LLVMRustDIFlags::FlagLValueReference)) { - Result |= DINode::DIFlags::FlagLValueReference; - } - if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) { - Result |= DINode::DIFlags::FlagRValueReference; - } - if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) { - Result |= DINode::DIFlags::FlagIntroducedVirtual; - } - if (isSet(Flags & LLVMRustDIFlags::FlagBitField)) { - Result |= DINode::DIFlags::FlagBitField; - } - if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) { - Result |= DINode::DIFlags::FlagNoReturn; + // Reject anything beyond the highest known flag. + if (static_cast(Flags) >= (LLVMDIFlagLittleEndian << 1)) { + report_fatal_error("bad LLVMDIFlags"); } return Result; @@ -959,34 +904,22 @@ extern "C" void LLVMRustGlobalAddMetadata(LLVMValueRef Global, unsigned Kind, unwrap(Global)->addMetadata(Kind, *unwrap(MD)); } -extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) { - return new DIBuilder(*unwrap(M)); -} - -extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) { - delete Builder; -} - -extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) { - Builder->finalize(); -} - extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateCompileUnit( - LLVMRustDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef, + LLVMDIBuilderRef Builder, unsigned Lang, LLVMMetadataRef FileRef, const char *Producer, size_t ProducerLen, bool isOptimized, const char *Flags, unsigned RuntimeVer, const char *SplitName, size_t SplitNameLen, LLVMRustDebugEmissionKind Kind, uint64_t DWOId, bool SplitDebugInlining, LLVMRustDebugNameTableKind TableKind) { auto *File = unwrapDI(FileRef); - return wrap(Builder->createCompileUnit( + return wrap(unwrap(Builder)->createCompileUnit( Lang, File, StringRef(Producer, ProducerLen), isOptimized, Flags, RuntimeVer, StringRef(SplitName, SplitNameLen), fromRust(Kind), DWOId, SplitDebugInlining, false, fromRust(TableKind))); } extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateFile(LLVMRustDIBuilderRef Builder, const char *Filename, +LLVMRustDIBuilderCreateFile(LLVMDIBuilderRef Builder, const char *Filename, size_t FilenameLen, const char *Directory, size_t DirectoryLen, LLVMRustChecksumKind CSKind, const char *Checksum, size_t ChecksumLen, @@ -999,29 +932,22 @@ LLVMRustDIBuilderCreateFile(LLVMRustDIBuilderRef Builder, const char *Filename, std::optional oSource{}; if (Source) oSource = StringRef(Source, SourceLen); - return wrap(Builder->createFile(StringRef(Filename, FilenameLen), - StringRef(Directory, DirectoryLen), CSInfo, - oSource)); -} - -extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateSubroutineType(LLVMRustDIBuilderRef Builder, - LLVMMetadataRef ParameterTypes) { - return wrap(Builder->createSubroutineType( - DITypeRefArray(unwrap(ParameterTypes)))); + return wrap(unwrap(Builder)->createFile(StringRef(Filename, FilenameLen), + StringRef(Directory, DirectoryLen), + CSInfo, oSource)); } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, const char *LinkageName, size_t LinkageNameLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, - unsigned ScopeLine, LLVMRustDIFlags Flags, LLVMRustDISPFlags SPFlags, + unsigned ScopeLine, LLVMDIFlags Flags, LLVMRustDISPFlags SPFlags, LLVMValueRef MaybeFn, LLVMMetadataRef TParam, LLVMMetadataRef Decl) { DITemplateParameterArray TParams = DITemplateParameterArray(unwrap(TParam)); DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags); DINode::DIFlags llvmFlags = fromRust(Flags); - DISubprogram *Sub = Builder->createFunction( + DISubprogram *Sub = unwrap(Builder)->createFunction( unwrapDI(Scope), StringRef(Name, NameLen), StringRef(LinkageName, LinkageNameLen), unwrapDI(File), LineNo, unwrapDI(Ty), ScopeLine, llvmFlags, llvmSPFlags, @@ -1032,15 +958,15 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction( } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMethod( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, const char *LinkageName, size_t LinkageNameLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, - LLVMRustDIFlags Flags, LLVMRustDISPFlags SPFlags, LLVMMetadataRef TParam) { + LLVMDIFlags Flags, LLVMRustDISPFlags SPFlags, LLVMMetadataRef TParam) { DITemplateParameterArray TParams = DITemplateParameterArray(unwrap(TParam)); DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags); DINode::DIFlags llvmFlags = fromRust(Flags); - DISubprogram *Sub = Builder->createMethod( + DISubprogram *Sub = unwrap(Builder)->createMethod( unwrapDI(Scope), StringRef(Name, NameLen), StringRef(LinkageName, LinkageNameLen), unwrapDI(File), LineNo, unwrapDI(Ty), 0, 0, @@ -1049,54 +975,13 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMethod( return wrap(Sub); } -extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateBasicType(LLVMRustDIBuilderRef Builder, const char *Name, - size_t NameLen, uint64_t SizeInBits, - unsigned Encoding) { - return wrap( - Builder->createBasicType(StringRef(Name, NameLen), SizeInBits, Encoding)); -} - -extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateTypedef(LLVMRustDIBuilderRef Builder, - LLVMMetadataRef Type, const char *Name, - size_t NameLen, LLVMMetadataRef File, - unsigned LineNo, LLVMMetadataRef Scope) { - return wrap(Builder->createTypedef( - unwrap(Type), StringRef(Name, NameLen), unwrap(File), - LineNo, unwrapDIPtr(Scope))); -} - -extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy, - uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace, - const char *Name, size_t NameLen) { - return wrap(Builder->createPointerType(unwrapDI(PointeeTy), - SizeInBits, AlignInBits, AddressSpace, - StringRef(Name, NameLen))); -} - -extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStructType( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, - size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, - uint64_t SizeInBits, uint32_t AlignInBits, LLVMRustDIFlags Flags, - LLVMMetadataRef DerivedFrom, LLVMMetadataRef Elements, unsigned RunTimeLang, - LLVMMetadataRef VTableHolder, const char *UniqueId, size_t UniqueIdLen) { - return wrap(Builder->createStructType( - unwrapDI(Scope), StringRef(Name, NameLen), - unwrapDI(File), LineNumber, SizeInBits, AlignInBits, - fromRust(Flags), unwrapDI(DerivedFrom), - DINodeArray(unwrapDI(Elements)), RunTimeLang, - unwrapDI(VTableHolder), StringRef(UniqueId, UniqueIdLen))); -} - extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, - uint64_t SizeInBits, uint32_t AlignInBits, LLVMRustDIFlags Flags, + uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags, LLVMMetadataRef Discriminator, LLVMMetadataRef Elements, const char *UniqueId, size_t UniqueIdLen) { - return wrap(Builder->createVariantPart( + return wrap(unwrap(Builder)->createVariantPart( unwrapDI(Scope), StringRef(Name, NameLen), unwrapDI(File), LineNumber, SizeInBits, AlignInBits, fromRust(Flags), unwrapDI(Discriminator), @@ -1104,58 +989,23 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantPart( StringRef(UniqueId, UniqueIdLen))); } -extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMemberType( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, - size_t NameLen, LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits, - uint32_t AlignInBits, uint64_t OffsetInBits, LLVMRustDIFlags Flags, - LLVMMetadataRef Ty) { - return wrap(Builder->createMemberType( - unwrapDI(Scope), StringRef(Name, NameLen), - unwrapDI(File), LineNo, SizeInBits, AlignInBits, OffsetInBits, - fromRust(Flags), unwrapDI(Ty))); -} - extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, LLVMValueRef Discriminant, - LLVMRustDIFlags Flags, LLVMMetadataRef Ty) { + LLVMDIFlags Flags, LLVMMetadataRef Ty) { llvm::ConstantInt *D = nullptr; if (Discriminant) { D = unwrap(Discriminant); } - return wrap(Builder->createVariantMemberType( + return wrap(unwrap(Builder)->createVariantMemberType( unwrapDI(Scope), StringRef(Name, NameLen), unwrapDI(File), LineNo, SizeInBits, AlignInBits, OffsetInBits, D, fromRust(Flags), unwrapDI(Ty))); } -extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticMemberType( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, - size_t NameLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, - LLVMRustDIFlags Flags, LLVMValueRef val, uint32_t AlignInBits) { - return wrap(Builder->createStaticMemberType( - unwrapDI(Scope), StringRef(Name, NameLen), - unwrapDI(File), LineNo, unwrapDI(Ty), fromRust(Flags), - unwrap(val), llvm::dwarf::DW_TAG_member, AlignInBits)); -} - -extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateLexicalBlock(LLVMRustDIBuilderRef Builder, - LLVMMetadataRef Scope, LLVMMetadataRef File, - unsigned Line, unsigned Col) { - return wrap(Builder->createLexicalBlock(unwrapDI(Scope), - unwrapDI(File), Line, Col)); -} - -extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateLexicalBlockFile( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef File) { - return wrap(Builder->createLexicalBlockFile(unwrapDI(Scope), - unwrapDI(File))); -} - extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Context, const char *Name, + LLVMDIBuilderRef Builder, LLVMMetadataRef Context, const char *Name, size_t NameLen, const char *LinkageName, size_t LinkageNameLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty, bool IsLocalToUnit, LLVMValueRef V, LLVMMetadataRef Decl = nullptr, @@ -1164,16 +1014,16 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable( llvm::DIExpression *InitExpr = nullptr; if (llvm::ConstantInt *IntVal = llvm::dyn_cast(InitVal)) { - InitExpr = Builder->createConstantValueExpression( + InitExpr = unwrap(Builder)->createConstantValueExpression( IntVal->getValue().getSExtValue()); } else if (llvm::ConstantFP *FPVal = llvm::dyn_cast(InitVal)) { - InitExpr = Builder->createConstantValueExpression( + InitExpr = unwrap(Builder)->createConstantValueExpression( FPVal->getValueAPF().bitcastToAPInt().getZExtValue()); } llvm::DIGlobalVariableExpression *VarExpr = - Builder->createGlobalVariableExpression( + unwrap(Builder)->createGlobalVariableExpression( unwrapDI(Context), StringRef(Name, NameLen), StringRef(LinkageName, LinkageNameLen), unwrapDI(File), LineNo, unwrapDI(Ty), IsLocalToUnit, @@ -1186,123 +1036,67 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable( } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariable( - LLVMRustDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope, + LLVMDIBuilderRef Builder, unsigned Tag, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNo, - LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMRustDIFlags Flags, - unsigned ArgNo, uint32_t AlignInBits) { + LLVMMetadataRef Ty, bool AlwaysPreserve, LLVMDIFlags Flags, unsigned ArgNo, + uint32_t AlignInBits) { if (Tag == 0x100) { // DW_TAG_auto_variable - return wrap(Builder->createAutoVariable( + return wrap(unwrap(Builder)->createAutoVariable( unwrapDI(Scope), StringRef(Name, NameLen), unwrapDI(File), LineNo, unwrapDI(Ty), AlwaysPreserve, fromRust(Flags), AlignInBits)); } else { - return wrap(Builder->createParameterVariable( + return wrap(unwrap(Builder)->createParameterVariable( unwrapDI(Scope), StringRef(Name, NameLen), ArgNo, unwrapDI(File), LineNo, unwrapDI(Ty), AlwaysPreserve, fromRust(Flags))); } } -extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateArrayType(LLVMRustDIBuilderRef Builder, uint64_t Size, - uint32_t AlignInBits, LLVMMetadataRef Ty, - LLVMMetadataRef Subscripts) { - return wrap( - Builder->createArrayType(Size, AlignInBits, unwrapDI(Ty), - DINodeArray(unwrapDI(Subscripts)))); -} - -extern "C" LLVMMetadataRef -LLVMRustDIBuilderGetOrCreateSubrange(LLVMRustDIBuilderRef Builder, int64_t Lo, - int64_t Count) { - return wrap(Builder->getOrCreateSubrange(Lo, Count)); +extern "C" void LLVMRustDIBuilderInsertDeclareRecordAtEnd( + LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo, + LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMBasicBlockRef Block) { + unwrap(Builder)->insertDeclare( + unwrap(Storage), unwrap(VarInfo), + unwrap(Expr), unwrap(DebugLoc), unwrap(Block)); } extern "C" LLVMMetadataRef -LLVMRustDIBuilderGetOrCreateArray(LLVMRustDIBuilderRef Builder, - LLVMMetadataRef *Ptr, unsigned Count) { - Metadata **DataValue = unwrap(Ptr); - return wrap( - Builder->getOrCreateArray(ArrayRef(DataValue, Count)).get()); -} - -extern "C" void LLVMRustDIBuilderInsertDeclareAtEnd( - LLVMRustDIBuilderRef Builder, LLVMValueRef V, LLVMMetadataRef VarInfo, - uint64_t *AddrOps, unsigned AddrOpsCount, LLVMMetadataRef DL, - LLVMBasicBlockRef InsertAtEnd) { - Builder->insertDeclare(unwrap(V), unwrap(VarInfo), - Builder->createExpression( - llvm::ArrayRef(AddrOps, AddrOpsCount)), - DebugLoc(cast(unwrap(DL))), - unwrap(InsertAtEnd)); -} - -extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator( - LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen, - const uint64_t Value[2], unsigned SizeInBits, bool IsUnsigned) { - return wrap(Builder->createEnumerator( +LLVMRustDIBuilderCreateEnumerator(LLVMDIBuilderRef Builder, const char *Name, + size_t NameLen, const uint64_t Value[2], + unsigned SizeInBits, bool IsUnsigned) { + return wrap(unwrap(Builder)->createEnumerator( StringRef(Name, NameLen), APSInt(APInt(SizeInBits, ArrayRef(Value, 2)), IsUnsigned))); } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits, uint32_t AlignInBits, LLVMMetadataRef Elements, LLVMMetadataRef ClassTy, bool IsScoped) { - return wrap(Builder->createEnumerationType( + return wrap(unwrap(Builder)->createEnumerationType( unwrapDI(Scope), StringRef(Name, NameLen), unwrapDI(File), LineNumber, SizeInBits, AlignInBits, DINodeArray(unwrapDI(Elements)), unwrapDI(ClassTy), /* RunTimeLang */ 0, "", IsScoped)); } -extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, - size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, - uint64_t SizeInBits, uint32_t AlignInBits, LLVMRustDIFlags Flags, - LLVMMetadataRef Elements, unsigned RunTimeLang, const char *UniqueId, - size_t UniqueIdLen) { - return wrap(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( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef Ty) { bool IsDefault = false; // FIXME: should we ever set this true? - return wrap(Builder->createTemplateTypeParameter( + return wrap(unwrap(Builder)->createTemplateTypeParameter( unwrapDI(Scope), StringRef(Name, NameLen), unwrapDI(Ty), IsDefault)); } -extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateNameSpace(LLVMRustDIBuilderRef Builder, - LLVMMetadataRef Scope, const char *Name, - size_t NameLen, bool ExportSymbols) { - return wrap(Builder->createNameSpace( - unwrapDI(Scope), StringRef(Name, NameLen), ExportSymbols)); -} - extern "C" void LLVMRustDICompositeTypeReplaceArrays( - LLVMRustDIBuilderRef Builder, LLVMMetadataRef CompositeTy, + LLVMDIBuilderRef Builder, LLVMMetadataRef CompositeTy, LLVMMetadataRef Elements, LLVMMetadataRef Params) { DICompositeType *Tmp = unwrapDI(CompositeTy); - Builder->replaceArrays(Tmp, DINodeArray(unwrap(Elements)), - DINodeArray(unwrap(Params))); -} - -extern "C" LLVMMetadataRef -LLVMRustDIBuilderCreateDebugLocation(unsigned Line, unsigned Column, - LLVMMetadataRef ScopeRef, - LLVMMetadataRef InlinedAt) { - MDNode *Scope = unwrapDIPtr(ScopeRef); - DILocation *Loc = DILocation::get(Scope->getContext(), Line, Column, Scope, - unwrapDIPtr(InlinedAt)); - return wrap(Loc); + unwrap(Builder)->replaceArrays(Tmp, DINodeArray(unwrap(Elements)), + DINodeArray(unwrap(Params))); } extern "C" LLVMMetadataRef @@ -1313,18 +1107,6 @@ LLVMRustDILocationCloneWithBaseDiscriminator(LLVMMetadataRef Location, return wrap(NewLoc.has_value() ? NewLoc.value() : nullptr); } -extern "C" uint64_t LLVMRustDIBuilderCreateOpDeref() { - return dwarf::DW_OP_deref; -} - -extern "C" uint64_t LLVMRustDIBuilderCreateOpPlusUconst() { - return dwarf::DW_OP_plus_uconst; -} - -extern "C" uint64_t LLVMRustDIBuilderCreateOpLLVMFragment() { - return dwarf::DW_OP_LLVM_fragment; -} - extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) { auto OS = RawRustStringOstream(Str); unwrap(Ty)->print(OS);