1 // RUN: %clang_cc1 -std=c++11 -fobjc-arc -fblocks -triple x86_64-apple-darwin10.0.0 -fobjc-runtime-has-weak -emit-llvm -o - %s | FileCheck %s
7 struct ObjCArrayMember {
11 struct ObjCBlockMember {
15 // CHECK: %[[STRUCT_CONTAINSWEAK:.*]] = type { %[[STRUCT_WEAK:.*]] }
16 // CHECK: %[[STRUCT_WEAK]] = type { ptr }
18 // The Weak object that is passed is destructed in this constructor.
20 // CHECK: define{{.*}} void @_ZN12ContainsWeakC2E4Weak(
21 // CHECK: call void @_ZN4WeakC1ERKS_(
22 // CHECK: call void @_ZN4WeakD1Ev(
24 // Check that the Weak object passed to this constructor is not destructed after
25 // the delegate constructor is called.
27 // CHECK: define{{.*}} void @_ZN12ContainsWeakC1E4Weak(
28 // CHECK: call void @_ZN12ContainsWeakC2E4Weak(
29 // CHECK-NEXT: ret void
41 ContainsWeak::ContainsWeak(Weak a) : w(a) {}
43 // The Weak object that is passed is destructed in this constructor.
45 // CHECK: define{{.*}} void @_ZN4BaseC2E4Weak(
46 // CHECK: call void @_ZN4WeakD1Ev(
49 // Check that the Weak object passed to this constructor is not destructed after
50 // the delegate constructor is called.
52 // CHECK: define linkonce_odr void @_ZN7DerivedCI14BaseE4Weak(
53 // CHECK: call void @_ZN7DerivedCI24BaseE4Weak(
54 // CHECK-NEXT: ret void
62 struct Derived : Base {
68 // CHECK-LABEL: define{{.*}} void @_Z42test_ObjCMember_default_construct_destructv(
69 void test_ObjCMember_default_construct_destruct() {
70 // CHECK: call void @_ZN10ObjCMemberC1Ev
71 // CHECK: call void @_ZN10ObjCMemberD1Ev
75 // CHECK-LABEL: define{{.*}} void @_Z39test_ObjCMember_copy_construct_destruct10ObjCMember
76 void test_ObjCMember_copy_construct_destruct(ObjCMember m1) {
77 // CHECK: call void @_ZN10ObjCMemberC1ERKS_
78 // CHECK: call void @_ZN10ObjCMemberD1Ev
83 // CHECK-LABEL: define{{.*}} void @_Z27test_ObjCMember_copy_assign10ObjCMemberS_
84 void test_ObjCMember_copy_assign(ObjCMember m1, ObjCMember m2) {
85 // CHECK: {{call.*_ZN10ObjCMemberaSERKS_}}
87 // CHECK-NEXT: call void @_ZN10ObjCMemberD1Ev(
88 // CHECK-NEXT: call void @_ZN10ObjCMemberD1Ev(
89 // CHECK-NEXT: ret void
92 // Implicitly-generated copy assignment operator for ObjCMember
93 // CHECK: {{define linkonce_odr.*@_ZN10ObjCMemberaSERKS_}}
94 // CHECK: call void @llvm.objc.storeStrong
97 // CHECK-LABEL: define{{.*}} void @_Z47test_ObjCArrayMember_default_construct_destructv
98 void test_ObjCArrayMember_default_construct_destruct() {
99 // CHECK: call void @_ZN15ObjCArrayMemberC1Ev
101 // CHECK: call void @_ZN15ObjCArrayMemberD1Ev
105 // CHECK-LABEL: define{{.*}} void @_Z44test_ObjCArrayMember_copy_construct_destruct15ObjCArrayMember
106 void test_ObjCArrayMember_copy_construct_destruct(ObjCArrayMember m1) {
107 // CHECK: call void @_ZN15ObjCArrayMemberC1ERKS_
108 ObjCArrayMember m2 = m1;
109 // CHECK: call void @_ZN15ObjCArrayMemberD1Ev
113 void test_ObjCArrayMember_copy_assign(ObjCArrayMember m1, ObjCArrayMember m2) {
114 // CHECK: {{call.*@_ZN15ObjCArrayMemberaSERKS_}}
116 // CHECK-NEXT: call void @_ZN15ObjCArrayMemberD1Ev(
117 // CHECK-NEXT: call void @_ZN15ObjCArrayMemberD1Ev(
118 // CHECK-NEXT: ret void
121 // Implicitly-generated copy assignment operator for ObjCArrayMember
122 // CHECK: {{define linkonce_odr.*@_ZN15ObjCArrayMemberaSERKS_}}
123 // CHECK: call void @llvm.objc.storeStrong
124 // CHECK-NEXT: br label
127 // CHECK-LABEL: define{{.*}} void @_Z47test_ObjCBlockMember_default_construct_destructv
128 void test_ObjCBlockMember_default_construct_destruct() {
129 // CHECK: call void @_ZN15ObjCBlockMemberC1Ev
131 // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev
132 // CHECK-NEXT: ret void
135 // CHECK-LABEL: define{{.*}} void @_Z44test_ObjCBlockMember_copy_construct_destruct15ObjCBlockMember
136 void test_ObjCBlockMember_copy_construct_destruct(ObjCBlockMember m1) {
137 // CHECK: call void @_ZN15ObjCBlockMemberC1ERKS_
138 ObjCBlockMember m2 = m1;
139 // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev(
140 // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev(
141 // CHECK-NEXT: ret void
144 // CHECK-LABEL: define{{.*}} void @_Z32test_ObjCBlockMember_copy_assign15ObjCBlockMemberS_
145 void test_ObjCBlockMember_copy_assign(ObjCBlockMember m1, ObjCBlockMember m2) {
146 // CHECK: {{call.*_ZN15ObjCBlockMemberaSERKS_}}
148 // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev(
149 // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev(
150 // CHECK-NEXT: ret void
153 // Implicitly-generated copy assignment operator for ObjCBlockMember
154 // CHECK: define linkonce_odr noundef nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @_ZN15ObjCBlockMemberaSERKS_(
155 // CHECK: [[T0:%.*]] = getelementptr inbounds [[T:%.*]], ptr {{%.*}}, i32 0, i32 0
156 // CHECK-NEXT: [[T1:%.*]] = load ptr, ptr [[T0]], align 8
157 // CHECK-NEXT: [[T3:%.*]] = call ptr @llvm.objc.retainBlock(ptr [[T1]])
158 // CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds [[T]], ptr {{%.*}}, i32 0, i32 0
159 // CHECK-NEXT: [[T6:%.*]] = load ptr, ptr [[T5]], align 8
160 // CHECK-NEXT: store ptr [[T3]], ptr [[T5]]
161 // CHECK-NEXT: call void @llvm.objc.release(ptr [[T6]])
164 // Check that the Weak object passed to this constructor is not destructed after
165 // the delegate constructor is called.
167 // CHECK: define linkonce_odr void @_ZN7DerivedCI24BaseE4Weak(
168 // CHECK: call void @_ZN4BaseC2E4Weak(
169 // CHECK-NEXT: ret void
171 // Implicitly-generated default constructor for ObjCMember
172 // CHECK-LABEL: define linkonce_odr void @_ZN10ObjCMemberC2Ev
173 // CHECK-NOT: objc_release
174 // CHECK: store ptr null
175 // CHECK-NEXT: ret void
177 // Implicitly-generated destructor for ObjCMember
178 // CHECK-LABEL: define linkonce_odr void @_ZN10ObjCMemberD2Ev
179 // CHECK: call void @llvm.objc.storeStrong
182 // Implicitly-generated copy constructor for ObjCMember
183 // CHECK-LABEL: define linkonce_odr void @_ZN10ObjCMemberC2ERKS_
184 // CHECK-NOT: objc_release
185 // CHECK: call ptr @llvm.objc.retain
186 // CHECK-NEXT: store ptr
187 // CHECK-NEXT: ret void
189 // Implicitly-generated default constructor for ObjCArrayMember
190 // CHECK-LABEL: define linkonce_odr void @_ZN15ObjCArrayMemberC2Ev
191 // CHECK: call void @llvm.memset.p0.i64
194 // Implicitly-generated destructor for ObjCArrayMember
195 // CHECK-LABEL: define linkonce_odr void @_ZN15ObjCArrayMemberD2Ev
196 // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [2 x [3 x ptr]], ptr
197 // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds ptr, ptr [[BEGIN]], i64 6
198 // CHECK-NEXT: br label
199 // CHECK: [[PAST:%.*]] = phi ptr [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
200 // CHECK-NEXT: [[CUR]] = getelementptr inbounds ptr, ptr [[PAST]], i64 -1
201 // CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[CUR]], ptr null)
202 // CHECK-NEXT: [[T1:%.*]] = icmp eq ptr [[CUR]], [[BEGIN]]
203 // CHECK-NEXT: br i1 [[T1]],
206 // Implicitly-generated copy constructor for ObjCArrayMember
207 // CHECK-LABEL: define linkonce_odr void @_ZN15ObjCArrayMemberC2ERKS_
208 // CHECK: call ptr @llvm.objc.retain
209 // CHECK-NEXT: store ptr
213 // Implicitly-generated default constructor for ObjCBlockMember
214 // CHECK-LABEL: define linkonce_odr void @_ZN15ObjCBlockMemberC2Ev
215 // CHECK: store {{.*}} null,
216 // CHECK-NEXT: ret void
218 // Implicitly-generated destructor for ObjCBlockMember
219 // CHECK-LABEL: define linkonce_odr void @_ZN15ObjCBlockMemberD2Ev
220 // CHECK: call void @llvm.objc.storeStrong(ptr
223 // Implicitly-generated copy constructor for ObjCBlockMember
224 // CHECK-LABEL: define linkonce_odr void @_ZN15ObjCBlockMemberC2ERKS_
225 // CHECK: call ptr @llvm.objc.retainBlock