[Lldb-commits] [lldb] [LLDB][NativePDB] Set IsDynmaicCXXType metadata for records (PR #155853)
via lldb-commits
lldb-commits at lists.llvm.org
Sat Aug 8 06:56:50 PDT 2026
https://github.com/Nerixyz updated https://github.com/llvm/llvm-project/pull/155853
>From 8c8271891df15699c6a13d3280e011206e407c70 Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Sat, 8 Aug 2026 15:56:33 +0200
Subject: [PATCH] [LLDB][NativePDB] Set IsDynmaicCXXType metadata for records
---
.../Clang/ClangASTMetadata.cpp | 10 ++---
.../NativePDB/PdbAstBuilderClang.cpp | 19 +++++---
.../SymbolFile/NativePDB/PdbAstBuilderClang.h | 5 ++-
.../NativePDB/UdtRecordCompleter.cpp | 7 +++
.../SymbolFile/NativePDB/UdtRecordCompleter.h | 1 +
.../TypeSystem/Clang/TypeSystemClang.cpp | 25 ++++++++---
.../SymbolFile/NativePDB/dynamic-types.cpp | 43 +++++++++++++++++++
7 files changed, 89 insertions(+), 21 deletions(-)
create mode 100644 lldb/test/Shell/SymbolFile/NativePDB/dynamic-types.cpp
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.cpp
index 2c5dacb60a9b8..d77509ef248d4 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTMetadata.cpp
@@ -31,12 +31,12 @@ void ClangASTMetadata::Dump(Stream *s) {
lldb::user_id_t uid = GetUserID();
if (uid != LLDB_INVALID_UID) {
- s->Printf("uid=0x%" PRIx64, uid);
+ s->Printf("uid=0x%" PRIx64 " ", uid);
}
uint64_t isa_ptr = GetISAPtr();
if (isa_ptr != 0) {
- s->Printf("isa_ptr=0x%" PRIx64, isa_ptr);
+ s->Printf("isa_ptr=0x%" PRIx64 " ", isa_ptr);
}
const char *obj_ptr_name = GetObjectPtrName();
@@ -44,8 +44,8 @@ void ClangASTMetadata::Dump(Stream *s) {
s->Printf("obj_ptr_name=\"%s\" ", obj_ptr_name);
}
- if (m_is_dynamic_cxx) {
- s->Printf("is_dynamic_cxx=%i ", m_is_dynamic_cxx);
- }
+ if (m_is_dynamic_cxx)
+ *s << "is_dynamic_cxx=" << (m_is_dynamic_cxx == 2) << ' ';
+
s->EOL();
}
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp
index 673bd2826b455..ca02b298f9f4d 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp
@@ -695,17 +695,24 @@ PdbAstBuilderClang::CreateModifierType(const ModifierRecord &modifier) {
}
clang::QualType PdbAstBuilderClang::CreateRecordType(PdbTypeSymId id,
- const TagRecord &record) {
+ const CVTagRecord &record) {
clang::DeclContext *context = nullptr;
std::string uname;
- std::tie(context, uname) = CreateDeclInfoForType(record, id.index);
+ std::tie(context, uname) = CreateDeclInfoForType(record.asTag(), id.index);
if (!context)
return {};
- clang::TagTypeKind ttk = TranslateUdtKind(record);
+ clang::TagTypeKind ttk = TranslateUdtKind(record.asTag());
ClangASTMetadata metadata;
metadata.SetUserID(toOpaqueUid(id));
- metadata.SetIsDynamicCXXType(false);
+ // unions can't be dynamic
+ if (record.contextKind() != CompilerContextKind::ClassOrStruct)
+ metadata.SetIsDynamicCXXType(false);
+ // If a class has a vtable, it is dynamic.
+ else if (!record.asClass().getVTableShape().isNoneType())
+ metadata.SetIsDynamicCXXType(true);
+ // else
+ // wait until the record is completed as it might have virtual bases
CompilerType ct = m_clang.CreateRecordType(
context, OptionalClangModuleID(), uname, llvm::to_underlying(ttk),
@@ -888,11 +895,9 @@ clang::QualType PdbAstBuilderClang::CreateType(PdbTypeSymId type) {
if (IsTagRecord(cvt)) {
CVTagRecord tag = CVTagRecord::create(cvt);
- if (tag.kind() == CVTagRecord::Union)
- return CreateRecordType(type.index, tag.asUnion());
if (tag.kind() == CVTagRecord::Enum)
return CreateEnumType(type.index, tag.asEnum());
- return CreateRecordType(type.index, tag.asClass());
+ return CreateRecordType(type.index, tag);
}
if (cvt.kind() == LF_ARRAY) {
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.h
index 0d214cb57f820..2abf1eb58f3ac 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.h
@@ -50,6 +50,8 @@ struct DeclStatus {
bool resolved = false;
};
+struct CVTagRecord;
+
class PdbAstBuilderClang : public PdbAstBuilder {
public:
PdbAstBuilderClang(TypeSystemClang &clang);
@@ -114,8 +116,7 @@ class PdbAstBuilderClang : public PdbAstBuilder {
clang::QualType
CreateModifierType(const llvm::codeview::ModifierRecord &modifier);
clang::QualType CreateArrayType(const llvm::codeview::ArrayRecord &array);
- clang::QualType CreateRecordType(PdbTypeSymId id,
- const llvm::codeview::TagRecord &record);
+ clang::QualType CreateRecordType(PdbTypeSymId id, const CVTagRecord &record);
clang::QualType CreateEnumType(PdbTypeSymId id,
const llvm::codeview::EnumRecord &record);
clang::QualType
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
index 871b053151c61..2476928eb5a3e 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp
@@ -133,6 +133,7 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr,
// LF_VBCLASS.
if (cvr.Kind == LF_VBCLASS)
AddBaseClassForTypeIndex(base.BaseType, base.getAccess(), base.VTableIndex);
+ m_any_virtual_base = true;
return Error::success();
}
@@ -384,6 +385,12 @@ void UdtRecordCompleter::complete() {
if (auto *record_decl = llvm::dyn_cast<clang::CXXRecordDecl>(&m_tag_decl)) {
m_ast_builder.GetClangASTImporter().SetRecordLayout(record_decl, m_layout);
}
+
+ if (auto meta = m_ast_builder.clang().GetMetadata(&m_tag_decl)) {
+ meta->SetIsDynamicCXXType(meta->GetIsDynamicCXXType().value_or(false) ||
+ m_any_virtual_base);
+ m_ast_builder.clang().SetMetadata(&m_tag_decl, *meta);
+ }
}
uint64_t
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
index 0a6aedefa69e8..54029e1e4d28a 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h
@@ -53,6 +53,7 @@ class UdtRecordCompleter : public llvm::codeview::TypeVisitorCallbacks {
llvm::DenseMap<lldb::opaque_compiler_type_t,
llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>, 8>>
&m_cxx_record_map;
+ bool m_any_virtual_base = false;
public:
UdtRecordCompleter(
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 4a637f0817759..54d4d3f26b47a 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -8784,12 +8784,6 @@ void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type,
lldb::DescriptionLevel level) {
StreamFile s(stdout, false);
DumpTypeDescription(type, s, level);
-
- CompilerType ct(weak_from_this(), type);
- const clang::Type *clang_type = ClangUtil::GetQualType(ct).getTypePtr();
- if (std::optional<ClangASTMetadata> metadata = GetMetadata(clang_type)) {
- metadata->Dump(&s);
- }
}
void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type,
@@ -8878,7 +8872,24 @@ void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type,
if (buf.size() > 0) {
s.Write(buf.data(), buf.size());
}
-}
+
+ if (level == eDescriptionLevelVerbose) {
+ std::optional<ClangASTMetadata> metadata =
+ GetMetadata(qual_type.getTypePtr());
+ if (metadata) {
+ s << "type-metadata = ";
+ metadata->Dump(&s);
+ }
+
+ if (const clang::TagDecl *tag = qual_type->getAsTagDecl())
+ metadata = GetMetadata(tag);
+
+ if (metadata) {
+ s << "decl-metadata = ";
+ metadata->Dump(&s);
+ }
+ }
+ }
}
void TypeSystemClang::DumpTypeName(const CompilerType &type) {
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/dynamic-types.cpp b/lldb/test/Shell/SymbolFile/NativePDB/dynamic-types.cpp
new file mode 100644
index 0000000000000..576a601c7190e
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/NativePDB/dynamic-types.cpp
@@ -0,0 +1,43 @@
+// clang-format off
+// REQUIRES: lld, x86
+
+// RUN: %clang_cl --target=x86_64-windows-msvc -Od -GS- -GR- -std:c++20 -Z7 -c /Fo%t.obj -- %s
+// RUN: lld-link -debug:full -nodefaultlib -entry:main %t.obj -out:%t.exe -pdb:%t.pdb
+
+// RUN: lldb-test symbols --dump-clang-ast --find=type --name=Base %t.exe | FileCheck %s --check-prefix=DYNAMIC
+// RUN: lldb-test symbols --dump-clang-ast --find=type --name=UsingBase %t.exe | FileCheck %s --check-prefix=DYNAMIC
+// RUN: lldb-test symbols --dump-clang-ast --find=type --name=UsingVBase %t.exe | FileCheck %s --check-prefix=DYNAMIC
+// RUN: lldb-test symbols --dump-clang-ast --find=type --name=UsingUsingVBase %t.exe | FileCheck %s --check-prefix=DYNAMIC
+
+// RUN: lldb-test symbols --dump-clang-ast --find=type --name=VBase %t.exe | FileCheck %s --check-prefix=NOT-DYNAMIC
+// RUN: lldb-test symbols --dump-clang-ast --find=type --name=NotDynamic %t.exe | FileCheck %s --check-prefix=NOT-DYNAMIC
+
+// DYNAMIC: Found 1 types:
+// DYNAMIC: decl-metadata = uid={{.*}} is_dynamic_cxx=true
+
+// NOT-DYNAMIC: Found 1 types:
+// NOT-DYNAMIC: decl-metadata = uid={{.*}} is_dynamic_cxx=false
+
+struct Base {
+ virtual ~Base() = default;
+};
+
+struct UsingBase : public Base {};
+
+struct VBase {};
+
+struct UsingVBase : public virtual VBase {};
+
+struct UsingUsingVBase : public UsingVBase {};
+
+struct NotDynamic : public VBase {};
+
+void operator delete(void *, unsigned __int64 i) throw() {}
+
+int main() {
+ UsingBase ub;
+ UsingVBase uvb;
+ UsingUsingVBase uuvb;
+ NotDynamic nd;
+ return 0;
+}
More information about the lldb-commits
mailing list