[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / CodeGenObjCXX / mrc-weak.mm
blob9e22885541c64157983fadde143f87ff63b2c42c
1 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-10.10 -emit-llvm -fblocks -fobjc-weak -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-MODERN
2 // RUN: %clang_cc1 -triple i386-apple-darwin10 -fobjc-runtime=macosx-fragile-10.10 -emit-llvm -fblocks -fobjc-weak -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-FRAGILE
4 @interface Object
5 - (instancetype) retain;
6 - (void) run;
7 @end
9 // CHECK-MODERN: @OBJC_CLASS_NAME_{{.*}} = {{.*}} c"\01\00"
10 // CHECK-MODERN: @"_OBJC_CLASS_RO_$_Foo" = {{.*}} { i32 772
11 //   772 == 0x304
12 //            ^ HasMRCWeakIvars
13 //            ^ HasCXXDestructorOnly
14 //              ^ HasCXXStructors
16 // CHECK-FRAGILE: @OBJC_CLASS_NAME_{{.*}} = {{.*}} c"\01\00"
17 // CHECK-FRAGILE: @OBJC_CLASS_Foo = {{.*}} i32 134225921,
18 //   134225921 == 0x08002001
19 //                   ^ HasMRCWeakIvars
20 //                      ^ HasCXXStructors
21 //                         ^ Factory
22 @interface Foo : Object {
23   __weak id ivar;
25 @end
27 @implementation Foo
28 // CHECK-LABEL: define internal void @"\01-[Foo .cxx_destruct]"
29 // CHECK: call void @llvm.objc.destroyWeak
30 @end
33 void test1(__weak id x) {}
34 // CHECK-LABEL: define{{.*}} void @_Z5test1P11objc_object(
35 // CHECK:      [[X:%.*]] = alloca ptr,
36 // CHECK-NEXT: llvm.objc.initWeak
37 // CHECK-NEXT: llvm.objc.destroyWeak
38 // CHECK-NEXT: ret void
40 void test2(id y) {
41   __weak id z = y;
43 // CHECK-LABEL: define{{.*}} void @_Z5test2P11objc_object(
44 // CHECK:      [[Y:%.*]] = alloca ptr,
45 // CHECK-NEXT: [[Z:%.*]] = alloca ptr,
46 // CHECK-NEXT: store
47 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[Y]]
48 // CHECK-NEXT: call ptr @llvm.objc.initWeak(ptr [[Z]], ptr [[T0]])
49 // CHECK-NEXT: call void @llvm.objc.destroyWeak(ptr [[Z]])
50 // CHECK-NEXT: ret void
52 void test3(id y) {
53   __weak id z;
54   z = y;
56 // CHECK-LABEL: define{{.*}} void @_Z5test3P11objc_object(
57 // CHECK:      [[Y:%.*]] = alloca ptr,
58 // CHECK-NEXT: [[Z:%.*]] = alloca ptr,
59 // CHECK-NEXT: store
60 // CHECK-NEXT: store ptr null, ptr [[Z]]
61 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[Y]]
62 // CHECK-NEXT: call ptr @llvm.objc.storeWeak(ptr [[Z]], ptr [[T0]])
63 // CHECK-NEXT: call void @llvm.objc.destroyWeak(ptr [[Z]])
64 // CHECK-NEXT: ret void
66 void test4(__weak id *p) {
67   id y = *p;
69 // CHECK-LABEL: define{{.*}} void @_Z5test4PU6__weakP11objc_object(
70 // CHECK:      [[P:%.*]] = alloca ptr,
71 // CHECK-NEXT: [[Y:%.*]] = alloca ptr,
72 // CHECK-NEXT: store
73 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[P]]
74 // CHECK-NEXT: [[T1:%.*]] = call ptr @llvm.objc.loadWeak(ptr [[T0]])
75 // CHECK-NEXT: store ptr [[T1]], ptr [[Y]]
76 // CHECK-NEXT: ret void
78 void test5(__weak id *p) {
79   id y = [*p retain];
81 // CHECK-LABEL: define{{.*}} void @_Z5test5PU6__weakP11objc_object
82 // CHECK:      [[P:%.*]] = alloca ptr,
83 // CHECK-NEXT: [[Y:%.*]] = alloca ptr,
84 // CHECK-NEXT: store
85 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[P]]
86 // CHECK-NEXT: [[T1:%.*]] = call ptr @llvm.objc.loadWeakRetained(ptr [[T0]])
87 // CHECK-NEXT: store ptr [[T1]], ptr [[Y]]
88 // CHECK-NEXT: ret void
90 void test6(__weak Foo **p) {
91   Foo *y = [*p retain];
93 // CHECK-LABEL: define{{.*}} void @_Z5test6PU6__weakP3Foo
94 // CHECK:      [[P:%.*]] = alloca ptr,
95 // CHECK-NEXT: [[Y:%.*]] = alloca ptr,
96 // CHECK-NEXT: store
97 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[P]]
98 // CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.loadWeakRetained(ptr [[T0]])
99 // CHECK-NEXT: store ptr [[T2]], ptr [[Y]]
100 // CHECK-NEXT: ret void
102 extern "C" id get_object(void);
103 extern "C" void use_block(void (^)(void));
105 void test7(void) {
106   __weak Foo *p = get_object();
107   use_block(^{ [p run ]; });
109 // CHECK-LABEL: define{{.*}} void @_Z5test7v
110 // CHECK:       [[P:%.*]] = alloca ptr,
111 // CHECK:       [[T0:%.*]] = call ptr @get_object()
112 // CHECK-NEXT:  call ptr @llvm.objc.initWeak(ptr [[P]], ptr [[T0]])
113 // CHECK:       call void @llvm.objc.copyWeak
114 // CHECK:       call void @use_block
115 // CHECK:       call void @llvm.objc.destroyWeak
117 // CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block
118 // CHECK:       @llvm.objc.copyWeak
120 // CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block
121 // CHECK:       @llvm.objc.destroyWeak
123 void test8(void) {
124   __block __weak Foo *p = get_object();
125   use_block(^{ [p run ]; });
127 // CHECK-LABEL: define{{.*}} void @_Z5test8v
128 // CHECK:       call ptr @llvm.objc.initWeak
129 // CHECK-NOT:   call void @llvm.objc.copyWeak
130 // CHECK:       call void @use_block
131 // CHECK:       call void @llvm.objc.destroyWeak
133 // CHECK-LABEL: define internal void @__Block_byref_object_copy
134 // CHECK:       call void @llvm.objc.moveWeak
136 // CHECK-LABEL: define internal void @__Block_byref_object_dispose
137 // CHECK:       call void @llvm.objc.destroyWeak
139 // CHECK-LABEL: define{{.*}} void @_Z14test9_baselinev()
140 // CHECK:       define linkonce_odr hidden void @__copy_helper
141 // CHECK:       define linkonce_odr hidden void @__destroy_helper
142 void test9_baseline(void) {
143   Foo *p = get_object();
144   use_block(^{ [p run]; });
147 // CHECK-LABEL: define{{.*}} void @_Z5test9v()
148 // CHECK-NOT:   define internal void @__copy_helper
149 // CHECK-NOT:   define internal void @__destroy_helper
150 // CHECK:       define{{.*}} void @_Z9test9_finv()
151 void test9(void) {
152   __unsafe_unretained Foo *p = get_object();
153   use_block(^{ [p run]; });
155 void test9_fin() {}
157 // CHECK-LABEL: define{{.*}} void @_Z6test10v()
158 // CHECK-NOT:   define internal void @__copy_helper
159 // CHECK-NOT:   define internal void @__destroy_helper
160 // CHECK:       define{{.*}} void @_Z10test10_finv()
161 void test10(void) {
162   typedef __unsafe_unretained Foo *UnsafeFooPtr;
163   UnsafeFooPtr p = get_object();
164   use_block(^{ [p run]; });
166 void test10_fin() {}
168 // CHECK-LABEL: define weak_odr void @_Z6test11ILj0EEvv()
169 // CHECK-NOT:   define internal void @__copy_helper
170 // CHECK-NOT:   define internal void @__destroy_helper
171 // CHECK:       define{{.*}} void @_Z10test11_finv()
172 template <unsigned i> void test11(void) {
173   typedef __unsafe_unretained Foo *UnsafeFooPtr;
174   UnsafeFooPtr p = get_object();
175   use_block(^{ [p run]; });
177 template void test11<0>();
178 void test11_fin() {}