xref: /aosp_15_r20/external/clang/test/CodeGenObjCXX/lambda-expressions.mm (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -fexceptions -std=c++11 -fblocks -fobjc-arc | FileCheck -check-prefix=ARC %s
2*67e74705SXin Li// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -fexceptions -std=c++11 -fblocks | FileCheck -check-prefix=MRC %s
3*67e74705SXin Li
4*67e74705SXin Litypedef int (^fp)();
5*67e74705SXin Lifp f() { auto x = []{ return 3; }; return x; }
6*67e74705SXin Li
7*67e74705SXin Li// MRC: @OBJC_METH_VAR_NAME{{.*}} = private global [5 x i8] c"copy\00"
8*67e74705SXin Li// MRC: @OBJC_METH_VAR_NAME{{.*}} = private global [12 x i8] c"autorelease\00"
9*67e74705SXin Li// MRC-LABEL: define i32 ()* @_Z1fv(
10*67e74705SXin Li// MRC-LABEL: define internal i32 ()* @"_ZZ1fvENK3$_0cvU13block_pointerFivEEv"
11*67e74705SXin Li// MRC: store i8* bitcast (i8** @_NSConcreteStackBlock to i8*)
12*67e74705SXin Li// MRC: store i8* bitcast (i32 (i8*)* @"___ZZ1fvENK3$_0cvU13block_pointerFivEEv_block_invoke" to i8*)
13*67e74705SXin Li// MRC: call i32 ()* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 ()* (i8*, i8*)*)
14*67e74705SXin Li// MRC: call i32 ()* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i32 ()* (i8*, i8*)*)
15*67e74705SXin Li// MRC: ret i32 ()*
16*67e74705SXin Li
17*67e74705SXin Li// ARC-LABEL: define i32 ()* @_Z1fv(
18*67e74705SXin Li// ARC-LABEL: define internal i32 ()* @"_ZZ1fvENK3$_0cvU13block_pointerFivEEv"
19*67e74705SXin Li// ARC: store i8* bitcast (i8** @_NSConcreteStackBlock to i8*)
20*67e74705SXin Li// ARC: store i8* bitcast (i32 (i8*)* @"___ZZ1fvENK3$_0cvU13block_pointerFivEEv_block_invoke" to i8*)
21*67e74705SXin Li// ARC: call i8* @objc_retainBlock
22*67e74705SXin Li// ARC: call i8* @objc_autoreleaseReturnValue
23*67e74705SXin Li
24*67e74705SXin Litypedef int (^fp)();
25*67e74705SXin Lifp global;
26*67e74705SXin Livoid f2() { global = []{ return 3; }; }
27*67e74705SXin Li
28*67e74705SXin Li// MRC: define void @_Z2f2v() [[NUW:#[0-9]+]] {
29*67e74705SXin Li// MRC: store i8* bitcast (i32 (i8*)* @___Z2f2v_block_invoke to i8*),
30*67e74705SXin Li// MRC-NOT: call
31*67e74705SXin Li// MRC: ret void
32*67e74705SXin Li// ("global" contains a dangling pointer after this function runs.)
33*67e74705SXin Li
34*67e74705SXin Li// ARC: define void @_Z2f2v() [[NUW:#[0-9]+]] {
35*67e74705SXin Li// ARC: store i8* bitcast (i32 (i8*)* @___Z2f2v_block_invoke to i8*),
36*67e74705SXin Li// ARC: call i8* @objc_retainBlock
37*67e74705SXin Li// ARC: call void @objc_release
38*67e74705SXin Li// ARC-LABEL: define internal i32 @___Z2f2v_block_invoke
39*67e74705SXin Li// ARC: call i32 @"_ZZ2f2vENK3$_1clEv
40*67e74705SXin Li
41*67e74705SXin Litemplate <class T> void take_lambda(T &&lambda) { lambda(); }
42*67e74705SXin Livoid take_block(void (^block)()) { block(); }
43*67e74705SXin Li
44*67e74705SXin Li// rdar://13800041
45*67e74705SXin Li@interface A
46*67e74705SXin Li- (void) test;
47*67e74705SXin Li@end
48*67e74705SXin Li@interface B : A @end
49*67e74705SXin Li@implementation B
50*67e74705SXin Li- (void) test {
51*67e74705SXin Li  take_block(^{
52*67e74705SXin Li      take_lambda([=]{
53*67e74705SXin Li          take_block(^{
54*67e74705SXin Li              take_lambda([=] {
55*67e74705SXin Li                  [super test];
56*67e74705SXin Li              });
57*67e74705SXin Li          });
58*67e74705SXin Li      });
59*67e74705SXin Li   });
60*67e74705SXin Li}
61*67e74705SXin Li@end
62*67e74705SXin Li
63*67e74705SXin Li// ARC-LABEL: define linkonce_odr i32 ()* @_ZZNK13StaticMembersIfE1fMUlvE_clEvENKUlvE_cvU13block_pointerFivEEv
64*67e74705SXin Li
65*67e74705SXin Li// Check lines for BlockInLambda test below
66*67e74705SXin Li// ARC-LABEL: define internal i32 @___ZZN13BlockInLambda1X1fEvENKUlvE_clEv_block_invoke
67*67e74705SXin Li// ARC: [[Y:%.*]] = getelementptr inbounds %"struct.BlockInLambda::X", %"struct.BlockInLambda::X"* {{.*}}, i32 0, i32 1
68*67e74705SXin Li// ARC-NEXT: [[YVAL:%.*]] = load i32, i32* [[Y]], align 4
69*67e74705SXin Li// ARC-NEXT: ret i32 [[YVAL]]
70*67e74705SXin Li
71*67e74705SXin Litypedef int (^fptr)();
72*67e74705SXin Litemplate<typename T> struct StaticMembers {
73*67e74705SXin Li  static fptr f;
74*67e74705SXin Li};
75*67e74705SXin Litemplate<typename T>
76*67e74705SXin Lifptr StaticMembers<T>::f = [] { auto f = []{return 5;}; return fptr(f); }();
77*67e74705SXin Litemplate fptr StaticMembers<float>::f;
78*67e74705SXin Li
79*67e74705SXin Linamespace BlockInLambda {
80*67e74705SXin Li  struct X {
81*67e74705SXin Li    int x,y;
82*67e74705SXin Li    void f() {
83*67e74705SXin Li      [this]{return ^{return y;}();}();
84*67e74705SXin Li    };
85*67e74705SXin Li  };
86*67e74705SXin Li  void g(X& x) {
87*67e74705SXin Li    x.f();
88*67e74705SXin Li  };
89*67e74705SXin Li}
90*67e74705SXin Li
91*67e74705SXin Li
92*67e74705SXin Li// ARC: attributes [[NUW]] = { nounwind{{.*}} }
93*67e74705SXin Li// MRC: attributes [[NUW]] = { nounwind{{.*}} }
94