[Lldb-commits] [lldb] [LLDB][DWARF] Use the same qualified name computation for Rust (PR #165840)
via lldb-commits
lldb-commits at lists.llvm.org
Fri Oct 31 01:49:16 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: Kiva (imkiva)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/165840.diff
3 Files Affected:
- (modified) lldb/include/lldb/Target/Language.h (+2)
- (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (+5-1)
- (modified) lldb/source/Target/Language.cpp (+4)
``````````diff
diff --git a/lldb/include/lldb/Target/Language.h b/lldb/include/lldb/Target/Language.h
index 9958b6ea2f815..f3aac6a324c34 100644
--- a/lldb/include/lldb/Target/Language.h
+++ b/lldb/include/lldb/Target/Language.h
@@ -436,6 +436,8 @@ class Language : public PluginInterface {
static bool LanguageIsC(lldb::LanguageType language);
+ static bool LanguageIsRust(lldb::LanguageType language);
+
/// Equivalent to \c LanguageIsC||LanguageIsObjC||LanguageIsCPlusPlus.
static bool LanguageIsCFamily(lldb::LanguageType language);
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index c049829f37219..388ec20cdc5fe 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -1700,7 +1700,11 @@ void DWARFASTParserClang::GetUniqueTypeNameAndDeclaration(
// For C++, we rely solely upon the one definition rule that says
// only one thing can exist at a given decl context. We ignore the
// file and line that things are declared on.
- if (!die.IsValid() || !Language::LanguageIsCPlusPlus(language) ||
+ // For Rust, we do the same since Rust also has a similar qualified name?
+ // Is there a better way to do this for Rust?
+ if (!die.IsValid() ||
+ (!Language::LanguageIsCPlusPlus(language) &&
+ !Language::LanguageIsRust(language)) ||
unique_typename.IsEmpty())
return;
decl_declaration.Clear();
diff --git a/lldb/source/Target/Language.cpp b/lldb/source/Target/Language.cpp
index 8268d4ae4bb27..ad11fd94bb6b6 100644
--- a/lldb/source/Target/Language.cpp
+++ b/lldb/source/Target/Language.cpp
@@ -316,6 +316,10 @@ bool Language::LanguageIsCPlusPlus(LanguageType language) {
}
}
+bool Language::LanguageIsRust(LanguageType language) {
+ return language == eLanguageTypeRust;
+}
+
bool Language::LanguageIsObjC(LanguageType language) {
switch (language) {
case eLanguageTypeObjC:
``````````
</details>
https://github.com/llvm/llvm-project/pull/165840
More information about the lldb-commits
mailing list