1*67e74705SXin Li// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fblocks -fobjc-arc -emit-llvm -o - %s | FileCheck %s 2*67e74705SXin Li 3*67e74705SXin Li// Parameterized classes have no effect on code generation; this test 4*67e74705SXin Li// mainly verifies that CodeGen doesn't assert when substituted types 5*67e74705SXin Li// in uses of methods don't line up exactly with the parameterized 6*67e74705SXin Li// types in the method declarations due to type erasure. "Not crash" 7*67e74705SXin Li// is the only interesting criteria here. 8*67e74705SXin Li 9*67e74705SXin Li@protocol NSObject 10*67e74705SXin Li@end 11*67e74705SXin Li 12*67e74705SXin Li@protocol NSCopying 13*67e74705SXin Li@end 14*67e74705SXin Li 15*67e74705SXin Li__attribute__((objc_root_class)) 16*67e74705SXin Li@interface NSObject <NSObject> 17*67e74705SXin Li@end 18*67e74705SXin Li 19*67e74705SXin Li@interface NSString : NSObject <NSCopying> 20*67e74705SXin Li@end 21*67e74705SXin Li 22*67e74705SXin Li@interface NSMutableArray<T> : NSObject <NSCopying> 23*67e74705SXin Li@property (copy,nonatomic) T firstObject; 24*67e74705SXin Li- (void)addObject:(T)object; 25*67e74705SXin Li- (void)sortWithFunction:(int (*)(T, T))function; 26*67e74705SXin Li- (void)getObjects:(T __strong *)objects length:(unsigned*)length; 27*67e74705SXin Li- (T)objectAtIndexedSubscript:(unsigned)index; 28*67e74705SXin Li- (void)setObject:(T)object atIndexedSubscript:(unsigned)index; 29*67e74705SXin Li@end 30*67e74705SXin Li 31*67e74705SXin LiNSString *getFirstObjectProp(NSMutableArray<NSString *> *array) { 32*67e74705SXin Li return array.firstObject; 33*67e74705SXin Li} 34*67e74705SXin Li 35*67e74705SXin LiNSString *getFirstObjectMethod(NSMutableArray<NSString *> *array) { 36*67e74705SXin Li return [array firstObject]; 37*67e74705SXin Li} 38*67e74705SXin Li 39*67e74705SXin Livoid addObject(NSMutableArray<NSString *> *array, NSString *obj) { 40*67e74705SXin Li [array addObject: obj]; 41*67e74705SXin Li} 42*67e74705SXin Li 43*67e74705SXin Liint compareStrings(NSString *x, NSString *y) { return 0; } 44*67e74705SXin Liint compareBlocks(NSString * (^x)(NSString *), 45*67e74705SXin Li NSString * (^y)(NSString *)) { return 0; } 46*67e74705SXin Li 47*67e74705SXin Livoid sortTest(NSMutableArray<NSString *> *array, 48*67e74705SXin Li NSMutableArray<NSString * (^)(NSString *)> *array2) { 49*67e74705SXin Li [array sortWithFunction: &compareStrings]; 50*67e74705SXin Li [array2 sortWithFunction: &compareBlocks]; 51*67e74705SXin Li} 52*67e74705SXin Li 53*67e74705SXin Livoid getObjectsTest(NSMutableArray<NSString *> *array) { 54*67e74705SXin Li NSString * __strong *objects; 55*67e74705SXin Li unsigned length; 56*67e74705SXin Li [array getObjects: objects length: &length]; 57*67e74705SXin Li} 58*67e74705SXin Li 59*67e74705SXin Livoid printMe(NSString *name) { } 60*67e74705SXin Li 61*67e74705SXin Li// CHECK-LABEL: define void @blockTest 62*67e74705SXin Livoid blockTest(NSMutableArray<void (^)(void)> *array, NSString *name) { 63*67e74705SXin Li // CHECK-NOT: ret void 64*67e74705SXin Li // CHECK: call i8* @objc_retainBlock 65*67e74705SXin Li [array addObject: ^ { printMe(name); }]; 66*67e74705SXin Li // CHECK-NOT: ret void 67*67e74705SXin Li array[0] = ^ { printMe(name); }; 68*67e74705SXin Li // CHECK: call i8* @objc_retainBlock 69*67e74705SXin Li // CHECK: ret void 70*67e74705SXin Li} 71