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.
46 lines
955 B
C++
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: }
|
|
|