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// -------------------------------------------------------------------------- 178// Interfaces involving type parameters 179// -------------------------------------------------------------------------- 180@interface PC20<T : id, U : NSObject *, V : NSString *> : NSObject { 181 T object; 182} 183 184- (U)method:(V)param; 185@end 186 187@interface PC20<T, U, V> (Cat1) 188- (U)catMethod:(V)param; 189@end 190 191@interface PC20<X, Y, Z>() 192- (X)extMethod:(Y)param; 193@end 194 195// -------------------------------------------------------------------------- 196// Parsing type arguments. 197// -------------------------------------------------------------------------- 198 199typedef NSString * ObjCStringRef; // expected-note{{'ObjCStringRef' declared here}} 200 201// Type arguments with a mix of identifiers and type-names. 202typedef PC4<id, NSObject *, NSString *> typeArgs1; 203 204// Type arguments with only identifiers. 205typedef PC4<id, id, id> typeArgs2; 206 207// Type arguments with only identifiers; one is ambiguous (resolved as 208// types). 209typedef PC4<NSObject, id, id> typeArgs3; // expected-error{{type argument 'NSObject' must be a pointer (requires a '*')}} 210 211// Type arguments with only identifiers; one is ambiguous (resolved as 212// protocol qualifiers). 213typedef PC4<NSObject, NSCopying> protocolQuals1; 214 215// Type arguments and protocol qualifiers. 216typedef PC4<id, NSObject *, id><NSObject, NSCopying> typeArgsAndProtocolQuals1; 217 218// Type arguments and protocol qualifiers in the wrong order. 219typedef PC4<NSObject, NSCopying><id, NSObject *, id> typeArgsAndProtocolQuals2; // expected-error{{protocol qualifiers must precede type arguments}} 220 221// Type arguments and protocol qualifiers (identifiers). 222typedef PC4<id, NSObject, id><NSObject, NSCopying> typeArgsAndProtocolQuals3; // expected-error{{type argument 'NSObject' must be a pointer (requires a '*')}} 223 224// Typo correction: protocol bias. 225typedef PC4<NSCopying, NSObjec> protocolQuals2; // expected-error{{cannot find protocol declaration for 'NSObjec'; did you mean 'NSObject'?}} 226 227// Typo correction: type bias. 228typedef PC4<id, id, NSObjec> typeArgs4; // expected-error{{unknown class name 'NSObjec'; did you mean 'NSObject'?}} 229// expected-error@-1{{type argument 'NSObject' must be a pointer (requires a '*')}} 230 231// Typo correction: bias set by correction itself to a protocol. 232typedef PC4<NSObject, NSObject, NSCopyin> protocolQuals3; // expected-error{{cannot find protocol declaration for 'NSCopyin'; did you mean 'NSCopying'?}} 233 234// Typo correction: bias set by correction itself to a type. 235typedef PC4<NSObject, NSObject, ObjCStringref> typeArgs5; // expected-error{{unknown type name 'ObjCStringref'; did you mean 'ObjCStringRef'?}} 236// expected-error@-1{{type argument 'NSObject' must be a pointer (requires a '*')}} 237// expected-error@-2{{type argument 'NSObject' must be a pointer (requires a '*')}} 238 239// Type/protocol conflict. 240typedef PC4<NSCopying, ObjCStringRef> typeArgsProtocolQualsConflict1; // expected-error{{angle brackets contain both a type ('ObjCStringRef') and a protocol ('NSCopying')}} 241 242// Handling the '>>' in type argument lists. 243typedef PC4<id<NSCopying>, NSObject *, id<NSObject>> typeArgs6; 244 245// -------------------------------------------------------------------------- 246// Checking type arguments. 247// -------------------------------------------------------------------------- 248 249@interface PC15<T : id, U : NSObject *, V : id<NSCopying>> : NSObject 250// expected-note@-1{{type parameter 'V' declared here}} 251// expected-note@-2{{type parameter 'V' declared here}} 252// expected-note@-3{{type parameter 'U' declared here}} 253@end 254 255typedef PC4<NSString *> tooFewTypeArgs1; // expected-error{{too few type arguments for class 'PC4' (have 1, expected 3)}} 256 257typedef PC4<NSString *, NSString *, NSString *, NSString *> tooManyTypeArgs1; // expected-error{{too many type arguments for class 'PC4' (have 4, expected 3)}} 258 259typedef PC15<int (^)(int, int), // block pointers as 'id' 260 NSString *, // subclass 261 NSString *> typeArgs7; // class that conforms to the protocol 262 263typedef PC15<NSObject *, NSObject *, id<NSCopying>> typeArgs8; 264 265typedef PC15<NSObject *, NSObject *, 266 NSObject *> typeArgs8b; // expected-error{{type argument 'NSObject *' does not satisfy the bound ('id<NSCopying>') of type parameter 'V'}} 267 268typedef PC15<id, 269 id, // expected-error{{type argument 'id' does not satisfy the bound ('NSObject *') of type parameter 'U'}} 270 id> typeArgs9; 271 272typedef PC15<id, NSObject *, 273 id> typeArgs10; // expected-error{{type argument 'id' does not satisfy the bound ('id<NSCopying>') of type parameter 'V'}} 274 275typedef PC15<id, 276 int (^)(int, int), // okay 277 id<NSCopying, NSObject>> typeArgs11; 278 279typedef PC15<id, NSString *, int (^)(int, int)> typeArgs12; // okay 280 281typedef NSObject<id, id> typeArgs13; // expected-error{{type arguments cannot be applied to non-parameterized class 'NSObject'}} 282 283typedef id<id, id> typeArgs14; // expected-error{{type arguments cannot be applied to non-class type 'id'}} 284 285typedef PC1<NSObject *, NSString *> typeArgs15; 286 287typedef PC1<NSObject *, NSString *><NSCopying> typeArgsAndProtocolQuals4; 288 289typedef typeArgs15<NSCopying> typeArgsAndProtocolQuals5; 290 291typedef typeArgs15<NSObject *, NSString *> typeArgs16; // expected-error{{type arguments cannot be applied to already-specialized class type 'typeArgs15' (aka 'PC1<NSObject *,NSString *>')}} 292 293typedef typeArgs15<NSObject> typeArgsAndProtocolQuals6; 294 295void testSpecializedTypePrinting() { 296 int *ip; 297 298 ip = (typeArgs15*)0; // expected-warning{{'typeArgs15 *' (aka 'PC1<NSObject *,NSString *> *')}} 299 ip = (typeArgsAndProtocolQuals4*)0; // expected-warning{{'typeArgsAndProtocolQuals4 *' (aka 'PC1<NSObject *,NSString *><NSCopying> *')}} 300 ip = (typeArgsAndProtocolQuals5*)0; // expected-warning{{'typeArgsAndProtocolQuals5 *' (aka 'typeArgs15<NSCopying> *')}} 301 ip = (typeArgsAndProtocolQuals6)0; // expected-error{{used type 'typeArgsAndProtocolQuals6' (aka 'typeArgs15<NSObject>')}} 302 ip = (typeArgsAndProtocolQuals6*)0;// expected-warning{{'typeArgsAndProtocolQuals6 *' (aka 'typeArgs15<NSObject> *')}} 303} 304 305// -------------------------------------------------------------------------- 306// Specialized superclasses 307// -------------------------------------------------------------------------- 308@interface PC21<T : NSObject *> : PC1<T, T> 309@end 310 311@interface PC22<T : NSObject *> : PC1<T> // expected-error{{too few type arguments for class 'PC1' (have 1, expected 2)}} 312@end 313 314@interface PC23<T : NSObject *> : PC1<T, U> // expected-error{{unknown type name 'U'}} 315@end 316 317@interface PC24<T> : PC1<T, T> // expected-error{{type argument 'T' (aka 'id') does not satisfy the bound ('NSObject *') of type parameter 'U'}} 318@end 319 320@interface NSFoo : PC1<NSObject *, NSObject *> // okay 321@end 322 323// -------------------------------------------------------------------------- 324// Co- and contra-variance. 325// -------------------------------------------------------------------------- 326@class Variance1<T, U>; 327 328@class Variance1<__covariant T, __contravariant U>; 329 330@interface Variance1<__covariant T, __contravariant U> : NSObject // expected-note 2{{declared here}} 331@end 332 333@interface Variance1<T, U> () // okay, inferred 334@end 335 336@interface Variance1<T, U> (Cat1) // okay, inferred 337@end 338 339@class Variance1<T, U>; // okay, inferred 340 341@interface Variance1<__covariant T, __contravariant U> () // okay, matches 342@end 343 344@interface Variance1<__covariant T, __contravariant U> (Cat2) // okay, matches 345@end 346 347@class Variance1<__covariant T, __contravariant U>; // okay, matches 348 349@interface Variance1<__contravariant X, // expected-error{{contravariant type parameter 'X' conflicts with previous covariant type parameter 'T'}} 350 __covariant Y> () // expected-error{{covariant type parameter 'Y' conflicts with previous contravariant type parameter 'U'}} 351@end 352 353@class Variance2<__covariant T, __contravariant U>; // expected-note 2{{declared here}} 354 355@interface Variance2<__contravariant T, // expected-error{{contravariant type parameter 'T' conflicts with previous covariant type parameter 'T'}} 356 U> : NSObject // expected-error{{invariant type parameter 'U' conflicts with previous contravariant type parameter 'U'}} 357@end 358