1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -fblocks 2 3void tovoid(void*); 4 5void tovoid_test(int (^f)(int, int)) { 6 tovoid(f); 7} 8 9void reference_lvalue_test(int& (^f)()) { 10 f() = 10; 11} 12 13// PR 7165 14namespace test1 { 15 void g(void (^)()); 16 struct Foo { 17 void foo(); 18 void test() { 19 (void) ^{ foo(); }; 20 } 21 }; 22} 23 24namespace test2 { 25 int repeat(int value, int (^block)(int), unsigned n) { 26 while (n--) value = block(value); 27 return value; 28 } 29 30 class Power { 31 int base; 32 33 public: 34 Power(int base) : base(base) {} 35 int calculate(unsigned n) { 36 return repeat(1, ^(int v) { return v * base; }, n); 37 } 38 }; 39 40 int test() { 41 return Power(2).calculate(10); 42 } 43} 44 45// rdar: // 8382559 46namespace radar8382559 { 47 void func(bool& outHasProperty); 48 49 int test3() { 50 __attribute__((__blocks__(byref))) bool hasProperty = false; 51 bool has = true; 52 53 bool (^b)() = ^ { 54 func(hasProperty); 55 if (hasProperty) 56 hasProperty = 0; 57 if (has) 58 hasProperty = 1; 59 return hasProperty; 60 }; 61 func(hasProperty); 62 func(has); 63 b(); 64 if (hasProperty) 65 hasProperty = 1; 66 if (has) 67 has = 2; 68 return hasProperty = 1; 69 } 70} 71 72// Move __block variables to the heap when possible. 73class MoveOnly { 74public: 75 MoveOnly(); 76 MoveOnly(const MoveOnly&) = delete; 77 MoveOnly(MoveOnly&&); 78}; 79 80void move_block() { 81 __block MoveOnly mo; 82} 83 84// Don't crash after failing to build a block due to a capture of an 85// invalid declaration. 86namespace test5 { 87 struct B { // expected-note 2 {{candidate constructor}} 88 void *p; 89 B(int); // expected-note {{candidate constructor}} 90 }; 91 92 void use_block(void (^)()); 93 void use_block_2(void (^)(), const B &a); 94 95 void test() { 96 B x; // expected-error {{no matching constructor for initialization}} 97 use_block(^{ 98 int y; 99 use_block_2(^{ (void) y; }, x); 100 }); 101 } 102} 103 104 105// rdar://16356628 106// 107// Ensure that we can end function bodies while parsing an 108// expression that requires an explicitly-tracked cleanup object 109// (i.e. a block literal). 110 111// The nested function body in this test case is a template 112// instantiation. The template function has to be constexpr because 113// we'll otherwise delay its instantiation to the end of the 114// translation unit. 115namespace test6a { 116 template <class T> constexpr int func() { return 0; } 117 void run(void (^)(), int); 118 119 void test() { 120 int aCapturedVar = 0; 121 run(^{ (void) aCapturedVar; }, func<int>()); 122 } 123} 124 125// The nested function body in this test case is a method of a local 126// class. 127namespace test6b { 128 void run(void (^)(), void (^)()); 129 void test() { 130 int aCapturedVar = 0; 131 run(^{ (void) aCapturedVar; }, 132 ^{ struct A { static void foo() {} }; 133 A::foo(); }); 134 } 135} 136 137// The nested function body in this test case is a lambda invocation 138// function. 139namespace test6c { 140 void run(void (^)(), void (^)()); 141 void test() { 142 int aCapturedVar = 0; 143 run(^{ (void) aCapturedVar; }, 144 ^{ struct A { static void foo() {} }; 145 A::foo(); }); 146 } 147} 148