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