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
53template<typename T>
54struct ConvertibleTo {
55  operator T();
56};
57
58template<typename T>
59struct ExplicitlyConvertibleTo {
60  explicit operator T();
61};
62
63template<typename T>
64class PrivateConvertibleTo {
65private:
66  operator T(); // expected-note{{declared private here}}
67};
68
69template<typename T> ConvertibleTo<T> makeConvertible();
70
71struct X {
72  ConvertibleTo<id> x;
73  ConvertibleTo<id> get();
74};
75
76template<typename T> T test_numeric_instantiation() {
77  return @-17.42;
78}
79
80template id test_numeric_instantiation();
81
82void test_convertibility(ConvertibleTo<NSArray*> toArray,
83                         ConvertibleTo<id> toId,
84                         ConvertibleTo<int (^)(int)> toBlock,
85                         ConvertibleTo<int> toInt,
86                         ExplicitlyConvertibleTo<NSArray *> toArrayExplicit) {
87  id array = @[ 
88               toArray,
89               toId,
90               toBlock,
91               toInt // expected-error{{collection element of type 'ConvertibleTo<int>' is not an Objective-C object}}
92              ];
93  id array2 = @[ toArrayExplicit ]; // expected-error{{collection element of type 'ExplicitlyConvertibleTo<NSArray *>' is not an Objective-C object}}
94
95  id array3 = @[ 
96                makeConvertible<id>(),
97                               makeConvertible<id>, // expected-error{{collection element of type 'ConvertibleTo<id> ()' is not an Objective-C object}}
98               ];
99
100  X x;
101  id array4 = @[ x.x ];
102  id array5 = @[ x.get ]; // expected-error{{reference to non-static member function must be called}}
103  id array6 = @[ PrivateConvertibleTo<NSArray*>() ]; // expected-error{{operator NSArray *' is a private member of 'PrivateConvertibleTo<NSArray *>'}}
104}
105
106template<typename T>
107void test_array_literals(T t) {
108  id arr = @[ @17, t ]; // expected-error{{collection element of type 'int' is not an Objective-C object}}
109}
110
111template void test_array_literals(id);
112template void test_array_literals(NSArray*);
113template void test_array_literals(int); // expected-note{{in instantiation of function template specialization 'test_array_literals<int>' requested here}}
114
115template<typename T, typename U>
116void test_dictionary_literals(T t, U u) {
117  NSObject *object;
118  id dict = @{ 
119    @17 : t, // expected-error{{collection element of type 'int' is not an Objective-C object}}
120    u : @42 // expected-error{{collection element of type 'int' is not an Objective-C object}}
121  };
122
123  id dict2 = @{ 
124    object : @"object" // expected-error{{cannot initialize a parameter of type 'const id<NSCopying>' with an rvalue of type 'NSObject *'}}
125  }; 
126}
127
128template void test_dictionary_literals(id, NSArray*);
129template void test_dictionary_literals(NSArray*, id);
130template void test_dictionary_literals(int, id); // expected-note{{in instantiation of function template specialization 'test_dictionary_literals<int, id>' requested here}}
131template void test_dictionary_literals(id, int); // expected-note{{in instantiation of function template specialization 'test_dictionary_literals<id, int>' requested here}}
132
133template<typename ...Args>
134void test_bad_variadic_array_literal(Args ...args) {
135  id arr1 = @[ args ]; // expected-error{{initializer contains unexpanded parameter pack 'args'}}
136}
137
138template<typename ...Args>
139void test_variadic_array_literal(Args ...args) {
140  id arr1 = @[ args... ]; // expected-error{{collection element of type 'int' is not an Objective-C object}}
141}
142template void test_variadic_array_literal(id);
143template void test_variadic_array_literal(id, NSArray*);
144template 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}}
145
146template<typename ...Args>
147void test_bad_variadic_dictionary_literal(Args ...args) {
148  id dict = @{ args : @17 }; // expected-error{{initializer contains unexpanded parameter pack 'args'}}
149}
150
151// Test array literal pack expansions. 
152template<typename T, typename U>
153struct pair {
154  T first;
155  U second;
156};
157
158template<typename T, typename ...Ts, typename ... Us>
159void test_variadic_dictionary_expansion(T t, pair<Ts, Us>... key_values) {
160  id dict = @{ 
161    t : key_values.second ..., // expected-error{{collection element of type 'int' is not an Objective-C object}}
162    key_values.first : key_values.second ..., // expected-error{{collection element of type 'float' is not an Objective-C object}}
163    key_values.second : t ...
164  };
165}
166
167template void test_variadic_dictionary_expansion(id, 
168                                                 pair<NSNumber*, id>,
169                                                 pair<id, ConvertibleTo<id>>);
170template void test_variadic_dictionary_expansion(NSNumber *, // expected-note{{in instantiation of function template specialization}}
171                                                 pair<NSNumber*, int>,
172                                                 pair<id, ConvertibleTo<id>>);
173template void test_variadic_dictionary_expansion(NSNumber *, // expected-note{{in instantiation of function template specialization}}
174                                                 pair<NSNumber*, id>,
175                                                 pair<float, ConvertibleTo<id>>);
176
177// Test parsing 
178struct key {
179  static id value;
180};
181
182id key;
183id value;
184
185void test_dictionary_colon() {
186  id dict = @{ key : value };
187}
188