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
5 - (instancetype) retain;
9 // CHECK-MODERN: @OBJC_CLASS_NAME_{{.*}} = {{.*}} c"\01\00"
10 // CHECK-MODERN: @"_OBJC_CLASS_RO_$_Foo" = {{.*}} { i32 772
13 // ^ HasCXXDestructorOnly
16 // CHECK-FRAGILE: @OBJC_CLASS_NAME_{{.*}} = {{.*}} c"\01\00"
17 // CHECK-FRAGILE: @OBJC_CLASS_Foo = {{.*}} i32 134225921,
18 // 134225921 == 0x08002001
22 @interface Foo : Object {
28 // CHECK-LABEL: define internal void @"\01-[Foo .cxx_destruct]"
29 // CHECK: call void @llvm.objc.destroyWeak
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
43 // CHECK-LABEL: define{{.*}} void @_Z5test2P11objc_object(
44 // CHECK: [[Y:%.*]] = alloca ptr,
45 // CHECK-NEXT: [[Z:%.*]] = alloca ptr,
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
56 // CHECK-LABEL: define{{.*}} void @_Z5test3P11objc_object(
57 // CHECK: [[Y:%.*]] = alloca ptr,
58 // CHECK-NEXT: [[Z:%.*]] = alloca ptr,
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) {
69 // CHECK-LABEL: define{{.*}} void @_Z5test4PU6__weakP11objc_object(
70 // CHECK: [[P:%.*]] = alloca ptr,
71 // CHECK-NEXT: [[Y:%.*]] = alloca ptr,
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) {
81 // CHECK-LABEL: define{{.*}} void @_Z5test5PU6__weakP11objc_object
82 // CHECK: [[P:%.*]] = alloca ptr,
83 // CHECK-NEXT: [[Y:%.*]] = alloca ptr,
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) {
93 // CHECK-LABEL: define{{.*}} void @_Z5test6PU6__weakP3Foo
94 // CHECK: [[P:%.*]] = alloca ptr,
95 // CHECK-NEXT: [[Y:%.*]] = alloca ptr,
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));
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
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()
152 __unsafe_unretained Foo *p = get_object();
153 use_block(^{ [p run]; });
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()
162 typedef __unsafe_unretained Foo *UnsafeFooPtr;
163 UnsafeFooPtr p = get_object();
164 use_block(^{ [p run]; });
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>();