1 | // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -std=c++03 -fexceptions -fcxx-exceptions -o - %s | FileCheck %s |
2 | // RUN: %clang_cc1 -triple i386-apple-darwin10 -emit-llvm -std=c++03 -o - %s | FileCheck --check-prefix=CHECK-2 %s |
3 | |
4 | struct POD { |
5 | int w, x, y, z; |
6 | }; |
7 | |
8 | struct PODLike { |
9 | int w, x, y, z; |
10 | PODLike(); |
11 | ~PODLike(); |
12 | }; |
13 | |
14 | struct NonPOD { |
15 | NonPOD(); |
16 | NonPOD(const NonPOD&); |
17 | NonPOD& operator=(const NonPOD&); |
18 | }; |
19 | |
20 | struct Basic { |
21 | int a, b, c, d; |
22 | NonPOD np; |
23 | int w, x, y, z; |
24 | }; |
25 | |
26 | struct PODMember { |
27 | int a, b, c, d; |
28 | POD p; |
29 | NonPOD np; |
30 | int w, x, y, z; |
31 | }; |
32 | |
33 | struct PODLikeMember { |
34 | int a, b, c, d; |
35 | PODLike pl; |
36 | NonPOD np; |
37 | int w, x, y, z; |
38 | }; |
39 | |
40 | struct ArrayMember { |
41 | int a, b, c, d; |
42 | int e[12]; |
43 | NonPOD np; |
44 | int f[12]; |
45 | int w, x, y, z; |
46 | }; |
47 | |
48 | struct VolatileMember { |
49 | int a, b, c, d; |
50 | volatile int v; |
51 | NonPOD np; |
52 | int w, x, y, z; |
53 | }; |
54 | |
55 | struct BitfieldMember { |
56 | int a, b, c, d; |
57 | NonPOD np; |
58 | int w : 6; |
59 | int x : 6; |
60 | int y : 6; |
61 | int z : 6; |
62 | }; |
63 | |
64 | struct BitfieldMember2 { |
65 | unsigned a : 1; |
66 | unsigned b, c, d; |
67 | NonPOD np; |
68 | }; |
69 | |
70 | struct BitfieldMember3 { |
71 | virtual void f(); |
72 | int : 8; |
73 | int x : 1; |
74 | int y; |
75 | }; |
76 | |
77 | struct InnerClassMember { |
78 | struct { |
79 | int a, b, c, d; |
80 | } a; |
81 | int b, c, d, e; |
82 | NonPOD np; |
83 | int w, x, y, z; |
84 | }; |
85 | |
86 | struct ReferenceMember { |
87 | ReferenceMember(int &a, int &b, int &c, int &d) |
88 | : a(a), b(b), c(c), d(d) {} |
89 | int &a; |
90 | int &b; |
91 | NonPOD np; |
92 | int &c; |
93 | int &d; |
94 | }; |
95 | |
96 | struct __attribute__((packed)) PackedMembers { |
97 | char c; |
98 | NonPOD np; |
99 | int w, x, y, z; |
100 | }; |
101 | |
102 | // COPY-ASSIGNMENT OPERATORS: |
103 | |
104 | // Assignment operators are output in the order they're encountered. |
105 | |
106 | #define CALL_AO(T) void callAO##T(T& a, const T& b) { a = b; } |
107 | |
108 | CALL_AO(Basic) |
109 | CALL_AO(PODMember) |
110 | CALL_AO(PODLikeMember) |
111 | CALL_AO(ArrayMember) |
112 | CALL_AO(VolatileMember) |
113 | CALL_AO(BitfieldMember) |
114 | CALL_AO(InnerClassMember) |
115 | CALL_AO(PackedMembers) |
116 | |
117 | // Basic copy-assignment: |
118 | // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.Basic* @_ZN5BasicaSERKS_(%struct.Basic* %this, %struct.Basic* dereferenceable({{[0-9]+}})) |
119 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}}) |
120 | // CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_ |
121 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}}) |
122 | // CHECK: ret %struct.Basic* |
123 | |
124 | // PODMember copy-assignment: |
125 | // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.PODMember* @_ZN9PODMemberaSERKS_(%struct.PODMember* %this, %struct.PODMember* dereferenceable({{[0-9]+}})) |
126 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 32, i1 {{.*}}) |
127 | // CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_ |
128 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}}) |
129 | // CHECK: ret %struct.PODMember* |
130 | |
131 | // PODLikeMember copy-assignment: |
132 | // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.PODLikeMember* @_ZN13PODLikeMemberaSERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember* dereferenceable({{[0-9]+}})) |
133 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 32, i1 {{.*}}) |
134 | // CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_ |
135 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}}) |
136 | // CHECK: ret %struct.PODLikeMember* |
137 | |
138 | // ArrayMember copy-assignment: |
139 | // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.ArrayMember* @_ZN11ArrayMemberaSERKS_(%struct.ArrayMember* %this, %struct.ArrayMember* dereferenceable({{[0-9]+}})) |
140 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 64, i1 {{.*}}) |
141 | // CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_ |
142 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 64, i1 {{.*}}) |
143 | // CHECK: ret %struct.ArrayMember* |
144 | |
145 | // VolatileMember copy-assignment: |
146 | // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.VolatileMember* @_ZN14VolatileMemberaSERKS_(%struct.VolatileMember* %this, %struct.VolatileMember* dereferenceable({{[0-9]+}})) |
147 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}}) |
148 | // CHECK: load volatile i32, i32* {{.*}}, align 4 |
149 | // CHECK: store volatile i32 {{.*}}, align 4 |
150 | // CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_ |
151 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}}) |
152 | // CHECK: ret %struct.VolatileMember* |
153 | |
154 | // BitfieldMember copy-assignment: |
155 | // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.BitfieldMember* @_ZN14BitfieldMemberaSERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember* dereferenceable({{[0-9]+}})) |
156 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}}) |
157 | // CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_ |
158 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 1 {{.*}} align 1 {{.*}}i64 3, i1 {{.*}}) |
159 | // CHECK: ret %struct.BitfieldMember* |
160 | |
161 | // InnerClass copy-assignment: |
162 | // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.InnerClassMember* @_ZN16InnerClassMemberaSERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember* dereferenceable({{[0-9]+}})) |
163 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 32, i1 {{.*}}) |
164 | // CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_ |
165 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}}) |
166 | // CHECK: ret %struct.InnerClassMember* |
167 | |
168 | // PackedMembers copy-assignment: |
169 | // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.PackedMembers* @_ZN13PackedMembersaSERKS_(%struct.PackedMembers* %this, %struct.PackedMembers* dereferenceable({{[0-9]+}})) |
170 | // CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_ |
171 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 1 {{.*}} align 1 {{.*}}i64 16, i1 {{.*}}) |
172 | // CHECK: ret %struct.PackedMembers* |
173 | |
174 | // COPY-CONSTRUCTORS: |
175 | |
176 | // Clang outputs copy-constructors in the reverse of the order that |
177 | // copy-constructor calls are encountered. Add functions that call the copy |
178 | // constructors of the classes above in reverse order here. |
179 | |
180 | #define CALL_CC(T) T callCC##T(const T& b) { return b; } |
181 | |
182 | CALL_CC(PackedMembers) |
183 | // PackedMembers copy-assignment: |
184 | // CHECK-LABEL: define linkonce_odr void @_ZN13PackedMembersC2ERKS_(%struct.PackedMembers* %this, %struct.PackedMembers* dereferenceable({{[0-9]+}})) |
185 | // CHECK: call void @_ZN6NonPODC1ERKS_ |
186 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 1 {{.*}} align 1 {{.*}}i64 16, i1 {{.*}}) |
187 | // CHECK: ret void |
188 | |
189 | CALL_CC(BitfieldMember2) |
190 | // BitfieldMember2 copy-constructor: |
191 | // CHECK-2-LABEL: define linkonce_odr void @_ZN15BitfieldMember2C2ERKS_(%struct.BitfieldMember2* %this, %struct.BitfieldMember2* dereferenceable({{[0-9]+}})) |
192 | // CHECK-2: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 false) |
193 | // CHECK-2: call void @_ZN6NonPODC1ERKS_ |
194 | // CHECK-2: ret void |
195 | |
196 | CALL_CC(BitfieldMember3) |
197 | // BitfieldMember3 copy-constructor: |
198 | // CHECK-LABEL: define linkonce_odr void @_ZN15BitfieldMember3C2ERKS_(%struct.BitfieldMember3* %this, %struct.BitfieldMember3* dereferenceable({{[0-9]+}})) |
199 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 8, i1 false) |
200 | // CHECK: ret void |
201 | |
202 | CALL_CC(ReferenceMember) |
203 | // ReferenceMember copy-constructor: |
204 | // CHECK-LABEL: define linkonce_odr void @_ZN15ReferenceMemberC2ERKS_(%struct.ReferenceMember* %this, %struct.ReferenceMember* dereferenceable({{[0-9]+}})) |
205 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 16, i1 {{.*}}) |
206 | // CHECK: call void @_ZN6NonPODC1ERKS_ |
207 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 16, i1 {{.*}}) |
208 | // CHECK: ret void |
209 | |
210 | CALL_CC(InnerClassMember) |
211 | // InnerClass copy-constructor: |
212 | // CHECK-LABEL: define linkonce_odr void @_ZN16InnerClassMemberC2ERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember* dereferenceable({{[0-9]+}})) |
213 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 32, i1 {{.*}}) |
214 | // CHECK: call void @_ZN6NonPODC1ERKS_ |
215 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}}) |
216 | // CHECK: ret void |
217 | |
218 | CALL_CC(BitfieldMember) |
219 | // BitfieldMember copy-constructor: |
220 | // CHECK-LABEL: define linkonce_odr void @_ZN14BitfieldMemberC2ERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember* dereferenceable({{[0-9]+}})) |
221 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}}) |
222 | // CHECK: call void @_ZN6NonPODC1ERKS_ |
223 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 1 {{.*}} align 1 {{.*}}i64 3, i1 {{.*}}) |
224 | // CHECK: ret void |
225 | |
226 | CALL_CC(VolatileMember) |
227 | // VolatileMember copy-constructor: |
228 | // CHECK-LABEL: define linkonce_odr void @_ZN14VolatileMemberC2ERKS_(%struct.VolatileMember* %this, %struct.VolatileMember* dereferenceable({{[0-9]+}})) |
229 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}}) |
230 | // CHECK: load volatile i32, i32* {{.*}}, align 4 |
231 | // CHECK: store volatile i32 {{.*}}, align 4 |
232 | // CHECK: call void @_ZN6NonPODC1ERKS_ |
233 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}}) |
234 | // CHECK: ret void |
235 | |
236 | CALL_CC(ArrayMember) |
237 | // ArrayMember copy-constructor: |
238 | // CHECK-LABEL: define linkonce_odr void @_ZN11ArrayMemberC2ERKS_(%struct.ArrayMember* %this, %struct.ArrayMember* dereferenceable({{[0-9]+}})) |
239 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 64, i1 {{.*}}) |
240 | // CHECK: call void @_ZN6NonPODC1ERKS_ |
241 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 64, i1 {{.*}}) |
242 | // CHECK: ret void |
243 | |
244 | CALL_CC(PODLikeMember) |
245 | // PODLikeMember copy-constructor: |
246 | // CHECK-LABEL: define linkonce_odr void @_ZN13PODLikeMemberC2ERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember* dereferenceable({{[0-9]+}})) |
247 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 32, i1 {{.*}}) |
248 | // CHECK: invoke void @_ZN6NonPODC1ERKS_ |
249 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}}) |
250 | // CHECK: ret void |
251 | // CHECK: landingpad |
252 | // CHECK: invoke void @_ZN7PODLikeD1Ev |
253 | |
254 | CALL_CC(PODMember) |
255 | // PODMember copy-constructor: |
256 | // CHECK-LABEL: define linkonce_odr void @_ZN9PODMemberC2ERKS_(%struct.PODMember* %this, %struct.PODMember* dereferenceable({{[0-9]+}})) |
257 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 32, i1 {{.*}}) |
258 | // CHECK: call void @_ZN6NonPODC1ERKS_ |
259 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}}) |
260 | // CHECK: ret void |
261 | |
262 | CALL_CC(Basic) |
263 | // Basic copy-constructor: |
264 | // CHECK-LABEL: define linkonce_odr void @_ZN5BasicC2ERKS_(%struct.Basic* %this, %struct.Basic* dereferenceable({{[0-9]+}})) |
265 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}}) |
266 | // CHECK: call void @_ZN6NonPODC1ERKS_ |
267 | // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 4 {{.*}} align 4 {{.*}}i64 16, i1 {{.*}}) |
268 | // CHECK: ret void |
269 | |