[Lldb-commits] [lldb] [LLDB][NativePDB] Implement `FindNamespace` (PR #151950)
via lldb-commits
lldb-commits at lists.llvm.org
Mon Aug 4 05:17:14 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: nerix (Nerixyz)
<details>
<summary>Changes</summary>
`FindNamespace` was not implemented for `SymbolFileNativePDB`. Without it, it wasn't possible to lookup items through namespaces when evaluating expressions.
This is mostly the same as in [SymbolFilePDB](https://github.com/llvm/llvm-project/blob/f1eb869bae2ab86726ee3a5a5c7980d5b2acbd5d/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp#L1664-L1696) as well as [PDBAstParser](https://github.com/llvm/llvm-project/blob/f1eb869bae2ab86726ee3a5a5c7980d5b2acbd5d/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp#L1126-L1150): The AST parser/builder saves the created namespaces in a map to lookup when a namespace is requested.
This is working towards making [Shell/SymbolFile/PDB/expressions.test](https://github.com/llvm/llvm-project/blob/f1eb869bae2ab86726ee3a5a5c7980d5b2acbd5d/lldb/test/Shell/SymbolFile/PDB/expressions.test) pass with the native PDB plugin.
---
Full diff: https://github.com/llvm/llvm-project/pull/151950.diff
4 Files Affected:
- (modified) lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp (+31-1)
- (modified) lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h (+12-1)
- (modified) lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp (+30-3)
- (modified) lldb/test/Shell/SymbolFile/NativePDB/namespace-access.test (+29-1)
``````````diff
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index 8137622842253..92a102bbc92a8 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -644,9 +644,12 @@ clang::Decl *PdbAstBuilder::TryGetDecl(PdbSymUid uid) const {
clang::NamespaceDecl *
PdbAstBuilder::GetOrCreateNamespaceDecl(const char *name,
clang::DeclContext &context) {
- return m_clang.GetUniqueNamespaceDeclaration(
+ clang::NamespaceDecl *ns = m_clang.GetUniqueNamespaceDeclaration(
IsAnonymousNamespaceName(name) ? nullptr : name, &context,
OptionalClangModuleID());
+ m_known_namespaces.insert(ns);
+ m_parent_to_namespaces[&context].insert(ns);
+ return ns;
}
clang::BlockDecl *
@@ -1452,3 +1455,30 @@ PdbAstBuilder::FromCompilerDeclContext(CompilerDeclContext context) {
void PdbAstBuilder::Dump(Stream &stream, llvm::StringRef filter) {
m_clang.Dump(stream.AsRawOstream(), filter);
}
+
+clang::NamespaceDecl *
+PdbAstBuilder::FindNamespaceDecl(const clang::DeclContext *parent,
+ llvm::StringRef name) {
+ NamespaceSet *set;
+ if (parent) {
+ auto it = m_parent_to_namespaces.find(parent);
+ if (it == m_parent_to_namespaces.end())
+ return nullptr;
+
+ set = &it->second;
+ } else {
+ // In this case, search through all known namespaces
+ set = &m_known_namespaces;
+ }
+ assert(set);
+
+ for (clang::NamespaceDecl *namespace_decl : *set)
+ if (namespace_decl->getName() == name)
+ return namespace_decl;
+
+ for (clang::NamespaceDecl *namespace_decl : *set)
+ if (namespace_decl->isAnonymousNamespace())
+ return FindNamespaceDecl(namespace_decl, name);
+
+ return nullptr;
+}
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
index 66a3836fac053..fef65227bc8f5 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h
@@ -89,6 +89,9 @@ class PdbAstBuilder {
void Dump(Stream &stream, llvm::StringRef filter);
+ clang::NamespaceDecl *FindNamespaceDecl(const clang::DeclContext *parent,
+ llvm::StringRef name);
+
private:
clang::Decl *TryGetDecl(PdbSymUid uid) const;
@@ -150,7 +153,15 @@ class PdbAstBuilder {
llvm::DenseMap<lldb::opaque_compiler_type_t,
llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>, 8>>
m_cxx_record_map;
- llvm::DenseSet<clang::NamespaceDecl *> m_parsed_namespaces;
+
+ using NamespaceSet = llvm::DenseSet<clang::NamespaceDecl *>;
+
+ // These namespaces are fully parsed
+ NamespaceSet m_parsed_namespaces;
+
+ // We know about these namespaces, but they might not be completely parsed yet
+ NamespaceSet m_known_namespaces;
+ llvm::DenseMap<clang::DeclContext *, NamespaceSet> m_parent_to_namespaces;
};
} // namespace npdb
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 7af53e16ce9d5..0fe411e598545 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -2164,9 +2164,36 @@ void SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
TypeClass type_mask,
lldb_private::TypeList &type_list) {}
-CompilerDeclContext SymbolFileNativePDB::FindNamespace(
- ConstString name, const CompilerDeclContext &parent_decl_ctx, bool) {
- return {};
+CompilerDeclContext
+SymbolFileNativePDB::FindNamespace(ConstString name,
+ const CompilerDeclContext &parent_decl_ctx,
+ bool /* only_root_namespaces */) {
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+ auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
+ if (auto err = ts_or_err.takeError())
+ return {};
+ auto ts = *ts_or_err;
+ if (!ts)
+ return {};
+ auto *clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
+ if (!clang)
+ return {};
+
+ PdbAstBuilder *ast_builder = clang->GetNativePDBParser();
+ if (!ast_builder)
+ return {};
+
+ clang::DeclContext *decl_context = nullptr;
+ if (parent_decl_ctx)
+ decl_context = static_cast<clang::DeclContext *>(
+ parent_decl_ctx.GetOpaqueDeclContext());
+
+ auto *namespace_decl =
+ ast_builder->FindNamespaceDecl(decl_context, name.GetStringRef());
+ if (!namespace_decl)
+ return CompilerDeclContext();
+
+ return clang->CreateDeclContext(namespace_decl);
}
llvm::Expected<lldb::TypeSystemSP>
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/namespace-access.test b/lldb/test/Shell/SymbolFile/NativePDB/namespace-access.test
index f6c1ccf22fa18..22ecfa16a11fb 100644
--- a/lldb/test/Shell/SymbolFile/NativePDB/namespace-access.test
+++ b/lldb/test/Shell/SymbolFile/NativePDB/namespace-access.test
@@ -77,8 +77,18 @@ type lookup Outer::Inner2::S
type lookup Outer::A
type lookup A
type lookup ::A
+# Test that Clang can find the namespaces as well
expr sizeof(S)
+expr sizeof(::S)
+expr sizeof(Outer::S)
+expr sizeof(Outer::Inner1::S)
+expr sizeof(Inner1::S)
+expr sizeof(Outer::Inner1::Inner2::S)
+expr sizeof(Inner2::S)
+expr sizeof(Outer::Inner2::S)
+expr sizeof(Outer::A)
expr sizeof(A)
+expr sizeof(::A)
quit
@@ -131,5 +141,23 @@ quit
# CHECK-NEXT: }
# CHECK-NEXT: (lldb) expr sizeof(S)
# CHECK-NEXT: (__size_t) $0 = 1
+# CHECK-NEXT: (lldb) expr sizeof(::S)
+# CHECK-NEXT: (__size_t) $1 = 1
+# CHECK-NEXT: (lldb) expr sizeof(Outer::S)
+# CHECK-NEXT: (__size_t) $2 = 2
+# CHECK-NEXT: (lldb) expr sizeof(Outer::Inner1::S)
+# CHECK-NEXT: (__size_t) $3 = 3
+# CHECK-NEXT: (lldb) expr sizeof(Inner1::S)
+# CHECK-NEXT: (__size_t) $4 = 3
+# CHECK-NEXT: (lldb) expr sizeof(Outer::Inner1::Inner2::S)
+# CHECK-NEXT: (__size_t) $5 = 4
+# CHECK-NEXT: (lldb) expr sizeof(Inner2::S)
+# CHECK-NEXT: (__size_t) $6 = 5
+# CHECK-NEXT: (lldb) expr sizeof(Outer::Inner2::S)
+# CHECK-NEXT: (__size_t) $7 = 5
+# CHECK-NEXT: (lldb) expr sizeof(Outer::A)
+# CHECK-NEXT: (__size_t) $8 = 6
# CHECK-NEXT: (lldb) expr sizeof(A)
-# CHECK-NEXT: (__size_t) $1 = 7
+# CHECK-NEXT: (__size_t) $9 = 7
+# CHECK-NEXT: (lldb) expr sizeof(::A)
+# CHECK-NEXT: (__size_t) $10 = 7
``````````
</details>
https://github.com/llvm/llvm-project/pull/151950
More information about the lldb-commits
mailing list