llvm-project
186 строк · 6.2 Кб
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
3
4@interface Object
5- (instancetype) retain;
6- (void) run;
7@end
8
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];
13}
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;
25}
26@end
27@implementation HighlyAlignedSubclass @end
28
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
35
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;
44}
45@end
46
47@implementation Foo
48// CHECK-LABEL: define internal void @"\01-[Foo .cxx_destruct]"
49// CHECK: call void @llvm.objc.destroyWeak
50@end
51
52
53void test1(__weak id x) {}
54// CHECK-LABEL: define{{.*}} void @test1
55// CHECK: [[X:%.*]] = alloca ptr,
56// CHECK-NEXT: @llvm.objc.initWeak
57// CHECK-NEXT: @llvm.objc.destroyWeak
58// CHECK-NEXT: ret void
59
60void test2(id y) {
61__weak id z = y;
62}
63// CHECK-LABEL: define{{.*}} void @test2
64// CHECK: [[Y:%.*]] = alloca ptr,
65// CHECK-NEXT: [[Z:%.*]] = alloca ptr,
66// CHECK-NEXT: store
67// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[Y]]
68// CHECK-NEXT: call ptr @llvm.objc.initWeak(ptr [[Z]], ptr [[T0]])
69// CHECK-NEXT: call void @llvm.objc.destroyWeak(ptr [[Z]])
70// CHECK-NEXT: ret void
71
72void test3(id y) {
73__weak id z;
74z = y;
75}
76// CHECK-LABEL: define{{.*}} void @test3
77// CHECK: [[Y:%.*]] = alloca ptr,
78// CHECK-NEXT: [[Z:%.*]] = alloca ptr,
79// CHECK-NEXT: store
80// CHECK-NEXT: store ptr null, ptr [[Z]]
81// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[Y]]
82// CHECK-NEXT: call ptr @llvm.objc.storeWeak(ptr [[Z]], ptr [[T0]])
83// CHECK-NEXT: call void @llvm.objc.destroyWeak(ptr [[Z]])
84// CHECK-NEXT: ret void
85
86void test4(__weak id *p) {
87id y = *p;
88}
89// CHECK-LABEL: define{{.*}} void @test4
90// CHECK: [[P:%.*]] = alloca ptr,
91// CHECK-NEXT: [[Y:%.*]] = alloca ptr,
92// CHECK-NEXT: store
93// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[P]]
94// CHECK-NEXT: [[T1:%.*]] = call ptr @llvm.objc.loadWeak(ptr [[T0]])
95// CHECK-NEXT: store ptr [[T1]], ptr [[Y]]
96// CHECK-NEXT: ret void
97
98void test5(__weak id *p) {
99id y = [*p retain];
100}
101// CHECK-LABEL: define{{.*}} void @test5
102// CHECK: [[P:%.*]] = alloca ptr,
103// CHECK-NEXT: [[Y:%.*]] = alloca ptr,
104// CHECK-NEXT: store
105// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[P]]
106// CHECK-NEXT: [[T1:%.*]] = call ptr @llvm.objc.loadWeakRetained(ptr [[T0]])
107// CHECK-NEXT: store ptr [[T1]], ptr [[Y]]
108// CHECK-NEXT: ret void
109
110void test6(__weak Foo **p) {
111Foo *y = [*p retain];
112}
113// CHECK-LABEL: define{{.*}} void @test6
114// CHECK: [[P:%.*]] = alloca ptr,
115// CHECK-NEXT: [[Y:%.*]] = alloca ptr,
116// CHECK-NEXT: store
117// CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[P]]
118// CHECK-NEXT: [[T2:%.*]] = call ptr @llvm.objc.loadWeakRetained(ptr [[T0]])
119// CHECK-NEXT: store ptr [[T2]], ptr [[Y]]
120// CHECK-NEXT: ret void
121
122extern id get_object(void);
123extern void use_block(void (^)(void));
124
125void test7(void) {
126__weak Foo *p = get_object();
127use_block(^{ [p run ]; });
128}
129// CHECK-LABEL: define{{.*}} void @test7
130// CHECK: [[P:%.*]] = alloca ptr,
131// CHECK: [[T0:%.*]] = call ptr @get_object()
132// CHECK-NEXT: call ptr @llvm.objc.initWeak(ptr [[P]], ptr [[T0]])
133// CHECK: call void @llvm.objc.copyWeak
134// CHECK: call void @use_block
135// CHECK: call void @llvm.objc.destroyWeak
136
137// CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block
138// CHECK: @llvm.objc.copyWeak
139
140// CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block
141// CHECK: @llvm.objc.destroyWeak
142
143void test8(void) {
144__block __weak Foo *p = get_object();
145use_block(^{ [p run ]; });
146}
147// CHECK-LABEL: define{{.*}} void @test8
148// CHECK: call ptr @llvm.objc.initWeak
149// CHECK-NOT: call void @llvm.objc.copyWeak
150// CHECK: call void @use_block
151// CHECK: call void @llvm.objc.destroyWeak
152
153// CHECK-LABEL: define internal void @__Block_byref_object_copy
154// CHECK: call void @llvm.objc.moveWeak
155
156// CHECK-LABEL: define internal void @__Block_byref_object_dispose
157// CHECK: call void @llvm.objc.destroyWeak
158
159// CHECK-LABEL: define{{.*}} void @test9_baseline()
160// CHECK: define linkonce_odr hidden void @__copy_helper
161// CHECK: define linkonce_odr hidden void @__destroy_helper
162void test9_baseline(void) {
163Foo *p = get_object();
164use_block(^{ [p run]; });
165}
166
167// CHECK-LABEL: define{{.*}} void @test9()
168// CHECK-NOT: define linkonce_odr hidden void @__copy_helper
169// CHECK-NOT: define linkonce_odr hidden void @__destroy_helper
170// CHECK: define{{.*}} void @test9_fin()
171void test9(void) {
172__unsafe_unretained Foo *p = get_object();
173use_block(^{ [p run]; });
174}
175void test9_fin(void) {}
176
177// CHECK-LABEL: define{{.*}} void @test10()
178// CHECK-NOT: define linkonce_odr hidden void @__copy_helper
179// CHECK-NOT: define linkonce_odr hidden void @__destroy_helper
180// CHECK: define{{.*}} void @test10_fin()
181void test10(void) {
182typedef __unsafe_unretained Foo *UnsafeFooPtr;
183UnsafeFooPtr p = get_object();
184use_block(^{ [p run]; });
185}
186void test10_fin(void) {}
187