Skip to content

Commit 852cc92

Browse files
authored
[LLDB][NativePDB] Implement FindNamespace (#151950)
`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.
1 parent 3bdfca5 commit 852cc92

File tree

4 files changed

+99
-6
lines changed

4 files changed

+99
-6
lines changed

lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -644,9 +644,12 @@ clang::Decl *PdbAstBuilder::TryGetDecl(PdbSymUid uid) const {
644644
clang::NamespaceDecl *
645645
PdbAstBuilder::GetOrCreateNamespaceDecl(const char *name,
646646
clang::DeclContext &context) {
647-
return m_clang.GetUniqueNamespaceDeclaration(
647+
clang::NamespaceDecl *ns = m_clang.GetUniqueNamespaceDeclaration(
648648
IsAnonymousNamespaceName(name) ? nullptr : name, &context,
649649
OptionalClangModuleID());
650+
m_known_namespaces.insert(ns);
651+
m_parent_to_namespaces[&context].insert(ns);
652+
return ns;
650653
}
651654

652655
clang::BlockDecl *
@@ -1452,3 +1455,30 @@ PdbAstBuilder::FromCompilerDeclContext(CompilerDeclContext context) {
14521455
void PdbAstBuilder::Dump(Stream &stream, llvm::StringRef filter) {
14531456
m_clang.Dump(stream.AsRawOstream(), filter);
14541457
}
1458+
1459+
clang::NamespaceDecl *
1460+
PdbAstBuilder::FindNamespaceDecl(const clang::DeclContext *parent,
1461+
llvm::StringRef name) {
1462+
NamespaceSet *set;
1463+
if (parent) {
1464+
auto it = m_parent_to_namespaces.find(parent);
1465+
if (it == m_parent_to_namespaces.end())
1466+
return nullptr;
1467+
1468+
set = &it->second;
1469+
} else {
1470+
// In this case, search through all known namespaces
1471+
set = &m_known_namespaces;
1472+
}
1473+
assert(set);
1474+
1475+
for (clang::NamespaceDecl *namespace_decl : *set)
1476+
if (namespace_decl->getName() == name)
1477+
return namespace_decl;
1478+
1479+
for (clang::NamespaceDecl *namespace_decl : *set)
1480+
if (namespace_decl->isAnonymousNamespace())
1481+
return FindNamespaceDecl(namespace_decl, name);
1482+
1483+
return nullptr;
1484+
}

lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ class PdbAstBuilder {
8989

9090
void Dump(Stream &stream, llvm::StringRef filter);
9191

92+
clang::NamespaceDecl *FindNamespaceDecl(const clang::DeclContext *parent,
93+
llvm::StringRef name);
94+
9295
private:
9396
clang::Decl *TryGetDecl(PdbSymUid uid) const;
9497

@@ -150,7 +153,15 @@ class PdbAstBuilder {
150153
llvm::DenseMap<lldb::opaque_compiler_type_t,
151154
llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>, 8>>
152155
m_cxx_record_map;
153-
llvm::DenseSet<clang::NamespaceDecl *> m_parsed_namespaces;
156+
157+
using NamespaceSet = llvm::DenseSet<clang::NamespaceDecl *>;
158+
159+
// These namespaces are fully parsed
160+
NamespaceSet m_parsed_namespaces;
161+
162+
// We know about these namespaces, but they might not be completely parsed yet
163+
NamespaceSet m_known_namespaces;
164+
llvm::DenseMap<clang::DeclContext *, NamespaceSet> m_parent_to_namespaces;
154165
};
155166

156167
} // namespace npdb

lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2168,9 +2168,36 @@ void SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
21682168
TypeClass type_mask,
21692169
lldb_private::TypeList &type_list) {}
21702170

2171-
CompilerDeclContext SymbolFileNativePDB::FindNamespace(
2172-
ConstString name, const CompilerDeclContext &parent_decl_ctx, bool) {
2173-
return {};
2171+
CompilerDeclContext
2172+
SymbolFileNativePDB::FindNamespace(ConstString name,
2173+
const CompilerDeclContext &parent_decl_ctx,
2174+
bool /* only_root_namespaces */) {
2175+
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
2176+
auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
2177+
if (auto err = ts_or_err.takeError())
2178+
return {};
2179+
auto ts = *ts_or_err;
2180+
if (!ts)
2181+
return {};
2182+
auto *clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
2183+
if (!clang)
2184+
return {};
2185+
2186+
PdbAstBuilder *ast_builder = clang->GetNativePDBParser();
2187+
if (!ast_builder)
2188+
return {};
2189+
2190+
clang::DeclContext *decl_context = nullptr;
2191+
if (parent_decl_ctx)
2192+
decl_context = static_cast<clang::DeclContext *>(
2193+
parent_decl_ctx.GetOpaqueDeclContext());
2194+
2195+
auto *namespace_decl =
2196+
ast_builder->FindNamespaceDecl(decl_context, name.GetStringRef());
2197+
if (!namespace_decl)
2198+
return CompilerDeclContext();
2199+
2200+
return clang->CreateDeclContext(namespace_decl);
21742201
}
21752202

21762203
llvm::Expected<lldb::TypeSystemSP>

lldb/test/Shell/SymbolFile/NativePDB/namespace-access.test

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,17 @@ type lookup Outer::Inner2::S
7777
type lookup Outer::A
7878
type lookup A
7979
type lookup ::A
80+
# Test that Clang can find the namespaces as well
8081
expr sizeof(S)
82+
expr sizeof(::S)
83+
expr sizeof(Outer::S)
84+
expr sizeof(Outer::Inner1::S)
85+
expr sizeof(Inner1::S)
86+
expr sizeof(Outer::Inner1::Inner2::S)
87+
expr sizeof(Outer::Inner2::S)
88+
expr sizeof(Outer::A)
8189
expr sizeof(A)
90+
expr sizeof(::A)
8291

8392
quit
8493

@@ -131,5 +140,21 @@ quit
131140
# CHECK-NEXT: }
132141
# CHECK-NEXT: (lldb) expr sizeof(S)
133142
# CHECK-NEXT: (__size_t) $0 = 1
143+
# CHECK-NEXT: (lldb) expr sizeof(::S)
144+
# CHECK-NEXT: (__size_t) $1 = 1
145+
# CHECK-NEXT: (lldb) expr sizeof(Outer::S)
146+
# CHECK-NEXT: (__size_t) $2 = 2
147+
# CHECK-NEXT: (lldb) expr sizeof(Outer::Inner1::S)
148+
# CHECK-NEXT: (__size_t) $3 = 3
149+
# CHECK-NEXT: (lldb) expr sizeof(Inner1::S)
150+
# CHECK-NEXT: (__size_t) $4 = 3
151+
# CHECK-NEXT: (lldb) expr sizeof(Outer::Inner1::Inner2::S)
152+
# CHECK-NEXT: (__size_t) $5 = 4
153+
# CHECK-NEXT: (lldb) expr sizeof(Outer::Inner2::S)
154+
# CHECK-NEXT: (__size_t) $6 = 5
155+
# CHECK-NEXT: (lldb) expr sizeof(Outer::A)
156+
# CHECK-NEXT: (__size_t) $7 = 6
134157
# CHECK-NEXT: (lldb) expr sizeof(A)
135-
# CHECK-NEXT: (__size_t) $1 = 7
158+
# CHECK-NEXT: (__size_t) $8 = 7
159+
# CHECK-NEXT: (lldb) expr sizeof(::A)
160+
# CHECK-NEXT: (__size_t) $9 = 7

0 commit comments

Comments
 (0)