aboutsummaryrefslogtreecommitdiff
path: root/lldb/test/Shell/SymbolFile/NativePDB
diff options
context:
space:
mode:
authornerix <nerixdev@outlook.de>2025-08-04 09:56:04 +0200
committerGitHub <noreply@github.com>2025-08-04 08:56:04 +0100
commitd95dadff8f094e793b79eec57737ec397fad7724 (patch)
tree85379c667e0d79de746db4a2766ce69aac3a9b20 /lldb/test/Shell/SymbolFile/NativePDB
parentdf71243fa885cd3db701dc35a0c8d157adaf93b3 (diff)
downloadllvm-d95dadff8f094e793b79eec57737ec397fad7724.zip
llvm-d95dadff8f094e793b79eec57737ec397fad7724.tar.gz
llvm-d95dadff8f094e793b79eec57737ec397fad7724.tar.bz2
[LLDB][NativePDB] Allow type lookup in namespaces (#149876)
Previously, `type lookup` for types in namespaces didn't work with the native PDB plugin, because `FindTypes` would only look for types whose base name was equal to their full name. PDB/CodeView does not store the base names in the TPI stream, but the types have their full name (e.g. `std::thread` instead of `thread`). So `findRecordsByName` would only return types in the top level namespace. This PR changes the lookup to go through all types and check their base name. As that could be a bit expensive, the names are first cached (similar to the function lookup in the DIA PDB plugin). Potential types are checked with `TypeQuery::ContextMatches`. To be able to handle anonymous namespaces, I changed `TypeQuery::ContextMatches`. The [`TypeQuery` constructor](https://github.com/llvm/llvm-project/blob/9ad7edef4276207ca4cefa6b39d11145f4145a72/lldb/source/Symbol/Type.cpp#L76-L79) inserts all name components as `CompilerContextKind::AnyDeclContext`. To skip over anonymous namespaces, `ContextMatches` checked if a component was empty and exactly of kind `Namespace`. For our query, the last check was always false, so we never skipped anonymous namespaces. DWARF doesn't have this problem, as it [constructs the context outside](https://github.com/llvm/llvm-project/blob/abe93d9d7e891a2a6596ddb0c6324280137c89dc/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp#L154-L160) and has proper information about namespaces. I'm not fully sure if my change is correct and that it doesn't break other users of `TypeQuery`. This enables `type lookup <type>` to work on types in namespaces. However, expressions don't work with this yet, because `FindNamespace` is unimplemented for native PDB.
Diffstat (limited to 'lldb/test/Shell/SymbolFile/NativePDB')
-rw-r--r--lldb/test/Shell/SymbolFile/NativePDB/namespace-access.test135
1 files changed, 135 insertions, 0 deletions
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/namespace-access.test b/lldb/test/Shell/SymbolFile/NativePDB/namespace-access.test
new file mode 100644
index 0000000..f6c1ccf
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/NativePDB/namespace-access.test
@@ -0,0 +1,135 @@
+# REQUIRES: target-windows
+
+# Test namespace lookup.
+# RUN: split-file %s %t
+# RUN: %build --nodefaultlib -o %t.exe -- %t/main.cpp
+# RUN: %lldb -f %t.exe -s \
+# RUN: %t/commands.input 2>&1 | FileCheck %s
+
+#--- main.cpp
+
+struct S {
+ char a[1];
+};
+
+namespace Outer {
+
+ struct S {
+ char a[2];
+ };
+
+ namespace Inner1 {
+ struct S {
+ char a[3];
+ };
+
+ namespace Inner2 {
+ struct S {
+ char a[4];
+ };
+ } // namespace Inner2
+ } // namespace Inner1
+
+ namespace Inner2 {
+ struct S {
+ char a[5];
+ };
+ } // namespace Inner2
+
+ namespace {
+ struct A {
+ char a[6];
+ };
+ } // namespace
+
+} // namespace Outer
+
+namespace {
+ struct A {
+ char a[7];
+ };
+} // namespace
+
+int main(int argc, char **argv) {
+ S s;
+ Outer::S os;
+ Outer::Inner1::S oi1s;
+ Outer::Inner1::Inner2::S oi1i2s;
+ Outer::Inner2::S oi2s;
+ A a1;
+ Outer::A a2;
+ return sizeof(s) + sizeof(os) + sizeof(oi1s) + sizeof(oi1i2s) + sizeof(oi2s) + sizeof(a1) + sizeof(a2);
+}
+
+#--- commands.input
+
+b main
+r
+
+type lookup S
+type lookup ::S
+type lookup Outer::S
+type lookup Outer::Inner1::S
+type lookup Inner1::S
+type lookup Outer::Inner1::Inner2::S
+type lookup Inner2::S
+type lookup Outer::Inner2::S
+type lookup Outer::A
+type lookup A
+type lookup ::A
+expr sizeof(S)
+expr sizeof(A)
+
+quit
+
+# CHECK: (lldb) type lookup S
+# CHECK: struct S {
+# CHECK: struct S {
+# CHECK: struct S {
+# CHECK: struct S {
+# CHECK: struct S {
+# CHECK: }
+# CHECK-NEXT: (lldb) type lookup ::S
+# CHECK-NEXT: struct S {
+# CHECK-NEXT: char a[1];
+# CHECK-NEXT: }
+# CHECK-NEXT: (lldb) type lookup Outer::S
+# CHECK-NEXT: struct S {
+# CHECK-NEXT: char a[2];
+# CHECK-NEXT: }
+# CHECK-NEXT: (lldb) type lookup Outer::Inner1::S
+# CHECK-NEXT: struct S {
+# CHECK-NEXT: char a[3];
+# CHECK-NEXT: }
+# CHECK-NEXT: (lldb) type lookup Inner1::S
+# CHECK-NEXT: struct S {
+# CHECK-NEXT: char a[3];
+# CHECK-NEXT: }
+# CHECK-NEXT: (lldb) type lookup Outer::Inner1::Inner2::S
+# CHECK-NEXT: struct S {
+# CHECK-NEXT: char a[4];
+# CHECK-NEXT: }
+# CHECK-NEXT: (lldb) type lookup Inner2::S
+# CHECK-NEXT: struct S {
+# CHECK: struct S {
+# CHECK: }
+# CHECK-NEXT: (lldb) type lookup Outer::Inner2::S
+# CHECK-NEXT: struct S {
+# CHECK-NEXT: char a[5];
+# CHECK-NEXT: }
+# CHECK-NEXT: (lldb) type lookup Outer::A
+# CHECK-NEXT: struct A {
+# CHECK-NEXT: char a[6];
+# CHECK-NEXT: }
+# CHECK-NEXT: (lldb) type lookup A
+# CHECK-NEXT: struct A {
+# CHECK: struct A {
+# CHECK: }
+# CHECK-NEXT: (lldb) type lookup ::A
+# CHECK-NEXT: struct A {
+# CHECK-NEXT: char a[7];
+# CHECK-NEXT: }
+# CHECK-NEXT: (lldb) expr sizeof(S)
+# CHECK-NEXT: (__size_t) $0 = 1
+# CHECK-NEXT: (lldb) expr sizeof(A)
+# CHECK-NEXT: (__size_t) $1 = 7