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 // 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 ptr,
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 ptr,
65 // CHECK-NEXT: [[Z:%.*]] = alloca ptr,
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
76 // CHECK-LABEL: define{{.*}} void @test3
77 // CHECK: [[Y:%.*]] = alloca ptr,
78 // CHECK-NEXT: [[Z:%.*]] = alloca ptr,
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
86 void test4(__weak id *p) {
89 // CHECK-LABEL: define{{.*}} void @test4
90 // CHECK: [[P:%.*]] = alloca ptr,
91 // CHECK-NEXT: [[Y:%.*]] = alloca ptr,
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
98 void test5(__weak id *p) {
101 // CHECK-LABEL: define{{.*}} void @test5
102 // CHECK: [[P:%.*]] = alloca ptr,
103 // CHECK-NEXT: [[Y:%.*]] = alloca ptr,
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
110 void test6(__weak Foo **p) {
111 Foo *y = [*p retain];
113 // CHECK-LABEL: define{{.*}} void @test6
114 // CHECK: [[P:%.*]] = alloca ptr,
115 // CHECK-NEXT: [[Y:%.*]] = alloca ptr,
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
122 extern id get_object(void);
123 extern void use_block(void (^)(void));
126 __weak Foo *p = get_object();
127 use_block(^{ [p run ]; });
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
137 // CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block
138 // CHECK: @llvm.objc.copyWeak
140 // CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block
141 // CHECK: @llvm.objc.destroyWeak
144 __block __weak Foo *p = get_object();
145 use_block(^{ [p run ]; });
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
153 // CHECK-LABEL: define internal void @__Block_byref_object_copy
154 // CHECK: call void @llvm.objc.moveWeak
156 // CHECK-LABEL: define internal void @__Block_byref_object_dispose
157 // CHECK: call void @llvm.objc.destroyWeak
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
162 void test9_baseline(void) {
163 Foo *p = get_object();
164 use_block(^{ [p run]; });
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()
172 __unsafe_unretained Foo *p = get_object();
173 use_block(^{ [p run]; });
175 void test9_fin(void) {}
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()
182 typedef __unsafe_unretained Foo *UnsafeFooPtr;
183 UnsafeFooPtr p = get_object();
184 use_block(^{ [p run]; });
186 void test10_fin(void) {}