summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/Index/annotate-parameterized-classes.m12
-rw-r--r--clang/test/Index/annotate-tokens.m7
-rw-r--r--clang/test/Parser/placeholder-recovery.m9
-rw-r--r--clang/test/SemaObjC/parameterized_classes.m12
-rw-r--r--clang/test/SemaObjC/protocol-archane.m4
-rw-r--r--clang/test/SemaObjCXX/parameterized_classes_subst.mm407
6 files changed, 434 insertions, 17 deletions
diff --git a/clang/test/Index/annotate-parameterized-classes.m b/clang/test/Index/annotate-parameterized-classes.m
index 6a53fed4bd7..762ae2aece1 100644
--- a/clang/test/Index/annotate-parameterized-classes.m
+++ b/clang/test/Index/annotate-parameterized-classes.m
@@ -17,19 +17,15 @@ typedef A<id<NSObject>, NSObject *> ASpecialization1;
// RUN: c-index-test -test-annotate-tokens=%s:7:1:9:1 %s -target x86_64-apple-macosx10.7.0 | FileCheck -check-prefix=CHECK-INTERFACE-DECL %s
// CHECK-INTERFACE-DECL: Identifier: "T" [7:14 - 7:15] TemplateTypeParameter=T:7:14
-// FIXME: Should be a type reference
-// CHECK-INTERFACE-DECL: Identifier: "id" [7:18 - 7:20] TemplateTypeParameter=T:7:14
+// CHECK-INTERFACE-DECL: Identifier: "id" [7:18 - 7:20] TypeRef=id:0:0
// CHECK-INTERFACE-DECL: Identifier: "U" [7:22 - 7:23] TemplateTypeParameter=U:7:22
-// FIXME: Should be a class reference
-// CHECK-INTERFACE-DECL: Identifier: "NSObject" [7:26 - 7:34] TemplateTypeParameter=U:7:22
+// CHECK-INTERFACE-DECL: Identifier: "NSObject" [7:26 - 7:34] ObjCClassRef=NSObject:4:12
// RUN: c-index-test -test-annotate-tokens=%s:10:1:12:1 %s -target x86_64-apple-macosx10.7.0 | FileCheck -check-prefix=CHECK-CATEGORY-DECL %s
// CHECK-CATEGORY-DECL: Identifier: "T" [10:14 - 10:15] TemplateTypeParameter=T:10:14
-// FIXME: Should be a type reference
-// CHECK-CATEGORY-DECL: Identifier: "id" [10:18 - 10:20] TemplateTypeParameter=T:10:14
+// CHECK-CATEGORY-DECL: Identifier: "id" [10:18 - 10:20] TypeRef=id:0:0
// CHECK-CATEGORY-DECL: Identifier: "U" [10:22 - 10:23] TemplateTypeParameter=U:10:22
-// FIXME: Should be a class reference
-// CHECK-CATEGORY-DECL: Identifier: "NSObject" [10:26 - 10:34] TemplateTypeParameter=U:10:22
+// CHECK-CATEGORY-DECL: Identifier: "NSObject" [10:26 - 10:34] ObjCClassRef=NSObject:4:12
// RUN: c-index-test -test-annotate-tokens=%s:13:1:14:1 %s -target x86_64-apple-macosx10.7.0 | FileCheck -check-prefix=CHECK-SPECIALIZATION %s
// CHECK-SPECIALIZATION: Identifier: "id" [13:11 - 13:13] TypeRef=id:0:0
diff --git a/clang/test/Index/annotate-tokens.m b/clang/test/Index/annotate-tokens.m
index 9a7e28a666b..0a76105a94d 100644
--- a/clang/test/Index/annotate-tokens.m
+++ b/clang/test/Index/annotate-tokens.m
@@ -152,6 +152,7 @@ static Rdar8595462_A * Rdar8595462_staticVar;
@property int extensionProperty;
@end
+typedef id<Proto> *proto_ptr;
// RUN: c-index-test -test-annotate-tokens=%s:1:1:118:1 %s -DIBOutlet='__attribute__((iboutlet))' -DIBAction='void)__attribute__((ibaction)' | FileCheck %s
// CHECK: Punctuation: "@" [1:1 - 1:2] ObjCInterfaceDecl=Foo:1:12
@@ -596,3 +597,9 @@ static Rdar8595462_A * Rdar8595462_staticVar;
// CHECK-PROP: Keyword: "property" [152:4 - 152:12] ObjCPropertyDecl=extensionProperty:152:17
// CHECK-PROP: Keyword: "int" [152:13 - 152:16] ObjCPropertyDecl=extensionProperty:152:17
// CHECK-PROP: Identifier: "extensionProperty" [152:17 - 152:34] ObjCPropertyDecl=extensionProperty:152:17
+
+// RUN: c-index-test -test-annotate-tokens=%s:155:1:156:1 %s -DIBOutlet='__attribute__((iboutlet))' -DIBAction='void)__attribute__((ibaction)' -target x86_64-apple-macosx10.7.0 | FileCheck -check-prefix=CHECK-ID-PROTO %s
+// CHECK-ID-PROTO: Identifier: "id" [155:9 - 155:11] TypeRef=id:0:0
+// CHECK-ID-PROTO: Punctuation: "<" [155:11 - 155:12] TypedefDecl=proto_ptr:155:20 (Definition)
+// CHECK-ID-PROTO: Identifier: "Proto" [155:12 - 155:17] ObjCProtocolRef=Proto
+// CHECK-ID-PROTO: Punctuation: ">" [155:17 - 155:18] TypedefDecl=proto_ptr:155:20 (Definition)
diff --git a/clang/test/Parser/placeholder-recovery.m b/clang/test/Parser/placeholder-recovery.m
index 3fe1d62c304..b43b0e4a57c 100644
--- a/clang/test/Parser/placeholder-recovery.m
+++ b/clang/test/Parser/placeholder-recovery.m
@@ -3,10 +3,9 @@
// FIXME: We could do much better with this, if we recognized
// placeholders somehow. However, we're content with not generating
// bogus 'archaic' warnings with bad location info.
-@protocol <#protocol name#> <NSObject> // expected-error 2{{expected identifier}} \
-// expected-error{{cannot find protocol declaration for 'NSObject'}} \
+@protocol <#protocol name#> <NSObject> // expected-error {{expected identifier or '('}} \
+// expected-error 2{{expected identifier}} \
// expected-warning{{protocol has no object type specified; defaults to qualified 'id'}}
+<#methods#>
-<#methods#> // expected-error{{expected identifier}}
-
-@end // expected-error{{prefix attribute}}
+@end
diff --git a/clang/test/SemaObjC/parameterized_classes.m b/clang/test/SemaObjC/parameterized_classes.m
index 9834f7cd11f..eb3e122e820 100644
--- a/clang/test/SemaObjC/parameterized_classes.m
+++ b/clang/test/SemaObjC/parameterized_classes.m
@@ -1,5 +1,9 @@
// RUN: %clang_cc1 -fblocks %s -verify
+#if !__has_feature(objc_generics)
+# error Compiler does not support Objective-C generics?
+#endif
+
@protocol NSObject // expected-note{{'NSObject' declared here}}
@end
@@ -255,14 +259,14 @@ typedef PC15<int (^)(int, int), // block pointers as 'id'
typedef PC15<NSObject *, NSObject *, id<NSCopying>> typeArgs8;
typedef PC15<NSObject *, NSObject *,
- NSObject *> typeArgs8b; // expected-error{{type argument 'NSObject *' does not satisy the bound ('id<NSCopying>') of type parameter 'V'}}
+ NSObject *> typeArgs8b; // expected-error{{type argument 'NSObject *' does not satisfy the bound ('id<NSCopying>') of type parameter 'V'}}
typedef PC15<id,
- id, // expected-error{{type argument 'id' does not satisy the bound ('NSObject *') of type parameter 'U'}}
+ id, // expected-error{{type argument 'id' does not satisfy the bound ('NSObject *') of type parameter 'U'}}
id> typeArgs9;
typedef PC15<id, NSObject *,
- id> typeArgs10; // expected-error{{type argument 'id' does not satisy the bound ('id<NSCopying>') of type parameter 'V'}}
+ id> typeArgs10; // expected-error{{type argument 'id' does not satisfy the bound ('id<NSCopying>') of type parameter 'V'}}
typedef PC15<id,
int (^)(int, int), // okay
@@ -306,7 +310,7 @@ void testSpecializedTypePrinting() {
@interface PC23<T : NSObject *> : PC1<T, U> // expected-error{{unknown type name 'U'}}
@end
-@interface PC24<T> : PC1<T, T> // expected-error{{type argument 'T' (aka 'id') does not satisy the bound ('NSObject *') of type parameter 'U'}}
+@interface PC24<T> : PC1<T, T> // expected-error{{type argument 'T' (aka 'id') does not satisfy the bound ('NSObject *') of type parameter 'U'}}
@end
@interface NSFoo : PC1<NSObject *, NSObject *> // okay
diff --git a/clang/test/SemaObjC/protocol-archane.m b/clang/test/SemaObjC/protocol-archane.m
index 788edf276d7..f2f6025a5ad 100644
--- a/clang/test/SemaObjC/protocol-archane.m
+++ b/clang/test/SemaObjC/protocol-archane.m
@@ -40,3 +40,7 @@ Class <SomeProtocol> UnfortunateGCCExtension;
- (void)crashWith:(<Broken>)a { // expected-warning {{protocol has no object type specified; defaults to qualified 'id'}}
}
@end
+
+typedef <SomeProtocol> id TwoTypeSpecs; // expected-warning{{no object type specified}}
+// expected-error@-1{{typedef redefinition with different types ('id<SomeProtocol>' vs 'id')}}
+// expected-error@-2{{expected ';' after top level declarator}}
diff --git a/clang/test/SemaObjCXX/parameterized_classes_subst.mm b/clang/test/SemaObjCXX/parameterized_classes_subst.mm
new file mode 100644
index 00000000000..cd0096c3fef
--- /dev/null
+++ b/clang/test/SemaObjCXX/parameterized_classes_subst.mm
@@ -0,0 +1,407 @@
+// RUN: %clang_cc1 -fblocks -fsyntax-only -std=c++11 %s -verify
+//
+// Test the substitution of type arguments for type parameters when
+// using parameterized classes in Objective-C.
+
+__attribute__((objc_root_class))
+@interface NSObject
++ (instancetype)alloc;
+- (instancetype)init;
+@end
+
+@protocol NSCopying
+@end
+
+@interface NSString : NSObject <NSCopying>
+@end
+
+@interface NSNumber : NSObject <NSCopying>
+@end
+
+@interface NSArray<T> : NSObject <NSCopying> {
+@public
+ T *data; // don't try this at home
+}
+- (T)objectAtIndexedSubscript:(int)index;
++ (NSArray<T> *)array;
+@property (copy,nonatomic) T lastObject;
+@end
+
+@interface NSMutableArray<T> : NSArray<T>
+-(instancetype)initWithArray:(NSArray<T> *)array; // expected-note{{passing argument}}
+- (void)setObject:(T)object atIndexedSubscript:(int)index; // expected-note 2{{passing argument to parameter 'object' here}}
+@end
+
+@interface NSStringArray : NSArray<NSString *>
+@end
+
+@interface NSSet<T> : NSObject <NSCopying>
+- (T)firstObject;
+@property (nonatomic, copy) NSArray<T> *allObjects;
+@end
+
+// Parameterized inheritance (simple case)
+@interface NSMutableSet<U : id<NSCopying>> : NSSet<U>
+- (void)addObject:(U)object; // expected-note 7{{passing argument to parameter 'object' here}}
+@end
+
+@interface Widget : NSObject <NSCopying>
+@end
+
+// Non-parameterized class inheriting from a specialization of a
+// parameterized class.
+@interface WidgetSet : NSMutableSet<Widget *>
+@end
+
+// Parameterized inheritance with a more interesting transformation in
+// the specialization.
+@interface MutableSetOfArrays<T> : NSMutableSet<NSArray<T>*>
+@end
+
+// Inheriting from an unspecialized form of a parameterized type.
+@interface UntypedMutableSet : NSMutableSet
+@end
+
+@interface Window : NSObject
+@end
+
+@interface NSDictionary<K, V> : NSObject <NSCopying>
+- (V)objectForKeyedSubscript:(K)key; // expected-note 2{{parameter 'key'}}
+@end
+
+@interface NSMutableDictionary<K : id<NSCopying>, V> : NSDictionary<K, V> // expected-note 2{{type parameter 'K' declared here}} \
+// expected-note 2{{'NSMutableDictionary' declared here}}
+- (void)setObject:(V)object forKeyedSubscript:(K)key;
+// expected-note@-1 {{parameter 'object' here}}
+// expected-note@-2 {{parameter 'object' here}}
+// expected-note@-3 {{parameter 'key' here}}
+// expected-note@-4 {{parameter 'key' here}}
+
+@property (strong) K someRandomKey;
+@end
+
+@interface WindowArray : NSArray<Window *>
+@end
+
+@interface NSSet<T> (Searching)
+- (T)findObject:(T)object;
+@end
+
+
+// --------------------------------------------------------------------------
+// Message sends.
+// --------------------------------------------------------------------------
+void test_message_send_result(
+ NSSet<NSString *> *stringSet,
+ NSMutableSet<NSString *> *mutStringSet,
+ WidgetSet *widgetSet,
+ UntypedMutableSet *untypedMutSet,
+ MutableSetOfArrays<NSString *> *mutStringArraySet,
+ NSSet *set,
+ NSMutableSet *mutSet,
+ MutableSetOfArrays *mutArraySet,
+ NSArray<NSString *> *stringArray,
+ void (^block)(void)) {
+ int *ip;
+ ip = [stringSet firstObject]; // expected-error{{from incompatible type 'NSString *'}}
+ ip = [mutStringSet firstObject]; // expected-error{{from incompatible type 'NSString *'}}
+ ip = [widgetSet firstObject]; // expected-error{{from incompatible type 'Widget *'}}
+ ip = [untypedMutSet firstObject]; // expected-error{{from incompatible type 'id'}}
+ ip = [mutStringArraySet firstObject]; // expected-error{{from incompatible type 'NSArray<NSString *> *'}}
+ ip = [set firstObject]; // expected-error{{from incompatible type 'id'}}
+ ip = [mutSet firstObject]; // expected-error{{from incompatible type 'id'}}
+ ip = [mutArraySet firstObject]; // expected-error{{from incompatible type 'id'}}
+ ip = [block firstObject]; // expected-error{{from incompatible type 'id'}}
+
+ ip = [stringSet findObject:@"blah"]; // expected-error{{from incompatible type 'NSString *'}}
+
+ // Class messages.
+ ip = [NSSet<NSString *> alloc]; // expected-error{{from incompatible type 'NSSet<NSString *> *'}}
+ ip = [NSSet alloc]; // expected-error{{from incompatible type 'NSSet *'}}
+ ip = [MutableSetOfArrays<NSString *> alloc]; // expected-error{{from incompatible type 'MutableSetOfArrays<NSString *> *'}}
+ ip = [MutableSetOfArrays alloc]; // expected-error{{from incompatible type 'MutableSetOfArrays *'}}
+ ip = [NSArray<NSString *> array]; // expected-error{{from incompatible type 'NSArray<NSString *> *'}}
+ ip = [NSArray<NSString *><NSCopying> array]; // expected-error{{from incompatible type 'NSArray<NSString *> *'}}
+
+ ip = [[NSMutableArray<NSString *> alloc] init]; // expected-error{{from incompatible type 'NSMutableArray<NSString *> *'}}
+
+ [[NSMutableArray alloc] initWithArray: stringArray]; // okay
+ [[NSMutableArray<NSString *> alloc] initWithArray: stringArray]; // okay
+ [[NSMutableArray<NSNumber *> alloc] initWithArray: stringArray]; // expected-error{{parameter of type 'NSArray<NSNumber *> *' with an lvalue of type 'NSArray<NSString *> *'}}
+}
+
+void test_message_send_param(
+ NSMutableSet<NSString *> *mutStringSet,
+ WidgetSet *widgetSet,
+ UntypedMutableSet *untypedMutSet,
+ MutableSetOfArrays<NSString *> *mutStringArraySet,
+ NSMutableSet *mutSet,
+ MutableSetOfArrays *mutArraySet,
+ void (^block)(void)) {
+ Window *window;
+
+ [mutStringSet addObject: window]; // expected-error{{parameter of type 'NSString *'}}
+ [widgetSet addObject: window]; // expected-error{{parameter of type 'Widget *'}}
+ [untypedMutSet addObject: window]; // expected-error{{parameter of type 'id<NSCopying>'}}
+ [mutStringArraySet addObject: window]; // expected-error{{parameter of type 'NSArray<NSString *> *'}}
+ [mutSet addObject: window]; // expected-error{{parameter of type 'id<NSCopying>'}}
+ [mutArraySet addObject: window]; // expected-error{{parameter of type 'id<NSCopying>'}}
+ [block addObject: window]; // expected-error{{parameter of type 'id<NSCopying>'}}
+}
+
+// --------------------------------------------------------------------------
+// Property accesses.
+// --------------------------------------------------------------------------
+void test_property_read(
+ NSSet<NSString *> *stringSet,
+ NSMutableSet<NSString *> *mutStringSet,
+ WidgetSet *widgetSet,
+ UntypedMutableSet *untypedMutSet,
+ MutableSetOfArrays<NSString *> *mutStringArraySet,
+ NSSet *set,
+ NSMutableSet *mutSet,
+ MutableSetOfArrays *mutArraySet,
+ NSMutableDictionary *mutDict) {
+ int *ip;
+ ip = stringSet.allObjects; // expected-error{{from incompatible type 'NSArray<NSString *> *'}}
+ ip = mutStringSet.allObjects; // expected-error{{from incompatible type 'NSArray<NSString *> *'}}
+ ip = widgetSet.allObjects; // expected-error{{from incompatible type 'NSArray<Widget *> *'}}
+ ip = untypedMutSet.allObjects; // expected-error{{from incompatible type 'NSArray *'}}
+ ip = mutStringArraySet.allObjects; // expected-error{{from incompatible type 'NSArray<NSArray<NSString *> *> *'}}
+ ip = set.allObjects; // expected-error{{from incompatible type 'NSArray *'}}
+ ip = mutSet.allObjects; // expected-error{{from incompatible type 'NSArray *'}}
+ ip = mutArraySet.allObjects; // expected-error{{from incompatible type 'NSArray *'}}
+
+ ip = mutDict.someRandomKey; // expected-error{{from incompatible type 'id'}}
+}
+
+void test_property_write(
+ NSMutableSet<NSString *> *mutStringSet,
+ WidgetSet *widgetSet,
+ UntypedMutableSet *untypedMutSet,
+ MutableSetOfArrays<NSString *> *mutStringArraySet,
+ NSMutableSet *mutSet,
+ MutableSetOfArrays *mutArraySet,
+ NSMutableDictionary *mutDict) {
+ int *ip;
+
+ mutStringSet.allObjects = ip; // expected-error{{to 'NSArray<NSString *> *'}}
+ widgetSet.allObjects = ip; // expected-error{{to 'NSArray<Widget *> *'}}
+ untypedMutSet.allObjects = ip; // expected-error{{to 'NSArray *'}}
+ mutStringArraySet.allObjects = ip; // expected-error{{to 'NSArray<NSArray<NSString *> *> *'}}
+ mutSet.allObjects = ip; // expected-error{{to 'NSArray *'}}
+ mutArraySet.allObjects = ip; // expected-error{{to 'NSArray *'}}
+
+ mutDict.someRandomKey = ip; // expected-error{{to 'id<NSCopying>'}}
+}
+
+// --------------------------------------------------------------------------
+// Subscripting
+// --------------------------------------------------------------------------
+void test_subscripting(
+ NSArray<NSString *> *stringArray,
+ NSMutableArray<NSString *> *mutStringArray,
+ NSArray *array,
+ NSMutableArray *mutArray,
+ NSDictionary<NSString *, Widget *> *stringWidgetDict,
+ NSMutableDictionary<NSString *, Widget *> *mutStringWidgetDict,
+ NSDictionary *dict,
+ NSMutableDictionary *mutDict) {
+ int *ip;
+ NSString *string;
+ Widget *widget;
+ Window *window;
+
+ ip = stringArray[0]; // expected-error{{from incompatible type 'NSString *'}}
+
+ ip = mutStringArray[0]; // expected-error{{from incompatible type 'NSString *'}}
+ mutStringArray[0] = ip; // expected-error{{parameter of type 'NSString *'}}
+
+ ip = array[0]; // expected-error{{from incompatible type 'id'}}
+
+ ip = mutArray[0]; // expected-error{{from incompatible type 'id'}}
+ mutArray[0] = ip; // expected-error{{parameter of type 'id'}}
+
+ ip = stringWidgetDict[string]; // expected-error{{from incompatible type 'Widget *'}}
+ widget = stringWidgetDict[widget]; // expected-error{{parameter of type 'NSString *'}}
+
+ ip = mutStringWidgetDict[string]; // expected-error{{from incompatible type 'Widget *'}}
+ widget = mutStringWidgetDict[widget]; // expected-error{{parameter of type 'NSString *'}}
+ mutStringWidgetDict[string] = ip; // expected-error{{parameter of type 'Widget *'}}
+ mutStringWidgetDict[widget] = widget; // expected-error{{parameter of type 'NSString *'}}
+
+ ip = dict[string]; // expected-error{{from incompatible type 'id'}}
+
+ ip = mutDict[string]; // expected-error{{incompatible type 'id'}}
+ mutDict[string] = ip; // expected-error{{parameter of type 'id'}}
+
+ widget = mutDict[window];
+ mutDict[window] = widget; // expected-error{{parameter of type 'id<NSCopying>'}}
+}
+
+// --------------------------------------------------------------------------
+// Instance variable access.
+// --------------------------------------------------------------------------
+void test_instance_variable(NSArray<NSString *> *stringArray,
+ NSArray *array) {
+ int *ip;
+
+ ip = stringArray->data; // expected-error{{from incompatible type 'NSString **'}}
+ ip = array->data; // expected-error{{from incompatible type 'id *'}}
+}
+
+@implementation WindowArray
+- (void)testInstanceVariable {
+ int *ip;
+
+ ip = data; // expected-error{{from incompatible type 'Window **'}}
+}
+@end
+
+// --------------------------------------------------------------------------
+// Implicit conversions.
+// --------------------------------------------------------------------------
+void test_implicit_conversions(NSArray<NSString *> *stringArray,
+ NSArray<NSNumber *> *numberArray,
+ NSMutableArray<NSString *> *mutStringArray,
+ NSArray *array,
+ NSMutableArray *mutArray) {
+ // Specialized -> unspecialized (same level)
+ array = stringArray;
+
+ // Unspecialized -> specialized (same level)
+ stringArray = array;
+
+ // Specialized -> specialized failure (same level).
+ stringArray = numberArray; // expected-error{{assigning to 'NSArray<NSString *> *' from incompatible type 'NSArray<NSNumber *> *'}}
+
+ // Specialized -> specialized (different levels).
+ stringArray = mutStringArray;
+
+ // Specialized -> specialized failure (different levels).
+ numberArray = mutStringArray; // expected-error{{assigning to 'NSArray<NSNumber *> *' from incompatible type 'NSMutableArray<NSString *> *'}}
+
+ // Unspecialized -> specialized (different levels).
+ stringArray = mutArray;
+
+ // Specialized -> unspecialized (different levels).
+ array = mutStringArray;
+}
+
+// --------------------------------------------------------------------------
+// Ternary operator
+// --------------------------------------------------------------------------
+void test_ternary_operator(NSArray<NSString *> *stringArray,
+ NSArray<NSNumber *> *numberArray,
+ NSMutableArray<NSString *> *mutStringArray,
+ NSStringArray *stringArray2,
+ NSArray *array,
+ NSMutableArray *mutArray,
+ int cond) {
+ int *ip;
+ id object;
+
+ ip = cond ? stringArray : mutStringArray; // expected-error{{from incompatible type 'NSArray<NSString *> *'}}
+ ip = cond ? mutStringArray : stringArray; // expected-error{{from incompatible type 'NSArray<NSString *> *'}}
+
+ ip = cond ? stringArray2 : mutStringArray; // expected-error{{from incompatible type 'NSArray<NSString *> *'}}
+ ip = cond ? mutStringArray : stringArray2; // expected-error{{from incompatible type 'NSArray<NSString *> *'}}
+
+ ip = cond ? stringArray : mutArray; // expected-error{{from incompatible type 'NSArray *'}}
+
+ ip = cond ? stringArray2 : mutArray; // expected-error{{from incompatible type 'NSArray *'}}
+
+ ip = cond ? mutArray : stringArray; // expected-error{{from incompatible type 'NSArray *'}}
+
+ ip = cond ? mutArray : stringArray2; // expected-error{{from incompatible type 'NSArray *'}}
+
+ object = cond ? stringArray : numberArray; // expected-warning{{incompatible operand types ('NSArray<NSString *> *' and 'NSArray<NSNumber *> *')}}
+}
+
+// --------------------------------------------------------------------------
+// super
+// --------------------------------------------------------------------------
+@implementation NSStringArray
+- (void)useSuperMethod {
+ int *ip;
+ ip = super.lastObject; // expected-error{{from incompatible type 'NSString *'}}
+ ip = [super objectAtIndexedSubscript:0]; // expected-error{{from incompatible type 'NSString *'}}
+}
+
++ (void)useSuperMethod {
+ int *ip;
+ ip = super.array; // expected-error{{from incompatible type 'NSArray<NSString *> *'}}
+ ip = [super array]; // expected-error{{from incompatible type 'NSArray<NSString *> *'}}
+}
+@end
+
+// --------------------------------------------------------------------------
+// Template instantiation
+// --------------------------------------------------------------------------
+template<typename K, typename V>
+struct NSMutableDictionaryOf {
+ typedef NSMutableDictionary<K, V> *type; // expected-error{{type argument 'NSObject *' does not satisfy the bound ('id<NSCopying>') of type parameter 'K'}}
+};
+
+template<typename ...Args>
+struct VariadicNSMutableDictionaryOf {
+ typedef NSMutableDictionary<Args...> *type; // expected-error{{type argument 'NSObject *' does not satisfy the bound ('id<NSCopying>') of type parameter 'K'}}
+ // expected-error@-1{{too many type arguments for class 'NSMutableDictionary' (have 3, expected 2)}}
+ // expected-error@-2{{too few type arguments for class 'NSMutableDictionary' (have 1, expected 2)}}
+};
+
+void testInstantiation() {
+ int *ip;
+
+ typedef NSMutableDictionaryOf<NSString *, NSObject *>::type Dict1;
+ Dict1 d1 = ip; // expected-error{{cannot initialize a variable of type 'Dict1' (aka 'NSMutableDictionary<NSString *,NSObject *> *')}}
+
+ typedef NSMutableDictionaryOf<NSObject *, NSString *>::type Dict2; // expected-note{{in instantiation of template}}
+}
+
+void testVariadicInstantiation() {
+ int *ip;
+
+ typedef VariadicNSMutableDictionaryOf<NSString *, NSObject *>::type Dict1;
+ Dict1 d1 = ip; // expected-error{{cannot initialize a variable of type 'Dict1' (aka 'NSMutableDictionary<NSString *,NSObject *> *')}}
+
+ typedef VariadicNSMutableDictionaryOf<NSObject *, NSString *>::type Dict2; // expected-note{{in instantiation of template}}
+
+ typedef VariadicNSMutableDictionaryOf<NSString *, NSObject *, NSObject *>::type Dict3; // expected-note{{in instantiation of template}}
+
+ typedef VariadicNSMutableDictionaryOf<NSString *>::type Dict3; // expected-note{{in instantiation of template}}
+}
+
+// --------------------------------------------------------------------------
+// Parameterized classes are not templates
+// --------------------------------------------------------------------------
+template<template<typename T, typename U> class TT>
+struct AcceptsTemplateTemplate { };
+
+typedef AcceptsTemplateTemplate<NSMutableDictionary> TemplateTemplateFail1; // expected-error{{template argument for template template parameter must be a class template or type alias template}}
+
+template<typename T>
+struct DependentTemplate {
+ typedef typename T::template apply<NSString *, NSObject *> type; // expected-error{{'apply' following the 'template' keyword does not refer to a template}}
+};
+
+struct NSMutableDictionaryBuilder {
+ typedef NSMutableDictionary apply;
+};
+
+typedef DependentTemplate<NSMutableDictionaryBuilder>::type DependentTemplateFail1; // expected-note{{in instantiation of template class}}
+
+template<typename K, typename V>
+struct NonDependentTemplate {
+ typedef NSMutableDictionaryBuilder::template apply<NSString *, NSObject *> type; // expected-error{{'apply' following the 'template' keyword does not refer to a template}}
+ // expected-error@-1{{expected member name or }}
+};
+
+// However, one can use an alias template to turn a parameterized
+// class into a template.
+template<typename K, typename V>
+using NSMutableDictionaryAlias = NSMutableDictionary<K, V>;
+
+typedef AcceptsTemplateTemplate<NSMutableDictionaryAlias> TemplateTemplateAlias1; // okay
+
+
OpenPOWER on IntegriCloud