[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / SemaObjC / blocks.m
blob4a13d1f0646544c9841f245b24d57503d6006e31
1 // RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify -fblocks -Wno-strict-prototypes %s
3 #define bool _Bool
4 @protocol NSObject;
6 void bar(id(^)(void));
7 void foo(id <NSObject>(^objectCreationBlock)(void)) {
8     return bar(objectCreationBlock);
11 void bar2(id(*)(void));
12 void foo2(id <NSObject>(*objectCreationBlock)(void)) {
13     return bar2(objectCreationBlock);
16 void bar3(id(*)());
17 void foo3(id (*objectCreationBlock)(int)) {
18     return bar3(objectCreationBlock);
21 void bar4(id(^)());
22 void foo4(id (^objectCreationBlock)(int)) {
23     return bar4(objectCreationBlock);
26 void bar5(id(^)(void)); // expected-note 3{{passing argument to parameter here}}
27 void foo5(id (^objectCreationBlock)(bool)) {
28     bar5(objectCreationBlock); // expected-error {{incompatible block pointer types passing 'id (^)(bool)' to parameter of type 'id (^)(void)'}}
29 #undef bool
30     bar5(objectCreationBlock); // expected-error {{incompatible block pointer types passing 'id (^)(_Bool)' to parameter of type 'id (^)(void)'}}
31 #define bool int
32     bar5(objectCreationBlock); // expected-error {{incompatible block pointer types passing 'id (^)(_Bool)' to parameter of type 'id (^)(void)'}}
35 void bar6(id(^)(int));
36 void foo6(id (^objectCreationBlock)()) {
37     return bar6(objectCreationBlock);
40 void foo7(id (^x)(int)) {
41   if (x) { }
44 @interface itf
45 @end
47 void foo8() {
48   void *P = ^(itf x) {};  // expected-error {{interface type 'itf' cannot be passed by value; did you forget * in 'itf'}}
49   P = ^itf(int x) {};     // expected-error {{interface type 'itf' cannot be returned by value; did you forget * in 'itf'}}
50   P = ^itf() {};          // expected-error {{interface type 'itf' cannot be returned by value; did you forget * in 'itf'}}
51   P = ^itf{};             // expected-error {{interface type 'itf' cannot be returned by value; did you forget * in 'itf'}}
55 int foo9() {
56   typedef void (^DVTOperationGroupScheduler)();
57   id _suboperationSchedulers;
59   for (DVTOperationGroupScheduler scheduler in _suboperationSchedulers) {
60             ;
61         }
65 // rdar 7725203
66 @class NSString;
68 extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
70 void foo10() {
71     void(^myBlock)(void) = ^{
72     };
73     NSLog(@"%@", myBlock);
77 // In C, enum constants have the type of the underlying integer type, not the
78 // enumeration they are part of. We pretend the constants have enum type if
79 // all the returns seem to be playing along.
80 enum CStyleEnum {
81   CSE_Value = 1,
82   CSE_Value2 = 2
84 enum CStyleEnum getCSE();
85 typedef enum CStyleEnum (^cse_block_t)();
87 void testCStyleEnumInference(bool arg) {
88   cse_block_t a;
89   enum CStyleEnum value;
91   // No warnings here.
92   a = ^{ return getCSE(); };
93   a = ^{ return value; };
95   a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}}
96     return 1;
97   };
99   // No warning here.
100   a = ^{
101     return CSE_Value;
102   };
104   // No warnings here.
105   a = ^{ if (arg) return CSE_Value; else return getCSE();  };
106   a = ^{ if (arg) return getCSE();  else return CSE_Value; };
107   a = ^{ if (arg) return value;     else return CSE_Value; };
109   // These two blocks actually return 'int'
110   a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}}
111     if (arg)
112       return 1;
113     else
114       return CSE_Value;
115   };
117   a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}}
118     if (arg)
119       return CSE_Value;
120     else
121       return 1;
122   };
124   a = ^{ // expected-error {{incompatible block pointer types assigning to 'cse_block_t' (aka 'enum CStyleEnum (^)()') from 'int (^)(void)'}}
125     if (arg)
126       return 1;
127     else
128       return value; // expected-error {{return type 'enum CStyleEnum' must match previous return type 'int'}}
129   };
131   // rdar://13200889
132   extern void check_enum(void);
133   a = ^{
134     return (arg ? (CSE_Value) : (check_enum(), (!arg ? CSE_Value2 : getCSE())));
135   };
136   a = ^{
137     return (arg ? (CSE_Value) : ({check_enum(); CSE_Value2; }));
138   };
142 enum FixedTypeEnum : unsigned {
143   FTE_Value = 1U
145 enum FixedTypeEnum getFTE();
146 typedef enum FixedTypeEnum (^fte_block_t)();
148 void testFixedTypeEnumInference(bool arg) {
149   fte_block_t a;
150   
151   // No warnings here.
152   a = ^{ return getFTE(); };
154   // Since we fixed the underlying type of the enum, this is considered a
155   // compatible block type.
156   a = ^{
157     return 1U;
158   };
159   a = ^{
160     return FTE_Value;
161   };
163   // No warnings here.
164   a = ^{ if (arg) return FTE_Value; else return FTE_Value; };
165   a = ^{ if (arg) return getFTE();  else return getFTE();  };
166   a = ^{ if (arg) return FTE_Value; else return getFTE();  };
167   a = ^{ if (arg) return getFTE();  else return FTE_Value; };
168   
169   // These two blocks actually return 'unsigned'.
170   a = ^{
171     if (arg)
172       return 1U;
173     else
174       return FTE_Value;
175   };
176   
177   a = ^{
178     if (arg)
179       return FTE_Value;
180     else
181       return 1U;
182   };
186 enum {
187   AnonymousValue = 1
190 enum : short {
191   FixedAnonymousValue = 1
194 typedef enum {
195   TDE_Value
196 } TypeDefEnum;
197 TypeDefEnum getTDE();
199 typedef enum : short {
200   TDFTE_Value
201 } TypeDefFixedTypeEnum;
202 TypeDefFixedTypeEnum getTDFTE();
204 typedef int (^int_block_t)();
205 typedef short (^short_block_t)();
206 void testAnonymousEnumTypes(int arg) {
207   int_block_t IB;
208   IB = ^{ return AnonymousValue; };
209   IB = ^{ if (arg) return TDE_Value; else return getTDE(); };
210   IB = ^{ if (arg) return getTDE(); else return TDE_Value; };
212   // Since we fixed the underlying type of the enum, these are considered
213   // compatible block types anyway.
214   short_block_t SB;
215   SB = ^{ return FixedAnonymousValue; };
216   SB = ^{ if (arg) return TDFTE_Value; else return getTDFTE(); };
217   SB = ^{ if (arg) return getTDFTE(); else return TDFTE_Value; };
220 static inline void inlinefunc() {
221   ^{}();
223 void inlinefunccaller() { inlinefunc(); }