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