mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-13 20:46:48 +00:00
Auto merge of #102717 - beetrees:repr128-c-style-debuginfo, r=nagisa
Pass 128-bit C-style enum enumerator values to LLVM Pass the full 128 bits of C-style enum enumerators through to LLVM. This means that debuginfo for C-style repr128 enums is now emitted correctly for DWARF platforms (as compared to not being correctly emitted on any platform). Tracking issue: #56071
This commit is contained in:
commit
ccde51a912
@ -462,7 +462,7 @@ fn build_variant_names_type_di_node<'ll, 'tcx>(
|
||||
cx,
|
||||
"VariantNames",
|
||||
variant_names_enum_base_type(cx),
|
||||
variants.map(|(variant_index, variant_name)| (variant_name, variant_index.as_u32() as u64)),
|
||||
variants.map(|(variant_index, variant_name)| (variant_name, variant_index.as_u32().into())),
|
||||
containing_scope,
|
||||
)
|
||||
}
|
||||
|
@ -91,9 +91,7 @@ fn build_c_style_enum_di_node<'ll, 'tcx>(
|
||||
tag_base_type(cx, enum_type_and_layout),
|
||||
enum_adt_def.discriminants(cx.tcx).map(|(variant_index, discr)| {
|
||||
let name = Cow::from(enum_adt_def.variant(variant_index).name.as_str());
|
||||
// Is there anything we can do to support 128-bit C-Style enums?
|
||||
let value = discr.val as u64;
|
||||
(name, value)
|
||||
(name, discr.val)
|
||||
}),
|
||||
containing_scope,
|
||||
),
|
||||
@ -147,14 +145,11 @@ fn tag_base_type<'ll, 'tcx>(
|
||||
/// This is a helper function and does not register anything in the type map by itself.
|
||||
///
|
||||
/// `variants` is an iterator of (discr-value, variant-name).
|
||||
///
|
||||
// NOTE: Handling of discriminant values is somewhat inconsistent. They can appear as u128,
|
||||
// u64, and i64. Here everything gets mapped to i64 because that's what LLVM's API expects.
|
||||
fn build_enumeration_type_di_node<'ll, 'tcx>(
|
||||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
type_name: &str,
|
||||
base_type: Ty<'tcx>,
|
||||
enumerators: impl Iterator<Item = (Cow<'tcx, str>, u64)>,
|
||||
enumerators: impl Iterator<Item = (Cow<'tcx, str>, u128)>,
|
||||
containing_scope: &'ll DIType,
|
||||
) -> &'ll DIType {
|
||||
let is_unsigned = match base_type.kind() {
|
||||
@ -162,21 +157,22 @@ fn build_enumeration_type_di_node<'ll, 'tcx>(
|
||||
ty::Uint(_) => true,
|
||||
_ => bug!("build_enumeration_type_di_node() called with non-integer tag type."),
|
||||
};
|
||||
let (size, align) = cx.size_and_align_of(base_type);
|
||||
|
||||
let enumerator_di_nodes: SmallVec<Option<&'ll DIType>> = enumerators
|
||||
.map(|(name, value)| unsafe {
|
||||
let value = [value as u64, (value >> 64) as u64];
|
||||
Some(llvm::LLVMRustDIBuilderCreateEnumerator(
|
||||
DIB(cx),
|
||||
name.as_ptr().cast(),
|
||||
name.len(),
|
||||
value as i64,
|
||||
value.as_ptr(),
|
||||
size.bits() as libc::c_uint,
|
||||
is_unsigned,
|
||||
))
|
||||
})
|
||||
.collect();
|
||||
|
||||
let (size, align) = cx.size_and_align_of(base_type);
|
||||
|
||||
unsafe {
|
||||
llvm::LLVMRustDIBuilderCreateEnumerationType(
|
||||
DIB(cx),
|
||||
|
@ -2127,7 +2127,8 @@ extern "C" {
|
||||
Builder: &DIBuilder<'a>,
|
||||
Name: *const c_char,
|
||||
NameLen: size_t,
|
||||
Value: i64,
|
||||
Value: *const u64,
|
||||
SizeInBits: c_uint,
|
||||
IsUnsigned: bool,
|
||||
) -> &'a DIEnumerator;
|
||||
|
||||
|
@ -1036,8 +1036,9 @@ extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
|
||||
|
||||
extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator(
|
||||
LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
|
||||
int64_t Value, bool IsUnsigned) {
|
||||
return wrap(Builder->createEnumerator(StringRef(Name, NameLen), Value, IsUnsigned));
|
||||
const uint64_t Value[2], unsigned SizeInBits, bool IsUnsigned) {
|
||||
return wrap(Builder->createEnumerator(StringRef(Name, NameLen),
|
||||
APSInt(APInt(SizeInBits, makeArrayRef(Value, 2)), IsUnsigned)));
|
||||
}
|
||||
|
||||
extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
|
||||
|
16
src/test/run-make/repr128-dwarf/Makefile
Normal file
16
src/test/run-make/repr128-dwarf/Makefile
Normal file
@ -0,0 +1,16 @@
|
||||
# ignore-windows
|
||||
# This test should be replaced with one in src/test/debuginfo once GDB or LLDB support 128-bit
|
||||
# enums.
|
||||
|
||||
include ../../run-make-fulldeps/tools.mk
|
||||
|
||||
all:
|
||||
$(RUSTC) -Cdebuginfo=2 lib.rs -o $(TMPDIR)/repr128.rlib
|
||||
"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128A $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 )"
|
||||
"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128B $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 )"
|
||||
"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128C $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 )"
|
||||
"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n U128D $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff )"
|
||||
"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128A $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 )"
|
||||
"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128B $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff )"
|
||||
"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128C $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 )"
|
||||
"$(LLVM_BIN_DIR)"/llvm-dwarfdump -n I128D $(TMPDIR)/repr128.rlib | $(CGREP) "DW_AT_const_value (<0x10> ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 7f )"
|
23
src/test/run-make/repr128-dwarf/lib.rs
Normal file
23
src/test/run-make/repr128-dwarf/lib.rs
Normal file
@ -0,0 +1,23 @@
|
||||
#![crate_type = "lib"]
|
||||
#![feature(repr128)]
|
||||
|
||||
// Use .to_le() to ensure that the bytes are in the same order on both little- and big-endian
|
||||
// platforms.
|
||||
|
||||
#[repr(u128)]
|
||||
pub enum U128Enum {
|
||||
U128A = 0_u128.to_le(),
|
||||
U128B = 1_u128.to_le(),
|
||||
U128C = (u64::MAX as u128 + 1).to_le(),
|
||||
U128D = u128::MAX.to_le(),
|
||||
}
|
||||
|
||||
#[repr(i128)]
|
||||
pub enum I128Enum {
|
||||
I128A = 0_i128.to_le(),
|
||||
I128B = (-1_i128).to_le(),
|
||||
I128C = i128::MIN.to_le(),
|
||||
I128D = i128::MAX.to_le(),
|
||||
}
|
||||
|
||||
pub fn f(_: U128Enum, _: I128Enum) {}
|
Loading…
Reference in New Issue
Block a user