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