1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -fblocks 2 3 void tovoid(void*); 4 5 void tovoid_test(int (^f)(int, int)) { 6 tovoid(f); 7 } 8 9 void reference_lvalue_test(int& (^f)()) { 10 f() = 10; 11 } 12 13 // PR 7165 14 namespace test1 { 15 void g(void (^)()); 16 struct Foo { 17 void foo(); 18 void test() { 19 (void) ^{ foo(); }; 20 } 21 }; 22 } 23 24 namespace 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 46 namespace 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. 73 class MoveOnly { 74 public: 75 MoveOnly(); 76 MoveOnly(const MoveOnly&) = delete; 77 MoveOnly(MoveOnly&&); 78 }; 79 80 void 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. 86 namespace 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. 115 namespace 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. 127 namespace 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. 139 namespace 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