[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