[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang / test / CodeGenObjC / convert-messages-to-runtime-calls.m
blob0221cc59b0a1cbab44d8d21a4531794bf1e78488
1 // RUN: %clang_cc1 -no-opaque-pointers -fobjc-runtime=macosx-10.10.0 -emit-llvm -o - %s -fno-objc-convert-messages-to-runtime-calls -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=MSGS
2 // RUN: %clang_cc1 -no-opaque-pointers -fobjc-runtime=macosx-10.10.0 -emit-llvm -o - %s -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=CALLS
3 // RUN: %clang_cc1 -no-opaque-pointers -fobjc-runtime=macosx-10.9.0 -emit-llvm -o - %s -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=MSGS
4 // RUN: %clang_cc1 -no-opaque-pointers -fobjc-runtime=macosx-fragile-10.10.0 -emit-llvm -o - %s -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=MSGS
5 // RUN: %clang_cc1 -no-opaque-pointers -fobjc-runtime=ios-8.0 -emit-llvm -o - %s -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=CALLS
6 // RUN: %clang_cc1 -no-opaque-pointers -fobjc-runtime=ios-7.0 -emit-llvm -o - %s -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=MSGS
7 // Note: This line below is for tvos for which the driver passes through to use the ios9.0 runtime.
8 // RUN: %clang_cc1 -no-opaque-pointers -fobjc-runtime=ios-9.0 -emit-llvm -o - %s -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=CALLS
9 // RUN: %clang_cc1 -no-opaque-pointers -fobjc-runtime=watchos-2.0 -emit-llvm -o - %s -fobjc-exceptions -fexceptions | FileCheck %s --check-prefix=CALLS
11 #define nil (id)0
13 @interface NSObject
14 + (id)alloc;
15 + (id)allocWithZone:(void*)zone;
16 + (id)alloc2;
17 - (id)retain;
18 - (void)release;
19 - (id)autorelease;
20 @end
22 // CHECK-LABEL: define {{.*}}void @test1
23 void test1(id x) {
24   // MSGS: {{call.*@objc_msgSend}}
25   // MSGS: {{call.*@objc_msgSend}}
26   // MSGS: {{call.*@objc_msgSend}}
27   // MSGS: {{call.*@objc_msgSend}}
28   // MSGS: {{call.*@objc_msgSend}}
29   // CALLS: {{call.*@objc_alloc}}
30   // CALLS: {{call.*@objc_allocWithZone}}
31   // CALLS: {{call.*@objc_retain}}
32   // CALLS: {{call.*@objc_release}}
33   // CALLS: {{tail call.*@objc_autorelease}}
34   [NSObject alloc];
35   [NSObject allocWithZone:nil];
36   [x retain];
37   [x release];
38   [x autorelease];
41 // CHECK-LABEL: define {{.*}}void @check_invoke
42 void check_invoke(void) {
43   // MSGS: {{invoke.*@objc_msgSend}}
44   // MSGS: {{invoke.*@objc_msgSend}}
45   // CALLS: {{invoke.*@objc_alloc}}
46   // CALLS: {{invoke.*@objc_allocWithZone}}
47   @try {
48     [NSObject alloc];
49     [NSObject allocWithZone:nil];
50   } @catch (...) {
51   }
54 // CHECK-LABEL: define {{.*}}void @test2
55 void test2(void* x) {
56   // MSGS: {{call.*@objc_msgSend}}
57   // MSGS: {{call.*@objc_msgSend}}
58   // MSGS: {{call.*@objc_msgSend}}
59   // CALLS: {{call.*@objc_msgSend}}
60   // CALLS: {{call.*@objc_msgSend}}
61   // CALLS: {{call.*@objc_msgSend}}
62   [NSObject alloc2];
63   [NSObject allocWithZone:(void*)-1];
64   [NSObject allocWithZone:x];
67 @class A;
68 @interface B
69 + (A*) alloc;
70 + (A*) allocWithZone:(void*)zone;
71 - (A*) alloc;
72 - (A*) allocWithZone:(void*)zone;
73 - (A*) retain;
74 - (A*) autorelease;
75 @end
77 // Make sure we get a bitcast on the return type as the
78 // call will return i8* which we have to cast to A*
79 // CHECK-LABEL: define {{.*}}void @test_alloc_class_ptr
80 A* test_alloc_class_ptr(void) {
81   // CALLS: {{call.*@objc_alloc}}
82   // CALLS-NEXT: bitcast i8*
83   // CALLS-NEXT: ret
84   return [B alloc];
87 // Make sure we get a bitcast on the return type as the
88 // call will return i8* which we have to cast to A*
89 // CHECK-LABEL: define {{.*}}void @test_alloc_class_ptr
90 A* test_allocWithZone_class_ptr(void) {
91   // CALLS: {{call.*@objc_allocWithZone}}
92   // CALLS-NEXT: bitcast i8*
93   // CALLS-NEXT: ret
94   return [B allocWithZone:nil];
97 // Only call objc_alloc on a Class, not an instance
98 // CHECK-LABEL: define {{.*}}void @test_alloc_instance
99 void test_alloc_instance(A *a) {
100   // CALLS: {{call.*@objc_alloc}}
101   // CALLS: {{call.*@objc_allocWithZone}}
102   // CALLS: {{call.*@objc_msgSend}}
103   // CALLS: {{call.*@objc_msgSend}}
104   [A alloc];
105   [A allocWithZone:nil];
106   [a alloc];
107   [a allocWithZone:nil];
110 // Make sure we get a bitcast on the return type as the
111 // call will return i8* which we have to cast to A*
112 // CHECK-LABEL: define {{.*}}void @test_retain_class_ptr
113 A* test_retain_class_ptr(B *b) {
114   // CALLS: {{call.*@objc_retain}}
115   // CALLS-NEXT: bitcast i8*
116   // CALLS-NEXT: ret
117   return [b retain];
120 // Make sure we get a bitcast on the return type as the
121 // call will return i8* which we have to cast to A*
122 // CHECK-LABEL: define {{.*}}void @test_autorelease_class_ptr
123 A* test_autorelease_class_ptr(B *b) {
124   // CALLS: {{tail call.*@objc_autorelease}}
125   // CALLS-NEXT: bitcast i8*
126   // CALLS-NEXT: ret
127   return [b autorelease];
131 @interface C
132 + (id)allocWithZone:(int)intArg;
133 - (float) retain;
134 @end
136 // Make sure we only accept pointer types
137 // CHECK-LABEL: define {{.*}}void @test_allocWithZone_int
138 C* test_allocWithZone_int(void) {
139   // MSGS: {{call.*@objc_msgSend}}
140   // CALLS: {{call.*@objc_msgSend}}
141   return [C allocWithZone:3];
144 // Make sure we use a message and not a call as the return type is
145 // not a pointer type.
146 // CHECK-LABEL: define {{.*}}void @test_cannot_message_return_float
147 float test_cannot_message_return_float(C *c) {
148   // MSGS: {{call.*@objc_msgSend}}
149   // CALLS: {{call.*@objc_msgSend}}
150   return [c retain];
153 @interface TestSelf
154 + (instancetype)alloc;
155 + (instancetype)allocWithZone:(void*)zone;
156 + (id)classMeth;
157 - (id)instanceMeth;
158 @end
160 @implementation TestSelf
161 // CHECK-LABEL: define internal i8* @"\01+[TestSelf classMeth]"(
162 + (id)classMeth {
163   // MSGS: {{call.*@objc_msgSend}}
164   // MSGS: {{call.*@objc_msgSend}}
165   // CALLS: {{call.*@objc_allocWithZone\(}}
166   // CALLS: {{call.*@objc_alloc\(}}
167   [self allocWithZone:nil];
168   return [self alloc];
170 // CHECK-LABEL: define internal i8* @"\01-[TestSelf instanceMeth]"(
171 - (id)instanceMeth {
172   // MSGS: {{call.*@objc_msgSend}}
173   // MSGS: {{call.*@objc_msgSend}}
174   // CALLS: {{call.*@objc_msgSend}}
175   // CALLS: {{call.*@objc_msgSend}}
176   [self allocWithZone:nil];
177   return [self alloc];
179 @end
181 @interface NSString : NSObject
182 + (void)retain_self;
183 - (void)retain_super;
184 @end
186 @implementation NSString
188 // Make sure we can convert a message to a dynamic receiver to a call
189 // CHECK-LABEL: define {{.*}}void @retain_self
190 + (void)retain_self {
191   // MSGS: {{call.*@objc_msgSend}}
192   // CALLS: {{call.*@objc_retain}}
193   [self retain];
196 // Make sure we never convert a message to super to a call
197 // CHECK-LABEL: define {{.*}}void @retain_super
198 - (void)retain_super {
199   // MSGS: {{call.*@objc_msgSend}}
200   // CALLS: {{call.*@objc_msgSend}}
201   [super retain];
204 @end
206 @class Ety;
208 // CHECK-LABEL: define {{.*}}void @testException_release
209 void testException_release(NSObject *a) {
210   // MSGS: {{invoke.*@objc_msgSend}}
211   // CALLS: invoke{{.*}}void @objc_release(i8* %
212   @try {
213     [a release];
214   } @catch (Ety *e) {
215   }
218 // CHECK-LABEL: define {{.*}}void @testException_autorelease
219 void testException_autorelease(NSObject *a) {
220   @try {
221     // MSGS: {{invoke.*@objc_msgSend}}
222     // CALLS: invoke{{.*}}objc_autorelease(i8* %
223     [a autorelease];
224   } @catch (Ety *e) {
225   }
228 // CHECK-LABEL: define {{.*}}void @testException_retain
229 void testException_retain(NSObject *a) {
230   @try {
231     // MSGS: {{invoke.*@objc_msgSend}}
232     // CALLS: invoke{{.*}}@objc_retain(i8* %
233     [a retain];
234   } @catch (Ety *e) {
235   }
239 // CHECK-LABEL: define {{.*}}void @testException_alloc(
240 void testException_alloc(void) {
241   @try {
242     // MSGS: {{invoke.*@objc_msgSend}}
243     // CALLS: invoke{{.*}}@objc_alloc(i8* %
244     [A alloc];
245   } @catch (Ety *e) {
246   }
249 // CHECK-LABEL: define {{.*}}void @testException_allocWithZone
250 void testException_allocWithZone(void) {
251   @try {
252     // MSGS: {{invoke.*@objc_msgSend}}
253     // CALLS: invoke{{.*}}@objc_allocWithZone(i8* %
254     [A allocWithZone:nil];
255   } @catch (Ety *e) {
256   }