diff options
Diffstat (limited to 'clang/test')
| -rw-r--r-- | clang/test/Index/comment-objc-parameterized-classes.m | 19 | ||||
| -rw-r--r-- | clang/test/PCH/objc_parameterized_classes.m | 30 | ||||
| -rw-r--r-- | clang/test/Parser/objc-error-qualified-implementation.m | 2 | ||||
| -rw-r--r-- | clang/test/SemaObjC/parameterized_classes.m | 192 |
4 files changed, 242 insertions, 1 deletions
diff --git a/clang/test/Index/comment-objc-parameterized-classes.m b/clang/test/Index/comment-objc-parameterized-classes.m new file mode 100644 index 00000000000..173fcecf331 --- /dev/null +++ b/clang/test/Index/comment-objc-parameterized-classes.m @@ -0,0 +1,19 @@ +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng -target x86_64-apple-darwin10 %s > %t/out +// RUN: FileCheck %s < %t/out + +// Ensure that XML we generate is not invalid. +// RUN: FileCheck %s -check-prefix=WRONG < %t/out +// WRONG-NOT: CommentXMLInvalid + +@protocol NSObject +@end + +@interface NSObject +@end + +// CHECK: <Declaration>@interface A <T : id, U : NSObject *> : NSObject +/// A +@interface A<T : id, U : NSObject *> : NSObject +@end diff --git a/clang/test/PCH/objc_parameterized_classes.m b/clang/test/PCH/objc_parameterized_classes.m new file mode 100644 index 00000000000..a541c33fbf2 --- /dev/null +++ b/clang/test/PCH/objc_parameterized_classes.m @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -emit-pch %s -o %t +// RUN: %clang_cc1 -include-pch %t -verify %s + +#ifndef HEADER_INCLUDED + +#define HEADER_INCLUDED + +@protocol NSObject +@end + +__attribute__((objc_root_class)) +@interface NSObject +@end + +@interface PC1<T, U : NSObject *> : NSObject +// expected-note@-2{{type parameter 'U' declared here}} +@end + +@interface PC1<T, U : NSObject *> (Cat1) +@end + +#else + +@interface PC1<T : NSObject *, // expected-error{{type bound 'NSObject *' for type parameter 'T' conflicts with implicit bound 'id}} + // expected-note@15{{type parameter 'T' declared here}} + U : id> (Cat2) // expected-error{{type bound 'id' for type parameter 'U' conflicts with previous bound 'NSObject *'}} + // expected-note@15{{type parameter 'U' declared here}} +@end + +#endif diff --git a/clang/test/Parser/objc-error-qualified-implementation.m b/clang/test/Parser/objc-error-qualified-implementation.m index 664737223e6..179e2d27479 100644 --- a/clang/test/Parser/objc-error-qualified-implementation.m +++ b/clang/test/Parser/objc-error-qualified-implementation.m @@ -17,7 +17,7 @@ @interface K @end -@implementation K <P // expected-error {{@implementation declaration cannot be protocol qualified}} +@implementation K <P // expected-error {{@implementation declaration cannot be protocol qualified}} expected-note{{to match this '<'}} @end // expected-error {{expected '>'}} // rdar://13920026 diff --git a/clang/test/SemaObjC/parameterized_classes.m b/clang/test/SemaObjC/parameterized_classes.m new file mode 100644 index 00000000000..e6eae442142 --- /dev/null +++ b/clang/test/SemaObjC/parameterized_classes.m @@ -0,0 +1,192 @@ +// RUN: %clang_cc1 %s -verify + +@protocol NSObject +@end + +__attribute__((objc_root_class)) +@interface NSObject <NSObject> // expected-note{{'NSObject' defined here}} +@end + +@interface NSString : NSObject +@end + +// -------------------------------------------------------------------------- +// Parsing parameterized classes. +// -------------------------------------------------------------------------- + +// Parse type parameters with a bound +@interface PC1<T, U : NSObject*> : NSObject +// expected-note@-1{{type parameter 'T' declared here}} +// expected-note@-2{{type parameter 'U' declared here}} +@end + +// Parse a type parameter with a bound that terminates in '>>'. +@interface PC2<T : id<NSObject>> : NSObject // expected-error{{a space is required between consecutive right angle brackets (use '> >')}} +@end + +// Parse multiple type parameters. +@interface PC3<T, U : id> : NSObject +@end + +// Parse multiple type parameters--grammatically ambiguous with protocol refs. +@interface PC4<T, U, V> : NSObject +@end + +// Parse a type parameter list without a superclass. +@interface PC5<T : id> // expected-error{{parameterized Objective-C class 'PC5' must have a superclass}} +@end + +// Parse a type parameter with name conflicts. +@interface PC6<T, U, + T> : NSObject // expected-error{{redeclaration of type parameter 'T'}} +@end + +// Parse Objective-C protocol references. +@interface PC7<T> // expected-error{{cannot find protocol declaration for 'T'}} +@end + +// Parse both type parameters and protocol references. +@interface PC8<T> : NSObject <NSObject> +@end + +// Type parameters with improper bounds. +@interface PC9<T : int, // expected-error{{type bound 'int' for type parameter 'T' is not an Objective-C pointer type}} + U : NSString> : NSObject // expected-error{{missing '*' in type bound 'NSString' for type parameter 'U'}} +@end + +// -------------------------------------------------------------------------- +// Parsing parameterized forward declarations classes. +// -------------------------------------------------------------------------- + +// Okay: forward declaration without type parameters. +@class PC10; + +// Okay: forward declarations with type parameters. +@class PC10<T, U : NSObject *>, PC11<T : NSObject *, U : id>; // expected-note{{type parameter 'T' declared here}} + +// Okay: forward declaration without type parameters following ones +// with type parameters. +@class PC10, PC11; + +// Okay: definition of class with type parameters that was formerly +// declared with the same type parameters. +@interface PC10<T, U : NSObject *> : NSObject +@end + +// Mismatched parameters in declaration of @interface following @class. +@interface PC11<T, U> : NSObject // expected-error{{missing type bound 'NSObject *' for type parameter 'T' in @interface}} +@end + +@interface PC12<T : NSObject *> : NSObject // expected-note{{type parameter 'T' declared here}} +@end + +@class PC12; + +// Mismatched parameters in subsequent forward declarations. +@class PC13<T : NSObject *>; // expected-note{{type parameter 'T' declared here}} +@class PC13; +@class PC13<U>; // expected-error{{missing type bound 'NSObject *' for type parameter 'U' in @class}} + +// Mismatch parameters in declaration of @class following @interface. +@class PC12<T>; // expected-error{{missing type bound 'NSObject *' for type parameter 'T' in @class}} + +// Parameterized forward declaration a class that is not parameterized. +@class NSObject<T>; // expected-error{{forward declaration of non-parameterized class 'NSObject' cannot have type parameters}} + +// Parameterized forward declaration preceding the definition (that is +// not parameterized). +@class NSNumber<T : NSObject *>; // expected-note{{'NSNumber' declared here}} +@interface NSNumber : NSObject // expected-error{{class 'NSNumber' previously declared with type parameters}} +@end + +@class PC14; + +// Okay: definition of class with type parameters that was formerly +// declared without type parameters. +@interface PC14<T, U : NSObject *> : NSObject +@end + +// -------------------------------------------------------------------------- +// Parsing parameterized categories and extensions. +// -------------------------------------------------------------------------- + +// Inferring type bounds +@interface PC1<T, U> (Cat1) <NSObject> +@end + +// Matching type bounds +@interface PC1<T : id, U : NSObject *> (Cat2) <NSObject> +@end + +// Inferring type bounds +@interface PC1<T, U> () <NSObject> +@end + +// Matching type bounds +@interface PC1<T : id, U : NSObject *> () <NSObject> +@end + +// Missing type parameters. +@interface PC1<T> () // expected-error{{extension has too few type parameters (expected 2, have 1)}} +@end + +// Extra type parameters. +@interface PC1<T, U, V> (Cat3) // expected-error{{category has too many type parameters (expected 2, have 3)}} +@end + +// Mismatched bounds. +@interface PC1<T : NSObject *, // expected-error{{type bound 'NSObject *' for type parameter 'T' conflicts with implicit bound 'id'}} + X : id> () // expected-error{{type bound 'id' for type parameter 'X' conflicts with previous bound 'NSObject *'for type parameter 'U'}} +@end + +// Parameterized category/extension of non-parameterized class. +@interface NSObject<T> (Cat1) // expected-error{{category of non-parameterized class 'NSObject' cannot have type parameters}} +@end + +@interface NSObject<T> () // expected-error{{extension of non-parameterized class 'NSObject' cannot have type parameters}} +@end + +// -------------------------------------------------------------------------- +// @implementations cannot have type parameters +// -------------------------------------------------------------------------- +@implementation PC1<T : id> // expected-error{{@implementation cannot have type parameters}} +@end + +@implementation PC2<T> // expected-error{{@implementation declaration cannot be protocol qualified}} +@end + +@implementation PC1<T> (Cat1) // expected-error{{@implementation cannot have type parameters}} +@end + +@implementation PC1<T : id> (Cat2) // expected-error{{@implementation cannot have type parameters}} +@end + +// -------------------------------------------------------------------------- +// Interfaces involving type parameters +// -------------------------------------------------------------------------- +@interface PC20<T : id, U : NSObject *, V : NSString *> : NSObject { + T object; +} + +- (U)method:(V)param; // expected-note{{passing argument to parameter 'param' here}} +@end + +@interface PC20<T, U, V> (Cat1) +- (U)catMethod:(V)param; // expected-note{{passing argument to parameter 'param' here}} +@end + +@interface PC20<X, Y, Z>() +- (X)extMethod:(Y)param; // expected-note{{passing argument to parameter 'param' here}} +@end + +void test_PC20_unspecialized(PC20 *pc20) { + // FIXME: replace type parameters with underlying types? + int *ip = [pc20 method: 0]; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'U' (aka 'NSObject *')}} + [pc20 method: ip]; // expected-warning{{incompatible pointer types sending 'int *' to parameter of type 'V' (aka 'NSString *')}} + + ip = [pc20 catMethod: 0]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'U' (aka 'NSObject *')}} + [pc20 catMethod: ip]; // expected-warning{{incompatible pointer types sending 'int *' to parameter of type 'V' (aka 'NSString *')}} + + ip = [pc20 extMethod: 0]; // expected-warning{{incompatible pointer types assigning to 'int *' from 'X' (aka 'id')}} + [pc20 extMethod: ip]; // expected-warning{{incompatible pointer types sending 'int *' to parameter of type 'Y' (aka 'NSObject *')}} +} |

