[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang / test / CodeGenObjC / mrc-weak.m
blob23079a52a97399d6113d1401511b3540138a7c5c
1 // RUN: %clang_cc1 -no-opaque-pointers -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 -no-opaque-pointers -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 // The ivars in HighlyAlignedSubclass should be placed in the tail-padding
10 // of the superclass.  Ensure that they're still covered by layouts.
11 @interface HighlyAligned : Object {
12   __attribute__((aligned(32))) void *array[2];
14 @end
15 // CHECK-MODERN: @"OBJC_IVAR_$_HighlyAlignedSubclass.ivar2" ={{.*}} global i64 24,
16 // CHECK-MODERN: @"OBJC_IVAR_$_HighlyAlignedSubclass.ivar" ={{.*}} global i64 16,
17 // CHECK-MODERN: @OBJC_CLASS_NAME_{{.*}} = {{.*}} c"\02\00"
18 // CHECK-MODERN: @"_OBJC_CLASS_RO_$_HighlyAlignedSubclass" = {{.*}} {
19 // CHECK-FRAGILE: @OBJC_INSTANCE_VARIABLES_HighlyAlignedSubclass = {{.*}}, i32 8 }, {{.*}}, i32 12 }]
20 // CHECK-FRAGILE: @OBJC_CLASS_NAME_{{.*}} = {{.*}} c"\02\00"
21 // CHECK-FRAGILE: @OBJC_CLASS_HighlyAlignedSubclass
22 @interface HighlyAlignedSubclass : HighlyAligned {
23   __weak id ivar;
24   __weak id ivar2;
26 @end
27 @implementation HighlyAlignedSubclass @end
29 // CHECK-MODERN: @OBJC_CLASS_NAME_{{.*}} = {{.*}} c"\01\00"
30 // CHECK-MODERN: @"_OBJC_CLASS_RO_$_Foo" = {{.*}} { i32 772
31 //   772 == 0x304
32 //            ^ HasMRCWeakIvars
33 //            ^ HasCXXDestructorOnly
34 //              ^ HasCXXStructors
36 // CHECK-FRAGILE: @OBJC_CLASS_NAME_{{.*}} = {{.*}} c"\01\00"
37 // CHECK-FRAGILE: @OBJC_CLASS_Foo = {{.*}} i32 134225921,
38 //   134225921 == 0x08002001
39 //                   ^ HasMRCWeakIvars
40 //                      ^ HasCXXStructors
41 //                         ^ Factory
42 @interface Foo : Object {
43   __weak id ivar;
45 @end
47 @implementation Foo
48 // CHECK-LABEL: define internal void @"\01-[Foo .cxx_destruct]"
49 // CHECK: call void @llvm.objc.destroyWeak
50 @end
53 void test1(__weak id x) {}
54 // CHECK-LABEL: define{{.*}} void @test1
55 // CHECK:      [[X:%.*]] = alloca i8*,
56 // CHECK-NEXT: @llvm.objc.initWeak
57 // CHECK-NEXT: @llvm.objc.destroyWeak
58 // CHECK-NEXT: ret void
60 void test2(id y) {
61   __weak id z = y;
63 // CHECK-LABEL: define{{.*}} void @test2
64 // CHECK:      [[Y:%.*]] = alloca i8*,
65 // CHECK-NEXT: [[Z:%.*]] = alloca i8*,
66 // CHECK-NEXT: store
67 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]]
68 // CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[Z]], i8* [[T0]])
69 // CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[Z]])
70 // CHECK-NEXT: ret void
72 void test3(id y) {
73   __weak id z;
74   z = y;
76 // CHECK-LABEL: define{{.*}} void @test3
77 // CHECK:      [[Y:%.*]] = alloca i8*,
78 // CHECK-NEXT: [[Z:%.*]] = alloca i8*,
79 // CHECK-NEXT: store
80 // CHECK-NEXT: store i8* null, i8** [[Z]]
81 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]]
82 // CHECK-NEXT: call i8* @llvm.objc.storeWeak(i8** [[Z]], i8* [[T0]])
83 // CHECK-NEXT: call void @llvm.objc.destroyWeak(i8** [[Z]])
84 // CHECK-NEXT: ret void
86 void test4(__weak id *p) {
87   id y = *p;
89 // CHECK-LABEL: define{{.*}} void @test4
90 // CHECK:      [[P:%.*]] = alloca i8**,
91 // CHECK-NEXT: [[Y:%.*]] = alloca i8*,
92 // CHECK-NEXT: store
93 // CHECK-NEXT: [[T0:%.*]] = load i8**, i8*** [[P]]
94 // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.loadWeak(i8** [[T0]])
95 // CHECK-NEXT: store i8* [[T1]], i8** [[Y]]
96 // CHECK-NEXT: ret void
98 void test5(__weak id *p) {
99   id y = [*p retain];
101 // CHECK-LABEL: define{{.*}} void @test5
102 // CHECK:      [[P:%.*]] = alloca i8**,
103 // CHECK-NEXT: [[Y:%.*]] = alloca i8*,
104 // CHECK-NEXT: store
105 // CHECK-NEXT: [[T0:%.*]] = load i8**, i8*** [[P]]
106 // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[T0]])
107 // CHECK-NEXT: store i8* [[T1]], i8** [[Y]]
108 // CHECK-NEXT: ret void
110 void test6(__weak Foo **p) {
111   Foo *y = [*p retain];
113 // CHECK-LABEL: define{{.*}} void @test6
114 // CHECK:      [[P:%.*]] = alloca [[FOO:%.*]]**,
115 // CHECK-NEXT: [[Y:%.*]] = alloca [[FOO]]*,
116 // CHECK-NEXT: store
117 // CHECK-NEXT: [[T0:%.*]] = load [[FOO]]**, [[FOO]]*** [[P]]
118 // CHECK-NEXT: [[T1:%.*]] = bitcast [[FOO]]** [[T0]] to i8**
119 // CHECK-NEXT: [[T2:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[T1]])
120 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[FOO]]*
121 // CHECK-NEXT: store [[FOO]]* [[T3]], [[FOO]]** [[Y]]
122 // CHECK-NEXT: ret void
124 extern id get_object(void);
125 extern void use_block(void (^)(void));
127 void test7(void) {
128   __weak Foo *p = get_object();
129   use_block(^{ [p run ]; });
131 // CHECK-LABEL: define{{.*}} void @test7
132 // CHECK:       [[P:%.*]] = alloca [[FOO]]*,
133 // CHECK:       [[T0:%.*]] = call i8* @get_object()
134 // CHECK-NEXT:  [[T1:%.*]] = bitcast i8* [[T0]] to [[FOO]]*
135 // CHECK-NEXT:  [[T2:%.*]] = bitcast [[FOO]]** [[P]] to i8**
136 // CHECK-NEXT:  [[T3:%.*]] = bitcast [[FOO]]* [[T1]] to i8*
137 // CHECK-NEXT:  call i8* @llvm.objc.initWeak(i8** [[T2]], i8* [[T3]])
138 // CHECK:       call void @llvm.objc.copyWeak
139 // CHECK:       call void @use_block
140 // CHECK:       call void @llvm.objc.destroyWeak
142 // CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block
143 // CHECK:       @llvm.objc.copyWeak
145 // CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block
146 // CHECK:       @llvm.objc.destroyWeak
148 void test8(void) {
149   __block __weak Foo *p = get_object();
150   use_block(^{ [p run ]; });
152 // CHECK-LABEL: define{{.*}} void @test8
153 // CHECK:       call i8* @llvm.objc.initWeak
154 // CHECK-NOT:   call void @llvm.objc.copyWeak
155 // CHECK:       call void @use_block
156 // CHECK:       call void @llvm.objc.destroyWeak
158 // CHECK-LABEL: define internal void @__Block_byref_object_copy
159 // CHECK:       call void @llvm.objc.moveWeak
161 // CHECK-LABEL: define internal void @__Block_byref_object_dispose
162 // CHECK:       call void @llvm.objc.destroyWeak
164 // CHECK-LABEL: define{{.*}} void @test9_baseline()
165 // CHECK:       define linkonce_odr hidden void @__copy_helper
166 // CHECK:       define linkonce_odr hidden void @__destroy_helper
167 void test9_baseline(void) {
168   Foo *p = get_object();
169   use_block(^{ [p run]; });
172 // CHECK-LABEL: define{{.*}} void @test9()
173 // CHECK-NOT:   define linkonce_odr hidden void @__copy_helper
174 // CHECK-NOT:   define linkonce_odr hidden void @__destroy_helper
175 // CHECK:       define{{.*}} void @test9_fin()
176 void test9(void) {
177   __unsafe_unretained Foo *p = get_object();
178   use_block(^{ [p run]; });
180 void test9_fin(void) {}
182 // CHECK-LABEL: define{{.*}} void @test10()
183 // CHECK-NOT:   define linkonce_odr hidden void @__copy_helper
184 // CHECK-NOT:   define linkonce_odr hidden void @__destroy_helper
185 // CHECK:       define{{.*}} void @test10_fin()
186 void test10(void) {
187   typedef __unsafe_unretained Foo *UnsafeFooPtr;
188   UnsafeFooPtr p = get_object();
189   use_block(^{ [p run]; });
191 void test10_fin(void) {}