1// RUN: %clang_cc1 %s -fblocks -fsyntax-only -verify
2
3#define ASYNC(...) __attribute__((swift_async(__VA_ARGS__)))
4#define ASYNC_ERROR(...) __attribute__((swift_async_error(__VA_ARGS__)))
5
6ASYNC(swift_private, 1)
7ASYNC_ERROR(zero_argument, 1)
8void test_good(void (^handler)(int));
9
10ASYNC(swift_private, 2)
11ASYNC_ERROR(nonzero_argument, 2)
12void test_good2(double, void (^handler)(double, int, double));
13
14enum SomeEnum { SE_a, SE_b };
15
16ASYNC(swift_private, 1)
17ASYNC_ERROR(nonzero_argument, 1)
18void test_good3(void (^handler)(enum SomeEnum, double));
19
20ASYNC_ERROR(zero_argument, 1)
21ASYNC(swift_private, 1)
22void test_rev_order(void (^handler)(int));
23
24@class NSError;
25
26ASYNC(swift_private, 1)
27ASYNC_ERROR(nonnull_error)
28void test_nserror(void (^handler)(NSError *));
29
30typedef struct __attribute__((objc_bridge(NSError))) __CFError * CFErrorRef;
31
32ASYNC(swift_private, 1)
33ASYNC_ERROR(nonnull_error)
34void test_cferror(void (^handler)(CFErrorRef));
35
36ASYNC(swift_private, 1)
37ASYNC_ERROR(nonnull_error) // expected-error {{'swift_async_error' attribute with 'nonnull_error' convention can only be applied to a function with a completion handler with an error parameter}}
38void test_interror(void (^handler)(int));
39
40ASYNC(swift_private, 1)
41ASYNC_ERROR(zero_argument, 1) // expected-error {{'swift_async_error' attribute with 'zero_argument' convention must have an integral-typed parameter in completion handler at index 1, type here is 'double'}}
42void test_not_integral(void (^handler)(double));
43
44ASYNC(swift_private, 1)
45ASYNC_ERROR(none)
46void test_none(void (^)());
47
48ASYNC(none)
49ASYNC_ERROR(none)
50void test_double_none(void (^)());
51
52ASYNC(none)
53ASYNC_ERROR(none, 1) // expected-error {{'swift_async_error' attribute takes one argument}}
54void test_double_none_args();
55
56ASYNC(swift_private, 1)
57ASYNC_ERROR(nonnull_error, 1) // expected-error{{'swift_async_error' attribute takes one argument}}
58void test_args(void (^)(void));
59
60ASYNC(swift_private, 1)
61ASYNC_ERROR(zero_argument, 1, 1) // expected-error{{'swift_async_error' attribute takes no more than 2 arguments}}
62void test_args2(void (^)(int));
63
64ASYNC_ERROR(none) int x; // expected-warning{{'swift_async_error' attribute only applies to functions and Objective-C methods}}
65
66@interface ObjC
67-(void)m1:(void (^)(int))handler
68  ASYNC(swift_private, 1)
69  ASYNC_ERROR(zero_argument, 1);
70
71-(void)m2:(int)first withSecond:(void (^)(int))handler
72  ASYNC(swift_private, 2)
73  ASYNC_ERROR(nonzero_argument, 1);
74
75-(void)m3:(void (^)(void))block
76  ASYNC_ERROR(zero_argument, 1) // expected-error {{'swift_async_error' attribute parameter 2 is out of bounds}}
77  ASYNC(swift_private, 1);
78
79-(void)m4:(void (^)(double, int, float))handler
80  ASYNC(swift_private, 1)
81  ASYNC_ERROR(nonzero_argument, 1); // expected-error{{swift_async_error' attribute with 'nonzero_argument' convention must have an integral-typed parameter in completion handler at index 1, type here is 'double'}}
82
83-(void)m5:(void (^)(NSError *))handler
84  ASYNC(swift_private, 1)
85  ASYNC_ERROR(nonnull_error);
86
87-(void)m6:(void (^)(void *))handler
88  ASYNC(swift_private, 1)
89  ASYNC_ERROR(nonnull_error); // expected-error{{'swift_async_error' attribute with 'nonnull_error' convention can only be applied to a method with a completion handler with an error parameter}}
90@end
91
92// 'swift_error' and 'swift_async_error' are OK on one function.
93ASYNC(swift_private, 1)
94ASYNC_ERROR(nonnull_error)
95__attribute__((swift_error(nonnull_error)))
96void swift_error_and_swift_async_error(void (^handler)(NSError *), NSError **);
97
98@interface TestNoSwiftAsync
99// swift_async_error can make sense without swift_async.
100-(void)doAThingWithCompletion:(void (^)(NSError *))completion
101  ASYNC_ERROR(nonnull_error);
102@end
103