[Lldb-commits] [lldb] [lldb][NativePDB] Reuse the method decl added while completing the class (PR #227010)
Charles Zablit via lldb-commits
lldb-commits at lists.llvm.org
Mon Sep 28 07:54:11 PDT 2026
https://github.com/charles-zablit created https://github.com/llvm/llvm-project/pull/227010
`PdbAstBuilderClang::CreateFunctionDecl` returned `nullptr` for a method that `UdtRecordCompleter` had already added to its class. Because of this, the `Function` of any method whose class was completed first had no decl and no decl context. `GetOrCreateDeclContextForUid` then passed that null `DeclContext` to `TypeSystemClang::CreateDeclContext`, which asserts:
```
Assertion failed: Val && "isa<> used on a null pointer"
...
lldb_private::TypeSystemClang::CreateDeclContext
lldb_private::npdb::PdbAstBuilderClang::GetOrCreateDeclContextForUid
lldb_private::npdb::SymbolFileNativePDB::GetDeclContextForUID
lldb_private::Function::GetDeclContext
lldb_private::ClangExpressionDeclMap::LookupFunction
```
Look up the existing `CXXMethodDecl` by name and type and return it instead, and make `ToCompilerDeclContext` return an invalid `CompilerDeclContext` for a null `DeclContext` rather than handing it to `CreateDeclContext`.
With PDB debug info this fixes the crashes in:
- `TestCppOperators`
- `TestCppMultipleInheritance`
- `TestCPPEnumPromotion`
- `TestExprInConstVolatileMethod`
- `TestExprInConstMethodWithFixit`
- `TestDataFormatterCategories`
- `TestDataFormatterSynthVal`
>From ffa3bd2a13f7443739c914b582f1a68e8e5cbfdd Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Mon, 28 Sep 2026 15:49:16 +0100
Subject: [PATCH] [lldb][NativePDB] Reuse the method decl added while
completing the class
---
.../NativePDB/PdbAstBuilderClang.cpp | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp
index 6d4af9ec6bf95..ad7898bb8e730 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilderClang.cpp
@@ -1001,6 +1001,15 @@ CompilerType PdbAstBuilderClang::GetOrCreateType(PdbTypeSymId type) {
return ToCompilerType(qt);
}
+static clang::CXXMethodDecl *FindMethodDecl(clang::CXXRecordDecl *record,
+ llvm::StringRef name,
+ clang::QualType type) {
+ for (clang::CXXMethodDecl *method : record->methods())
+ if (method->getType() == type && method->getNameAsString() == name)
+ return method;
+ return nullptr;
+}
+
clang::FunctionDecl *PdbAstBuilderClang::CreateFunctionDecl(
PdbCompilandSymId func_id, llvm::StringRef func_name, TypeIndex func_ti,
CompilerType func_ct, uint32_t param_count,
@@ -1016,11 +1025,14 @@ clang::FunctionDecl *PdbAstBuilderClang::CreateFunctionDecl(
llvm::cast<clang::TypeDecl>(parent));
lldb::opaque_compiler_type_t parent_opaque_ty =
ToCompilerType(parent_qt).GetOpaqueQualType();
- // FIXME: Remove this workaround.
+ // The method may already have been added while completing the class.
auto iter = m_cxx_record_map.find(parent_opaque_ty);
if (iter != m_cxx_record_map.end()) {
if (iter->getSecond().contains({func_name, func_ct})) {
- return nullptr;
+ auto *record = llvm::dyn_cast<clang::CXXRecordDecl>(parent);
+ return record ? FindMethodDecl(record, func_name,
+ FromCompilerType(func_ct))
+ : nullptr;
}
}
@@ -1732,6 +1744,8 @@ clang::QualType PdbAstBuilderClang::FromCompilerType(CompilerType ct) {
CompilerDeclContext
PdbAstBuilderClang::ToCompilerDeclContext(clang::DeclContext *context) {
+ if (!context)
+ return CompilerDeclContext();
return m_clang.CreateDeclContext(context);
}
More information about the lldb-commits
mailing list