1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x -fblocks %s
2
3// rdar://11231426
4typedef signed char BOOL;
5
6void y(BOOL (^foo)());
7
8void x() {
9    y(^{
10        return __objc_yes;
11    });
12}
13
14@protocol NSCopying
15- copy;
16@end
17
18@interface NSObject
19@end
20
21@interface NSNumber : NSObject <NSCopying>
22-copy;
23@end
24
25@interface NSNumber (NSNumberCreation)
26+ (NSNumber *)numberWithChar:(char)value;
27+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
28+ (NSNumber *)numberWithShort:(short)value;
29+ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
30+ (NSNumber *)numberWithInt:(int)value;
31+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
32+ (NSNumber *)numberWithLong:(long)value;
33+ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
34+ (NSNumber *)numberWithLongLong:(long long)value;
35+ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
36+ (NSNumber *)numberWithFloat:(float)value;
37+ (NSNumber *)numberWithDouble:(double)value;
38+ (NSNumber *)numberWithBool:(BOOL)value;
39@end
40
41@interface NSArray : NSObject <NSCopying>
42-copy;
43@end
44
45@interface NSArray (NSArrayCreation)
46+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
47@end
48
49@interface NSDictionary
50+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id<NSCopying> [])keys count:(unsigned long)cnt;
51@end
52
53@interface NSString
54@end
55
56template<typename T>
57struct ConvertibleTo {
58  operator T();
59};
60
61template<typename T>
62struct ExplicitlyConvertibleTo {
63  explicit operator T();
64};
65
66template<typename T>
67class PrivateConvertibleTo {
68private:
69  operator T(); // expected-note{{declared private here}}
70};
71
72template<typename T> ConvertibleTo<T> makeConvertible();
73
74struct X {
75  ConvertibleTo<id> x;
76  ConvertibleTo<id> get();
77};
78
79template<typename T> T test_numeric_instantiation() {
80  return @-17.42;
81}
82
83template id test_numeric_instantiation();
84
85void test_convertibility(ConvertibleTo<NSArray*> toArray,
86                         ConvertibleTo<id> toId,
87                         ConvertibleTo<int (^)(int)> toBlock,
88                         ConvertibleTo<int> toInt,
89                         ExplicitlyConvertibleTo<NSArray *> toArrayExplicit) {
90  id array = @[
91               toArray,
92               toId,
93               toBlock,
94               toInt // expected-error{{collection element of type 'ConvertibleTo<int>' is not an Objective-C object}}
95              ];
96  id array2 = @[ toArrayExplicit ]; // expected-error{{collection element of type 'ExplicitlyConvertibleTo<NSArray *>' is not an Objective-C object}}
97
98  id array3 = @[
99                makeConvertible<id>(),
100                               makeConvertible<id>, // expected-error{{collection element of type 'ConvertibleTo<id> ()' is not an Objective-C object}}
101               ];
102
103  X x;
104  id array4 = @[ x.x ];
105  id array5 = @[ x.get ]; // expected-error{{reference to non-static member function must be called}}
106  id array6 = @[ PrivateConvertibleTo<NSArray*>() ]; // expected-error{{operator NSArray *' is a private member of 'PrivateConvertibleTo<NSArray *>'}}
107}
108
109template<typename T>
110void test_array_literals(T t) {
111  id arr = @[ @17, t ]; // expected-error{{collection element of type 'int' is not an Objective-C object}}
112}
113
114template void test_array_literals(id);
115template void test_array_literals(NSArray*);
116template void test_array_literals(int); // expected-note{{in instantiation of function template specialization 'test_array_literals<int>' requested here}}
117
118template<typename T, typename U>
119void test_dictionary_literals(T t, U u) {
120  NSObject *object;
121  id dict = @{
122    @17 : t, // expected-error{{collection element of type 'int' is not an Objective-C object}}
123    u : @42 // expected-error{{collection element of type 'int' is not an Objective-C object}}
124  };
125
126  id dict2 = @{
127    object : @"object" // expected-error{{cannot initialize a parameter of type 'const id<NSCopying>' with an rvalue of type 'NSObject *'}}
128  };
129}
130
131template void test_dictionary_literals(id, NSArray*);
132template void test_dictionary_literals(NSArray*, id);
133template void test_dictionary_literals(int, id); // expected-note{{in instantiation of function template specialization 'test_dictionary_literals<int, id>' requested here}}
134template void test_dictionary_literals(id, int); // expected-note{{in instantiation of function template specialization 'test_dictionary_literals<id, int>' requested here}}
135
136template<typename ...Args>
137void test_bad_variadic_array_literal(Args ...args) {
138  id arr1 = @[ args ]; // expected-error{{initializer contains unexpanded parameter pack 'args'}}
139}
140
141template<typename ...Args>
142void test_variadic_array_literal(Args ...args) {
143  id arr1 = @[ args... ]; // expected-error{{collection element of type 'int' is not an Objective-C object}}
144}
145template void test_variadic_array_literal(id);
146template void test_variadic_array_literal(id, NSArray*);
147template void test_variadic_array_literal(id, int, NSArray*); // expected-note{{in instantiation of function template specialization 'test_variadic_array_literal<id, int, NSArray *>' requested here}}
148
149template<typename ...Args>
150void test_bad_variadic_dictionary_literal(Args ...args) {
151  id dict = @{ args : @17 }; // expected-error{{initializer contains unexpanded parameter pack 'args'}}
152}
153
154// Test array literal pack expansions.
155template<typename T, typename U>
156struct pair {
157  T first;
158  U second;
159};
160
161template<typename T, typename ...Ts, typename ... Us>
162void test_variadic_dictionary_expansion(T t, pair<Ts, Us>... key_values) {
163  id dict = @{
164    t : key_values.second ..., // expected-error{{collection element of type 'int' is not an Objective-C object}}
165    key_values.first : key_values.second ..., // expected-error{{collection element of type 'float' is not an Objective-C object}}
166    key_values.second : t ...
167  };
168}
169
170template void test_variadic_dictionary_expansion(id,
171                                                 pair<NSNumber*, id>,
172                                                 pair<id, ConvertibleTo<id>>);
173template void test_variadic_dictionary_expansion(NSNumber *, // expected-note{{in instantiation of function template specialization}}
174                                                 pair<NSNumber*, int>,
175                                                 pair<id, ConvertibleTo<id>>);
176template void test_variadic_dictionary_expansion(NSNumber *, // expected-note{{in instantiation of function template specialization}}
177                                                 pair<NSNumber*, id>,
178                                                 pair<float, ConvertibleTo<id>>);
179
180// Test parsing
181struct key {
182  static id value;
183};
184
185id key;
186id value;
187
188void test_dictionary_colon() {
189  id dict = @{ key : value };
190}
191
192void testConstExpr() {
193  constexpr NSString *t0 = @"abc";
194  constexpr NSString *t1 = @("abc");
195}
196