[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