diff options
Diffstat (limited to 'clang/test/CodeGenObjC')
-rw-r--r-- | clang/test/CodeGenObjC/Inputs/literal-support.h | 35 | ||||
-rw-r--r-- | clang/test/CodeGenObjC/arc-literals.m | 121 | ||||
-rw-r--r-- | clang/test/CodeGenObjC/objc-arc-container-subscripting.m | 21 | ||||
-rw-r--r-- | clang/test/CodeGenObjC/objc-container-subscripting-1.m | 56 | ||||
-rw-r--r-- | clang/test/CodeGenObjC/objc-container-subscripting.m | 45 | ||||
-rw-r--r-- | clang/test/CodeGenObjC/objc-dictionary-literal.m | 25 | ||||
-rw-r--r-- | clang/test/CodeGenObjC/objc-literal-debugger-test.m | 16 | ||||
-rw-r--r-- | clang/test/CodeGenObjC/objc-literal-tests.m | 95 | ||||
-rw-r--r-- | clang/test/CodeGenObjC/optimized-setter.m | 33 |
9 files changed, 447 insertions, 0 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 + |