diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs index 556158c286a84..f7fe0eb8cb3b8 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs @@ -21,8 +21,8 @@ use crate::debuginfo::metadata::{ file_metadata_from_def_id, type_di_node, unknown_file_metadata, }; use crate::debuginfo::utils::{DIB, create_DIArray, get_namespace_for_item}; -use crate::llvm; use crate::llvm::debuginfo::{DIFlags, DIType}; +use crate::llvm::{self, ToLlvmBool}; mod cpp_like; mod native; @@ -111,16 +111,23 @@ fn build_enumeration_type_di_node<'ll, 'tcx>( let (size, align) = cx.size_and_align_of(base_type); let enumerator_di_nodes: SmallVec> = enumerators - .map(|(name, value)| unsafe { - let value = [value as u64, (value >> 64) as u64]; - Some(llvm::LLVMRustDIBuilderCreateEnumerator( - DIB(cx), - name.as_c_char_ptr(), - name.len(), - value.as_ptr(), - size.bits() as libc::c_uint, - is_unsigned, - )) + .map(|(name, value)| { + let value_words = [value as u64, (value >> 64) as u64]; + let size_in_bits = size.bits(); + // LLVM computes `NumWords = (SizeInBits + 63) / 64`. + assert!((size_in_bits + 63) / 64 <= value_words.len() as u64); + + let enumerator = unsafe { + llvm::LLVMDIBuilderCreateEnumeratorOfArbitraryPrecision( + DIB(cx), + name.as_ptr(), + name.len(), + size_in_bits, + value_words.as_ptr(), + is_unsigned.to_llvm_bool(), + ) + }; + Some(enumerator) }) .collect(); diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 2728152b5d209..eb9b2ab121296 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -22,9 +22,8 @@ use libc::{c_char, c_int, c_uchar, c_uint, c_ulonglong, c_void, size_t}; use super::RustString; use super::debuginfo::{ - DIArray, DIBuilder, DIDerivedType, DIDescriptor, DIEnumerator, DIFile, DIFlags, DILocation, - DISPFlags, DIScope, DISubprogram, DITemplateTypeParameter, DIType, DebugEmissionKind, - DebugNameTableKind, + DIArray, DIBuilder, DIDerivedType, DIDescriptor, DIFile, DIFlags, DILocation, DISPFlags, + DIScope, DISubprogram, DITemplateTypeParameter, DIType, DebugEmissionKind, DebugNameTableKind, }; use crate::llvm::MetadataKindId; use crate::{TryFromU32, llvm}; @@ -752,7 +751,6 @@ pub(crate) mod debuginfo { pub(crate) type DICompositeType = DIDerivedType; pub(crate) type DIVariable = DIDescriptor; pub(crate) type DIArray = DIDescriptor; - pub(crate) type DIEnumerator = DIDescriptor; pub(crate) type DITemplateTypeParameter = DIDescriptor; bitflags! { @@ -1794,6 +1792,15 @@ unsafe extern "C" { Flags: DIFlags, // (default is `DIFlags::DIFlagZero`) ) -> &'ll Metadata; + pub(crate) fn LLVMDIBuilderCreateEnumeratorOfArbitraryPrecision<'ll>( + Builder: &DIBuilder<'ll>, + Name: *const c_uchar, // See "PTR_LEN_STR". + NameLen: size_t, + SizeInBits: u64, + Words: *const u64, // LLVM computes `NumWords = (SizeInBits + 63) / 64`. + IsUnsigned: llvm::Bool, + ) -> &'ll Metadata; + pub(crate) fn LLVMDIBuilderCreateUnionType<'ll>( Builder: &DIBuilder<'ll>, Scope: Option<&'ll Metadata>, @@ -1989,6 +1996,7 @@ unsafe extern "C" { pub(crate) fn LLVMRustDisableSystemDialogsOnCrash(); // Operations on all values + /// FIXME: After dropping LLVM 21, migrate to LLVM-C's `LLVMGlobalAddMetadata`. pub(crate) fn LLVMRustGlobalAddMetadata<'a>( Val: &'a Value, KindID: MetadataKindId, @@ -2058,6 +2066,7 @@ unsafe extern "C" { ) -> &Attribute; // Operations on functions + /// FIXME: After dropping LLVM 21, migrate to LLVM-C's `LLVMGetOrInsertFunction`. pub(crate) fn LLVMRustGetOrInsertFunction<'a>( M: &'a Module, Name: *const c_char, @@ -2208,6 +2217,9 @@ unsafe extern "C" { ValueLen: size_t, ); + /// We can't use LLVM-C's `LLVMDIBuilderCreateCompileUnit` because it hardcodes + /// `DICompileUnit::DebugNameTableKind::Default`, but we want to be able to + /// pass other values. pub(crate) fn LLVMRustDIBuilderCreateCompileUnit<'a>( Builder: &DIBuilder<'a>, Lang: c_uint, @@ -2225,6 +2237,8 @@ unsafe extern "C" { DebugNameTableKind: DebugNameTableKind, ) -> &'a DIDescriptor; + /// We can't use LLVM-C's `LLVMDIBuilderCreateFileWithChecksum` because it + /// _requires_ a checksum, but we sometimes don't provide one. pub(crate) fn LLVMRustDIBuilderCreateFile<'a>( Builder: &DIBuilder<'a>, Filename: *const c_char, @@ -2238,6 +2252,8 @@ unsafe extern "C" { SourceLen: size_t, ) -> &'a DIFile; + /// We can't use LLVM-C's `LLVMDIBuilderCreateFunction` because it only + /// supports a subset of `DISubprogram::DISPFlags`. pub(crate) fn LLVMRustDIBuilderCreateFunction<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIDescriptor, @@ -2256,6 +2272,7 @@ unsafe extern "C" { Decl: Option<&'a DIDescriptor>, ) -> &'a DISubprogram; + /// As of LLVM 22 there is no corresponding LLVM-C function. pub(crate) fn LLVMRustDIBuilderCreateMethod<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIDescriptor, @@ -2271,6 +2288,7 @@ unsafe extern "C" { TParam: &'a DIArray, ) -> &'a DISubprogram; + /// As of LLVM 22 there is no corresponding LLVM-C function. pub(crate) fn LLVMRustDIBuilderCreateVariantMemberType<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIScope, @@ -2286,15 +2304,7 @@ unsafe extern "C" { Ty: &'a DIType, ) -> &'a DIType; - pub(crate) fn LLVMRustDIBuilderCreateEnumerator<'a>( - Builder: &DIBuilder<'a>, - Name: *const c_char, - NameLen: size_t, - Value: *const u64, - SizeInBits: c_uint, - IsUnsigned: bool, - ) -> &'a DIEnumerator; - + /// As of LLVM 22 there is no corresponding LLVM-C function. pub(crate) fn LLVMRustDIBuilderCreateEnumerationType<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIScope, @@ -2309,6 +2319,7 @@ unsafe extern "C" { IsScoped: bool, ) -> &'a DIType; + /// As of LLVM 22 there is no corresponding LLVM-C function. pub(crate) fn LLVMRustDIBuilderCreateVariantPart<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIScope, @@ -2325,6 +2336,7 @@ unsafe extern "C" { UniqueIdLen: size_t, ) -> &'a DIDerivedType; + /// As of LLVM 22 there is no corresponding LLVM-C function. pub(crate) fn LLVMRustDIBuilderCreateTemplateTypeParameter<'a>( Builder: &DIBuilder<'a>, Scope: Option<&'a DIScope>, @@ -2333,6 +2345,8 @@ unsafe extern "C" { Ty: &'a DIType, ) -> &'a DITemplateTypeParameter; + /// We can't use LLVM-C's `LLVMReplaceArrays` because it doesn't take a + /// `Params` argument. pub(crate) fn LLVMRustDICompositeTypeReplaceArrays<'a>( Builder: &DIBuilder<'a>, CompositeType: &'a DIType, @@ -2340,6 +2354,8 @@ unsafe extern "C" { Params: Option<&'a DIArray>, ); + /// We can't use LLVM-C's `LLVMDIBuilderGetOrCreateSubrange` because it doesn't + /// call the overload that takes a `Metadata` upper bound. pub(crate) fn LLVMRustDIGetOrCreateSubrange<'a>( Builder: &DIBuilder<'a>, CountNode: Option<&'a Metadata>, @@ -2348,6 +2364,8 @@ unsafe extern "C" { Stride: Option<&'a Metadata>, ) -> &'a Metadata; + /// We can't use LLVM-C's `LLVMDIBuilderCreateVectorType` because it doesn't + /// take a `BitStride` argument. pub(crate) fn LLVMRustDICreateVectorType<'a>( Builder: &DIBuilder<'a>, Size: u64, @@ -2357,6 +2375,7 @@ unsafe extern "C" { BitStride: Option<&'a Metadata>, ) -> &'a Metadata; + /// As of LLVM 22 there is no corresponding LLVM-C function. pub(crate) fn LLVMRustDILocationCloneWithBaseDiscriminator<'a>( Location: &'a DILocation, BD: c_uint, diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 63e3119ee96f7..28037d28fa44a 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1198,15 +1198,6 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType( fromRust(Flags), unwrapDI(Ty))); } -extern "C" LLVMMetadataRef -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( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,