Files
Nerixyz 09ad100529 [lldb][NativePDB] Use decl context from a method's class (#199221)
When we look up the parent decl context for a method, we used to look
for that by name. For "regular" types that works well.
Say, we have a `struct ns::Foo` and `ns::Foo::bar`. We'd search for
`ns::Foo` and use its context.

For special types - mainly lambdas - this doesn't work. They can't be
found by looking for the name we get from the function symbol. That name
won't be in the TPI hash table we use.

I'm not fully sure under which name they're in that table. For example,
if we get the name `Foo::fun::<lambda_1>::operator()` from the function
symbol, we'd look for `Foo::fun::<lambda_1>`. This fails. A class with
this name is actually present, but it has a different unique name. Its
unique name demangles to `` `public: void __cdecl
Foo::fun(void)'::`1'::<lambda_1> `` which doesn't match what we searched
for. That might be the issue.

If we can't find a class/struct, we create namespaces. So before, we
created namespaces for each segment and added a regular function inside.
This was wrong for methods.

However, we can tell that a function is a method by looking at its
function type. And we know the parent class from this type. With this PR
that parent class is used if it's available.
2026-05-28 20:51:24 +02:00

46 lines
955 B
C++

// clang-format off
// REQUIRES: lld, x86
// RUN: %clang_cl --target=x86_64-windows-msvc -Od -GS- -std:c++20 -Z7 -c /Fo%t.obj -- %s
// RUN: lld-link -debug:full -nodefaultlib -entry:main %t.obj -out:%t.exe -pdb:%t.pdb
// RUN: lldb-test symbols --dump-ast %t.exe | FileCheck %s
class Foo {
public:
void fun() {
auto f = [this]() {
int c = a;
int d = b;
return a + b;
};
f();
int local = 42;
auto g = [=]() mutable {
return local + 1;
};
g();
}
private:
int a = 1;
int b = 2;
};
int main() {
Foo f;
f.fun();
return 0;
}
// CHECK: namespace `public: void __cdecl Foo::fun(void)'::`1' {
// CHECK-NEXT: class <lambda_1> {
// CHECK-NEXT: int operator()() const;
// CHECK-NEXT: Foo *__this;
// CHECK-NEXT: };
// CHECK-NEXT: class <lambda_2> {
// CHECK-NEXT: int operator()();
// CHECK-NEXT: int local;
// CHECK-NEXT: };
// CHECK-NEXT: }