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