[all-commits] [llvm/llvm-project] 3bdf53: [lldb] Use `llvm::APInt` for `VariantMember` Discr...
Walnut via All-commits
all-commits at lists.llvm.org
Thu Jul 9 15:04:29 PDT 2026
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: 3bdf536992084d0a30efc65f8198549b3a824c56
https://github.com/llvm/llvm-project/commit/3bdf536992084d0a30efc65f8198549b3a824c56
Author: Walnut <ant_b356 at me.com>
Date: 2026-07-09 (Thu, 09 Jul 2026)
Changed paths:
M lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
M lldb/unittests/SymbolFile/DWARF/CMakeLists.txt
M lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
A lldb/unittests/SymbolFile/DWARF/Inputs/DW_TAG_variant_rust-test.yaml
Log Message:
-----------
[lldb] Use `llvm::APInt` for `VariantMember` Discriminants (#188487)
resolves #177812
It currently uses a `uint32_t` even though Rust can output 64- and
128-bit discriminants. This became a more obvious issue when Rust
started niche-optimizing based on the capacity of strings (which are
`NoHighBit` values, guaranteed to be less than `u64::MAX / 2`), rather
than the `NonNull` heap pointer. With this optimization, the `None`
variant of strings is 9223372036854775808, which LLDB truncates to 0.
This means whenever the capacity is 0 (e.g. `Some(String::new())`, LLDB
will mistakenly read it as the `None` variant. Additionally, when trying
to determine the `None` variant, lldb will read the discr from memory
correctly (9223372036854775808), and the visualizer scripts will compare
that to the value in the variant name (`$variant$0`), see that it
doesn't match, and incorrectly decides that it must not be the `None`
variant.
This patch simply swaps the `uint32_t` with an `llvm::APInt`.
Sample program:
```rust
#[repr(u128)]
enum BigDiscr {
Value(u64),
None = 0x16151413121110090807060504030201,
}
fn main() {
let big_discr_none = BigDiscr::None;
let big_disr_some = BigDiscr::Value(31);
let some_string = Some(String::from("asdf"));
let some_empty_string = Some(String::new());
let none_string: Option<String> = Option::None;
println!("Hello world!"); // break
}
```
New output without visualizers:
```txt
(sample::BigDiscr) big_discr_none = {
$variants$ = {
$variant$0 = {
$discr$ = 29352461300415899028694309177919734273
value = (__0 = 0)
}
$variant$29352461300415899028694309177919734273 = ($discr$ = 29352461300415899028694309177919734273, value = sample::BigDiscr::None:128 @ 0x000000710a7ff7d0)
}
}
(sample::BigDiscr) big_disr_some = {
$variants$ = {
$variant$0 = {
$discr$ = 0
value = (__0 = 31)
}
$variant$29352461300415899028694309177919734273 = ($discr$ = 0, value = sample::BigDiscr::None:128 @ 0x000000710a7ff7f0)
}
}
(core::option::Option<alloc::string::String>) some_string = {
$variants$ = {
$variant$9223372036854775808 = ($discr$ = 4, value = core::option::Option<alloc::string::String>::None<alloc::string::String>:64 @ 0x000000710a7ff750)
$variant$ = {
value = {
__0 = {
vec = {...}
}
}
}
}
}
(core::option::Option<alloc::string::String>) some_empty_string = {
$variants$ = {
$variant$9223372036854775808 = ($discr$ = 0, value = core::option::Option<alloc::string::String>::None<alloc::string::String>:64 @ 0x000000710a7ff780)
$variant$ = {
value = {
__0 = {
vec = {...}
}
}
}
}
}
(core::option::Option<alloc::string::String>) none_string = {
$variants$ = {
$variant$9223372036854775808 = ($discr$ = 9223372036854775808, value = core::option::Option<alloc::string::String>::None<alloc::string::String>:64 @ 0x000000710a7ff7b8)
$variant$ = {
value = {
__0 = {
vec = {...}
}
}
}
}
}
```
New output with Rust's current visualizers:
```txt
# this one is incorrect because the visualizer scripts are wrong, not because of LLDB.
# the scripts use `GetValue()`, which returns a 64 bit number. They can be modified
# on Rust's end to use `GetData()` instead. The rest work as expected
(sample::BigDiscr) big_discr_none = Value(0) {
0 = 0
}
(sample::BigDiscr) big_disr_some = Value(31) {
0 = 31
}
(core::option::Option<alloc::string::String>) some_string = Some("asdf") {
0 = "asdf" {
[0] = 'a'
[1] = 's'
[2] = 'd'
[3] = 'f'
}
}
(core::option::Option<alloc::string::String>) some_empty_string = Some("") {
0 = ""
}
```
To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications
More information about the All-commits
mailing list