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 4typedef int (^fp)(); 5fp 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 24typedef int (^fp)(); 25fp global; 26void 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 41template <class T> void take_lambda(T &&lambda) { lambda(); } 42void 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 71typedef int (^fptr)(); 72template<typename T> struct StaticMembers { 73 static fptr f; 74}; 75template<typename T> 76fptr StaticMembers<T>::f = [] { auto f = []{return 5;}; return fptr(f); }(); 77template fptr StaticMembers<float>::f; 78 79namespace 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