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 InnerClassMember {
71   struct {
72     int a, b, c, d;
73   } a;
74   int b, c, d, e;
75   NonPOD np;
76   int w, x, y, z;
77 };
78 
79 struct ReferenceMember {
80   ReferenceMember(int &a, int &b, int &c, int &d)
81     : a(a), b(b), c(c), d(d) {}
82   int &a;
83   int &b;
84   NonPOD np;
85   int &c;
86   int &d;
87 };
88 
89 struct __attribute__((packed)) PackedMembers {
90   char c;
91   NonPOD np;
92   int w, x, y, z;
93 };
94 
95 // COPY-ASSIGNMENT OPERATORS:
96 
97 // Assignment operators are output in the order they're encountered.
98 
99 #define CALL_AO(T) void callAO##T(T& a, const T& b) { a = b; }
100 
101 CALL_AO(Basic)
102 CALL_AO(PODMember)
103 CALL_AO(PODLikeMember)
104 CALL_AO(ArrayMember)
105 CALL_AO(VolatileMember)
106 CALL_AO(BitfieldMember)
107 CALL_AO(InnerClassMember)
108 CALL_AO(PackedMembers)
109 
110 // Basic copy-assignment:
111 // CHECK-LABEL: define linkonce_odr %struct.Basic* @_ZN5BasicaSERKS_(%struct.Basic* %this, %struct.Basic*)
112 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
113 // CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
114 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
115 // CHECK: ret %struct.Basic*
116 
117 // PODMember copy-assignment:
118 // CHECK-LABEL: define linkonce_odr %struct.PODMember* @_ZN9PODMemberaSERKS_(%struct.PODMember* %this, %struct.PODMember*)
119 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
120 // CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
121 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
122 // CHECK: ret %struct.PODMember*
123 
124 // PODLikeMember copy-assignment:
125 // CHECK-LABEL: define linkonce_odr %struct.PODLikeMember* @_ZN13PODLikeMemberaSERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember*)
126 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
127 // CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
128 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
129 // CHECK: ret %struct.PODLikeMember*
130 
131 // ArrayMember copy-assignment:
132 // CHECK-LABEL: define linkonce_odr %struct.ArrayMember* @_ZN11ArrayMemberaSERKS_(%struct.ArrayMember* %this, %struct.ArrayMember*)
133 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
134 // CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
135 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
136 // CHECK: ret %struct.ArrayMember*
137 
138 // VolatileMember copy-assignment:
139 // CHECK-LABEL: define linkonce_odr %struct.VolatileMember* @_ZN14VolatileMemberaSERKS_(%struct.VolatileMember* %this, %struct.VolatileMember*)
140 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
141 // CHECK: load volatile i32* {{.*}}, align 4
142 // CHECK: store volatile i32 {{.*}}, align 4
143 // CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
144 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
145 // CHECK: ret %struct.VolatileMember*
146 
147 // BitfieldMember copy-assignment:
148 // CHECK-LABEL: define linkonce_odr %struct.BitfieldMember* @_ZN14BitfieldMemberaSERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember*)
149 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
150 // CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
151 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 3, i32 1{{.*}})
152 // CHECK: ret %struct.BitfieldMember*
153 
154 // InnerClass copy-assignment:
155 // CHECK-LABEL: define linkonce_odr %struct.InnerClassMember* @_ZN16InnerClassMemberaSERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember*)
156 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
157 // CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
158 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
159 // CHECK: ret %struct.InnerClassMember*
160 
161 // PackedMembers copy-assignment:
162 // CHECK-LABEL: define linkonce_odr %struct.PackedMembers* @_ZN13PackedMembersaSERKS_(%struct.PackedMembers* %this, %struct.PackedMembers*)
163 // CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
164 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 1{{.*}})
165 // CHECK: ret %struct.PackedMembers*
166 
167 // COPY-CONSTRUCTORS:
168 
169 // Clang outputs copy-constructors in the reverse of the order that
170 // copy-constructor calls are encountered. Add functions that call the copy
171 // constructors of the classes above in reverse order here.
172 
173 #define CALL_CC(T) T callCC##T(const T& b) { return b; }
174 
175 CALL_CC(PackedMembers)
176 CALL_CC(BitfieldMember2)
177 CALL_CC(ReferenceMember)
178 CALL_CC(InnerClassMember)
179 CALL_CC(BitfieldMember)
180 CALL_CC(VolatileMember)
181 CALL_CC(ArrayMember)
182 CALL_CC(PODLikeMember)
183 CALL_CC(PODMember)
184 CALL_CC(Basic)
185 
186 // Basic copy-constructor:
187 // CHECK-LABEL: define linkonce_odr void @_ZN5BasicC2ERKS_(%struct.Basic* %this, %struct.Basic*)
188 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
189 // CHECK: call void @_ZN6NonPODC1ERKS_
190 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
191 // CHECK: ret void
192 
193 // PODMember copy-constructor:
194 // CHECK-LABEL: define linkonce_odr void @_ZN9PODMemberC2ERKS_(%struct.PODMember* %this, %struct.PODMember*)
195 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
196 // CHECK: call void @_ZN6NonPODC1ERKS_
197 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
198 // CHECK: ret void
199 
200 // PODLikeMember copy-constructor:
201 // CHECK-LABEL: define linkonce_odr void @_ZN13PODLikeMemberC2ERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember*)
202 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
203 // CHECK: invoke void @_ZN6NonPODC1ERKS_
204 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
205 // CHECK: ret void
206 // CHECK: landingpad
207 // CHECK: invoke void @_ZN7PODLikeD1Ev
208 
209 // ArrayMember copy-constructor:
210 // CHECK-LABEL: define linkonce_odr void @_ZN11ArrayMemberC2ERKS_(%struct.ArrayMember* %this, %struct.ArrayMember*)
211 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
212 // CHECK: call void @_ZN6NonPODC1ERKS_
213 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
214 // CHECK: ret void
215 
216 // VolatileMember copy-constructor:
217 // CHECK-LABEL: define linkonce_odr void @_ZN14VolatileMemberC2ERKS_(%struct.VolatileMember* %this, %struct.VolatileMember*)
218 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
219 // CHECK: load volatile i32* {{.*}}, align 4
220 // CHECK: store volatile i32 {{.*}}, align 4
221 // CHECK: call void @_ZN6NonPODC1ERKS_
222 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
223 // CHECK: ret void
224 
225 // BitfieldMember copy-constructor:
226 // CHECK-LABEL: define linkonce_odr void @_ZN14BitfieldMemberC2ERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember*)
227 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
228 // CHECK: call void @_ZN6NonPODC1ERKS_
229 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 3, i32 1{{.*}})
230 // CHECK: ret void
231 
232 // InnerClass copy-constructor:
233 // CHECK-LABEL: define linkonce_odr void @_ZN16InnerClassMemberC2ERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember*)
234 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
235 // CHECK: call void @_ZN6NonPODC1ERKS_
236 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
237 // CHECK: ret void
238 
239 // ReferenceMember copy-constructor:
240 // CHECK-LABEL: define linkonce_odr void @_ZN15ReferenceMemberC2ERKS_(%struct.ReferenceMember* %this, %struct.ReferenceMember*)
241 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 8{{.*}})
242 // CHECK: call void @_ZN6NonPODC1ERKS_
243 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 8{{.*}})
244 // CHECK: ret void
245 
246 // BitfieldMember2 copy-constructor:
247 // CHECK-2-LABEL: define linkonce_odr void @_ZN15BitfieldMember2C2ERKS_(%struct.BitfieldMember2* %this, %struct.BitfieldMember2*)
248 // CHECK-2: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4, i1 false)
249 // CHECK-2: call void @_ZN6NonPODC1ERKS_
250 // CHECK-2: ret void
251 
252 // PackedMembers copy-assignment:
253 // CHECK-LABEL: define linkonce_odr void @_ZN13PackedMembersC2ERKS_(%struct.PackedMembers* %this, %struct.PackedMembers*)
254 // CHECK: call void @_ZN6NonPODC1ERKS_
255 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 1{{.*}})
256 // CHECK: ret void
257