diff options
| author | nerix <nerixdev@outlook.de> | 2025-08-04 09:56:04 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-04 08:56:04 +0100 |
| commit | d95dadff8f094e793b79eec57737ec397fad7724 (patch) | |
| tree | 85379c667e0d79de746db4a2766ce69aac3a9b20 /lldb/test/Shell/SymbolFile/NativePDB | |
| parent | df71243fa885cd3db701dc35a0c8d157adaf93b3 (diff) | |
| download | llvm-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.test | 135 |
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 |
