xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGenCXX/cxx1y-init-captures.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -std=c++1y -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s
2*f4a2713aSLionel Sambuc 
3*f4a2713aSLionel Sambuc struct S {
4*f4a2713aSLionel Sambuc   S();
5*f4a2713aSLionel Sambuc   S(S &&);
6*f4a2713aSLionel Sambuc   ~S();
7*f4a2713aSLionel Sambuc };
8*f4a2713aSLionel Sambuc 
f()9*f4a2713aSLionel Sambuc void f() {
10*f4a2713aSLionel Sambuc   (void) [s(S{})] {};
11*f4a2713aSLionel Sambuc }
12*f4a2713aSLionel Sambuc 
13*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_Z1fv(
14*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1SC1Ev(
15*f4a2713aSLionel Sambuc // CHECK: call void @"_ZZ1fvEN3$_0D1Ev"(
16*f4a2713aSLionel Sambuc 
17*f4a2713aSLionel Sambuc // CHECK-LABEL: define internal void @"_ZZ1fvEN3$_0D1Ev"(
18*f4a2713aSLionel Sambuc // CHECK: @"_ZZ1fvEN3$_0D2Ev"(
19*f4a2713aSLionel Sambuc 
20*f4a2713aSLionel Sambuc // D2 at end of file.
21*f4a2713aSLionel Sambuc 
g()22*f4a2713aSLionel Sambuc void g() {
23*f4a2713aSLionel Sambuc   [a(1), b(2)] { return a + b; } ();
24*f4a2713aSLionel Sambuc }
25*f4a2713aSLionel Sambuc 
26*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @_Z1gv(
27*f4a2713aSLionel Sambuc // CHECK: getelementptr inbounds {{.*}}, i32 0, i32 0
28*f4a2713aSLionel Sambuc // CHECK: store i32 1, i32*
29*f4a2713aSLionel Sambuc // CHECK: getelementptr inbounds {{.*}}, i32 0, i32 1
30*f4a2713aSLionel Sambuc // CHECK: store i32 2, i32*
31*f4a2713aSLionel Sambuc // CHECK: call i32 @"_ZZ1gvENK3$_1clEv"(
32*f4a2713aSLionel Sambuc 
33*f4a2713aSLionel Sambuc // CHECK-LABEL: define internal i32 @"_ZZ1gvENK3$_1clEv"(
34*f4a2713aSLionel Sambuc // CHECK: getelementptr inbounds {{.*}}, i32 0, i32 0
35*f4a2713aSLionel Sambuc // CHECK: load i32*
36*f4a2713aSLionel Sambuc // CHECK: getelementptr inbounds {{.*}}, i32 0, i32 1
37*f4a2713aSLionel Sambuc // CHECK: load i32*
38*f4a2713aSLionel Sambuc // CHECK: add nsw i32
39*f4a2713aSLionel Sambuc 
h(int a)40*f4a2713aSLionel Sambuc int h(int a) {
41*f4a2713aSLionel Sambuc   // CHECK-LABEL: define i32 @_Z1hi(
42*f4a2713aSLionel Sambuc   // CHECK: %[[A_ADDR:.*]] = alloca i32,
43*f4a2713aSLionel Sambuc   // CHECK: %[[OUTER:.*]] = alloca
44*f4a2713aSLionel Sambuc   // CHECK: store i32 {{.*}}, i32* %[[A_ADDR]],
45*f4a2713aSLionel Sambuc   //
46*f4a2713aSLionel Sambuc   // Initialize init-capture 'b(a)' by reference.
47*f4a2713aSLionel Sambuc   // CHECK: getelementptr inbounds {{.*}}* %[[OUTER]], i32 0, i32 0
48*f4a2713aSLionel Sambuc   // CHECK: store i32* %[[A_ADDR]], i32** {{.*}},
49*f4a2713aSLionel Sambuc   //
50*f4a2713aSLionel Sambuc   // Initialize init-capture 'c(a)' by copy.
51*f4a2713aSLionel Sambuc   // CHECK: getelementptr inbounds {{.*}}* %[[OUTER]], i32 0, i32 1
52*f4a2713aSLionel Sambuc   // CHECK: load i32* %[[A_ADDR]],
53*f4a2713aSLionel Sambuc   // CHECK: store i32
54*f4a2713aSLionel Sambuc   //
55*f4a2713aSLionel Sambuc   // CHECK: call i32 @"_ZZ1hiENK3$_2clEv"({{.*}}* %[[OUTER]])
56*f4a2713aSLionel Sambuc   return [&b(a), c(a)] {
57*f4a2713aSLionel Sambuc     // CHECK-LABEL: define internal i32 @"_ZZ1hiENK3$_2clEv"(
58*f4a2713aSLionel Sambuc     // CHECK: %[[OUTER_ADDR:.*]] = alloca
59*f4a2713aSLionel Sambuc     // CHECK: %[[INNER:.*]] = alloca
60*f4a2713aSLionel Sambuc     // CHECK: store {{.*}}, {{.*}}** %[[OUTER_ADDR]],
61*f4a2713aSLionel Sambuc     //
62*f4a2713aSLionel Sambuc     // Capture outer 'c' by reference.
63*f4a2713aSLionel Sambuc     // CHECK: %[[OUTER:.*]] = load {{.*}}** %[[OUTER_ADDR]]
64*f4a2713aSLionel Sambuc     // CHECK: getelementptr inbounds {{.*}}* %[[INNER]], i32 0, i32 0
65*f4a2713aSLionel Sambuc     // CHECK-NEXT: getelementptr inbounds {{.*}}* %[[OUTER]], i32 0, i32 1
66*f4a2713aSLionel Sambuc     // CHECK-NEXT: store i32* %
67*f4a2713aSLionel Sambuc     //
68*f4a2713aSLionel Sambuc     // Capture outer 'b' by copy.
69*f4a2713aSLionel Sambuc     // CHECK: getelementptr inbounds {{.*}}* %[[INNER]], i32 0, i32 1
70*f4a2713aSLionel Sambuc     // CHECK-NEXT: getelementptr inbounds {{.*}}* %[[OUTER]], i32 0, i32 0
71*f4a2713aSLionel Sambuc     // CHECK-NEXT: load i32** %
72*f4a2713aSLionel Sambuc     // CHECK-NEXT: load i32* %
73*f4a2713aSLionel Sambuc     // CHECK-NEXT: store i32
74*f4a2713aSLionel Sambuc     //
75*f4a2713aSLionel Sambuc     // CHECK: call i32 @"_ZZZ1hiENK3$_2clEvENKUlvE_clEv"({{.*}}* %[[INNER]])
76*f4a2713aSLionel Sambuc     return [=, &c] {
77*f4a2713aSLionel Sambuc       // CHECK-LABEL: define internal i32 @"_ZZZ1hiENK3$_2clEvENKUlvE_clEv"(
78*f4a2713aSLionel Sambuc       // CHECK: %[[INNER_ADDR:.*]] = alloca
79*f4a2713aSLionel Sambuc       // CHECK: store {{.*}}, {{.*}}** %[[INNER_ADDR]],
80*f4a2713aSLionel Sambuc       // CHECK: %[[INNER:.*]] = load {{.*}}** %[[INNER_ADDR]]
81*f4a2713aSLionel Sambuc       //
82*f4a2713aSLionel Sambuc       // Load capture of 'b'
83*f4a2713aSLionel Sambuc       // CHECK: getelementptr inbounds {{.*}}* %[[INNER]], i32 0, i32 1
84*f4a2713aSLionel Sambuc       // CHECK: load i32* %
85*f4a2713aSLionel Sambuc       //
86*f4a2713aSLionel Sambuc       // Load capture of 'c'
87*f4a2713aSLionel Sambuc       // CHECK: getelementptr inbounds {{.*}}* %[[INNER]], i32 0, i32 0
88*f4a2713aSLionel Sambuc       // CHECK: load i32** %
89*f4a2713aSLionel Sambuc       // CHECK: load i32* %
90*f4a2713aSLionel Sambuc       //
91*f4a2713aSLionel Sambuc       // CHECK: add nsw i32
92*f4a2713aSLionel Sambuc       return b + c;
93*f4a2713aSLionel Sambuc     } ();
94*f4a2713aSLionel Sambuc   } ();
95*f4a2713aSLionel Sambuc }
96*f4a2713aSLionel Sambuc 
97*f4a2713aSLionel Sambuc // Ensure we can emit code for init-captures in global lambdas too.
__anon3d7a89ff0502() 98*f4a2713aSLionel Sambuc auto global_lambda = [a = 0] () mutable { return ++a; };
get_incremented()99*f4a2713aSLionel Sambuc int get_incremented() { return global_lambda(); }
100*f4a2713aSLionel Sambuc 
101*f4a2713aSLionel Sambuc // CHECK-LABEL: define internal void @"_ZZ1fvEN3$_0D2Ev"(
102*f4a2713aSLionel Sambuc // CHECK: call void @_ZN1SD1Ev(
103