about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs16
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs3
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp5
-rw-r--r--src/test/run-make/repr128-dwarf/Makefile16
-rw-r--r--src/test/run-make/repr128-dwarf/lib.rs23
6 files changed, 51 insertions, 14 deletions
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 129e336c7e4..53e8a291d1e 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
@@ -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,
     )
 }
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 14044d0f99b..cb558a50d91 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
@@ -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),
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 8f7728da9dd..f4519849730 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -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;
 
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 6f8bb676104..216c35d6da0 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -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(
diff --git a/src/test/run-make/repr128-dwarf/Makefile b/src/test/run-make/repr128-dwarf/Makefile
new file mode 100644
index 00000000000..a840e3ee6d8
--- /dev/null
+++ b/src/test/run-make/repr128-dwarf/Makefile
@@ -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 )"
diff --git a/src/test/run-make/repr128-dwarf/lib.rs b/src/test/run-make/repr128-dwarf/lib.rs
new file mode 100644
index 00000000000..63675441d4b
--- /dev/null
+++ b/src/test/run-make/repr128-dwarf/lib.rs
@@ -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) {}