1*67e74705SXin Li // RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s 2*67e74705SXin Li 3*67e74705SXin Li namespace test0 { 4*67e74705SXin Li // CHECK-LABEL: define void @_ZN5test04testEi( 5*67e74705SXin Li // CHECK: define internal void @___ZN5test04testEi_block_invoke{{.*}}( 6*67e74705SXin Li // CHECK: define internal void @___ZN5test04testEi_block_invoke_2{{.*}}( test(int x)7*67e74705SXin Li void test(int x) { 8*67e74705SXin Li ^{ ^{ (void) x; }; }; 9*67e74705SXin Li } 10*67e74705SXin Li } 11*67e74705SXin Li 12*67e74705SXin Li extern void (^out)(); 13*67e74705SXin Li 14*67e74705SXin Li namespace test1 { 15*67e74705SXin Li // Capturing const objects doesn't require a local block. 16*67e74705SXin Li // CHECK-LABEL: define void @_ZN5test15test1Ev() 17*67e74705SXin Li // CHECK: store void ()* bitcast ({{.*}} @__block_literal_global{{.*}} to void ()*), void ()** @out test1()18*67e74705SXin Li void test1() { 19*67e74705SXin Li const int NumHorsemen = 4; 20*67e74705SXin Li out = ^{ (void) NumHorsemen; }; 21*67e74705SXin Li } 22*67e74705SXin Li 23*67e74705SXin Li // That applies to structs too... 24*67e74705SXin Li // CHECK-LABEL: define void @_ZN5test15test2Ev() 25*67e74705SXin Li // CHECK: store void ()* bitcast ({{.*}} @__block_literal_global{{.*}} to void ()*), void ()** @out 26*67e74705SXin Li struct loc { double x, y; }; test2()27*67e74705SXin Li void test2() { 28*67e74705SXin Li const loc target = { 5, 6 }; 29*67e74705SXin Li out = ^{ (void) target; }; 30*67e74705SXin Li } 31*67e74705SXin Li 32*67e74705SXin Li // ...unless they have mutable fields... 33*67e74705SXin Li // CHECK-LABEL: define void @_ZN5test15test3Ev() 34*67e74705SXin Li // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], 35*67e74705SXin Li // CHECK: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()* 36*67e74705SXin Li // CHECK: store void ()* [[T0]], void ()** @out 37*67e74705SXin Li struct mut { mutable int x; }; test3()38*67e74705SXin Li void test3() { 39*67e74705SXin Li const mut obj = { 5 }; 40*67e74705SXin Li out = ^{ (void) obj; }; 41*67e74705SXin Li } 42*67e74705SXin Li 43*67e74705SXin Li // ...or non-trivial destructors... 44*67e74705SXin Li // CHECK-LABEL: define void @_ZN5test15test4Ev() 45*67e74705SXin Li // CHECK: [[OBJ:%.*]] = alloca 46*67e74705SXin Li // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], 47*67e74705SXin Li // CHECK: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()* 48*67e74705SXin Li // CHECK: store void ()* [[T0]], void ()** @out 49*67e74705SXin Li struct scope { int x; ~scope(); }; test4()50*67e74705SXin Li void test4() { 51*67e74705SXin Li const scope obj = { 5 }; 52*67e74705SXin Li out = ^{ (void) obj; }; 53*67e74705SXin Li } 54*67e74705SXin Li 55*67e74705SXin Li // ...or non-trivial copy constructors, but it's not clear how to do 56*67e74705SXin Li // that and still have a constant initializer in '03. 57*67e74705SXin Li } 58*67e74705SXin Li 59*67e74705SXin Li namespace test2 { 60*67e74705SXin Li struct A { 61*67e74705SXin Li A(); 62*67e74705SXin Li A(const A &); 63*67e74705SXin Li ~A(); 64*67e74705SXin Li }; 65*67e74705SXin Li 66*67e74705SXin Li struct B { 67*67e74705SXin Li B(); 68*67e74705SXin Li B(const B &); 69*67e74705SXin Li ~B(); 70*67e74705SXin Li }; 71*67e74705SXin Li 72*67e74705SXin Li // CHECK-LABEL: define void @_ZN5test24testEv() test()73*67e74705SXin Li void test() { 74*67e74705SXin Li __block A a; 75*67e74705SXin Li __block B b; 76*67e74705SXin Li } 77*67e74705SXin Li 78*67e74705SXin Li // CHECK-LABEL: define internal void @__Block_byref_object_copy 79*67e74705SXin Li // CHECK: call void @_ZN5test21AC1ERKS0_( 80*67e74705SXin Li 81*67e74705SXin Li // CHECK-LABEL: define internal void @__Block_byref_object_dispose 82*67e74705SXin Li // CHECK: call void @_ZN5test21AD1Ev( 83*67e74705SXin Li 84*67e74705SXin Li // CHECK-LABEL: define internal void @__Block_byref_object_copy 85*67e74705SXin Li // CHECK: call void @_ZN5test21BC1ERKS0_( 86*67e74705SXin Li 87*67e74705SXin Li // CHECK-LABEL: define internal void @__Block_byref_object_dispose 88*67e74705SXin Li // CHECK: call void @_ZN5test21BD1Ev( 89*67e74705SXin Li } 90*67e74705SXin Li 91*67e74705SXin Li // rdar://problem/9334739 92*67e74705SXin Li // Make sure we mark destructors for parameters captured in blocks. 93*67e74705SXin Li namespace test3 { 94*67e74705SXin Li struct A { 95*67e74705SXin Li A(const A&); 96*67e74705SXin Li ~A(); 97*67e74705SXin Li }; 98*67e74705SXin Li 99*67e74705SXin Li struct B : A { 100*67e74705SXin Li }; 101*67e74705SXin Li test(B b)102*67e74705SXin Li void test(B b) { 103*67e74705SXin Li extern void consume(void(^)()); 104*67e74705SXin Li consume(^{ (void) b; }); 105*67e74705SXin Li } 106*67e74705SXin Li } 107*67e74705SXin Li 108*67e74705SXin Li // rdar://problem/9971485 109*67e74705SXin Li namespace test4 { 110*67e74705SXin Li struct A { 111*67e74705SXin Li A(); 112*67e74705SXin Li ~A(); 113*67e74705SXin Li }; 114*67e74705SXin Li 115*67e74705SXin Li void foo(A a); 116*67e74705SXin Li test()117*67e74705SXin Li void test() { 118*67e74705SXin Li extern void consume(void(^)()); 119*67e74705SXin Li consume(^{ return foo(A()); }); 120*67e74705SXin Li } 121*67e74705SXin Li // CHECK-LABEL: define void @_ZN5test44testEv() 122*67e74705SXin Li // CHECK-LABEL: define internal void @___ZN5test44testEv_block_invoke 123*67e74705SXin Li // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1 124*67e74705SXin Li // CHECK-NEXT: store i8* [[BLOCKDESC:%.*]], i8** {{.*}}, align 8 125*67e74705SXin Li // CHECK-NEXT: load i8*, i8** 126*67e74705SXin Li // CHECK-NEXT: bitcast i8* [[BLOCKDESC]] to <{ i8*, i32, i32, i8*, %struct.__block_descriptor* }>* 127*67e74705SXin Li // CHECK: call void @_ZN5test41AC1Ev([[A]]* [[TMP]]) 128*67e74705SXin Li // CHECK-NEXT: call void @_ZN5test43fooENS_1AE([[A]]* [[TMP]]) 129*67e74705SXin Li // CHECK-NEXT: call void @_ZN5test41AD1Ev([[A]]* [[TMP]]) 130*67e74705SXin Li // CHECK-NEXT: ret void 131*67e74705SXin Li } 132*67e74705SXin Li 133*67e74705SXin Li namespace test5 { 134*67e74705SXin Li struct A { 135*67e74705SXin Li unsigned afield; 136*67e74705SXin Li A(); 137*67e74705SXin Li A(const A&); 138*67e74705SXin Li ~A(); 139*67e74705SXin Li void foo() const; 140*67e74705SXin Li }; 141*67e74705SXin Li 142*67e74705SXin Li void doWithBlock(void(^)()); 143*67e74705SXin Li test(bool cond)144*67e74705SXin Li void test(bool cond) { 145*67e74705SXin Li A x; 146*67e74705SXin Li void (^b)() = (cond ? ^{ x.foo(); } : (void(^)()) 0); 147*67e74705SXin Li doWithBlock(b); 148*67e74705SXin Li } 149*67e74705SXin Li 150*67e74705SXin Li // CHECK-LABEL: define void @_ZN5test54testEb( 151*67e74705SXin Li // CHECK: [[COND:%.*]] = alloca i8 152*67e74705SXin Li // CHECK-NEXT: [[X:%.*]] = alloca [[A:%.*]], align 4 153*67e74705SXin Li // CHECK-NEXT: [[B:%.*]] = alloca void ()*, align 8 154*67e74705SXin Li // CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:.*]], align 8 155*67e74705SXin Li // CHECK-NEXT: [[CLEANUP_ACTIVE:%.*]] = alloca i1 156*67e74705SXin Li // CHECK-NEXT: [[T0:%.*]] = zext i1 157*67e74705SXin Li // CHECK-NEXT: store i8 [[T0]], i8* [[COND]], align 1 158*67e74705SXin Li // CHECK-NEXT: call void @_ZN5test51AC1Ev([[A]]* [[X]]) 159*67e74705SXin Li // CHECK-NEXT: [[CLEANUP_ADDR:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 160*67e74705SXin Li // CHECK-NEXT: [[T0:%.*]] = load i8, i8* [[COND]], align 1 161*67e74705SXin Li // CHECK-NEXT: [[T1:%.*]] = trunc i8 [[T0]] to i1 162*67e74705SXin Li // CHECK-NEXT: store i1 false, i1* [[CLEANUP_ACTIVE]] 163*67e74705SXin Li // CHECK-NEXT: br i1 [[T1]], 164*67e74705SXin Li 165*67e74705SXin Li // CHECK-NOT: br 166*67e74705SXin Li // CHECK: [[CAPTURE:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 167*67e74705SXin Li // CHECK-NEXT: call void @_ZN5test51AC1ERKS0_([[A]]* [[CAPTURE]], [[A]]* dereferenceable({{[0-9]+}}) [[X]]) 168*67e74705SXin Li // CHECK-NEXT: store i1 true, i1* [[CLEANUP_ACTIVE]] 169*67e74705SXin Li // CHECK-NEXT: bitcast [[BLOCK_T]]* [[BLOCK]] to void ()* 170*67e74705SXin Li // CHECK-NEXT: br label 171*67e74705SXin Li // CHECK: br label 172*67e74705SXin Li // CHECK: phi 173*67e74705SXin Li // CHECK-NEXT: store 174*67e74705SXin Li // CHECK-NEXT: load 175*67e74705SXin Li // CHECK-NEXT: call void @_ZN5test511doWithBlockEU13block_pointerFvvE( 176*67e74705SXin Li // CHECK-NEXT: [[T0:%.*]] = load i1, i1* [[CLEANUP_ACTIVE]] 177*67e74705SXin Li // CHECK-NEXT: br i1 [[T0]] 178*67e74705SXin Li // CHECK: call void @_ZN5test51AD1Ev([[A]]* [[CLEANUP_ADDR]]) 179*67e74705SXin Li // CHECK-NEXT: br label 180*67e74705SXin Li // CHECK: call void @_ZN5test51AD1Ev([[A]]* [[X]]) 181*67e74705SXin Li // CHECK-NEXT: ret void 182*67e74705SXin Li } 183*67e74705SXin Li 184*67e74705SXin Li namespace test6 { 185*67e74705SXin Li struct A { 186*67e74705SXin Li A(); 187*67e74705SXin Li ~A(); 188*67e74705SXin Li }; 189*67e74705SXin Li 190*67e74705SXin Li void foo(const A &, void (^)()); 191*67e74705SXin Li void bar(); 192*67e74705SXin Li test()193*67e74705SXin Li void test() { 194*67e74705SXin Li // Make sure that the temporary cleanup isn't somehow captured 195*67e74705SXin Li // within the block. 196*67e74705SXin Li foo(A(), ^{ bar(); }); 197*67e74705SXin Li bar(); 198*67e74705SXin Li } 199*67e74705SXin Li 200*67e74705SXin Li // CHECK-LABEL: define void @_ZN5test64testEv() 201*67e74705SXin Li // CHECK: [[TEMP:%.*]] = alloca [[A:%.*]], align 1 202*67e74705SXin Li // CHECK-NEXT: call void @_ZN5test61AC1Ev([[A]]* [[TEMP]]) 203*67e74705SXin Li // CHECK-NEXT: call void @_ZN5test63fooERKNS_1AEU13block_pointerFvvE( 204*67e74705SXin Li // CHECK-NEXT: call void @_ZN5test61AD1Ev([[A]]* [[TEMP]]) 205*67e74705SXin Li // CHECK-NEXT: call void @_ZN5test63barEv() 206*67e74705SXin Li // CHECK-NEXT: ret void 207*67e74705SXin Li } 208*67e74705SXin Li 209*67e74705SXin Li namespace test7 { f()210*67e74705SXin Li int f() { 211*67e74705SXin Li static int n; 212*67e74705SXin Li int *const p = &n; 213*67e74705SXin Li return ^{ return *p; }(); 214*67e74705SXin Li } 215*67e74705SXin Li } 216*67e74705SXin Li 217*67e74705SXin Li namespace test8 { 218*67e74705SXin Li // <rdar://problem/10832617>: failure to capture this after skipping rebuild 219*67e74705SXin Li // of the 'this' pointer. 220*67e74705SXin Li struct X { 221*67e74705SXin Li int x; 222*67e74705SXin Li 223*67e74705SXin Li template<typename T> footest8::X224*67e74705SXin Li int foo() { 225*67e74705SXin Li return ^ { return x; }(); 226*67e74705SXin Li } 227*67e74705SXin Li }; 228*67e74705SXin Li 229*67e74705SXin Li template int X::foo<int>(); 230*67e74705SXin Li } 231*67e74705SXin Li 232*67e74705SXin Li // rdar://13459289 233*67e74705SXin Li namespace test9 { 234*67e74705SXin Li struct B { 235*67e74705SXin Li void *p; 236*67e74705SXin Li B(); 237*67e74705SXin Li B(const B&); 238*67e74705SXin Li ~B(); 239*67e74705SXin Li }; 240*67e74705SXin Li 241*67e74705SXin Li void use_block(void (^)()); 242*67e74705SXin Li void use_block_2(void (^)(), const B &a); 243*67e74705SXin Li 244*67e74705SXin Li // Ensuring that creating a non-trivial capture copy expression 245*67e74705SXin Li // doesn't end up stealing the block registration for the block we 246*67e74705SXin Li // just parsed. That block must have captures or else it won't 247*67e74705SXin Li // force registration. Must occur within a block for some reason. test()248*67e74705SXin Li void test() { 249*67e74705SXin Li B x; 250*67e74705SXin Li use_block(^{ 251*67e74705SXin Li int y; 252*67e74705SXin Li use_block_2(^{ (void)y; }, x); 253*67e74705SXin Li }); 254*67e74705SXin Li } 255*67e74705SXin Li } 256