[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