blob: e6eae442142e6bf9c62185cca312e4f7baef062a [file] [log] [blame]
Douglas Gregor85f3f952015-07-07 03:57:15 +00001// RUN: %clang_cc1 %s -verify
2
3@protocol NSObject
4@end
5
6__attribute__((objc_root_class))
7@interface NSObject <NSObject> // expected-note{{'NSObject' defined here}}
8@end
9
10@interface NSString : NSObject
11@end
12
13// --------------------------------------------------------------------------
14// Parsing parameterized classes.
15// --------------------------------------------------------------------------
16
17// Parse type parameters with a bound
18@interface PC1<T, U : NSObject*> : NSObject
19// expected-note@-1{{type parameter 'T' declared here}}
20// expected-note@-2{{type parameter 'U' declared here}}
21@end
22
23// Parse a type parameter with a bound that terminates in '>>'.
24@interface PC2<T : id<NSObject>> : NSObject // expected-error{{a space is required between consecutive right angle brackets (use '> >')}}
25@end
26
27// Parse multiple type parameters.
28@interface PC3<T, U : id> : NSObject
29@end
30
31// Parse multiple type parameters--grammatically ambiguous with protocol refs.
32@interface PC4<T, U, V> : NSObject
33@end
34
35// Parse a type parameter list without a superclass.
36@interface PC5<T : id> // expected-error{{parameterized Objective-C class 'PC5' must have a superclass}}
37@end
38
39// Parse a type parameter with name conflicts.
40@interface PC6<T, U,
41 T> : NSObject // expected-error{{redeclaration of type parameter 'T'}}
42@end
43
44// Parse Objective-C protocol references.
45@interface PC7<T> // expected-error{{cannot find protocol declaration for 'T'}}
46@end
47
48// Parse both type parameters and protocol references.
49@interface PC8<T> : NSObject <NSObject>
50@end
51
52// Type parameters with improper bounds.
53@interface PC9<T : int, // expected-error{{type bound 'int' for type parameter 'T' is not an Objective-C pointer type}}
54 U : NSString> : NSObject // expected-error{{missing '*' in type bound 'NSString' for type parameter 'U'}}
55@end
56
57// --------------------------------------------------------------------------
58// Parsing parameterized forward declarations classes.
59// --------------------------------------------------------------------------
60
61// Okay: forward declaration without type parameters.
62@class PC10;
63
64// Okay: forward declarations with type parameters.
65@class PC10<T, U : NSObject *>, PC11<T : NSObject *, U : id>; // expected-note{{type parameter 'T' declared here}}
66
67// Okay: forward declaration without type parameters following ones
68// with type parameters.
69@class PC10, PC11;
70
71// Okay: definition of class with type parameters that was formerly
72// declared with the same type parameters.
73@interface PC10<T, U : NSObject *> : NSObject
74@end
75
76// Mismatched parameters in declaration of @interface following @class.
77@interface PC11<T, U> : NSObject // expected-error{{missing type bound 'NSObject *' for type parameter 'T' in @interface}}
78@end
79
80@interface PC12<T : NSObject *> : NSObject // expected-note{{type parameter 'T' declared here}}
81@end
82
83@class PC12;
84
85// Mismatched parameters in subsequent forward declarations.
86@class PC13<T : NSObject *>; // expected-note{{type parameter 'T' declared here}}
87@class PC13;
88@class PC13<U>; // expected-error{{missing type bound 'NSObject *' for type parameter 'U' in @class}}
89
90// Mismatch parameters in declaration of @class following @interface.
91@class PC12<T>; // expected-error{{missing type bound 'NSObject *' for type parameter 'T' in @class}}
92
93// Parameterized forward declaration a class that is not parameterized.
94@class NSObject<T>; // expected-error{{forward declaration of non-parameterized class 'NSObject' cannot have type parameters}}
95
96// Parameterized forward declaration preceding the definition (that is
97// not parameterized).
98@class NSNumber<T : NSObject *>; // expected-note{{'NSNumber' declared here}}
99@interface NSNumber : NSObject // expected-error{{class 'NSNumber' previously declared with type parameters}}
100@end
101
102@class PC14;
103
104// Okay: definition of class with type parameters that was formerly
105// declared without type parameters.
106@interface PC14<T, U : NSObject *> : NSObject
107@end
108
109// --------------------------------------------------------------------------
110// Parsing parameterized categories and extensions.
111// --------------------------------------------------------------------------
112
113// Inferring type bounds
114@interface PC1<T, U> (Cat1) <NSObject>
115@end
116
117// Matching type bounds
118@interface PC1<T : id, U : NSObject *> (Cat2) <NSObject>
119@end
120
121// Inferring type bounds
122@interface PC1<T, U> () <NSObject>
123@end
124
125// Matching type bounds
126@interface PC1<T : id, U : NSObject *> () <NSObject>
127@end
128
129// Missing type parameters.
130@interface PC1<T> () // expected-error{{extension has too few type parameters (expected 2, have 1)}}
131@end
132
133// Extra type parameters.
134@interface PC1<T, U, V> (Cat3) // expected-error{{category has too many type parameters (expected 2, have 3)}}
135@end
136
137// Mismatched bounds.
138@interface PC1<T : NSObject *, // expected-error{{type bound 'NSObject *' for type parameter 'T' conflicts with implicit bound 'id'}}
139 X : id> () // expected-error{{type bound 'id' for type parameter 'X' conflicts with previous bound 'NSObject *'for type parameter 'U'}}
140@end
141
142// Parameterized category/extension of non-parameterized class.
143@interface NSObject<T> (Cat1) // expected-error{{category of non-parameterized class 'NSObject' cannot have type parameters}}
144@end
145
146@interface NSObject<T> () // expected-error{{extension of non-parameterized class 'NSObject' cannot have type parameters}}
147@end
148
149// --------------------------------------------------------------------------
150// @implementations cannot have type parameters
151// --------------------------------------------------------------------------
152@implementation PC1<T : id> // expected-error{{@implementation cannot have type parameters}}
153@end
154
155@implementation PC2<T> // expected-error{{@implementation declaration cannot be protocol qualified}}
156@end
157
158@implementation PC1<T> (Cat1) // expected-error{{@implementation cannot have type parameters}}
159@end
160
161@implementation PC1<T : id> (Cat2) // expected-error{{@implementation cannot have type parameters}}
162@end
163
164// --------------------------------------------------------------------------
165// Interfaces involving type parameters
166// --------------------------------------------------------------------------
167@interface PC20<T : id, U : NSObject *, V : NSString *> : NSObject {
168 T object;
169}
170
171- (U)method:(V)param; // expected-note{{passing argument to parameter 'param' here}}
172@end
173
174@interface PC20<T, U, V> (Cat1)
175- (U)catMethod:(V)param; // expected-note{{passing argument to parameter 'param' here}}
176@end
177
178@interface PC20<X, Y, Z>()
179- (X)extMethod:(Y)param; // expected-note{{passing argument to parameter 'param' here}}
180@end
181
182void test_PC20_unspecialized(PC20 *pc20) {
183 // FIXME: replace type parameters with underlying types?
184 int *ip = [pc20 method: 0]; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'U' (aka 'NSObject *')}}
185 [pc20 method: ip]; // expected-warning{{incompatible pointer types sending 'int *' to parameter of type 'V' (aka 'NSString *')}}
186
187 ip = [pc20 catMethod: 0]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'U' (aka 'NSObject *')}}
188 [pc20 catMethod: ip]; // expected-warning{{incompatible pointer types sending 'int *' to parameter of type 'V' (aka 'NSString *')}}
189
190 ip = [pc20 extMethod: 0]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'X' (aka 'id')}}
191 [pc20 extMethod: ip]; // expected-warning{{incompatible pointer types sending 'int *' to parameter of type 'Y' (aka 'NSObject *')}}
192}