Files
llvm-project/lldb/test/API/lang/rust/enum-variant-same-name/TestRustEnumVariantSameName.py
Kiva bdae26f3b4 [LLDB][DWARF] Use the same qualified name computation for Rust (#165840)
Currently LLDB's `ParseRustVariantPart` generates the following
`CXXRecordDecl` for a Rust enum
```rust
enum AA {
  A(u8)
}
```

```
CXXRecordDecl 0x5555568d5970 <<invalid sloc>> <invalid sloc> struct AA
|-CXXRecordDecl 0x5555568d5ab0 <<invalid sloc>> <invalid sloc> union test_issue::AA$Inner definition
| |-CXXRecordDecl 0x5555568d5d18 <<invalid sloc>> <invalid sloc> struct A$Variant definition
| | |-DefinitionData pass_in_registers aggregate standard_layout trivially_copyable trivial
| | | `-Destructor simple irrelevant trivial needs_implicit
| | `-FieldDecl 0x555555a77880 <<invalid sloc>> <invalid sloc> value 'test_issue::AA::A'
| `-FieldDecl 0x555555a778f0 <<invalid sloc>> <invalid sloc> $variant$ 'test_issue::AA::test_issue::AA$Inner::A$Variant'
|-CXXRecordDecl 0x5555568d5c48 <<invalid sloc>> <invalid sloc> struct A definition
| `-FieldDecl 0x555555a777e0 <<invalid sloc>> <invalid sloc> __0 'unsigned char'
`-FieldDecl 0x555555a77960 <<invalid sloc>> <invalid sloc> $variants$ 'test_issue::AA::test_issue::AA$Inner'
```

While when the Rust enum type name is the same as its variant name, the
generated `CXXRecordDecl` becomes the following – there's a circular
reference between `struct A$Variant` and `struct A`, causing #163048.

```rust
enum A {
  A(u8)
}
```

```
CXXRecordDecl 0x5555568d5760 <<invalid sloc>> <invalid sloc> struct A
|-CXXRecordDecl 0x5555568d58a0 <<invalid sloc>> <invalid sloc> union test_issue::A$Inner definition
| |-CXXRecordDecl 0x5555568d5a38 <<invalid sloc>> <invalid sloc> struct A$Variant definition
| | `-FieldDecl 0x5555568d5b70 <<invalid sloc>> <invalid sloc> value 'test_issue::A'    <---- bug here
| `-FieldDecl 0x5555568d5be0 <<invalid sloc>> <invalid sloc> $variant$ 'test_issue::A::test_issue::A$Inner::A$Variant'
`-FieldDecl 0x5555568d5c50 <<invalid sloc>> <invalid sloc> $variants$ 'test_issue::A::test_issue::A$Inner'
```

The problem was caused by `GetUniqueTypeNameAndDeclaration` not
returning the correct qualified name for DWARF DIE `test_issue::A::A`,
instead, it returned `A`. This caused `ParseStructureLikeDIE` to find
the wrong type `test_issue::A` and returned early.

The failure in `GetUniqueTypeNameAndDeclaration` appears to stem from a
language check that returns early unless the language is C++. I changed
it so Rust follows the C++ path rather than returning. I’m not entirely
sure this is the right approach — Rust’s qualified name rules look
similar, but not identical? Alternatively, we could add a Rust-specific
implementation that forms qualified names according to Rust's rules.
2025-11-17 10:38:40 +00:00

37 lines
1.2 KiB
Python

"""Test that lldb recognizes enum variant emitted by Rust compiler """
import logging
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from RustEnumValue import RustEnumValue
class TestRustEnumStructs(TestBase):
def setUp(self):
TestBase.setUp(self)
src_dir = self.getSourceDir()
yaml_path = os.path.join(src_dir, "main.yaml")
obj_path = self.getBuildArtifact("main.o")
self.yaml2obj(yaml_path, obj_path)
self.dbg.CreateTarget(obj_path)
def getFromGlobal(self, name):
values = self.target().FindGlobalVariables(name, 1)
self.assertEqual(values.GetSize(), 1)
return RustEnumValue(values[0])
def test_enum_instance(self):
# static ENUM_INSTANCE: A = A::A(B::B(10));
value = self.getFromGlobal("ENUM_INSTANCE").getCurrentValue()
self.assertEqual(value.GetType().GetDisplayTypeName(), "main::A::A")
value_b = RustEnumValue(value.GetChildAtIndex(0))
self.assertEqual(
value_b.getCurrentValue()
.GetChildAtIndex(0)
.GetData()
.GetUnsignedInt8(lldb.SBError(), 0),
10,
)