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