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