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
5 - (instancetype) retain;
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];
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 {
27 @implementation HighlyAlignedSubclass @end
29 // CHECK-MODERN: @OBJC_CLASS_NAME_{{.*}} = {{.*}} c"\01\00"
30 // CHECK-MODERN: @"_OBJC_CLASS_RO_$_Foo" = {{.*}} { i32 772
33 // ^ HasCXXDestructorOnly
36 // CHECK-FRAGILE: @OBJC_CLASS_NAME_{{.*}} = {{.*}} c"\01\00"
37 // CHECK-FRAGILE: @OBJC_CLASS_Foo = {{.*}} i32 134225921,
38 // 134225921 == 0x08002001
42 @interface Foo : Object {
48 // CHECK-LABEL: define internal void @"\01-[Foo .cxx_destruct]"
49 // CHECK: call void @llvm.objc.destroyWeak
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
63 // CHECK-LABEL: define{{.*}} void @test2
64 // CHECK: [[Y:%.*]] = alloca i8*,
65 // CHECK-NEXT: [[Z:%.*]] = alloca i8*,
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
76 // CHECK-LABEL: define{{.*}} void @test3
77 // CHECK: [[Y:%.*]] = alloca i8*,
78 // CHECK-NEXT: [[Z:%.*]] = alloca i8*,
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) {
89 // CHECK-LABEL: define{{.*}} void @test4
90 // CHECK: [[P:%.*]] = alloca i8**,
91 // CHECK-NEXT: [[Y:%.*]] = alloca i8*,
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) {
101 // CHECK-LABEL: define{{.*}} void @test5
102 // CHECK: [[P:%.*]] = alloca i8**,
103 // CHECK-NEXT: [[Y:%.*]] = alloca i8*,
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]]*,
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));
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
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()
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()
187 typedef __unsafe_unretained Foo *UnsafeFooPtr;
188 UnsafeFooPtr p = get_object();
189 use_block(^{ [p run]; });
191 void test10_fin(void) {}