diff options
Diffstat (limited to 'clang/test')
34 files changed, 1713 insertions, 5 deletions
diff --git a/clang/test/CodeGenObjC/Inputs/literal-support.h b/clang/test/CodeGenObjC/Inputs/literal-support.h new file mode 100644 index 00000000000..5680a20c9fb --- /dev/null +++ b/clang/test/CodeGenObjC/Inputs/literal-support.h @@ -0,0 +1,35 @@ +#ifndef OBJC_LITERAL_SUPPORT_H +#define OBJC_LITERAL_SUPPORT_H + +typedef unsigned char BOOL; + +@interface NSNumber @end + +@interface NSNumber (NSNumberCreation) ++ (NSNumber *)numberWithChar:(char)value; ++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value; ++ (NSNumber *)numberWithShort:(short)value; ++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value; ++ (NSNumber *)numberWithInt:(int)value; ++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value; ++ (NSNumber *)numberWithLong:(long)value; ++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; ++ (NSNumber *)numberWithLongLong:(long long)value; ++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; ++ (NSNumber *)numberWithFloat:(float)value; ++ (NSNumber *)numberWithDouble:(double)value; ++ (NSNumber *)numberWithBool:(BOOL)value; +@end + +@interface NSArray +@end + +@interface NSArray (NSArrayCreation) ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; +@end + +@interface NSDictionary ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; +@end + +#endif // OBJC_LITERAL_SUPPORT_H diff --git a/clang/test/CodeGenObjC/arc-literals.m b/clang/test/CodeGenObjC/arc-literals.m new file mode 100644 index 00000000000..203c2ad1eea --- /dev/null +++ b/clang/test/CodeGenObjC/arc-literals.m @@ -0,0 +1,121 @@ +// RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -O2 -disable-llvm-optzns -o - %s | FileCheck %s + +#include "literal-support.h" + +// Check the various selector names we'll be using, in order. + +// CHECK: c"numberWithInt:\00" +// CHECK: c"numberWithUnsignedInt:\00" +// CHECK: c"numberWithUnsignedLongLong:\00" +// CHECK: c"numberWithChar:\00" +// CHECK: c"arrayWithObjects:count:\00" +// CHECK: c"dictionaryWithObjects:forKeys:count:\00" +// CHECK: c"prop\00" + +// CHECK: define void @test_numeric() +void test_numeric() { + // CHECK: {{call.*objc_msgSend.*i32 17}} + // CHECK: call i8* @objc_retainAutoreleasedReturnValue + id ilit = @17; + // CHECK: {{call.*objc_msgSend.*i32 25}} + // CHECK: call i8* @objc_retainAutoreleasedReturnValue + id ulit = @25u; + // CHECK: {{call.*objc_msgSend.*i64 42}} + // CHECK: call i8* @objc_retainAutoreleasedReturnValue + id ulllit = @42ull; + // CHECK: {{call.*objc_msgSend.*i8 signext 97}} + // CHECK: call i8* @objc_retainAutoreleasedReturnValue + id charlit = @'a'; + // CHECK: call void @objc_release + // CHECK: call void @objc_release + // CHECK: call void @objc_release + // CHECK: call void @objc_release + // CHECK-NEXT: ret void +} + +// CHECK: define void @test_array +void test_array(id a, id b) { + // Retaining parameters + // CHECK: call i8* @objc_retain(i8* + // CHECK: call i8* @objc_retain(i8* + + // Constructing the array + // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS:%[A-Za-z0-9]+]], i32 0, i32 0 + // CHECK: store i8* + // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1 + // CHECK: store i8* + + // CHECK: {{call i8*.*objc_msgSend.*i64 2}} + // CHECK: call i8* @objc_retainAutoreleasedReturnValue + id arr = @[a, b]; + + // CHECK: call void @objc_release + // CHECK: call void @objc_release + // CHECK: call void @objc_release + // CHECK-NEXT: ret void +} + +// CHECK: define void @test_dictionary +void test_dictionary(id k1, id o1, id k2, id o2) { + // Retaining parameters + // CHECK: call i8* @objc_retain(i8* + // CHECK: call i8* @objc_retain(i8* + // CHECK: call i8* @objc_retain(i8* + // CHECK: call i8* @objc_retain(i8* + + // Constructing the arrays + // CHECK: getelementptr inbounds [2 x i8*]* [[KEYS:%[A-Za-z0-9]+]], i32 0, i32 0 + // CHECK: store i8* + // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS:%[A-Za-z0-9]+]], i32 0, i32 0 + // CHECK: store i8* + // CHECK: getelementptr inbounds [2 x i8*]* [[KEYS]], i32 0, i32 1 + // CHECK: store i8* + // CHECK: getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1 + // CHECK: store i8* + + // Constructing the dictionary + // CHECK: {{call i8.*@objc_msgSend}} + // CHECK: call i8* @objc_retainAutoreleasedReturnValue + id dict = @{ k1 : o1, k2 : o2 }; + + // CHECK: call void @objc_release + // CHECK: call void @objc_release + // CHECK: call void @objc_release + // CHECK: call void @objc_release + // CHECK: call void @objc_release + // CHECK-NEXT: ret void +} + +@interface A +@end + +@interface B +@property (retain) A* prop; +@end + +// CHECK: define void @test_property +void test_property(B *b) { + // Retain parameter + // CHECK: call i8* @objc_retain + + // Invoke 'prop' + // CHECK: load i8** @"\01L_OBJC_SELECTOR_REFERENCES + // CHECK: {{call.*@objc_msgSend}} + // CHECK: call i8* @objc_retainAutoreleasedReturnValue + + // Invoke arrayWithObjects:count: + // CHECK: load i8** @"\01L_OBJC_SELECTOR_REFERENCES + // CHECK: {{call.*objc_msgSend}} + // CHECK: call i8* @objc_retainAutoreleasedReturnValue + id arr = @[ b.prop ]; + + // Release b.prop + // CHECK: call void @objc_release + + // Destroy arr + // CHECK: call void @objc_release + + // Destroy b + // CHECK: call void @objc_release + // CHECK-NEXT: ret void +} diff --git a/clang/test/CodeGenObjC/objc-arc-container-subscripting.m b/clang/test/CodeGenObjC/objc-arc-container-subscripting.m new file mode 100644 index 00000000000..892491630e6 --- /dev/null +++ b/clang/test/CodeGenObjC/objc-arc-container-subscripting.m @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fobjc-arc -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s + +@interface NSMutableArray +- (id)objectAtIndexedSubscript:(int)index; +- (void)setObject:(id)object atIndexedSubscript:(int)index; +@end + +id func() { + NSMutableArray *array; + array[3] = 0; + return array[3]; +} + +// CHECK: [[call:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend +// CHECK: [[SIX:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[call]]) nounwind +// CHECK: [[ARRAY:%.*]] = load %0** +// CHECK: [[ARRAY_CASTED:%.*]] = bitcast{{.*}}[[ARRAY]] to i8* +// CHECK: call void @objc_release(i8* [[ARRAY_CASTED]]) +// CHECK: [[EIGHT:%.*]] = call i8* @objc_autoreleaseReturnValue(i8* [[SIX]]) nounwind +// CHECK: ret i8* [[EIGHT]] + diff --git a/clang/test/CodeGenObjC/objc-container-subscripting-1.m b/clang/test/CodeGenObjC/objc-container-subscripting-1.m new file mode 100644 index 00000000000..91b7f468ea9 --- /dev/null +++ b/clang/test/CodeGenObjC/objc-container-subscripting-1.m @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s + +typedef unsigned int size_t; +@protocol P @end + +@interface NSMutableArray +- (id)objectAtIndexedSubscript:(size_t)index; +- (void)setObject:(id)object atIndexedSubscript:(size_t)index; +@end + +@interface NSMutableDictionary +- (id)objectForKeyedSubscript:(id)key; +- (void)setObject:(id)object forKeyedSubscript:(id)key; +@end + +int main() { + NSMutableArray *array; + id val; + + id oldObject = array[10]; +// CHECK: [[ARR:%.*]] = load {{%.*}} [[array:%.*]], align 8 +// CHECK-NEXT: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_" +// CHECK-NEXT: [[ARRC:%.*]] = bitcast {{%.*}} [[ARR]] to i8* +// CHECK-NEXT: [[CALL:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i32)*)(i8* [[ARRC]], i8* [[SEL]], i32 10) +// CHECK-NEXT: store i8* [[CALL]], i8** [[OLDOBJ:%.*]], align 8 + + val = (array[10] = oldObject); +// CHECK: [[THREE:%.*]] = load {{%.*}} [[array:%.*]], align 8 +// CHECK-NEXT: [[FOUR:%.*]] = load i8** [[oldObject:%.*]], align 8 +// CHECK-NEXT: [[FIVE:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_2" +// CHECK-NEXT: [[SIX:%.*]] = bitcast {{%.*}} [[THREE]] to i8* +// CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*, i32)*)(i8* [[SIX]], i8* [[FIVE]], i8* [[FOUR]], i32 10) +// CHECK-NEXT: store i8* [[FOUR]], i8** [[val:%.*]] + + NSMutableDictionary *dictionary; + id key; + id newObject; + oldObject = dictionary[key]; +// CHECK: [[SEVEN:%.*]] = load {{%.*}} [[DICTIONARY:%.*]], align 8 +// CHECK-NEXT: [[EIGHT:%.*]] = load i8** [[KEY:%.*]], align 8 +// CHECK-NEXT: [[TEN:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_4" +// CHECK-NEXT: [[ELEVEN:%.*]] = bitcast {{%.*}} [[SEVEN]] to i8* +// CHECK-NEXT: [[CALL1:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* [[ELEVEN]], i8* [[TEN]], i8* [[EIGHT]]) +// CHECK-NEXT: store i8* [[CALL1]], i8** [[oldObject:%.*]], align 8 + + + val = (dictionary[key] = newObject); +// CHECK: [[TWELVE:%.*]] = load {{%.*}} [[DICTIONARY]], align 8 +// CHECK-NEXT: [[THIRTEEN:%.*]] = load i8** [[KEY]], align 8 +// CHECK-NEXT: [[FOURTEEN:%.*]] = load i8** [[NEWOBJECT:%.*]], align 8 +// CHECK-NEXT: [[SIXTEEN:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_6" +// CHECK-NEXT: [[SEVENTEEN:%.*]] = bitcast {{%.*}} [[TWELVE]] to i8* +// CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*, i8*)*)(i8* [[SEVENTEEN]], i8* [[SIXTEEN]], i8* [[FOURTEEN]], i8* [[THIRTEEN]]) +// CHECK-NEXT: store i8* [[FOURTEEN]], i8** [[val:%.*]] +} + diff --git a/clang/test/CodeGenObjC/objc-container-subscripting.m b/clang/test/CodeGenObjC/objc-container-subscripting.m new file mode 100644 index 00000000000..fd8f8effac6 --- /dev/null +++ b/clang/test/CodeGenObjC/objc-container-subscripting.m @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin %s -o /dev/null + +typedef unsigned int size_t; +@protocol P @end + +@interface NSMutableArray +#if __has_feature(objc_subscripting) +- (id)objectAtIndexedSubscript:(size_t)index; +- (void)setObject:(id)object atIndexedSubscript:(size_t)index; +#endif +@end + +#if __has_feature(objc_subscripting) +@interface XNSMutableArray +- (id)objectAtIndexedSubscript:(size_t)index; +- (void)setObject:(id)object atIndexedSubscript:(size_t)index; +#endif +@end + +@interface NSMutableDictionary +- (id)objectForKeyedSubscript:(id)key; +- (void)setObject:(id)object forKeyedSubscript:(id)key; +@end + +@class NSString; + +int main() { + NSMutableArray<P> * array; + id oldObject = array[10]; + + array[10] = oldObject; + + id unknown_array; + oldObject = unknown_array[1]; + + unknown_array[1] = oldObject; + + NSMutableDictionary *dictionary; + NSString *key; + id newObject; + oldObject = dictionary[key]; + dictionary[key] = newObject; // replace oldObject with newObject + +} + diff --git a/clang/test/CodeGenObjC/objc-dictionary-literal.m b/clang/test/CodeGenObjC/objc-dictionary-literal.m new file mode 100644 index 00000000000..b335582ed2b --- /dev/null +++ b/clang/test/CodeGenObjC/objc-dictionary-literal.m @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -x objective-c -triple x86_64-apple-darwin10 -fblocks -emit-llvm %s -o /dev/null +// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fblocks -emit-llvm %s -o /dev/null +// rdar://10614657 + +@interface NSNumber ++ (NSNumber *)numberWithChar:(char)value; ++ (NSNumber *)numberWithInt:(int)value; +@end + +@protocol NSCopying @end +typedef unsigned long NSUInteger; + +@interface NSDictionary ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id <NSCopying> [])keys count:(NSUInteger)cnt; +@end + +@interface NSString<NSCopying> +@end + +int main() { + NSDictionary *dict = @{ @"name":@666 }; + NSDictionary *dict1 = @{ @"name":@666 }; + NSDictionary *dict2 = @{ @"name":@666 }; + return 0; +} diff --git a/clang/test/CodeGenObjC/objc-literal-debugger-test.m b/clang/test/CodeGenObjC/objc-literal-debugger-test.m new file mode 100644 index 00000000000..389ef2248a4 --- /dev/null +++ b/clang/test/CodeGenObjC/objc-literal-debugger-test.m @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fdebugger-objc-literal -emit-llvm -o - %s | FileCheck %s + +int main() { + id l = @'a'; + l = @'a'; + l = @42; + l = @-42; + l = @42u; + l = @3.141592654f; + l = @__objc_yes; + l = @__objc_no; + l = @{ @"name":@666 }; + l = @[ @"foo", @"bar" ]; +} + +// CHECK: declare i8* @objc_msgSend(i8*, i8*, ...) nonlazybind diff --git a/clang/test/CodeGenObjC/objc-literal-tests.m b/clang/test/CodeGenObjC/objc-literal-tests.m new file mode 100644 index 00000000000..c513d496110 --- /dev/null +++ b/clang/test/CodeGenObjC/objc-literal-tests.m @@ -0,0 +1,95 @@ +// RUN: %clang_cc1 -x objective-c -triple x86_64-apple-darwin10 -fblocks -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fblocks -emit-llvm %s -o - | FileCheck %s +// rdar://10111397 + +#if __has_feature(objc_bool) +#define YES __objc_yes +#define NO __objc_no +#else +#define YES ((BOOL)1) +#define NO ((BOOL)0) +#endif + +#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64 +typedef unsigned long NSUInteger; +typedef long NSInteger; +#else +typedef unsigned int NSUInteger; +typedef int NSInteger; +#endif +typedef signed char BOOL; + +@interface NSNumber @end + +@interface NSNumber (NSNumberCreation) +#if __has_feature(objc_array_literals) ++ (NSNumber *)numberWithChar:(char)value; ++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value; ++ (NSNumber *)numberWithShort:(short)value; ++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value; ++ (NSNumber *)numberWithInt:(int)value; ++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value; ++ (NSNumber *)numberWithLong:(long)value; ++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; ++ (NSNumber *)numberWithLongLong:(long long)value; ++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; ++ (NSNumber *)numberWithFloat:(float)value; ++ (NSNumber *)numberWithDouble:(double)value; ++ (NSNumber *)numberWithBool:(BOOL)value; ++ (NSNumber *)numberWithInteger:(NSInteger)value ; ++ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value ; +#endif +@end + +@interface NSDate ++ (NSDate *) date; +@end + +#if __has_feature(objc_dictionary_literals) +@interface NSDictionary ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(NSUInteger)cnt; +@end +#endif + +id NSUserName(); + +// CHECK: define i32 @main() nounwind +int main() { + // CHECK: call{{.*}}@objc_msgSend{{.*}}i8 signext 97 + NSNumber *aNumber = @'a'; + // CHECK: call{{.*}}@objc_msgSend{{.*}}i32 42 + NSNumber *fortyTwo = @42; + // CHECK: call{{.*}}@objc_msgSend{{.*}}i32 -42 + NSNumber *negativeFortyTwo = @-42; + // CHECK: call{{.*}}@objc_msgSend{{.*}}i32 42 + NSNumber *positiveFortyTwo = @+42; + // CHECK: call{{.*}}@objc_msgSend{{.*}}i32 42 + NSNumber *fortyTwoUnsigned = @42u; + // CHECK: call{{.*}}@objc_msgSend{{.*}}i64 42 + NSNumber *fortyTwoLong = @42l; + // CHECK: call{{.*}}@objc_msgSend{{.*}}i64 42 + NSNumber *fortyTwoLongLong = @42ll; + // CHECK: call{{.*}}@objc_msgSend{{.*}}float 0x400921FB60000000 + NSNumber *piFloat = @3.141592654f; + // CHECK: call{{.*}}@objc_msgSend{{.*}}double 0x400921FB54411744 + NSNumber *piDouble = @3.1415926535; + // CHECK: call{{.*}}@objc_msgSend{{.*}}i8 signext 1 + NSNumber *yesNumber = @__objc_yes; + // CHECK: call{{.*}}@objc_msgSend{{.*}}i8 signext 0 + NSNumber *noNumber = @__objc_no; + // CHECK: call{{.*}}@objc_msgSend{{.*}}i8 signext 1 + NSNumber *yesNumber1 = @YES; + // CHECK: call{{.*}}@objc_msgSend{{.*}}i8 signext 0 + NSNumber *noNumber1 = @NO; +NSDictionary *dictionary = @{@"name" : NSUserName(), + @"date" : [NSDate date] }; + return __objc_yes == __objc_no; +} + +// rdar://10579122 +typedef BOOL (^foo)(void); +extern void bar(foo a); + +void baz(void) { + bar(^(void) { return YES; }); +} diff --git a/clang/test/CodeGenObjC/optimized-setter.m b/clang/test/CodeGenObjC/optimized-setter.m new file mode 100644 index 00000000000..0e1b3885951 --- /dev/null +++ b/clang/test/CodeGenObjC/optimized-setter.m @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-apple-macosx10.8.0 -o - | FileCheck %s +// rdar://10179974 + +@interface I +// void objc_setProperty_nonatomic(id self, SEL _cmd, id newValue, ptrdiff_t offset); +// objc_setProperty(..., NO, NO) +@property (nonatomic, retain) id nonatomicProperty; + +// void objc_setProperty_nonatomic_copy(id self, SEL _cmd, id newValue, ptrdiff_t offset); +// objc_setProperty(..., NO, YES) +@property (nonatomic, copy) id nonatomicPropertyCopy; + +// void objc_setProperty_atomic(id self, SEL _cmd, id newValue, ptrdiff_t offset); +// objc_setProperty(..., YES, NO) +@property (retain) id atomicProperty; + +// void objc_setProperty_atomic_copy(id self, SEL _cmd, id newValue, ptrdiff_t offset); +// objc_setProperty(..., YES, YES) +@property (copy) id atomicPropertyCopy; +@end + +@implementation I +@synthesize nonatomicProperty; +@synthesize nonatomicPropertyCopy; +@synthesize atomicProperty; +@synthesize atomicPropertyCopy; +@end + +// CHECK: call void @objc_setProperty_nonatomic +// CHECK: call void @objc_setProperty_nonatomic_copy +// CHECK: call void @objc_setProperty_atomic +// CHECK: call void @objc_setProperty_atomic_copy + diff --git a/clang/test/CodeGenObjCXX/Inputs/literal-support.h b/clang/test/CodeGenObjCXX/Inputs/literal-support.h new file mode 100644 index 00000000000..5680a20c9fb --- /dev/null +++ b/clang/test/CodeGenObjCXX/Inputs/literal-support.h @@ -0,0 +1,35 @@ +#ifndef OBJC_LITERAL_SUPPORT_H +#define OBJC_LITERAL_SUPPORT_H + +typedef unsigned char BOOL; + +@interface NSNumber @end + +@interface NSNumber (NSNumberCreation) ++ (NSNumber *)numberWithChar:(char)value; ++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value; ++ (NSNumber *)numberWithShort:(short)value; ++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value; ++ (NSNumber *)numberWithInt:(int)value; ++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value; ++ (NSNumber *)numberWithLong:(long)value; ++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; ++ (NSNumber *)numberWithLongLong:(long long)value; ++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; ++ (NSNumber *)numberWithFloat:(float)value; ++ (NSNumber *)numberWithDouble:(double)value; ++ (NSNumber *)numberWithBool:(BOOL)value; +@end + +@interface NSArray +@end + +@interface NSArray (NSArrayCreation) ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; +@end + +@interface NSDictionary ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; +@end + +#endif // OBJC_LITERAL_SUPPORT_H diff --git a/clang/test/CodeGenObjCXX/literals.mm b/clang/test/CodeGenObjCXX/literals.mm new file mode 100644 index 00000000000..b8946fa3f80 --- /dev/null +++ b/clang/test/CodeGenObjCXX/literals.mm @@ -0,0 +1,111 @@ +// RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -fexceptions -fobjc-exceptions -fcxx-exceptions -fobjc-arc-exceptions -O2 -disable-llvm-optzns -o - %s | FileCheck %s + +#include "literal-support.h" + +struct X { + X(); + ~X(); + operator id() const; +}; + +struct Y { + Y(); + ~Y(); + operator id() const; +}; + +// CHECK: define void @_Z10test_arrayv +void test_array() { + // CHECK: [[OBJECTS:%[a-zA-Z0-9.]+]] = alloca [2 x i8*] + + // Initializing first element + // CHECK: [[ELEMENT0:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 0 + // CHECK-NEXT: call void @_ZN1XC1Ev + // CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv + // CHECK: [[RET0:%[a-zA-Z0-9.]+]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[OBJECT0]]) + // CHECK: store i8* [[RET0]], i8** [[ELEMENT0]] + + // Initializing the second element + // CHECK: [[ELEMENT1:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1 + // CHECK-NEXT: invoke void @_ZN1YC1Ev + // CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv + // CHECK: [[RET1:%[a-zA-Z0-9.]+]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[OBJECT1]]) + // CHECK: store i8* [[RET1]], i8** [[ELEMENT1]] + + // Build the array + // CHECK: {{invoke.*@objc_msgSend}} + // CHECK: call i8* @objc_retainAutoreleasedReturnValue + id arr = @[ X(), Y() ]; + + // Destroy temporaries + // CHECK-NOT: ret void + // CHECK: call void @objc_release + // CHECK-NOT: ret void + // CHECK: invoke void @_ZN1YD1Ev + // CHECK-NOT: ret void + // CHECK: call void @objc_release + // CHECK-NEXT: call void @_ZN1XD1Ev + // CHECK-NOT: ret void + // CHECK: call void @objc_release + // CHECK-NEXT: ret void + + // Check cleanups + // CHECK: call void @objc_release + // CHECK-NOT: call void @objc_release + // CHECK: invoke void @_ZN1YD1Ev + // CHECK: call void @objc_release + // CHECK-NOT: call void @objc_release + // CHECK: invoke void @_ZN1XD1Ev + // CHECK-NOT: call void @objc_release + // CHECK: unreachable +} + +// CHECK: define weak_odr void @_Z24test_array_instantiationIiEvv +template<typename T> +void test_array_instantiation() { + // CHECK: [[OBJECTS:%[a-zA-Z0-9.]+]] = alloca [2 x i8*] + + // Initializing first element + // CHECK: [[ELEMENT0:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 0 + // CHECK-NEXT: call void @_ZN1XC1Ev + // CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv + // CHECK: [[RET0:%[a-zA-Z0-9.]+]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[OBJECT0]]) + // CHECK: store i8* [[RET0]], i8** [[ELEMENT0]] + + // Initializing the second element + // CHECK: [[ELEMENT1:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*]* [[OBJECTS]], i32 0, i32 1 + // CHECK-NEXT: invoke void @_ZN1YC1Ev + // CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv + // CHECK: [[RET1:%[a-zA-Z0-9.]+]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[OBJECT1]]) + // CHECK: store i8* [[RET1]], i8** [[ELEMENT1]] + + // Build the array + // CHECK: {{invoke.*@objc_msgSend}} + // CHECK: call i8* @objc_retainAutoreleasedReturnValue + id arr = @[ X(), Y() ]; + + // Destroy temporaries + // CHECK-NOT: ret void + // CHECK: call void @objc_release + // CHECK-NOT: ret void + // CHECK: invoke void @_ZN1YD1Ev + // CHECK-NOT: ret void + // CHECK: call void @objc_release + // CHECK-NEXT: call void @_ZN1XD1Ev + // CHECK-NOT: ret void + // CHECK: call void @objc_release + // CHECK-NEXT: ret void + + // Check cleanups + // CHECK: call void @objc_release + // CHECK-NOT: call void @objc_release + // CHECK: invoke void @_ZN1YD1Ev + // CHECK: call void @objc_release + // CHECK-NOT: call void @objc_release + // CHECK: invoke void @_ZN1XD1Ev + // CHECK-NOT: call void @objc_release + // CHECK: unreachable +} + +template void test_array_instantiation<int>(); + diff --git a/clang/test/CodeGenObjCXX/objc-container-subscripting-1.mm b/clang/test/CodeGenObjCXX/objc-container-subscripting-1.mm new file mode 100644 index 00000000000..c0dd0f8bae4 --- /dev/null +++ b/clang/test/CodeGenObjCXX/objc-container-subscripting-1.mm @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s + +typedef unsigned int size_t; +@protocol P @end +@protocol NSCopying @end + +@interface NSMutableArray +- (id)objectAtIndexedSubscript:(size_t)index; +- (void)setObject:(id)object atIndexedSubscript:(size_t)index; +@end + +struct S { + operator unsigned int (); + operator id (); +}; + +@interface NSMutableDictionary +- (id)objectForKeyedSubscript:(id<NSCopying>)key; +- (void)setObject:(id)object forKeyedSubscript:(id<NSCopying>)key; +@end + +int main() { + NSMutableArray<P> * array; + S s; + id oldObject = array[(int)s]; + + NSMutableDictionary<P> *dict; + dict[(id)s] = oldObject; + oldObject = dict[(id)s]; + +} + +template <class T> void test2(NSMutableArray *a) { + a[10] = 0; +} +template void test2<int>(NSMutableArray*); +// CHECK: define weak_odr void @_Z5test2IiEvP14NSMutableArray +// CHECK: @objc_msgSend +// CHECK: ret void + + +template <class T> void test3(NSMutableArray *a) { + a[sizeof(T)] = 0; +} + +template void test3<int>(NSMutableArray*); +// CHECK: define weak_odr void @_Z5test3IiEvP14NSMutableArray +// CHECK: @objc_msgSend +// CHECK: ret void + diff --git a/clang/test/CodeGenObjCXX/objc-container-subscripting.mm b/clang/test/CodeGenObjCXX/objc-container-subscripting.mm new file mode 100644 index 00000000000..dfe48e9d6dc --- /dev/null +++ b/clang/test/CodeGenObjCXX/objc-container-subscripting.mm @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s + +typedef unsigned int size_t; +@protocol P @end + +@interface NSMutableArray +- (id)objectAtIndexedSubscript:(size_t)index; +- (void)setObject:(id)object atIndexedSubscript:(size_t)index; +@end + +struct S { + operator unsigned int (); + operator id (); +}; + +@interface NSMutableDictionary +- (id)objectForKeyedSubscript:(id)key; +- (void)setObject:(id)object forKeyedSubscript:(id)key; +@end + +int main() { + NSMutableArray<P> * array; + S s; + id oldObject = array[(int)s]; + + NSMutableDictionary<P> *dict; + dict[(id)s] = oldObject; + oldObject = dict[(id)s]; + +} + +template <class T> void test2(NSMutableArray *a) { + a[10] = 0; +} +template void test2<int>(NSMutableArray*); +// CHECK: define weak_odr void @_Z5test2IiEvP14NSMutableArray +// CHECK: @objc_msgSend +// CHECK: ret void + + +template <class T> void test3(NSMutableArray *a) { + a[sizeof(T)] = 0; +} + +template void test3<int>(NSMutableArray*); +// CHECK: define weak_odr void @_Z5test3IiEvP14NSMutableArray +// CHECK: @objc_msgSend +// CHECK: ret void + +// CHECK: define void @_Z11static_dataP14NSMutableArray +void static_data(NSMutableArray *array) { + // CHECK: call i32 @__cxa_guard_acquire + // CHECK: {{call i8*.*@objc_msgSend }} + // CHECK: call void @__cxa_guard_release + static id x = array[4]; + // CHECK: ret void +} diff --git a/clang/test/Driver/arclite-link.c b/clang/test/Driver/arclite-link.c new file mode 100644 index 00000000000..9cf1efe987c --- /dev/null +++ b/clang/test/Driver/arclite-link.c @@ -0,0 +1,8 @@ +// RUN: touch %t.o +// RUN: %clang -### -target x86_64-apple-darwin10 -fobjc-link-runtime -mmacosx-version-min=10.7 %t.o 2>&1 | FileCheck -check-prefix=CHECK-ARCLITE-OSX %s +// RUN: %clang -### -target x86_64-apple-darwin10 -fobjc-link-runtime -mmacosx-version-min=10.8 %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOARCLITE %s +// RUN: %clang -### -target i386-apple-darwin10 -fobjc-link-runtime -mmacosx-version-min=10.7 %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOARCLITE %s + +// CHECK-ARCLITE-OSX: libarclite_macosx.a +// CHECK-ARCLITE-OSX: -lobjc +// CHECK-NOARCLITE-NOT: libarclite diff --git a/clang/test/Driver/darwin-ld.c b/clang/test/Driver/darwin-ld.c index 056d34706aa..3206f654d5c 100644 --- a/clang/test/Driver/darwin-ld.c +++ b/clang/test/Driver/darwin-ld.c @@ -117,3 +117,7 @@ // LINK_VERSION_MIN: "-macosx_version_min" "10.6.0" // LINK_VERSION_MIN: {{ld(.exe)?"}} // LINK_VERSION_MIN: "-macosx_version_min" "10.7.0" + +// RUN: %clang -target x86_64-apple-darwin12 -### %t.o 2> %t.log +// RUN: FileCheck -check-prefix=LINK_NO_CRT1 %s < %t.log +// LINK_NO_CRT1-NOT: crt diff --git a/clang/test/Driver/rewrite-objc.m b/clang/test/Driver/rewrite-objc.m index 9e779f76b13..30883f3bf51 100644 --- a/clang/test/Driver/rewrite-objc.m +++ b/clang/test/Driver/rewrite-objc.m @@ -3,7 +3,7 @@ // TEST0: clang{{.*}}" "-cc1" // TEST0: "-rewrite-objc" // FIXME: CHECK-NOT is broken somehow, it doesn't work here. Check adjacency instead. -// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-mstackrealign" "-fblocks" "-fobjc-runtime-has-arc" "-fobjc-runtime-has-weak" "-fobjc-fragile-abi" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fdiagnostics-show-option" +// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-mstackrealign" "-fblocks" "-fobjc-runtime-has-arc" "-fobjc-runtime-has-weak" "-fobjc-fragile-abi" "-fobjc-default-synthesize-properties" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fdiagnostics-show-option" // TEST0: rewrite-objc.m" // RUN: not %clang -ccc-no-clang -target unknown -rewrite-objc %s -o - -### 2>&1 | \ diff --git a/clang/test/PCH/objc_container.h b/clang/test/PCH/objc_container.h new file mode 100644 index 00000000000..c83f90238b6 --- /dev/null +++ b/clang/test/PCH/objc_container.h @@ -0,0 +1,26 @@ +@protocol P @end + +@interface NSMutableArray +- (id)objectAtIndexedSubscript:(unsigned int)index; +- (void)setObject:(id)object atIndexedSubscript:(unsigned int)index; +@end + +@interface NSMutableDictionary +- (id)objectForKeyedSubscript:(id)key; +- (void)setObject:(id)object forKeyedSubscript:(id)key; +@end + +void all() { + NSMutableArray *array; + id oldObject = array[10]; + + array[10] = oldObject; + + NSMutableDictionary *dictionary; + id key; + id newObject; + oldObject = dictionary[key]; + + dictionary[key] = newObject; +} + diff --git a/clang/test/PCH/objc_container.m b/clang/test/PCH/objc_container.m new file mode 100644 index 00000000000..1e59054a2e5 --- /dev/null +++ b/clang/test/PCH/objc_container.m @@ -0,0 +1,20 @@ +// Test this without pch. +// RUN: %clang_cc1 -include %S/objc_container.h -fsyntax-only -verify %s + +// Test with pch. +// RUN: %clang_cc1 -x objective-c -emit-pch -o %t %S/objc_container.h +// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s +// RUN: %clang -cc1 -include-pch %t -ast-print %s | FileCheck -check-prefix=PRINT %s +// RUN: %clang -cc1 -include-pch %t -emit-llvm -o - %s | FileCheck -check-prefix=IR %s + +// CHECK-PRINT: id oldObject = array[10]; +// CHECK-PRINT: array[10] = oldObject; +// CHECK-PRINT: oldObject = dictionary[key]; +// CHECK-PRINT: dictionary[key] = newObject; + +// CHECK-IR: define void @all() nounwind +// CHECK-IR: {{call.*objc_msgSend}} +// CHECK-IR: {{call.*objc_msgSend}} +// CHECK-IR: {{call.*objc_msgSend}} +// CHECK-IR: {{call.*objc_msgSend}} +// CHECK-IR: ret void diff --git a/clang/test/PCH/objc_literals.m b/clang/test/PCH/objc_literals.m new file mode 100644 index 00000000000..cce3173bba0 --- /dev/null +++ b/clang/test/PCH/objc_literals.m @@ -0,0 +1,66 @@ +// RUN: %clang -cc1 -emit-pch -o %t %s +// RUN: %clang -cc1 -include-pch %t -verify %s +// RUN: %clang -cc1 -include-pch %t -ast-print %s | FileCheck -check-prefix=PRINT %s +// RUN: %clang -cc1 -include-pch %t -emit-llvm -o - %s | FileCheck -check-prefix=IR %s + +#ifndef HEADER +#define HEADER + +typedef unsigned char BOOL; + +@interface NSNumber @end + +@interface NSNumber (NSNumberCreation) ++ (NSNumber *)numberWithChar:(char)value; ++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value; ++ (NSNumber *)numberWithShort:(short)value; ++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value; ++ (NSNumber *)numberWithInt:(int)value; ++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value; ++ (NSNumber *)numberWithLong:(long)value; ++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; ++ (NSNumber *)numberWithLongLong:(long long)value; ++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; ++ (NSNumber *)numberWithFloat:(float)value; ++ (NSNumber *)numberWithDouble:(double)value; ++ (NSNumber *)numberWithBool:(BOOL)value; +@end + +@interface NSArray +@end + +@interface NSArray (NSArrayCreation) ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; +@end + +@interface NSDictionary ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; +@end + +// CHECK-IR: define internal void @test_numeric_literals() +static inline void test_numeric_literals() { + // CHECK-PRINT: id intlit = @17 + // CHECK-IR: {{call.*17}} + id intlit = @17; + // CHECK-PRINT: id floatlit = @17.45 + // CHECK-IR: {{call.*1.745}} + id floatlit = @17.45; +} + +static inline void test_array_literals() { + // CHECK-PRINT: id arraylit = @[ @17, @17.45 + id arraylit = @[@17, @17.45]; +} + +static inline void test_dictionary_literals() { + // CHECK-PRINT: id dictlit = @{ @17 : {{@17.45[^,]*}}, @"hello" : @"world" }; + id dictlit = @{@17 : @17.45, @"hello" : @"world" }; +} + +#else +void test_all() { + test_numeric_literals(); + test_array_literals(); + test_dictionary_literals(); +} +#endif diff --git a/clang/test/PCH/objc_literals.mm b/clang/test/PCH/objc_literals.mm new file mode 100644 index 00000000000..8ef33511503 --- /dev/null +++ b/clang/test/PCH/objc_literals.mm @@ -0,0 +1,65 @@ +// RUN: %clang -cc1 -emit-pch -x objective-c++ -std=c++0x -o %t %s +// RUN: %clang -cc1 -include-pch %t -x objective-c++ -std=c++0x -verify %s +// RUN: %clang -cc1 -include-pch %t -x objective-c++ -std=c++0x -ast-print %s | FileCheck -check-prefix=PRINT %s +// RUN: %clang -cc1 -include-pch %t -x objective-c++ -std=c++0x -emit-llvm -o - %s | FileCheck -check-prefix=IR %s + +#ifndef HEADER +#define HEADER + +typedef unsigned char BOOL; + +@interface NSNumber @end + +@interface NSNumber (NSNumberCreation) ++ (NSNumber *)numberWithChar:(char)value; ++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value; ++ (NSNumber *)numberWithShort:(short)value; ++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value; ++ (NSNumber *)numberWithInt:(int)value; ++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value; ++ (NSNumber *)numberWithLong:(long)value; ++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; ++ (NSNumber *)numberWithLongLong:(long long)value; ++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; ++ (NSNumber *)numberWithFloat:(float)value; ++ (NSNumber *)numberWithDouble:(double)value; ++ (NSNumber *)numberWithBool:(BOOL)value; +@end + +@interface NSArray +@end + +@interface NSArray (NSArrayCreation) ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; +@end + +@interface NSDictionary ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; +@end + +template<typename T, typename U> +struct pair { + T first; + U second; +}; + +template<typename T, typename U> +pair<T, U> make_pair(const T& first, const U& second) { + return { first, second }; +} + +// CHECK-IR: define linkonce_odr void @_Z29variadic_dictionary_expansionIJP8NSStringS1_EJP8NSNumberS3_EEvDp4pairIT_T0_E +template<typename ...Ts, typename ... Us> +void variadic_dictionary_expansion(pair<Ts, Us>... key_values) { + // CHECK-PRINT: id dict = @{ key_values.first : key_values.second... }; + // CHECK-IR: {{call.*objc_msgSend}} + // CHECK-IR: ret void + id dict = @{ key_values.first : key_values.second ... }; +} + +#else +void test_all() { + variadic_dictionary_expansion(make_pair(@"Seventeen", @17), + make_pair(@"YES", @true)); +} +#endif diff --git a/clang/test/PCH/subscripting-literals.m b/clang/test/PCH/subscripting-literals.m new file mode 100644 index 00000000000..1675373441c --- /dev/null +++ b/clang/test/PCH/subscripting-literals.m @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o %t.nopch.ll %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-pch -o %t.pch %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o %t.pch.ll %s -include-pch %t.pch +// RUN: diff %t.nopch.ll %t.pch.ll + +#ifndef HEADER +#define HEADER + +@interface NSArray +- (id)objectAtIndexedSubscript:(int)index; ++ (id)arrayWithObjects:(id *)objects count:(unsigned)count; +@end + +@interface NSMutableArray : NSArray +- (void)setObject:(id)object atIndexedSubscript:(int)index; +@end + +@interface NSDictionary +- (id)objectForKeyedSubscript:(id)key; ++ (id)dictionaryWithObjects:(id *)objects forKeys:(id *)keys count:(unsigned)count; +@end + +@interface NSMutableDictionary : NSDictionary +- (void)setObject:(id)object forKeyedSubscript:(id)key; +@end + +@interface NSNumber ++ (NSNumber *)numberWithInt:(int)value; +@end + +@class NSString; + +id testArray(int idx, id p) { + NSMutableArray *array; + array[idx] = p; + NSArray *arr = @[ p, @7 ]; + return array[idx]; +} + +void testDict(NSString *key, id newObject, id oldObject) { + NSMutableDictionary *dictionary; + oldObject = dictionary[key]; + dictionary[key] = newObject; + NSDictionary *dict = @{ key: newObject, key: oldObject }; +} + +#endif diff --git a/clang/test/SemaObjC/cocoa-api-usage.m b/clang/test/SemaObjC/cocoa-api-usage.m new file mode 100644 index 00000000000..85e21154a9e --- /dev/null +++ b/clang/test/SemaObjC/cocoa-api-usage.m @@ -0,0 +1,88 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -fsyntax-only -Wobjc-cocoa-api -verify +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc %s -fsyntax-only -Wobjc-cocoa-api -verify +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x objective-c %s.fixed -fsyntax-only +// RUN: cp %s %t.m +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %t.m -fixit -Wobjc-cocoa-api +// RUN: diff %s.fixed %t.m +// RUN: cp %s %t.m +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc %t.m -fixit -Wobjc-cocoa-api +// RUN: diff %s.fixed %t.m + +typedef signed char BOOL; +#define nil ((void*) 0) + +@interface NSObject ++ (id)alloc; +@end + +@interface NSString : NSObject ++ (id)stringWithString:(NSString *)string; +- (id)initWithString:(NSString *)aString; +@end + +@interface NSArray : NSObject +- (id)objectAtIndex:(unsigned long)index; +- (id)objectAtIndexedSubscript:(int)index; +@end + +@interface NSArray (NSArrayCreation) ++ (id)array; ++ (id)arrayWithObject:(id)anObject; ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; ++ (id)arrayWithObjects:(id)firstObj, ...; ++ (id)arrayWithArray:(NSArray *)array; + +- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt; +- (id)initWithObjects:(id)firstObj, ...; +- (id)initWithArray:(NSArray *)array; + +- (id)objectAtIndex:(unsigned long)index; +@end + +@interface NSMutableArray : NSArray +- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; +- (void)setObject:(id)object atIndexedSubscript:(int)index; +@end + +@interface NSDictionary : NSObject +- (id)objectForKeyedSubscript:(id)key; +@end + +@interface NSDictionary (NSDictionaryCreation) ++ (id)dictionary; ++ (id)dictionaryWithObject:(id)object forKey:(id)key; ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; ++ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...; ++ (id)dictionaryWithDictionary:(NSDictionary *)dict; ++ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; + +- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; +- (id)initWithObjectsAndKeys:(id)firstObject, ...; +- (id)initWithDictionary:(NSDictionary *)otherDictionary; +- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; + +- (id)objectForKey:(id)aKey; +@end + +@interface NSMutableDictionary : NSDictionary +- (void)setObject:(id)anObject forKey:(id)aKey; +- (void)setObject:(id)object forKeyedSubscript:(id)key; +@end + +@interface NSNumber : NSObject +@end + +@interface NSNumber (NSNumberCreation) ++ (NSNumber *)numberWithInt:(int)value; +@end + +#define M(x) (x) +#define PAIR(x) @#x, [NSNumber numberWithInt:(x)] +#define TWO(x) ((x), (x)) + +void foo() { + NSString *str = M([NSString stringWithString:@"foo"]); // expected-warning {{redundant}} + str = [[NSString alloc] initWithString:@"foo"]; + NSArray *arr = [NSArray arrayWithArray:@[str]]; // expected-warning {{redundant}} + NSDictionary *dict = [NSDictionary dictionaryWithDictionary:@{str: arr}]; // expected-warning {{redundant}} +} diff --git a/clang/test/SemaObjC/cocoa-api-usage.m.fixed b/clang/test/SemaObjC/cocoa-api-usage.m.fixed new file mode 100644 index 00000000000..55e060a068b --- /dev/null +++ b/clang/test/SemaObjC/cocoa-api-usage.m.fixed @@ -0,0 +1,88 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -fsyntax-only -Wobjc-cocoa-api -verify +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc %s -fsyntax-only -Wobjc-cocoa-api -verify +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x objective-c %s.fixed -fsyntax-only +// RUN: cp %s %t.m +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %t.m -fixit -Wobjc-cocoa-api +// RUN: diff %s.fixed %t.m +// RUN: cp %s %t.m +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc %t.m -fixit -Wobjc-cocoa-api +// RUN: diff %s.fixed %t.m + +typedef signed char BOOL; +#define nil ((void*) 0) + +@interface NSObject ++ (id)alloc; +@end + +@interface NSString : NSObject ++ (id)stringWithString:(NSString *)string; +- (id)initWithString:(NSString *)aString; +@end + +@interface NSArray : NSObject +- (id)objectAtIndex:(unsigned long)index; +- (id)objectAtIndexedSubscript:(int)index; +@end + +@interface NSArray (NSArrayCreation) ++ (id)array; ++ (id)arrayWithObject:(id)anObject; ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; ++ (id)arrayWithObjects:(id)firstObj, ...; ++ (id)arrayWithArray:(NSArray *)array; + +- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt; +- (id)initWithObjects:(id)firstObj, ...; +- (id)initWithArray:(NSArray *)array; + +- (id)objectAtIndex:(unsigned long)index; +@end + +@interface NSMutableArray : NSArray +- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; +- (void)setObject:(id)object atIndexedSubscript:(int)index; +@end + +@interface NSDictionary : NSObject +- (id)objectForKeyedSubscript:(id)key; +@end + +@interface NSDictionary (NSDictionaryCreation) ++ (id)dictionary; ++ (id)dictionaryWithObject:(id)object forKey:(id)key; ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; ++ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...; ++ (id)dictionaryWithDictionary:(NSDictionary *)dict; ++ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; + +- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; +- (id)initWithObjectsAndKeys:(id)firstObject, ...; +- (id)initWithDictionary:(NSDictionary *)otherDictionary; +- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; + +- (id)objectForKey:(id)aKey; +@end + +@interface NSMutableDictionary : NSDictionary +- (void)setObject:(id)anObject forKey:(id)aKey; +- (void)setObject:(id)object forKeyedSubscript:(id)key; +@end + +@interface NSNumber : NSObject +@end + +@interface NSNumber (NSNumberCreation) ++ (NSNumber *)numberWithInt:(int)value; +@end + +#define M(x) (x) +#define PAIR(x) @#x, [NSNumber numberWithInt:(x)] +#define TWO(x) ((x), (x)) + +void foo() { + NSString *str = M(@"foo"); // expected-warning {{redundant}} + str = [[NSString alloc] initWithString:@"foo"]; + NSArray *arr = @[str]; // expected-warning {{redundant}} + NSDictionary *dict = @{str: arr}; // expected-warning {{redundant}} +} diff --git a/clang/test/SemaObjC/invalid-code.m b/clang/test/SemaObjC/invalid-code.m index 8378ed761c4..7b6591205b4 100644 --- a/clang/test/SemaObjC/invalid-code.m +++ b/clang/test/SemaObjC/invalid-code.m @@ -2,7 +2,8 @@ // rdar://6124613 void test1() { - void *p = @1; // expected-error {{unexpected '@' in program}} + void *xyzzy = 0; + void *p = @xyzzy; // expected-error {{unexpected '@' in program}} } // <rdar://problem/7495713> diff --git a/clang/test/SemaObjC/objc-array-literal.m b/clang/test/SemaObjC/objc-array-literal.m new file mode 100644 index 00000000000..9f59316219c --- /dev/null +++ b/clang/test/SemaObjC/objc-array-literal.m @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://10111397 + +#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64 +typedef unsigned long NSUInteger; +#else +typedef unsigned int NSUInteger; +#endif + +@class NSString; + +extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); + +@class NSFastEnumerationState; + +@protocol NSFastEnumeration + +- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id [])buffer count:(NSUInteger)len; + +@end + +@interface NSNumber ++ (NSNumber *)numberWithInt:(int)value; +@end + +@interface NSArray <NSFastEnumeration> ++ (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt; +@end + + +int main() { + NSArray *array = @[@"Hello", @"There", @"How Are You", [NSNumber numberWithInt:42]]; + + for (id string in array) + NSLog(@"%@\n", string); + + NSArray *array1 = @["Forgot"]; // expected-error {{string literal must be prefixed by '@' in a collection}} + + const char *blah; + NSArray *array2 = @[blah]; // expected-error{{collection element of type 'const char *' is not an Objective-C object}} +} diff --git a/clang/test/SemaObjC/objc-container-subscripting-1.m b/clang/test/SemaObjC/objc-container-subscripting-1.m new file mode 100644 index 00000000000..a58a7c3bda8 --- /dev/null +++ b/clang/test/SemaObjC/objc-container-subscripting-1.m @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef unsigned int size_t; +@protocol P @end + +@interface NSMutableArray +@end + +@interface XNSMutableArray +@end + +int main() { +id array; +id oldObject = array[10]; // expected-warning {{instance method '-objectAtIndexedSubscript:' not found (return type defaults to 'id')}} + +array[10] = 0; // expected-warning {{instance method '-setObject:atIndexedSubscript:' not found (return type defaults to 'id')}} + +id<P> p_array; +oldObject = p_array[10]; // expected-warning {{instance method '-objectAtIndexedSubscript:' not found (return type defaults to 'id')}} + +p_array[10] = 0; // expected-warning {{instance method '-setObject:atIndexedSubscript:' not found (return type defaults to 'id')}} +} + diff --git a/clang/test/SemaObjC/objc-container-subscripting-2.m b/clang/test/SemaObjC/objc-container-subscripting-2.m new file mode 100644 index 00000000000..2564975f4d4 --- /dev/null +++ b/clang/test/SemaObjC/objc-container-subscripting-2.m @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef unsigned int size_t; +@protocol P @end + +@interface NSMutableArray +- (id)objectAtIndexedSubscript:(size_t)index; +- (void)setObject:(id)object atIndexedSubscript:(size_t)index; +@end + +@interface NSMutableDictionary +- (id)objectForKeyedSubscript:(id)key; +- (void)setObject:(id)object forKeyedSubscript:(size_t)key; +@end + +id func() { + NSMutableArray *array; + float f; + array[f] = array; // expected-error {{expected method to write dictionary element not found on object of type 'NSMutableArray *'}} + return array[3.14]; // expected-error {{expected method to read dictionary element not found on object of type 'NSMutableArray *'}} +} + +void test_unused() { + NSMutableArray *array; + array[10]; // expected-warning {{container access result unused - container access should not be used for side effects}} + + NSMutableDictionary *dict; + dict[array]; // expected-warning {{container access result unused - container access should not be used for side effects}} +} + diff --git a/clang/test/SemaObjC/objc-container-subscripting-3.m b/clang/test/SemaObjC/objc-container-subscripting-3.m new file mode 100644 index 00000000000..5fd1a10915f --- /dev/null +++ b/clang/test/SemaObjC/objc-container-subscripting-3.m @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// rdar://10904488 + +@interface Test +- (int)objectAtIndexedSubscript:(int)index; // expected-note {{method 'objectAtIndexedSubscript:' declared here}} +- (void)setObject:(int)object atIndexedSubscript:(int)index; // expected-note {{parameter of type 'int' is declared here}} +@end + +@interface NSMutableDictionary +- (int)objectForKeyedSubscript:(id)key; // expected-note {{method 'objectForKeyedSubscript:' declared here}} +- (void)setObject:(int)object forKeyedSubscript:(id)key; // expected-note {{parameter of type 'int' is declared here}} +@end + +int main() { + Test *array; + int i = array[10]; // expected-error {{method for accessing array element must have Objective-C object return type instead of 'int'}} + array[2] = i; // expected-error {{cannot assign to this array because assigning method's 2nd parameter of type 'int' is not an objective-C pointer type}} + + NSMutableDictionary *dict; + id key, val; + val = dict[key]; // expected-error {{method for accessing dictionary element must have Objective-C object return type instead of 'int'}} \ + // expected-warning {{incompatible integer to pointer conversion assigning to 'id' from 'int'}} + dict[key] = val; // expected-error {{method object parameter type 'int' is not object type}} +} + diff --git a/clang/test/SemaObjC/objc-container-subscripting.m b/clang/test/SemaObjC/objc-container-subscripting.m new file mode 100644 index 00000000000..4125bc634a7 --- /dev/null +++ b/clang/test/SemaObjC/objc-container-subscripting.m @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef unsigned int size_t; +@protocol P @end + +@interface NSMutableArray +- (id)objectAtIndexedSubscript:(double)index; // expected-note {{parameter of type 'double' is declared here}} +- (void)setObject:(id *)object atIndexedSubscript:(void *)index; // expected-note {{parameter of type 'void *' is declared here}} \ + // expected-note {{parameter of type 'id *' is declared here}} +@end +@interface I @end + +int main() { + NSMutableArray<P> * array; + id oldObject = array[10]; // expected-error {{method index parameter type 'double' is not integral type}} + array[3] = 0; // expected-error {{method index parameter type 'void *' is not integral type}} \ + // expected-error {{cannot assign to this array because assigning method's 2nd parameter of type 'id *' is not an objective-C pointer type}} + + I* iarray; + iarray[3] = 0; // expected-error {{expected method to write array element not found on object of type 'I *'}} + I* p = iarray[4]; // expected-error {{expected method to read array element not found on object of type 'I *'}} + + oldObject = array[10]++; // expected-error {{illegal operation on objective-c container subscripting}} + oldObject = array[10]--; // expected-error {{illegal operation on objective-c container subscripting}} + oldObject = --array[10]; // expected-error {{illegal operation on objective-c container subscripting}} +} + +@interface NSMutableDictionary +- (id)objectForKeyedSubscript:(id*)key; // expected-note {{parameter of type 'id *' is declared here}} +- (void)setObject:(void*)object forKeyedSubscript:(id*)key; // expected-note {{parameter of type 'void *' is declared here}} \ + // expected-note {{parameter of type 'id *' is declared here}} +@end +@class NSString; + +void testDict() { + NSMutableDictionary *dictionary; + NSString *key; + id newObject, oldObject; + oldObject = dictionary[key]; // expected-error {{method key parameter type 'id *' is not object type}} + dictionary[key] = newObject; // expected-error {{method object parameter type 'void *' is not object type}} \ + // expected-error {{method key parameter type 'id *' is not object type}} +} diff --git a/clang/test/SemaObjC/objc-literal-nsnumber.m b/clang/test/SemaObjC/objc-literal-nsnumber.m new file mode 100644 index 00000000000..db6183e6bb2 --- /dev/null +++ b/clang/test/SemaObjC/objc-literal-nsnumber.m @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s +// rdar://10111397 + +#if __LP64__ +typedef unsigned long NSUInteger; +#else +typedef unsigned int NSUInteger; +#endif + +@interface NSObject ++ (NSObject*)nsobject; +@end + +@interface NSNumber : NSObject ++ (NSNumber *)numberWithChar:(char)value; ++ (NSNumber *)numberWithInt:(int)value; ++ (NSNumber *)numberWithFloat:(float)value; +@end + +int main() { + NSNumber * N = @3.1415926535; // expected-error {{declaration of 'numberWithDouble:' is missing in NSNumber class}} + NSNumber *noNumber = @__objc_yes; // expected-error {{declaration of 'numberWithBool:' is missing in NSNumber class}} + NSNumber * NInt = @1000; + NSNumber * NLongDouble = @1000.0l; // expected-error{{'long double' is not a valid literal type for NSNumber}} + id character = @ 'a'; + + NSNumber *NNegativeInt = @-1000; + NSNumber *NPositiveInt = @+1000; + NSNumber *NNegativeFloat = @-1000.1f; + NSNumber *NPositiveFloat = @+1000.1f; + + int five = 5; + @-five; // expected-error{{@- must be followed by a number to form an NSNumber object}} + @+five; // expected-error{{@+ must be followed by a number to form an NSNumber object}} +} + +// Dictionary test +@class NSDictionary; + +NSDictionary *err() { + return @{@"name" : @"value"}; // expected-error {{declaration of 'dictionaryWithObjects:forKeys:count:' is missing in NSDictionary class}} +} + +@interface NSDate : NSObject ++ (NSDate *) date; +@end + +@protocol NSCopying +- copy; +@end + +@interface NSDictionary : NSObject ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id<NSCopying> [])keys count:(NSUInteger)cnt; +@end + +@interface NSString<NSCopying> +@end + +id NSUserName(); + +int Int(); + +NSDictionary * blocks() { + return @{ @"task" : ^ { return 17; } }; +} + +NSDictionary * warn() { + NSDictionary *dictionary = @{@"name" : NSUserName(), + @"date" : [NSDate date], + @"name2" : @"other", + NSObject.nsobject : @"nsobject" }; // expected-warning{{passing 'NSObject *' to parameter of incompatible type 'const id<NSCopying>'}} + NSDictionary *dictionary2 = @{@"name" : Int()}; // expected-error {{collection element of type 'int' is not an Objective-C object}} + + NSObject *o; + NSDictionary *dictionary3 = @{o : o, // expected-warning{{passing 'NSObject *' to parameter of incompatible type 'const id<NSCopying>'}} + @"date" : [NSDate date] }; + return dictionary3; +} diff --git a/clang/test/SemaObjC/objc-literal-sig.m b/clang/test/SemaObjC/objc-literal-sig.m new file mode 100644 index 00000000000..fb5c79fd843 --- /dev/null +++ b/clang/test/SemaObjC/objc-literal-sig.m @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +typedef _Bool BOOL; + +@interface NSNumber @end + +@interface NSNumber (NSNumberCreation) ++ (NSNumber *)numberWithChar:(char)value; ++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value; ++ (NSNumber *)numberWithShort:(short)value; ++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value; ++ (NSNumber *)numberWithInt:(int)value; ++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value; ++ (NSNumber *)numberWithLong:(long)value; ++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; ++ (NSNumber *)numberWithLongLong:(long long)value; ++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; ++ (NSNumber *)numberWithFloat:(float)value; ++ (NSNumber *)numberWithDouble:(double)value; ++ (int)numberWithBool:(BOOL)value; // expected-note{{method returns unexpected type 'int' (should be an object type)}} +@end + +@interface NSArray +@end + +@interface NSArray (NSArrayCreation) ++ (id)arrayWithObjects:(const int [])objects // expected-note{{first parameter has unexpected type 'const int *' (should be 'const id *')}} + count:(unsigned long)cnt; +@end + +@interface NSDictionary ++ (id)dictionaryWithObjects:(const id [])objects + forKeys:(const int [])keys // expected-note{{second parameter has unexpected type 'const int *' (should be 'const id *')}} + count:(unsigned long)cnt; +@end + +void test_sig() { + (void)@__objc_yes; // expected-error{{literal construction method 'numberWithBool:' has incompatible signature}} + id array = @[ @17 ]; // expected-error{{literal construction method 'arrayWithObjects:count:' has incompatible signature}} + id dict = @{ @"hello" : @17 }; // expected-error{{literal construction method 'dictionaryWithObjects:forKeys:count:' has incompatible signature}} +} diff --git a/clang/test/SemaObjC/sizeof-interface.m b/clang/test/SemaObjC/sizeof-interface.m index dd8c1fdca00..dc99befeefc 100644 --- a/clang/test/SemaObjC/sizeof-interface.m +++ b/clang/test/SemaObjC/sizeof-interface.m @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -verify -fsyntax-only %s -@class I0; // expected-note 3{{forward declaration of class here}} +@class I0; // expected-note 2{{forward declaration of class here}} // rdar://6811884 int g0 = sizeof(I0); // expected-error{{invalid application of 'sizeof' to an incomplete type 'I0'}} @@ -9,7 +9,7 @@ int g0 = sizeof(I0); // expected-error{{invalid application of 'sizeof' to an in void *g3(I0 *P) { P = P+5; // expected-error {{arithmetic on a pointer to an incomplete type 'I0'}} - return &P[4]; // expected-error{{subscript of pointer to incomplete type 'I0'}} + return &P[4]; // expected-error{{expected method to read array element not found on object of type 'I0 *'}} } @@ -55,7 +55,7 @@ int bar(I0 *P) { P = 5+P; // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size in non-fragile ABI}} P = P-5; // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size in non-fragile ABI}} - return P[4].x[2]; // expected-error {{subscript requires size of interface 'I0', which is not constant in non-fragile ABI}} + return P[4].x[2]; // expected-error {{expected method to read array element not found on object of type 'I0 *'}} } diff --git a/clang/test/SemaObjCXX/literals.mm b/clang/test/SemaObjCXX/literals.mm new file mode 100644 index 00000000000..1f6782abbec --- /dev/null +++ b/clang/test/SemaObjCXX/literals.mm @@ -0,0 +1,178 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x -fblocks %s + +typedef unsigned char BOOL; + +@protocol NSCopying +- copy; +@end + +@interface NSObject +@end + +@interface NSNumber : NSObject <NSCopying> +-copy; +@end + +@interface NSNumber (NSNumberCreation) ++ (NSNumber *)numberWithChar:(char)value; ++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value; ++ (NSNumber *)numberWithShort:(short)value; ++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value; ++ (NSNumber *)numberWithInt:(int)value; ++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value; ++ (NSNumber *)numberWithLong:(long)value; ++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; ++ (NSNumber *)numberWithLongLong:(long long)value; ++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; ++ (NSNumber *)numberWithFloat:(float)value; ++ (NSNumber *)numberWithDouble:(double)value; ++ (NSNumber *)numberWithBool:(BOOL)value; +@end + +@interface NSArray : NSObject <NSCopying> +-copy; +@end + +@interface NSArray (NSArrayCreation) ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; +@end + +@interface NSDictionary ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id<NSCopying> [])keys count:(unsigned long)cnt; +@end + +template<typename T> +struct ConvertibleTo { + operator T(); +}; + +template<typename T> +struct ExplicitlyConvertibleTo { + explicit operator T(); +}; + +template<typename T> +class PrivateConvertibleTo { +private: + operator T(); // expected-note{{declared private here}} +}; + +template<typename T> ConvertibleTo<T> makeConvertible(); + +struct X { + ConvertibleTo<id> x; + ConvertibleTo<id> get(); +}; + +template<typename T> T test_numeric_instantiation() { + return @-17.42; +} + +template id test_numeric_instantiation(); + +void test_convertibility(ConvertibleTo<NSArray*> toArray, + ConvertibleTo<id> toId, + ConvertibleTo<int (^)(int)> toBlock, + ConvertibleTo<int> toInt, + ExplicitlyConvertibleTo<NSArray *> toArrayExplicit) { + id array = @[ + toArray, + toId, + toBlock, + toInt // expected-error{{collection element of type 'ConvertibleTo<int>' is not an Objective-C object}} + ]; + id array2 = @[ toArrayExplicit ]; // expected-error{{collection element of type 'ExplicitlyConvertibleTo<NSArray *>' is not an Objective-C object}} + + id array3 = @[ + makeConvertible<id>(), + makeConvertible<id>, // expected-error{{collection element of type 'ConvertibleTo<id> ()' is not an Objective-C object}} + ]; + + X x; + id array4 = @[ x.x ]; + id array5 = @[ x.get ]; // expected-error{{reference to non-static member function must be called}} + id array6 = @[ PrivateConvertibleTo<NSArray*>() ]; // expected-error{{operator NSArray *' is a private member of 'PrivateConvertibleTo<NSArray *>'}} +} + +template<typename T> +void test_array_literals(T t) { + id arr = @[ @17, t ]; // expected-error{{collection element of type 'int' is not an Objective-C object}} +} + +template void test_array_literals(id); +template void test_array_literals(NSArray*); +template void test_array_literals(int); // expected-note{{in instantiation of function template specialization 'test_array_literals<int>' requested here}} + +template<typename T, typename U> +void test_dictionary_literals(T t, U u) { + NSObject *object; + id dict = @{ + @17 : t, // expected-error{{collection element of type 'int' is not an Objective-C object}} + u : @42 // expected-error{{collection element of type 'int' is not an Objective-C object}} + }; + + id dict2 = @{ + object : @"object" // expected-error{{cannot initialize a parameter of type 'const id<NSCopying>' with an rvalue of type 'NSObject *'}} + }; +} + +template void test_dictionary_literals(id, NSArray*); +template void test_dictionary_literals(NSArray*, id); +template void test_dictionary_literals(int, id); // expected-note{{in instantiation of function template specialization 'test_dictionary_literals<int, id>' requested here}} +template void test_dictionary_literals(id, int); // expected-note{{in instantiation of function template specialization 'test_dictionary_literals<id, int>' requested here}} + +template<typename ...Args> +void test_bad_variadic_array_literal(Args ...args) { + id arr1 = @[ args ]; // expected-error{{initializer contains unexpanded parameter pack 'args'}} +} + +template<typename ...Args> +void test_variadic_array_literal(Args ...args) { + id arr1 = @[ args... ]; // expected-error{{collection element of type 'int' is not an Objective-C object}} +} +template void test_variadic_array_literal(id); +template void test_variadic_array_literal(id, NSArray*); +template void test_variadic_array_literal(id, int, NSArray*); // expected-note{{in instantiation of function template specialization 'test_variadic_array_literal<id, int, NSArray *>' requested here}} + +template<typename ...Args> +void test_bad_variadic_dictionary_literal(Args ...args) { + id dict = @{ args : @17 }; // expected-error{{initializer contains unexpanded parameter pack 'args'}} +} + +// Test array literal pack expansions. +template<typename T, typename U> +struct pair { + T first; + U second; +}; + +template<typename T, typename ...Ts, typename ... Us> +void test_variadic_dictionary_expansion(T t, pair<Ts, Us>... key_values) { + id dict = @{ + t : key_values.second ..., // expected-error{{collection element of type 'int' is not an Objective-C object}} + key_values.first : key_values.second ..., // expected-error{{collection element of type 'float' is not an Objective-C object}} + key_values.second : t ... + }; +} + +template void test_variadic_dictionary_expansion(id, + pair<NSNumber*, id>, + pair<id, ConvertibleTo<id>>); +template void test_variadic_dictionary_expansion(NSNumber *, // expected-note{{in instantiation of function template specialization}} + pair<NSNumber*, int>, + pair<id, ConvertibleTo<id>>); +template void test_variadic_dictionary_expansion(NSNumber *, // expected-note{{in instantiation of function template specialization}} + pair<NSNumber*, id>, + pair<float, ConvertibleTo<id>>); + +// Test parsing +struct key { + static id value; +}; + +id key; +id value; + +void test_dictionary_colon() { + id dict = @{ key : value }; +} diff --git a/clang/test/SemaObjCXX/objc-container-subscripting.mm b/clang/test/SemaObjCXX/objc-container-subscripting.mm new file mode 100644 index 00000000000..ccbc45e3b4c --- /dev/null +++ b/clang/test/SemaObjCXX/objc-container-subscripting.mm @@ -0,0 +1,138 @@ +// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin11 -fsyntax-only -std=c++11 -verify %s + +@class NSArray; + +@interface NSMutableDictionary +- (id)objectForKeyedSubscript:(id)key; +- (void)setObject:(id)object forKeyedSubscript:(id)key; // expected-note {{passing argument to parameter 'object' here}} +@end + +template<typename T, typename U, typename O> +void test_dictionary_subscripts(T base, U key, O obj) { + base[key] = obj; // expected-error {{expected method to write array element not found on object of type 'NSMutableDictionary *'}} \ + // expected-error {{cannot initialize a parameter of type 'id' with an lvalue of type 'int'}} + obj = base[key]; // expected-error {{expected method to read array element not found on object of type 'NSMutableDictionary *'}} \ + // expected-error {{assigning to 'int' from incompatible type 'id'}} + +} + +template void test_dictionary_subscripts(NSMutableDictionary*, id, NSArray *ns); + +template void test_dictionary_subscripts(NSMutableDictionary*, NSArray *ns, id); + +template void test_dictionary_subscripts(NSMutableDictionary*, int, id); // expected-note {{in instantiation of function template specialization 'test_dictionary_subscripts<NSMutableDictionary *, int, id>' requested here}} + +template void test_dictionary_subscripts(NSMutableDictionary*, id, int); // expected-note {{in instantiation of function template specialization 'test_dictionary_subscripts<NSMutableDictionary *, id, int>' requested here}} + + +@interface NSMutableArray +- (id)objectAtIndexedSubscript:(int)index; +- (void)setObject:(id)object atIndexedSubscript:(int)index; +@end + +template<typename T, typename U, typename O> +void test_array_subscripts(T base, U index, O obj) { + base[index] = obj; // expected-error {{expected method to write dictionary element not found on object of type 'NSMutableArray *'}} + obj = base[index]; // expected-error {{expected method to read dictionary element not found on object of type 'NSMutableArray *'}} +} + +template void test_array_subscripts(NSMutableArray *, int, id); +template void test_array_subscripts(NSMutableArray *, short, id); +enum E { e }; + +template void test_array_subscripts(NSMutableArray *, E, id); + +template void test_array_subscripts(NSMutableArray *, double, id); // expected-note {{in instantiation of function template specialization 'test_array_subscripts<NSMutableArray *, double, id>' requested here}} + +template<typename T> +struct ConvertibleTo { + operator T(); +}; + +template<typename T> +struct ExplicitlyConvertibleTo { + explicit operator T(); +}; + +template<typename T> ConvertibleTo<T> makeConvertible(); + +struct X { + ConvertibleTo<id> x; + ConvertibleTo<id> get(); +}; + +NSMutableArray *test_array_convertibility(ConvertibleTo<NSMutableArray*> toArray, + ConvertibleTo<id> toId, + ConvertibleTo<int (^)(int)> toBlock, + ConvertibleTo<int> toInt, + ExplicitlyConvertibleTo<NSMutableArray *> toArrayExplicit) { + id array; + + array[1] = toArray; + + array[4] = array[1]; + + toArrayExplicit[2] = toId; // expected-error {{type 'ExplicitlyConvertibleTo<NSMutableArray *>' does not provide a subscript operator}} + + return array[toInt]; + +} + +id test_dict_convertibility(ConvertibleTo<NSMutableDictionary*> toDict, + ConvertibleTo<id> toId, + ConvertibleTo<int (^)(int)> toBlock, + ConvertibleTo<int> toInt, + ExplicitlyConvertibleTo<NSMutableDictionary *> toDictExplicit) { + + + NSMutableDictionary *Dict; + id Id; + Dict[toId] = toBlock; + + Dict[toBlock] = toBlock; + + Dict[toBlock] = Dict[toId] = Dict[toBlock]; + + Id = toDictExplicit[toId] = Id; // expected-error {{no viable overloaded operator[] for type 'ExplicitlyConvertibleTo<NSMutableDictionary *>'}} + + return Dict[toBlock]; +} + + +template<typename ...Args> +void test_bad_variadic_array_subscripting(Args ...args) { + id arr1; + arr1[3] = args; // expected-error {{expression contains unexpanded parameter pack 'args'}} +} + +template<typename ...Args> +void test_variadic_array_subscripting(Args ...args) { + id arr[] = {args[3]...}; // which means: {a[3], b[3], c[3]}; +} + +template void test_variadic_array_subscripting(id arg1, NSMutableArray* arg2, id arg3); + +@class Key; + +template<typename Index, typename ...Args> +void test_variadic_dictionary_subscripting(Index I, Args ...args) { + id arr[] = {args[I]...}; // which means: {a[3], b[3], c[3]}; +} + +template void test_variadic_dictionary_subscripting(Key *key, id arg1, NSMutableDictionary* arg2, id arg3); + +template<int N> +id get(NSMutableArray *array) { + return array[N]; // array[N] should be a value- and instantiation-dependent ObjCSubscriptRefExpr +} + +struct WeirdIndex { + operator int(); // expected-note {{type conversion function declared here}} + operator id(); // expected-note {{type conversion function declared here}} +}; + +id FUNC(WeirdIndex w) { + NSMutableArray *array; + return array[w]; // expected-error {{indexing expression is invalid because subscript type 'WeirdIndex' has multiple type conversion functions}} +} + |