diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 60a29e5c73b16..87e0612bc102d 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -6,6 +6,7 @@ use std::{assert_matches, iter, ptr}; use libc::{c_longlong, c_uint}; use rustc_abi::{Align, Endian, Layout, NumScalableVectors, Size}; +use rustc_ast::{IntTy, UintTy}; use rustc_codegen_ssa::debuginfo::type_names::{VTableNameKind, cpp_like_debuginfo}; use rustc_codegen_ssa::traits::*; use rustc_hir::def::{CtorKind, DefKind}; @@ -794,9 +795,50 @@ fn build_basic_type_di_node<'ll, 'tcx>( _ => bug!("debuginfo::build_basic_type_di_node - `t` is invalid type"), }; - let ty_di_node = create_basic_type(cx, name, cx.size_of(t), encoding); + // Around LLDB 21 or 22, LLDB started using prebuilt Clang type nodes for primitives rather than + // reading the full DWARF data. These nodes are based on the size and signedness of the + // primitive, and ignore pretty much all other fields. This causes 2 issues: + // 1. type names get normalized to C-style names which isn't ideal. The normalization occurs + // even in generic args. + // 2. if you have a generic type `S`, and 2 instantiations are `S` + // and `S` (on a 64-bit target), the use of prebuilt nodes causes a name collision. + // Whichever instantiation is interacted with first will work fine, all others will break a + // bunch of stuff in the LLDB pipeline. To avoid this, we explicitly treat `usize` and `isize` + // as typedefs of their equivalent types. For more info see: llvm/llvm-project#196812 + + let mut needs_typedef = cpp_like_debuginfo; + + let ty_di_node = match t.kind() { + ty::Uint(UintTy::Usize) => { + needs_typedef = true; + + let equivalent = match t.primitive_size(cx.tcx).bits() { + 8 => cx.tcx.types.u8, + 16 => cx.tcx.types.u16, + 32 => cx.tcx.types.u32, + 64 => cx.tcx.types.u64, + 128 => cx.tcx.types.u128, + x => bug!("Unexpected signed int size {x}"), + }; + type_di_node(cx, equivalent) + } + ty::Int(IntTy::Isize) => { + needs_typedef = true; + + let equivalent = match t.primitive_size(cx.tcx).bits() { + 8 => cx.tcx.types.i8, + 16 => cx.tcx.types.i16, + 32 => cx.tcx.types.i32, + 64 => cx.tcx.types.i64, + 128 => cx.tcx.types.i128, + x => bug!("Unexpected signed int size: {x}"), + }; + type_di_node(cx, equivalent) + } + _ => create_basic_type(cx, name, cx.size_of(t), encoding), + }; - if !cpp_like_debuginfo { + if !needs_typedef { return DINodeCreationResult::new(ty_di_node, false); } diff --git a/tests/codegen-llvm/debug-vtable.rs b/tests/codegen-llvm/debug-vtable.rs index 8a7b1cc3c4bcc..031153832629c 100644 --- a/tests/codegen-llvm/debug-vtable.rs +++ b/tests/codegen-llvm/debug-vtable.rs @@ -19,7 +19,7 @@ // CHECK: @vtable.3 = private constant <{ // CHECK: @vtable.4 = private constant <{ -// NONMSVC: ![[USIZE:[0-9]+]] = !DIBasicType(name: "usize" +// NONMSVC: ![[USIZE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_typedef, name: "usize" // MSVC: ![[USIZE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_typedef, name: "usize" // NONMSVC: ![[PTR:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "*const ()" // MSVC: ![[PTR:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "ptr_const$ >" diff --git a/tests/debuginfo/basic-types/lldb_input/non_windows.json b/tests/debuginfo/basic-types/lldb_input/non_windows.json index af225246e6109..67c45674981a2 100644 --- a/tests/debuginfo/basic-types/lldb_input/non_windows.json +++ b/tests/debuginfo/basic-types/lldb_input/non_windows.json @@ -12,7 +12,7 @@ "value": false }, "i": { - "type": "long", + "type": "isize", "pretty_print": "-1", "value": -1 }, @@ -43,7 +43,7 @@ "value": -64 }, "u": { - "type": "unsigned long", + "type": "usize", "pretty_print": "1", "value": 1 }, diff --git a/tests/debuginfo/basic-types/lldb_input/windows_gnu.json b/tests/debuginfo/basic-types/lldb_input/windows_gnu.json index 80c35ffcbea60..06b21d7cb0b35 100644 --- a/tests/debuginfo/basic-types/lldb_input/windows_gnu.json +++ b/tests/debuginfo/basic-types/lldb_input/windows_gnu.json @@ -1,7 +1,7 @@ { "bless_metadata": { "python_version": "3.11.9 (tags/v3.11.9:de54cf5, Apr 2 2024, 10:12:12) [MSC v.1938 64 bit (AMD64)]", - "debugger_version": "lldb version 22.1.2 (https://github.com/llvm/llvm-project revision 1ab49a973e210e97d61e5db6557180dcb92c3e98)\n clang revision 1ab49a973e210e97d61e5db6557180dcb92c3e98\n llvm revision 1ab49a973e210e97d61e5db6557180dcb92c3e98", + "debugger_version": "lldb version 22.1.8 (https://github.com/llvm/llvm-project revision ca7933e47d3a3451d81e72ac174dcb5aa28b59d1)\n clang revision ca7933e47d3a3451d81e72ac174dcb5aa28b59d1\n llvm revision ca7933e47d3a3451d81e72ac174dcb5aa28b59d1", "feature_flags": "LLDBFeature.StaticFields|TypeRecognizers|Float128" }, "breakpoints": [ @@ -12,7 +12,7 @@ "value": false }, "i": { - "type": "long long", + "type": "isize", "pretty_print": "-1", "value": -1 }, @@ -43,7 +43,7 @@ "value": -64 }, "u": { - "type": "unsigned long long", + "type": "usize", "pretty_print": "1", "value": 1 }, diff --git a/tests/debuginfo/pretty-std/lldb_input/non_windows.json b/tests/debuginfo/pretty-std/lldb_input/non_windows.json index 737eb5004b2bf..f76ba1ded06a1 100644 --- a/tests/debuginfo/pretty-std/lldb_input/non_windows.json +++ b/tests/debuginfo/pretty-std/lldb_input/non_windows.json @@ -162,7 +162,7 @@ }, { "name": "length", - "type": "unsigned long", + "type": "usize", "offset": 8 } ] @@ -178,7 +178,7 @@ }, { "name": "length", - "type": "unsigned long", + "type": "usize", "offset": 8 } ] @@ -273,7 +273,7 @@ }, { "name": "len", - "type": "unsigned long", + "type": "usize", "offset": 16 } ], @@ -293,7 +293,7 @@ }, { "name": "len", - "type": "unsigned long", + "type": "usize", "offset": 16 } ], @@ -322,7 +322,7 @@ "fields": [ { "name": "__0", - "type": "unsigned long", + "type": "usize", "offset": 0 } ] @@ -560,6 +560,11 @@ "size": 2, "type_class": 4, "basic_type": 12 + }, + "usize": { + "size": 8, + "type_class": 32768, + "basic_type": 16 } } } diff --git a/tests/debuginfo/pretty-std/lldb_input/windows_gnu.json b/tests/debuginfo/pretty-std/lldb_input/windows_gnu.json index 7f7772bd4caa1..56bfb83deef32 100644 --- a/tests/debuginfo/pretty-std/lldb_input/windows_gnu.json +++ b/tests/debuginfo/pretty-std/lldb_input/windows_gnu.json @@ -173,7 +173,7 @@ }, { "name": "length", - "type": "unsigned long long", + "type": "usize", "offset": 8 } ] @@ -284,7 +284,7 @@ }, { "name": "len", - "type": "unsigned long long", + "type": "usize", "offset": 16 } ], diff --git a/tests/debuginfo/rc_arc.rs b/tests/debuginfo/rc_arc.rs index adeb96dba1b80..e1af1eba02193 100644 --- a/tests/debuginfo/rc_arc.rs +++ b/tests/debuginfo/rc_arc.rs @@ -21,6 +21,11 @@ //@ lldb-check:[...] strong=11, weak=2 { value = 111 } //@ lldb-command:v arc //@ lldb-check:[...] strong=21, weak=2 { data = 222 } +//@ lldb-command:continue +//@ lldb-command:v rc_u64 +//@ lldb-check:[...] rc_u64 = strong=1, weak=1 { value = 10 } +//@ lldb-command:v rc_usize +//@ lldb-check:[...] rc_usize = strong=1, weak=1 { value = 20 } // === CDB TESTS ================================================================================== @@ -132,6 +137,11 @@ fn main() { let slice_arc_weak = Arc::downgrade(&slice_arc); zzz(); // #break + + let rc_u64 = Rc::new(10u64); + let rc_usize = Rc::new(20usize); + + zzz(); // #break } fn inc_ref_count(rc: &T, count: usize) {