https://github.com/Nerixyz updated https://github.com/llvm/llvm-project/pull/169248
>From 66148315c58efd99056b91fd8984da33048052e0 Mon Sep 17 00:00:00 2001 From: Nerixyz <[email protected]> Date: Sun, 23 Nov 2025 23:01:12 +0100 Subject: [PATCH 1/2] [LLDB][NativePDB] Create typedefs in structs --- .../NativePDB/UdtRecordCompleter.cpp | 26 +++++++++ .../Shell/SymbolFile/NativePDB/ast-types.cpp | 6 +- .../SymbolFile/NativePDB/nested-types.cpp | 57 ++++++++++++++----- 3 files changed, 72 insertions(+), 17 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp index 46cf9b8524ede..d8e4255b4823f 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp @@ -233,6 +233,32 @@ Error UdtRecordCompleter::visitKnownMember( Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, NestedTypeRecord &nested) { + // Typedefs can only be added on structs. + if (m_record.record.kind != Member::Struct) + return Error::success(); + + clang::QualType qt = + m_ast_builder.GetOrCreateType(PdbTypeSymId(nested.Type, false)); + if (qt.isNull()) + return Error::success(); + CompilerType ct = m_ast_builder.ToCompilerType(qt); + + // There's no distinction between nested types and typedefs, so check if we + // encountered a nested type. + auto *pdb = static_cast<SymbolFileNativePDB *>( + m_ast_builder.clang().GetSymbolFile()->GetBackingSymbolFile()); + std::optional<TypeIndex> parent = pdb->GetParentType(nested.Type); + if (parent && *parent == m_id.index && ct.GetTypeName(true) == nested.Name) + return Error::success(); + + clang::DeclContext *decl_ctx = + m_ast_builder.GetOrCreateDeclContextForUid(m_id); + if (!decl_ctx) + return Error::success(); + + std::string name = nested.Name.str(); + ct.CreateTypedef(name.c_str(), m_ast_builder.ToCompilerDeclContext(*decl_ctx), + 0); return Error::success(); } diff --git a/lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp b/lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp index ac0d87e95dbf9..dea124c6d6145 100644 --- a/lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp +++ b/lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp @@ -175,9 +175,9 @@ int SI::*mp9 = nullptr; // CHECK: | |-CXXRecordDecl {{.*}} struct Anonymous<int> definition // CHECK: | | `-FieldDecl {{.*}} AnonymousMember 'int' // CHECK: | `-CXXRecordDecl {{.*}} struct Anonymous<A::B::C<void>> definition -// CHECK: | |-FieldDecl {{.*}} AnonymousMember 'int' -// CHECK: | `-CXXRecordDecl {{.*}} struct D definition -// CHECK: | `-FieldDecl {{.*}} AnonymousDMember 'int' +// CHECK: | |-CXXRecordDecl {{.*}} struct D definition +// CHECK: | | `-FieldDecl {{.*}} AnonymousDMember 'int' +// CHECK: | `-FieldDecl {{.*}} AnonymousMember 'int' int main(int argc, char **argv) { AnonInt.AnonymousMember = 1; diff --git a/lldb/test/Shell/SymbolFile/NativePDB/nested-types.cpp b/lldb/test/Shell/SymbolFile/NativePDB/nested-types.cpp index f725037a220d9..a4b07cdb1b1b7 100644 --- a/lldb/test/Shell/SymbolFile/NativePDB/nested-types.cpp +++ b/lldb/test/Shell/SymbolFile/NativePDB/nested-types.cpp @@ -126,30 +126,59 @@ int main(int argc, char **argv) { // CHECK: (lldb) target modules dump ast // CHECK: Dumping clang ast for 1 modules. // CHECK: TranslationUnitDecl {{.*}} + // CHECK: |-CXXRecordDecl {{.*}} struct S definition -// CHECK: | |-FieldDecl {{.*}} C 'int' -// CHECK: | |-FieldDecl {{.*}} D 'int' -// CHECK: | |-FieldDecl {{.*}} DD 'void *' // CHECK: | |-CXXRecordDecl {{.*}} struct NestedStruct definition // CHECK: | | |-FieldDecl {{.*}} A 'int' // CHECK: | | `-FieldDecl {{.*}} B 'int' -// CHECK: | `-EnumDecl {{.*}} NestedEnum -// CHECK: | |-EnumConstantDecl {{.*}} EnumValue1 'S::NestedEnum' -// CHECK: | `-EnumConstantDecl {{.*}} EnumValue2 'S::NestedEnum' +// CHECK: | |-EnumDecl {{.*}} NestedEnum +// CHECK: | | |-EnumConstantDecl {{.*}} EnumValue1 'S::NestedEnum' +// CHECK: | | `-EnumConstantDecl {{.*}} EnumValue2 'S::NestedEnum' +// CHECK: | |-TypedefDecl {{.*}} VoidPtrT 'void *' +// CHECK: | | `-PointerType {{.*}} 'void *' +// CHECK: | | `-BuiltinType {{.*}} 'void' +// CHECK: | |-FieldDecl {{.*}} C 'int' +// CHECK: | |-FieldDecl {{.*}} D 'int' +// CHECK: | `-FieldDecl {{.*}} DD 'void *' + // CHECK: |-CXXRecordDecl {{.*}} struct T definition -// CHECK: | |-FieldDecl {{.*}} NT 'int' +// CHECK: | |-TypedefDecl {{.*}} NestedTypedef 'int' +// CHECK: | | `-BuiltinType {{.*}} 'int' +// CHECK: | |-TypedefDecl {{.*}} NestedTypedef2 'S' +// CHECK: | | `-RecordType {{.*}} 'S' canonical +// CHECK: | | `-CXXRecord {{.*}} 'S' // CHECK: | |-CXXRecordDecl {{.*}} struct NestedStruct definition // CHECK: | | |-FieldDecl {{.*}} E 'int' // CHECK: | | `-FieldDecl {{.*}} F 'int' -// CHECK: | `-CXXRecordDecl {{.*}} struct U definition -// CHECK: | |-FieldDecl {{.*}} G 'int' -// CHECK: | `-FieldDecl {{.*}} H 'int' +// CHECK: | |-TypedefDecl {{.*}} NestedStructAlias 'T::NestedStruct' +// CHECK: | | `-RecordType {{.*}} 'T::NestedStruct' canonical +// CHECK: | | `-CXXRecord {{.*}} 'NestedStruct' +// CHECK: | |-TypedefDecl {{.*}} NST 'S::NestedStruct' +// CHECK: | | `-RecordType {{.*}} 'S::NestedStruct' canonical +// CHECK: | | `-CXXRecord {{.*}} 'NestedStruct' +// CHECK: | |-CXXRecordDecl {{.*}} struct U definition +// CHECK: | | |-FieldDecl {{.*}} G 'int' +// CHECK: | | `-FieldDecl {{.*}} H 'int' +// CHECK: | `-FieldDecl {{.*}} NT 'int' + // CHECK: |-CXXRecordDecl {{.*}} class U<int> definition +// CHECK: | |-CXXRecordDecl {{.*}} struct W definition +// CHECK: | | |-FieldDecl {{.*}} M 'int' +// CHECK: | | `-FieldDecl {{.*}} N 'int' +// CHECK: | |-TypedefDecl {{.*}} Y 'U<int>::V<int>' +// CHECK: | | `-RecordType {{.*}} 'U<int>::V<int>' canonical +// CHECK: | | `-CXXRecord {{.*}} 'U<int>::V<int>' +// CHECK: | |-TypedefDecl {{.*}} Z 'U<int>::V<T>' +// CHECK: | | `-RecordType {{.*}} 'U<int>::V<T>' canonical +// CHECK: | | `-CXXRecord {{.*}} 'U<int>::V<T>' // CHECK: | |-FieldDecl {{.*}} K 'int' -// CHECK: | |-FieldDecl {{.*}} L 'int' -// CHECK: | `-CXXRecordDecl {{.*}} struct W definition -// CHECK: | |-FieldDecl {{.*}} M 'int' -// CHECK: | `-FieldDecl {{.*}} N 'int' +// CHECK: | `-FieldDecl {{.*}} L 'int' + // CHECK: |-CXXRecordDecl {{.*}} struct U<int>::V<int> definition +// CHECK: | |-TypedefDecl {{.*}}> W 'int' +// CHECK: | | `-BuiltinType {{.*}} 'int' +// CHECK: | |-TypedefDecl {{.*}} X 'U<int>' +// CHECK: | | `-RecordType {{.*}} 'U<int>' canonical +// CHECK: | | `-CXXRecord {{.*}} 'U<int>' // CHECK: | |-FieldDecl {{.*}} I 'int' // CHECK: | `-FieldDecl {{.*}} J 'int' >From e19984600ae12c58c093af82e72d06edb9373591 Mon Sep 17 00:00:00 2001 From: Nerixyz <[email protected]> Date: Fri, 12 Dec 2025 21:19:23 +0100 Subject: [PATCH 2/2] fix: test (fields are now at the bottom) --- lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp b/lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp index e3af6d21893a7..4cc0b376d3ef9 100644 --- a/lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp +++ b/lldb/test/Shell/SymbolFile/NativePDB/ast-types.cpp @@ -183,15 +183,15 @@ int SI::*mp9 = nullptr; // CHECK: | |-CXXRecordDecl {{.*}} struct Anonymous<int> definition // 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 {{.*}} union U definition -// CHECK: | |-VarDecl {{.*}} StaticMember 'const int' static -// CHECK: | | `-IntegerLiteral {{.*}} 'int' 2 -// CHECK: | `-FieldDecl {{.*}} AnonymousUMember 'int' +// CHECK: | |-CXXRecordDecl {{.*}} union U definition +// CHECK: | | |-VarDecl {{.*}} StaticMember 'const int' static +// CHECK: | | | `-IntegerLiteral {{.*}} 'int' 2 +// CHECK: | | `-FieldDecl {{.*}} AnonymousUMember 'int' +// CHECK: | `-FieldDecl {{.*}} AnonymousMember 'int' int main(int argc, char **argv) { _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
