1*67e74705SXin Li // RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - | FileCheck %s 2*67e74705SXin Li 3*67e74705SXin Li template <class T> void takeItByValue(T); 4*67e74705SXin Li void takeABlock(void (^)()); 5*67e74705SXin Li 6*67e74705SXin Li // rdar://problem/11022704 7*67e74705SXin Li namespace test_int { test()8*67e74705SXin Li void test() { 9*67e74705SXin Li const int x = 100; 10*67e74705SXin Li takeABlock(^{ takeItByValue(x); }); 11*67e74705SXin Li // CHECK: call void @_Z13takeItByValueIiEvT_(i32 100) 12*67e74705SXin Li } 13*67e74705SXin Li } 14*67e74705SXin Li 15*67e74705SXin Li namespace test_int_ref { test()16*67e74705SXin Li void test() { 17*67e74705SXin Li const int y = 200; 18*67e74705SXin Li const int &x = y; 19*67e74705SXin Li takeABlock(^{ takeItByValue(x); }); 20*67e74705SXin Li 21*67e74705SXin Li // TODO: there's no good reason that this isn't foldable. 22*67e74705SXin Li // CHECK: call void @_Z13takeItByValueIiEvT_(i32 {{%.*}}) 23*67e74705SXin Li } 24*67e74705SXin Li } 25*67e74705SXin Li 26*67e74705SXin Li namespace test_float { test()27*67e74705SXin Li void test() { 28*67e74705SXin Li const float x = 1; 29*67e74705SXin Li takeABlock(^{ takeItByValue(x); }); 30*67e74705SXin Li // CHECK: call void @_Z13takeItByValueIfEvT_(float 1.0 31*67e74705SXin Li } 32*67e74705SXin Li } 33*67e74705SXin Li 34*67e74705SXin Li namespace test_float_ref { test()35*67e74705SXin Li void test() { 36*67e74705SXin Li const float y = 100; 37*67e74705SXin Li const float &x = y; 38*67e74705SXin Li takeABlock(^{ takeItByValue(x); }); 39*67e74705SXin Li 40*67e74705SXin Li // TODO: there's no good reason that this isn't foldable. 41*67e74705SXin Li // CHECK: call void @_Z13takeItByValueIfEvT_(float {{%.*}}) 42*67e74705SXin Li } 43*67e74705SXin Li } 44*67e74705SXin Li 45*67e74705SXin Li namespace test_complex_int { test()46*67e74705SXin Li void test() { 47*67e74705SXin Li constexpr _Complex int x = 500; 48*67e74705SXin Li takeABlock(^{ takeItByValue(x); }); 49*67e74705SXin Li // CHECK: store { i32, i32 } { i32 500, i32 0 }, 50*67e74705SXin Li 51*67e74705SXin Li // CHECK: store i32 500, 52*67e74705SXin Li // CHECK-NEXT: store i32 0, 53*67e74705SXin Li // CHECK-NEXT: [[COERCE:%.*]] = bitcast 54*67e74705SXin Li // CHECK-NEXT: [[CVAL:%.*]] = load i64, i64* [[COERCE]] 55*67e74705SXin Li // CHECK-NEXT: call void @_Z13takeItByValueICiEvT_(i64 [[CVAL]]) 56*67e74705SXin Li } 57*67e74705SXin Li } 58*67e74705SXin Li 59*67e74705SXin Li namespace test_complex_int_ref { test()60*67e74705SXin Li void test() { 61*67e74705SXin Li const _Complex int y = 100; 62*67e74705SXin Li const _Complex int &x = y; 63*67e74705SXin Li takeABlock(^{ takeItByValue(x); }); 64*67e74705SXin Li // CHECK: call void @_Z13takeItByValueICiEvT_(i64 65*67e74705SXin Li } 66*67e74705SXin Li } 67*67e74705SXin Li 68*67e74705SXin Li namespace test_complex_int_ref_mutable { 69*67e74705SXin Li _Complex int y = 100; test()70*67e74705SXin Li void test() { 71*67e74705SXin Li const _Complex int &x = y; 72*67e74705SXin Li takeABlock(^{ takeItByValue(x); }); 73*67e74705SXin Li // CHECK: [[R:%.*]] = load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @_ZN28test_complex_int_ref_mutable1yE, i32 0, i32 0) 74*67e74705SXin Li // CHECK-NEXT: [[I:%.*]] = load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @_ZN28test_complex_int_ref_mutable1yE, i32 0, i32 1) 75*67e74705SXin Li // CHECK-NEXT: [[RSLOT:%.*]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[CSLOT:%.*]], i32 0, i32 0 76*67e74705SXin Li // CHECK-NEXT: [[ISLOT:%.*]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[CSLOT]], i32 0, i32 1 77*67e74705SXin Li // CHECK-NEXT: store i32 [[R]], i32* [[RSLOT]] 78*67e74705SXin Li // CHECK-NEXT: store i32 [[I]], i32* [[ISLOT]] 79*67e74705SXin Li // CHECK-NEXT: [[COERCE:%.*]] = bitcast { i32, i32 }* [[CSLOT]] to i64* 80*67e74705SXin Li // CHECK-NEXT: [[CVAL:%.*]] = load i64, i64* [[COERCE]], 81*67e74705SXin Li // CHECK-NEXT: call void @_Z13takeItByValueICiEvT_(i64 [[CVAL]]) 82*67e74705SXin Li } 83*67e74705SXin Li } 84*67e74705SXin Li 85*67e74705SXin Li // rdar://13295759 86*67e74705SXin Li namespace test_block_in_lambda { 87*67e74705SXin Li void takeBlock(void (^block)()); 88*67e74705SXin Li 89*67e74705SXin Li // The captured variable has to be non-POD so that we have a copy expression. 90*67e74705SXin Li struct A { 91*67e74705SXin Li void *p; 92*67e74705SXin Li A(const A &); 93*67e74705SXin Li ~A(); 94*67e74705SXin Li void use() const; 95*67e74705SXin Li }; 96*67e74705SXin Li test(A a)97*67e74705SXin Li void test(A a) { 98*67e74705SXin Li auto lambda = [a]() { 99*67e74705SXin Li takeBlock(^{ a.use(); }); 100*67e74705SXin Li }; 101*67e74705SXin Li lambda(); // make sure we emit the invocation function 102*67e74705SXin Li } 103*67e74705SXin Li // CHECK-LABEL: define internal void @"_ZZN20test_block_in_lambda4testENS_1AEENK3$_0clEv"( 104*67e74705SXin Li // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], align 8 105*67e74705SXin Li // CHECK: [[THIS:%.*]] = load [[LAMBDA_T:%.*]]*, [[LAMBDA_T:%.*]]** 106*67e74705SXin Li // CHECK: [[TO_DESTROY:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 107*67e74705SXin Li // CHECK: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 108*67e74705SXin Li // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[LAMBDA_T]], [[LAMBDA_T]]* [[THIS]], i32 0, i32 0 109*67e74705SXin Li // CHECK-NEXT: call void @_ZN20test_block_in_lambda1AC1ERKS0_({{.*}}* [[T0]], {{.*}}* dereferenceable({{[0-9]+}}) [[T1]]) 110*67e74705SXin Li // CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()* 111*67e74705SXin Li // CHECK-NEXT: call void @_ZN20test_block_in_lambda9takeBlockEU13block_pointerFvvE(void ()* [[T0]]) 112*67e74705SXin Li // CHECK-NEXT: call void @_ZN20test_block_in_lambda1AD1Ev({{.*}}* [[TO_DESTROY]]) 113*67e74705SXin Li // CHECK-NEXT: ret void 114*67e74705SXin Li } 115