1 // RUN: %clang_cc1 -fblocks %s -verify 2 3 #if !__has_feature(objc_generics) 4 # error Compiler does not support Objective-C generics? 5 #endif 6 7 #if !__has_feature(objc_generics_variance) 8 # error Compiler does not support co- and contr-variance? 9 #endif 10 11 @protocol NSObject // expected-note{{'NSObject' declared here}} 12 @end 13 14 @protocol NSCopying // expected-note{{'NSCopying' declared here}} 15 @end 16 17 __attribute__((objc_root_class)) 18 @interface NSObject <NSObject> // expected-note{{'NSObject' defined here}} 19 @end 20 21 @interface NSString : NSObject <NSCopying> 22 @end 23 24 // -------------------------------------------------------------------------- 25 // Parsing parameterized classes. 26 // -------------------------------------------------------------------------- 27 28 // Parse type parameters with a bound 29 @interface PC1<T, U : NSObject*> : NSObject // expected-note{{'PC1' declared here}} 30 // expected-note@-1{{type parameter 'T' declared here}} 31 // expected-note@-2{{type parameter 'U' declared here}} 32 // expected-note@-3{{type parameter 'U' declared here}} 33 @end 34 35 // Parse a type parameter with a bound that terminates in '>>'. 36 @interface PC2<T : id<NSObject>> : NSObject 37 @end 38 39 // Parse multiple type parameters. 40 @interface PC3<T, U : id> : NSObject 41 @end 42 43 // Parse multiple type parameters--grammatically ambiguous with protocol refs. 44 @interface PC4<T, U, V> : NSObject // expected-note 2{{'PC4' declared here}} 45 @end 46 47 // Parse a type parameter list without a superclass. 48 @interface PC5<T : id> 49 @end 50 51 // Parse a type parameter with name conflicts. 52 @interface PC6<T, U, 53 T> : NSObject // expected-error{{redeclaration of type parameter 'T'}} 54 @end 55 56 // Parse Objective-C protocol references. 57 @interface PC7<T> // expected-error{{cannot find protocol declaration for 'T'}} 58 @end 59 60 // Parse both type parameters and protocol references. 61 @interface PC8<T> : NSObject <NSObject> 62 @end 63 64 // Type parameters with improper bounds. 65 @interface PC9<T : int, // expected-error{{type bound 'int' for type parameter 'T' is not an Objective-C pointer type}} 66 U : NSString> : NSObject // expected-error{{missing '*' in type bound 'NSString' for type parameter 'U'}} 67 @end 68 69 // -------------------------------------------------------------------------- 70 // Parsing parameterized forward declarations classes. 71 // -------------------------------------------------------------------------- 72 73 // Okay: forward declaration without type parameters. 74 @class PC10; 75 76 // Okay: forward declarations with type parameters. 77 @class PC10<T, U : NSObject *>, PC11<T : NSObject *, U : id>; // expected-note{{type parameter 'T' declared here}} 78 79 // Okay: forward declaration without type parameters following ones 80 // with type parameters. 81 @class PC10, PC11; 82 83 // Okay: definition of class with type parameters that was formerly 84 // declared with the same type parameters. 85 @interface PC10<T, U : NSObject *> : NSObject 86 @end 87 88 // Mismatched parameters in declaration of @interface following @class. 89 @interface PC11<T, U> : NSObject // expected-error{{missing type bound 'NSObject *' for type parameter 'T' in @interface}} 90 @end 91 92 @interface PC12<T : NSObject *> : NSObject // expected-note{{type parameter 'T' declared here}} 93 @end 94 95 @class PC12; 96 97 // Mismatched parameters in subsequent forward declarations. 98 @class PC13<T : NSObject *>; // expected-note{{type parameter 'T' declared here}} 99 @class PC13; 100 @class PC13<U>; // expected-error{{missing type bound 'NSObject *' for type parameter 'U' in @class}} 101 102 // Mismatch parameters in declaration of @class following @interface. 103 @class PC12<T>; // expected-error{{missing type bound 'NSObject *' for type parameter 'T' in @class}} 104 105 // Parameterized forward declaration a class that is not parameterized. 106 @class NSObject<T>; // expected-error{{forward declaration of non-parameterized class 'NSObject' cannot have type parameters}} 107 // expected-note@-1{{'NSObject' declared here}} 108 109 // Parameterized forward declaration preceding the definition (that is 110 // not parameterized). 111 @class NSNumber<T : NSObject *>; // expected-note{{'NSNumber' declared here}} 112 @interface NSNumber : NSObject // expected-error{{class 'NSNumber' previously declared with type parameters}} 113 @end 114 115 @class PC14; 116 117 // Okay: definition of class with type parameters that was formerly 118 // declared without type parameters. 119 @interface PC14<T, U : NSObject *> : NSObject 120 @end 121 122 // -------------------------------------------------------------------------- 123 // Parsing parameterized categories and extensions. 124 // -------------------------------------------------------------------------- 125 126 // Inferring type bounds 127 @interface PC1<T, U> (Cat1) <NSObject> 128 @end 129 130 // Matching type bounds 131 @interface PC1<T : id, U : NSObject *> (Cat2) <NSObject> 132 @end 133 134 // Inferring type bounds 135 @interface PC1<T, U> () <NSObject> 136 @end 137 138 // Matching type bounds 139 @interface PC1<T : id, U : NSObject *> () <NSObject> 140 @end 141 142 // Missing type parameters. 143 @interface PC1<T> () // expected-error{{extension has too few type parameters (expected 2, have 1)}} 144 @end 145 146 // Extra type parameters. 147 @interface PC1<T, U, V> (Cat3) // expected-error{{category has too many type parameters (expected 2, have 3)}} 148 @end 149 150 // Mismatched bounds. 151 @interface PC1<T : NSObject *, // expected-error{{type bound 'NSObject *' for type parameter 'T' conflicts with implicit bound 'id'}} 152 X : id> () // expected-error{{type bound 'id' for type parameter 'X' conflicts with previous bound 'NSObject *'for type parameter 'U'}} 153 @end 154 155 // Parameterized category/extension of non-parameterized class. 156 @interface NSObject<T> (Cat1) // expected-error{{category of non-parameterized class 'NSObject' cannot have type parameters}} 157 @end 158 159 @interface NSObject<T> () // expected-error{{extension of non-parameterized class 'NSObject' cannot have type parameters}} 160 @end 161 162 // -------------------------------------------------------------------------- 163 // @implementations cannot have type parameters 164 // -------------------------------------------------------------------------- 165 @implementation PC1<T : id> // expected-error{{@implementation cannot have type parameters}} 166 @end 167 168 @implementation PC2<T> // expected-error{{@implementation declaration cannot be protocol qualified}} 169 @end 170 171 @implementation PC1<T> (Cat1) // expected-error{{@implementation cannot have type parameters}} 172 @end 173 174 @implementation PC1<T : id> (Cat2) // expected-error{{@implementation cannot have type parameters}} 175 @end 176 177 typedef T undeclaredT; // expected-error{{unknown type name 'T'}} 178 179 // -------------------------------------------------------------------------- 180 // Interfaces involving type parameters 181 // -------------------------------------------------------------------------- 182 @interface PC20<T : id, U : NSObject *, V : NSString *> : NSObject { 183 T object; 184 } 185 186 - (U)method:(V)param; 187 @end 188 189 @interface PC20<T, U, V> (Cat1) 190 - (U)catMethod:(V)param; 191 @end 192 193 @interface PC20<X, Y, Z>() 194 - (X)extMethod:(Y)param; 195 @end 196 197 // -------------------------------------------------------------------------- 198 // Parsing type arguments. 199 // -------------------------------------------------------------------------- 200 201 typedef NSString * ObjCStringRef; // expected-note{{'ObjCStringRef' declared here}} 202 203 // Type arguments with a mix of identifiers and type-names. 204 typedef PC4<id, NSObject *, NSString *> typeArgs1; 205 206 // Type arguments with only identifiers. 207 typedef PC4<id, id, id> typeArgs2; 208 209 // Type arguments with only identifiers; one is ambiguous (resolved as 210 // types). 211 typedef PC4<NSObject, id, id> typeArgs3; // expected-error{{type argument 'NSObject' must be a pointer (requires a '*')}} 212 213 // Type arguments with only identifiers; one is ambiguous (resolved as 214 // protocol qualifiers). 215 typedef PC4<NSObject, NSCopying> protocolQuals1; 216 217 // Type arguments and protocol qualifiers. 218 typedef PC4<id, NSObject *, id><NSObject, NSCopying> typeArgsAndProtocolQuals1; 219 220 // Type arguments and protocol qualifiers in the wrong order. 221 typedef PC4<NSObject, NSCopying><id, NSObject *, id> typeArgsAndProtocolQuals2; // expected-error{{protocol qualifiers must precede type arguments}} 222 223 // Type arguments and protocol qualifiers (identifiers). 224 typedef PC4<id, NSObject, id><NSObject, NSCopying> typeArgsAndProtocolQuals3; // expected-error{{type argument 'NSObject' must be a pointer (requires a '*')}} 225 226 // Typo correction: protocol bias. 227 typedef PC4<NSCopying, NSObjec> protocolQuals2; // expected-error{{cannot find protocol declaration for 'NSObjec'; did you mean 'NSObject'?}} 228 229 // Typo correction: type bias. 230 typedef PC4<id, id, NSObjec> typeArgs4; // expected-error{{unknown class name 'NSObjec'; did you mean 'NSObject'?}} 231 // expected-error@-1{{type argument 'NSObject' must be a pointer (requires a '*')}} 232 233 // Typo correction: bias set by correction itself to a protocol. 234 typedef PC4<NSObject, NSObject, NSCopyin> protocolQuals3; // expected-error{{cannot find protocol declaration for 'NSCopyin'; did you mean 'NSCopying'?}} 235 236 // Typo correction: bias set by correction itself to a type. 237 typedef PC4<NSObject, NSObject, ObjCStringref> typeArgs5; // expected-error{{unknown type name 'ObjCStringref'; did you mean 'ObjCStringRef'?}} 238 // expected-error@-1{{type argument 'NSObject' must be a pointer (requires a '*')}} 239 // expected-error@-2{{type argument 'NSObject' must be a pointer (requires a '*')}} 240 241 // Type/protocol conflict. 242 typedef PC4<NSCopying, ObjCStringRef> typeArgsProtocolQualsConflict1; // expected-error{{angle brackets contain both a type ('ObjCStringRef') and a protocol ('NSCopying')}} 243 244 // Handling the '>>' in type argument lists. 245 typedef PC4<id<NSCopying>, NSObject *, id<NSObject>> typeArgs6; 246 247 // -------------------------------------------------------------------------- 248 // Checking type arguments. 249 // -------------------------------------------------------------------------- 250 251 @interface PC15<T : id, U : NSObject *, V : id<NSCopying>> : NSObject 252 // expected-note@-1{{type parameter 'V' declared here}} 253 // expected-note@-2{{type parameter 'V' declared here}} 254 // expected-note@-3{{type parameter 'U' declared here}} 255 @end 256 257 typedef PC4<NSString *> tooFewTypeArgs1; // expected-error{{too few type arguments for class 'PC4' (have 1, expected 3)}} 258 259 typedef PC4<NSString *, NSString *, NSString *, NSString *> tooManyTypeArgs1; // expected-error{{too many type arguments for class 'PC4' (have 4, expected 3)}} 260 261 typedef PC15<int (^)(int, int), // block pointers as 'id' 262 NSString *, // subclass 263 NSString *> typeArgs7; // class that conforms to the protocol 264 265 typedef PC15<NSObject *, NSObject *, id<NSCopying>> typeArgs8; 266 267 typedef PC15<NSObject *, NSObject *, 268 NSObject *> typeArgs8b; // expected-error{{type argument 'NSObject *' does not satisfy the bound ('id<NSCopying>') of type parameter 'V'}} 269 270 typedef PC15<id, 271 id, // expected-error{{type argument 'id' does not satisfy the bound ('NSObject *') of type parameter 'U'}} 272 id> typeArgs9; 273 274 typedef PC15<id, NSObject *, 275 id> typeArgs10; // expected-error{{type argument 'id' does not satisfy the bound ('id<NSCopying>') of type parameter 'V'}} 276 277 typedef PC15<id, 278 int (^)(int, int), // okay 279 id<NSCopying, NSObject>> typeArgs11; 280 281 typedef PC15<id, NSString *, int (^)(int, int)> typeArgs12; // okay 282 283 typedef NSObject<id, id> typeArgs13; // expected-error{{type arguments cannot be applied to non-parameterized class 'NSObject'}} 284 285 typedef id<id, id> typeArgs14; // expected-error{{type arguments cannot be applied to non-class type 'id'}} 286 287 typedef PC1<NSObject *, NSString *> typeArgs15; 288 289 typedef PC1<NSObject *, NSString *><NSCopying> typeArgsAndProtocolQuals4; 290 291 typedef typeArgs15<NSCopying> typeArgsAndProtocolQuals5; 292 293 typedef typeArgs15<NSObject *, NSString *> typeArgs16; // expected-error{{type arguments cannot be applied to already-specialized class type 'typeArgs15' (aka 'PC1<NSObject *,NSString *>')}} 294 295 typedef typeArgs15<NSObject> typeArgsAndProtocolQuals6; 296 297 void testSpecializedTypePrinting() { 298 int *ip; 299 300 ip = (typeArgs15*)0; // expected-warning{{'typeArgs15 *' (aka 'PC1<NSObject *,NSString *> *')}} 301 ip = (typeArgsAndProtocolQuals4*)0; // expected-warning{{'typeArgsAndProtocolQuals4 *' (aka 'PC1<NSObject *,NSString *><NSCopying> *')}} 302 ip = (typeArgsAndProtocolQuals5*)0; // expected-warning{{'typeArgsAndProtocolQuals5 *' (aka 'typeArgs15<NSCopying> *')}} 303 ip = (typeArgsAndProtocolQuals6)0; // expected-error{{used type 'typeArgsAndProtocolQuals6' (aka 'typeArgs15<NSObject>')}} 304 ip = (typeArgsAndProtocolQuals6*)0;// expected-warning{{'typeArgsAndProtocolQuals6 *' (aka 'typeArgs15<NSObject> *')}} 305 } 306 307 // -------------------------------------------------------------------------- 308 // Specialized superclasses 309 // -------------------------------------------------------------------------- 310 @interface PC21<T : NSObject *> : PC1<T, T> 311 @end 312 313 @interface PC22<T : NSObject *> : PC1<T> // expected-error{{too few type arguments for class 'PC1' (have 1, expected 2)}} 314 @end 315 316 @interface PC23<T : NSObject *> : PC1<T, U> // expected-error{{unknown type name 'U'}} 317 @end 318 319 @interface PC24<T> : PC1<T, T> // expected-error{{type argument 'T' (aka 'id') does not satisfy the bound ('NSObject *') of type parameter 'U'}} 320 @end 321 322 @interface NSFoo : PC1<NSObject *, NSObject *> // okay 323 @end 324 325 // -------------------------------------------------------------------------- 326 // Co- and contra-variance. 327 // -------------------------------------------------------------------------- 328 @class Variance1<T, U>; 329 330 @class Variance1<__covariant T, __contravariant U>; 331 332 @interface Variance1<__covariant T, __contravariant U> : NSObject // expected-note 2{{declared here}} 333 @end 334 335 @interface Variance1<T, U> () // okay, inferred 336 @end 337 338 @interface Variance1<T, U> (Cat1) // okay, inferred 339 @end 340 341 @class Variance1<T, U>; // okay, inferred 342 343 @interface Variance1<__covariant T, __contravariant U> () // okay, matches 344 @end 345 346 @interface Variance1<__covariant T, __contravariant U> (Cat2) // okay, matches 347 @end 348 349 @class Variance1<__covariant T, __contravariant U>; // okay, matches 350 351 @interface Variance1<__contravariant X, // expected-error{{contravariant type parameter 'X' conflicts with previous covariant type parameter 'T'}} 352 __covariant Y> () // expected-error{{covariant type parameter 'Y' conflicts with previous contravariant type parameter 'U'}} 353 @end 354 355 @class Variance2<__covariant T, __contravariant U>; // expected-note 2{{declared here}} 356 357 @interface Variance2<__contravariant T, // expected-error{{contravariant type parameter 'T' conflicts with previous covariant type parameter 'T'}} 358 U> : NSObject // expected-error{{invariant type parameter 'U' conflicts with previous contravariant type parameter 'U'}} 359 @end 360