1 | // clang-format off |
2 | // REQUIRES: lld, x86 |
3 | |
4 | // Test lldb finds the correct parent context decl for functions and class methods when icf happens. |
5 | // RUN: %clang_cl --target=x86_64-windows-msvc -Od -Z7 -GS- -fno-addrsig -c /Fo%t.obj -- %s |
6 | // RUN: lld-link -opt:icf -debug:full -nodefaultlib -entry:main %t.obj -out:%t.exe -pdb:%t.pdb |
7 | // RUN: env LLDB_USE_NATIVE_PDB_READER=1 lldb-test symbols --dump-ast %t.exe | FileCheck %s |
8 | |
9 | struct A { |
10 | int f1(int x) { |
11 | return x * 2; |
12 | } |
13 | }; |
14 | struct B { |
15 | int f2(int x) { |
16 | return x * 2; |
17 | } |
18 | }; |
19 | namespace N1 { |
20 | int f3(void*, int x) { |
21 | return x * 2; |
22 | } |
23 | } // namespace N1 |
24 | |
25 | namespace N2 { |
26 | namespace N3 { |
27 | int f4(void*, int x) { |
28 | return x * 2; |
29 | } |
30 | } // namespace N3 |
31 | } // namespace N2 |
32 | |
33 | namespace N4 { |
34 | // Same base name as N1::f3 but different namespaces. |
35 | int f3(void*, int x) { |
36 | return x * 2; |
37 | } |
38 | // Same base name as B::f2 but this is in namespace. |
39 | int f2(void*, int x) { |
40 | return x * 2; |
41 | } |
42 | } // namespace N4 |
43 | |
44 | |
45 | int main() { |
46 | A a; |
47 | B b; |
48 | return a.f1(x: 1) + b.f2(x: 1) + N1::f3(nullptr, x: 1) + N2::N3::f4(nullptr, x: 1) + |
49 | N4::f3(nullptr, x: 1); |
50 | } |
51 | |
52 | |
53 | // CHECK: namespace N1 { |
54 | // CHECK-NEXT: int f3(void *, int x); |
55 | // CHECK-NEXT: } |
56 | // CHECK-NEXT: namespace N2 { |
57 | // CHECK-NEXT: namespace N3 { |
58 | // CHECK-NEXT: int f4(void *, int x); |
59 | // CHECK-NEXT: } |
60 | // CHECK-NEXT: } |
61 | // CHECK-NEXT: namespace N4 { |
62 | // CHECK-NEXT: int f3(void *, int x); |
63 | // CHECK-NEXT: int f2(void *, int x); |
64 | // CHECK-NEXT: } |
65 | // CHECK-NEXT: int main(); |
66 | // CHECK-NEXT: struct A { |
67 | // CHECK-NEXT: int f1(int); |
68 | // CHECK-NEXT: }; |
69 | // CHECK-NEXT: struct B { |
70 | // CHECK-NEXT: int f2(int); |
71 | // CHECK-NEXT: }; |
72 | |