[Lldb-commits] [lldb] [LLDB][NativePDB] Use original struct name when searching for constants (PR #166845)
via lldb-commits
lldb-commits at lists.llvm.org
Wed Dec 10 08:35:47 PST 2025
https://github.com/Nerixyz updated https://github.com/llvm/llvm-project/pull/166845
>From 7566542a194db8d8516432e0213d4f9d43aa488d Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Thu, 6 Nov 2025 21:45:05 +0100
Subject: [PATCH 1/3] [LLDB][NativePDB] Use original struct name when searching
for constants
---
.../Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp | 8 +++++++-
lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp | 5 ++++-
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
index 46cf9b8524ede..bfaba7f91b711 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
@@ -168,7 +168,13 @@ Error UdtRecordCompleter::visitKnownMember(
// Static constant members may be a const[expr] declaration.
// Query the symbol's value as the variable initializer if valid.
if (member_ct.IsConst() && member_ct.IsCompleteType()) {
- std::string qual_name = decl->getQualifiedNameAsString();
+ std::string qual_name;
+ if (m_record.record.kind == Member::Struct)
+ qual_name = (m_cvr.cr.Name + "::" + static_data_member.Name).str();
+ else if (m_record.record.kind == Member::Union)
+ qual_name = (m_cvr.ur.Name + "::" + static_data_member.Name).str();
+ else
+ qual_name = decl->getQualifiedNameAsString();
auto results =
m_index.globals().findRecordsByName(qual_name, m_index.symrecords());
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp b/lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp
index ac0d87e95dbf9..4b267c398e766 100644
--- a/lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp
+++ b/lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp
@@ -56,6 +56,7 @@ namespace {
int AnonymousMember;
// And a nested class within an anonymous namespace
struct D {
+ static constexpr int StaticMember = 1;
int AnonymousDMember;
};
};
@@ -177,6 +178,8 @@ int SI::*mp9 = nullptr;
// CHECK: | `-CXXRecordDecl {{.*}} struct Anonymous<A::B::C<void>> definition
// CHECK: | |-FieldDecl {{.*}} AnonymousMember 'int'
// CHECK: | `-CXXRecordDecl {{.*}} struct D definition
+// CHECK: | |-VarDecl {{.*}} StaticMember 'const int' static cinit
+// CHECK: | | `-IntegerLiteral {{.*}} 'int' 1
// CHECK: | `-FieldDecl {{.*}} AnonymousDMember 'int'
int main(int argc, char **argv) {
@@ -184,5 +187,5 @@ int main(int argc, char **argv) {
AnonABCVoid.AnonymousMember = 2;
AnonABCVoidD.AnonymousDMember = 3;
- return 0;
+ return AnonABCVoidD.StaticMember;
}
>From be1123fa94dee98e2a01293cbed7245b56ba7d33 Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Wed, 10 Dec 2025 17:35:04 +0100
Subject: [PATCH 2/3] refactor: use `CVTagRecord` to store the record
---
.../NativePDB/UdtRecordCompleter.cpp | 38 +++++++------------
.../SymbolFile/NativePDB/UdtRecordCompleter.h | 9 +----
2 files changed, 16 insertions(+), 31 deletions(-)
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
index bfaba7f91b711..8ab06e09b024e 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
@@ -41,30 +41,22 @@ UdtRecordCompleter::UdtRecordCompleter(
llvm::DenseMap<lldb::opaque_compiler_type_t,
llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>, 8>>
&cxx_record_map)
- : m_id(id), m_derived_ct(derived_ct), m_tag_decl(tag_decl),
+ : m_cv_tag_record(CVTagRecord::create(index.tpi().getType(id.index))),
+ m_id(id), m_derived_ct(derived_ct), m_tag_decl(tag_decl),
m_ast_builder(ast_builder), m_index(index),
m_decl_to_status(decl_to_status), m_cxx_record_map(cxx_record_map) {
- CVType cvt = m_index.tpi().getType(m_id.index);
- switch (cvt.kind()) {
- case LF_ENUM:
- m_cvr.er.Options = ClassOptions::None;
- llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, m_cvr.er));
+ switch (m_cv_tag_record.kind()) {
+ case CVTagRecord::Enum:
break;
- case LF_UNION:
- m_cvr.ur.Options = ClassOptions::None;
- llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, m_cvr.ur));
- m_layout.bit_size = m_cvr.ur.getSize() * 8;
+ case CVTagRecord::Union:
+ m_layout.bit_size = m_cv_tag_record.asUnion().getSize() * 8;
m_record.record.kind = Member::Union;
break;
- case LF_CLASS:
- case LF_STRUCTURE:
- m_cvr.cr.Options = ClassOptions::None;
- llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, m_cvr.cr));
- m_layout.bit_size = m_cvr.cr.getSize() * 8;
+ case CVTagRecord::Class:
+ case CVTagRecord::Struct:
+ m_layout.bit_size = m_cv_tag_record.asClass().getSize() * 8;
m_record.record.kind = Member::Struct;
break;
- default:
- llvm_unreachable("unreachable!");
}
}
@@ -168,13 +160,11 @@ Error UdtRecordCompleter::visitKnownMember(
// Static constant members may be a const[expr] declaration.
// Query the symbol's value as the variable initializer if valid.
if (member_ct.IsConst() && member_ct.IsCompleteType()) {
- std::string qual_name;
- if (m_record.record.kind == Member::Struct)
- qual_name = (m_cvr.cr.Name + "::" + static_data_member.Name).str();
- else if (m_record.record.kind == Member::Union)
- qual_name = (m_cvr.ur.Name + "::" + static_data_member.Name).str();
- else
- qual_name = decl->getQualifiedNameAsString();
+ // Reconstruct the full name for the static member. Use the names as given
+ // in the PDB. This ensures we match the compiler's style of names (e.g.
+ // "A<B<int> >::Foo" vs "A<B<int>>::Foo").
+ std::string qual_name =
+ (m_cv_tag_record.name() + "::" + static_data_member.Name).str();
auto results =
m_index.globals().findRecordsByName(qual_name, m_index.symrecords());
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
index e6e91d0f2c3e4..73c45456899e4 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
@@ -11,6 +11,7 @@
#include "PdbAstBuilder.h"
#include "PdbSymUid.h"
+#include "PdbUtil.h"
#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
@@ -41,13 +42,7 @@ class UdtRecordCompleter : public llvm::codeview::TypeVisitorCallbacks {
using IndexedBase =
std::pair<uint64_t, std::unique_ptr<clang::CXXBaseSpecifier>>;
- union UdtTagRecord {
- UdtTagRecord() {}
- llvm::codeview::UnionRecord ur;
- llvm::codeview::ClassRecord cr;
- llvm::codeview::EnumRecord er;
- } m_cvr;
-
+ CVTagRecord m_cv_tag_record;
PdbTypeSymId m_id;
CompilerType &m_derived_ct;
clang::TagDecl &m_tag_decl;
>From 3aade9c0a43ae3c880743ac461d98c9e7615f41b Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Wed, 10 Dec 2025 17:35:27 +0100
Subject: [PATCH 3/3] test: Add check for static member in union
---
.../NativePDB/Inputs/ast-types.lldbinit | 1 +
.../Shell/SymbolFile/NativePDB/ast-types.cpp | 23 +++++++++++++++----
2 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/Inputs/ast-types.lldbinit b/lldb/test/Shell/SymbolFile/NativePDB/Inputs/ast-types.lldbinit
index a79d18fcfbe70..5062faa97db00 100644
--- a/lldb/test/Shell/SymbolFile/NativePDB/Inputs/ast-types.lldbinit
+++ b/lldb/test/Shell/SymbolFile/NativePDB/Inputs/ast-types.lldbinit
@@ -19,6 +19,7 @@ target variable ADE
target variable AnonInt
target variable AnonABCVoid
target variable AnonABCVoidD
+target variable AnonABCVoidU
target variable mp1 mp2 mp3 mp4 mp5 mp6 mp7 mp8 mp9
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp b/lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp
index 4b267c398e766..e3af6d21893a7 100644
--- a/lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp
+++ b/lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp
@@ -59,6 +59,11 @@ namespace {
static constexpr int StaticMember = 1;
int AnonymousDMember;
};
+
+ union U {
+ static constexpr int StaticMember = 2;
+ int AnonymousUMember;
+ };
};
}
@@ -86,6 +91,7 @@ A::D::E ADE;
Anonymous<int> AnonInt;
Anonymous<A::B::C<void>> AnonABCVoid;
Anonymous<A::B::C<void>>::D AnonABCVoidD;
+Anonymous<A::B::C<void>>::U AnonABCVoidU;
// The following tests that MSInheritanceAttr are set for record decls.
class SI { int si; };
@@ -132,6 +138,7 @@ int SI::*mp9 = nullptr;
// CHECK: (Anonymous<int>) AnonInt = (AnonymousMember = 0)
// CHECK: (Anonymous<A::B::C<void>>) AnonABCVoid = (AnonymousMember = 0)
// CHECK: (Anonymous<A::B::C<void>>::D) AnonABCVoidD = (AnonymousDMember = 0)
+// CHECK: (Anonymous<A::B::C<void>>::U) AnonABCVoidU = (AnonymousUMember = 0)
// CHECK: (void (SI::*)()) mp1 = 0x0000000000000000
// CHECK: (void (MI::*)()) mp2 = 0x0000000000000000
// CHECK: (void (MI2::*)()) mp3 = 0x0000000000000000
@@ -177,15 +184,21 @@ int SI::*mp9 = nullptr;
// CHECK: | | `-FieldDecl {{.*}} AnonymousMember 'int'
// CHECK: | `-CXXRecordDecl {{.*}} struct Anonymous<A::B::C<void>> definition
// CHECK: | |-FieldDecl {{.*}} AnonymousMember 'int'
-// CHECK: | `-CXXRecordDecl {{.*}} struct D definition
-// CHECK: | |-VarDecl {{.*}} StaticMember 'const int' static cinit
-// CHECK: | | `-IntegerLiteral {{.*}} 'int' 1
-// CHECK: | `-FieldDecl {{.*}} AnonymousDMember 'int'
+// CHECK: | |-CXXRecordDecl {{.*}} struct D definition
+// CHECK: | | |-VarDecl {{.*}} StaticMember 'const int' static cinit
+// CHECK: | | | `-IntegerLiteral {{.*}} 'int' 1
+// CHECK: | | `-FieldDecl {{.*}} AnonymousDMember 'int'
+// CHECK: | `-CXXRecordDecl {{.*}} union U definition
+// CHECK: | |-VarDecl {{.*}} StaticMember 'const int' static
+// CHECK: | | `-IntegerLiteral {{.*}} 'int' 2
+// CHECK: | `-FieldDecl {{.*}} AnonymousUMember 'int'
+
int main(int argc, char **argv) {
AnonInt.AnonymousMember = 1;
AnonABCVoid.AnonymousMember = 2;
AnonABCVoidD.AnonymousDMember = 3;
+ AnonABCVoidU.AnonymousUMember = 4;
- return AnonABCVoidD.StaticMember;
+ return AnonABCVoidD.StaticMember + AnonABCVoidU.StaticMember;
}
More information about the lldb-commits
mailing list