• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o - | FileCheck %s
2 
3 // See microsoft-abi-structors.cpp for constructor codegen tests.
4 
5 namespace Test1 {
6 // Classic diamond, fully virtual.
7 struct A { int a; };
8 struct B : virtual A { int b; };
9 struct C : virtual A { int c; };
10 struct D : virtual B, virtual C { int d; };
11 D d; // Force vbtable emission.
12 
13 // Layout should be:
14 // D: vbptr D
15 //    int d
16 // A: int a
17 // B: vbptr B
18 //    int b
19 // C: vbptr C
20 //    int c
21 
22 // CHECK-DAG: @"\01??_8D@Test1@@7B01@@" = linkonce_odr unnamed_addr constant [4 x i32] [i32 0, i32 8, i32 12, i32 20]
23 // CHECK-DAG: @"\01??_8D@Test1@@7BB@1@@" = {{.*}} [2 x i32] [i32 0, i32 -4]
24 // CHECK-DAG: @"\01??_8D@Test1@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 -12]
25 // CHECK-DAG: @"\01??_8C@Test1@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
26 // CHECK-DAG: @"\01??_8B@Test1@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
27 }
28 
29 namespace Test2 {
30 // Classic diamond, only A is virtual.
31 struct A { int a; };
32 struct B : virtual A { int b; };
33 struct C : virtual A { int c; };
34 struct D : B, C { int d; };
35 D d; // Force vbtable emission.
36 
37 // Layout should be:
38 // B: vbptr B
39 //    int b
40 // C: vbptr C
41 //    int c
42 // D: int d
43 // A: int a
44 
45 // CHECK-DAG: @"\01??_8D@Test2@@7BB@1@@" = {{.*}} [2 x i32] [i32 0, i32 20]
46 // CHECK-DAG: @"\01??_8D@Test2@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 12]
47 // CHECK-DAG: @"\01??_8C@Test2@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
48 // CHECK-DAG: @"\01??_8B@Test2@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
49 }
50 
51 namespace Test3 {
52 struct A { int a; };
53 struct B { int b; };
54 struct C : virtual A, virtual B { int c; };
55 C c;
56 
57 // CHECK-DAG: @"\01??_8C@Test3@@7B@" = {{.*}} [3 x i32] [i32 0, i32 8, i32 12]
58 }
59 
60 namespace Test4 {
61 // Test reusing a vbptr from a non-virtual base.
62 struct A { int a; };
63 struct B : virtual A { int b; };
64 struct C : B, virtual A { int c; };
65 C c; // Force vbtable emission.
66 
67 // CHECK-DAG: @"\01??_8C@Test4@@7B@" = {{.*}} [2 x i32] [i32 0, i32 12]
68 // CHECK-DAG: @"\01??_8B@Test4@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
69 }
70 
71 namespace Test5 {
72 // Test multiple base subobjects of the same type when that type has a virtual
73 // base.
74 struct A { int a; };
75 struct B : virtual A { int b; };
76 struct C : B { int c; };
77 struct D : B, C { int d; };
78 D d; // Force vbtable emission.
79 
80 // CHECK-DAG: @"\01??_8D@Test5@@7BB@1@@"
81 // CHECK-DAG: @"\01??_8D@Test5@@7BC@1@@"
82 // CHECK-DAG: @"\01??_8C@Test5@@7B@"
83 // CHECK-DAG: @"\01??_8B@Test5@@7B@"
84 }
85 
86 namespace Test6 {
87 // Test that we skip unneeded base path component names.
88 struct A { int a; };
89 struct B : virtual A { int b; };
90 struct C : B { int c; };
91 struct D : B, C { int d; };
92 struct E : D { int e; };
93 struct F : E, B, C { int f; };
94 struct G : F, virtual E { int g; };
95 G g;
96 
97 // CHECK-DAG: @"\01??_8G@Test6@@7BB@1@E@1@F@1@@" =
98 // CHECK-DAG: @"\01??_8G@Test6@@7BC@1@E@1@F@1@@" =
99 // CHECK-DAG: @"\01??_8G@Test6@@7BB@1@F@1@@" =
100 // CHECK-DAG: @"\01??_8G@Test6@@7BC@1@F@1@@" =
101 // CHECK-DAG: @"\01??_8G@Test6@@7BB@1@E@1@@" =
102 // CHECK-DAG: @"\01??_8G@Test6@@7BC@1@E@1@@" =
103 // CHECK-DAG: @"\01??_8F@Test6@@7BB@1@E@1@@" = {{.*}} [2 x i32] [i32 0, i32 52]
104 // CHECK-DAG: @"\01??_8F@Test6@@7BC@1@E@1@@" = {{.*}} [2 x i32] [i32 0, i32 44]
105 // CHECK-DAG: @"\01??_8F@Test6@@7BB@1@@" = {{.*}} [2 x i32] [i32 0, i32 24]
106 // CHECK-DAG: @"\01??_8F@Test6@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 16]
107 // CHECK-DAG: @"\01??_8C@Test6@@7B@" = {{.*}} [2 x i32] [i32 0, i32 12]
108 // CHECK-DAG: @"\01??_8B@Test6@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
109 // CHECK-DAG: @"\01??_8E@Test6@@7BB@1@@" = {{.*}} [2 x i32] [i32 0, i32 28]
110 // CHECK-DAG: @"\01??_8E@Test6@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 20]
111 // CHECK-DAG: @"\01??_8D@Test6@@7BB@1@@" = {{.*}} [2 x i32] [i32 0, i32 24]
112 // CHECK-DAG: @"\01??_8D@Test6@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 16]
113 }
114 
115 namespace Test7 {
116 // Test a non-virtual base which reuses the vbptr of another base.
117 struct A { int a; };
118 struct B { int b; };
119 struct C { int c; };
120 struct D : virtual A { int d; };
121 struct E : B, D, virtual A, virtual C { int e; };
122 E o;
123 
124 // CHECK-DAG: @"\01??_8E@Test7@@7B@" = {{.*}} [3 x i32] [i32 0, i32 12, i32 16]
125 // CHECK-DAG: @"\01??_8D@Test7@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
126 }
127 
128 namespace Test8 {
129 // Test a virtual base which reuses the vbptr of another base.
130 struct A { int a; };
131 struct B : virtual A { int b; };
132 struct C : B { int c; };
133 struct D : virtual C { int d; };
134 D o;
135 
136 // CHECK-DAG: @"\01??_8D@Test8@@7B01@@" = {{.*}} [3 x i32] [i32 0, i32 8, i32 12]
137 // CHECK-DAG: @"\01??_8D@Test8@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 -4]
138 // CHECK-DAG: @"\01??_8C@Test8@@7B@" = {{.*}} [2 x i32] [i32 0, i32 12]
139 // CHECK-DAG: @"\01??_8B@Test8@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]
140 }
141 
142 namespace Test9 {
143 // D has to add to B's vbtable because D has more morally virtual bases than B.
144 // D then takes B's vbptr and the vbtable is named for D, not B.
145 struct A { int a; };
146 struct B : virtual A { int b; };
147 struct C : virtual B { int c; };
148 struct BB : B { int bb; };  // Indirection =/
149 struct D : BB, C { int d; };
150 struct E : virtual D { };
151 E e;
152 
153 // CHECK-DAG: @"\01??_8E@Test9@@7B01@@" =
154 // CHECK-DAG: @"\01??_8E@Test9@@7BD@1@@" =
155 // CHECK-DAG: @"\01??_8E@Test9@@7BC@1@@" =
156 // CHECK-DAG: @"\01??_8E@Test9@@7BB@1@@" =
157 // CHECK-DAG: @"\01??_8D@Test9@@7B@" =
158 // CHECK-DAG: @"\01??_8D@Test9@@7BC@1@@" =
159 // CHECK-DAG: @"\01??_8D@Test9@@7BB@1@@" =
160 // CHECK-DAG: @"\01??_8C@Test9@@7B01@@" =
161 // CHECK-DAG: @"\01??_8C@Test9@@7BB@1@@" =
162 // CHECK-DAG: @"\01??_8BB@Test9@@7B@" =
163 // CHECK-DAG: @"\01??_8B@Test9@@7B@" =
164 }
165 
166 namespace Test10 {
167 struct A { int a; };
168 struct B { int b; };
169 struct C : virtual A { int c; };
170 struct D : B, C { int d; };
171 D d;
172 
173 // CHECK-DAG: @"\01??_8D@Test10@@7B@" =
174 // CHECK-DAG: @"\01??_8C@Test10@@7B@" =
175 
176 }
177 
178 namespace Test11 {
179 // Typical diamond with an extra single inheritance indirection for B and C.
180 struct A { int a; };
181 struct B : virtual A { int b; };
182 struct C : virtual A { int c; };
183 struct D : B { int d; };
184 struct E : C { int e; };
185 struct F : D, E { int f; };
186 F f;
187 
188 // CHECK-DAG: @"\01??_8F@Test11@@7BD@1@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 28]
189 // CHECK-DAG: @"\01??_8F@Test11@@7BE@1@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 16]
190 // CHECK-DAG: @"\01??_8E@Test11@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 12]
191 // CHECK-DAG: @"\01??_8C@Test11@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]
192 // CHECK-DAG: @"\01??_8D@Test11@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 12]
193 // CHECK-DAG: @"\01??_8B@Test11@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]
194 
195 }
196 
197 namespace Test12 {
198 // Another vbptr inside a virtual base.
199 struct A { int a; };
200 struct B : virtual A { int b; };
201 struct C : virtual B { int c; };
202 struct D : C, B { int d; };
203 struct E : D, C, B { int e; };
204 E e;
205 
206 // CHECK-DAG: @"\01??_8E@Test12@@7BC@1@D@1@@" =
207 // CHECK-DAG: @"\01??_8E@Test12@@7BB@1@D@1@@" =
208 // CHECK-DAG: @"\01??_8E@Test12@@7BD@1@@" =
209 // CHECK-DAG: @"\01??_8E@Test12@@7BC@1@@" =
210 // CHECK-DAG: @"\01??_8E@Test12@@7BB@1@@" =
211 // CHECK-DAG: @"\01??_8C@Test12@@7B01@@" =
212 // CHECK-DAG: @"\01??_8C@Test12@@7BB@1@@" =
213 // CHECK-DAG: @"\01??_8D@Test12@@7BC@1@@" =
214 // CHECK-DAG: @"\01??_8D@Test12@@7BB@1@@" =
215 // CHECK-DAG: @"\01??_8D@Test12@@7B@" =
216 // CHECK-DAG: @"\01??_8B@Test12@@7B@" =
217 }
218 
219 namespace Test13 {
220 struct A { int a; };
221 struct B : virtual A { int b; };
222 struct C : virtual B { int c; };
223 struct D : virtual C { int d; };
224 struct E : D, C, B { int e; };
225 E e;
226 
227 // CHECK-DAG: @"\01??_8E@Test13@@7BD@1@@" =
228 // CHECK-DAG: @"\01??_8E@Test13@@7BC@1@D@1@@" =
229 // CHECK-DAG: @"\01??_8E@Test13@@7BB@1@D@1@@" =
230 // CHECK-DAG: @"\01??_8E@Test13@@7BC@1@@" =
231 // CHECK-DAG: @"\01??_8E@Test13@@7BB@1@@" =
232 // CHECK-DAG: @"\01??_8D@Test13@@7B@" =
233 // CHECK-DAG: @"\01??_8D@Test13@@7BC@1@@" =
234 // CHECK-DAG: @"\01??_8D@Test13@@7BB@1@@" =
235 // CHECK-DAG: @"\01??_8C@Test13@@7B01@@" =
236 // CHECK-DAG: @"\01??_8C@Test13@@7BB@1@@" =
237 // CHECK-DAG: @"\01??_8B@Test13@@7B@" =
238 }
239 
240 namespace Test14 {
241 struct A { int a; };
242 struct B : virtual A { int b; };
243 struct C : virtual B { int c; };
244 struct D : virtual C { int d; };
245 struct E : D, virtual C, virtual B { int e; };
246 E e;
247 
248 // CHECK-DAG: @"\01??_8E@Test14@@7B@" =
249 // CHECK-DAG: @"\01??_8E@Test14@@7BC@1@@" =
250 // CHECK-DAG: @"\01??_8E@Test14@@7BB@1@@" =
251 // CHECK-DAG: @"\01??_8D@Test14@@7B@" =
252 // CHECK-DAG: @"\01??_8D@Test14@@7BC@1@@" =
253 // CHECK-DAG: @"\01??_8D@Test14@@7BB@1@@" =
254 // CHECK-DAG: @"\01??_8C@Test14@@7B01@@" =
255 // CHECK-DAG: @"\01??_8C@Test14@@7BB@1@@" =
256 // CHECK-DAG: @"\01??_8B@Test14@@7B@" =
257 }
258 
259 namespace Test15 {
260 struct A { int a; };
261 struct B : virtual A { int b; };
262 struct C : virtual A { int c; };
263 struct D : virtual B { int d; };
264 struct E : D, C, B { int e; };
265 E e;
266 
267 // CHECK-DAG: @"\01??_8E@Test15@@7BD@1@@" =
268 // CHECK-DAG: @"\01??_8E@Test15@@7BB@1@D@1@@" =
269 // CHECK-DAG: @"\01??_8E@Test15@@7BC@1@@" =
270 // CHECK-DAG: @"\01??_8E@Test15@@7BB@1@@" =
271 // CHECK-DAG: @"\01??_8C@Test15@@7B@" =
272 // CHECK-DAG: @"\01??_8D@Test15@@7B01@@" =
273 // CHECK-DAG: @"\01??_8D@Test15@@7BB@1@@" =
274 // CHECK-DAG: @"\01??_8B@Test15@@7B@" =
275 }
276 
277 namespace Test16 {
278 struct A { int a; };
279 struct B : virtual A { int b; };
280 struct C : virtual B { int c; }; // ambig
281 struct D : virtual C { int d; };
282 struct E : virtual D { int e; }; // ambig
283 struct F : E, D, C, B { int f; };  // ambig
284 F f;
285 
286 // CHECK-DAG: @"\01??_8F@Test16@@7BE@1@@" =
287 // CHECK-DAG: @"\01??_8F@Test16@@7BD@1@E@1@@" =
288 // CHECK-DAG: @"\01??_8F@Test16@@7BC@1@E@1@@" =
289 // CHECK-DAG: @"\01??_8F@Test16@@7BB@1@E@1@@" =
290 // CHECK-DAG: @"\01??_8F@Test16@@7BD@1@@" =
291 // CHECK-DAG: @"\01??_8F@Test16@@7BC@1@@" =
292 // CHECK-DAG: @"\01??_8F@Test16@@7BB@1@@" =
293 // CHECK-DAG: @"\01??_8E@Test16@@7B01@@" =
294 // CHECK-DAG: @"\01??_8E@Test16@@7BD@1@@" =
295 // CHECK-DAG: @"\01??_8E@Test16@@7BC@1@@" =
296 // CHECK-DAG: @"\01??_8E@Test16@@7BB@1@@" =
297 // CHECK-DAG: @"\01??_8D@Test16@@7B@" =
298 // CHECK-DAG: @"\01??_8D@Test16@@7BC@1@@" =
299 // CHECK-DAG: @"\01??_8D@Test16@@7BB@1@@" =
300 // CHECK-DAG: @"\01??_8C@Test16@@7B01@@" =
301 // CHECK-DAG: @"\01??_8C@Test16@@7BB@1@@" =
302 // CHECK-DAG: @"\01??_8B@Test16@@7B@" =
303 }
304 
305 namespace Test17 {
306 // This test case has an interesting alternating pattern of using "vbtable of B"
307 // and "vbtable of C for C".  This may be the key to the underlying algorithm.
308 struct A { int a; };
309 struct B : virtual A { int b; };
310 struct C : virtual B { int c; }; // ambig
311 struct D : virtual C { int d; };
312 struct E : virtual D { int e; }; // ambig
313 struct F : virtual E { int f; };
314 struct G : virtual F { int g; }; // ambig
315 struct H : virtual G { int h; };
316 struct I : virtual H { int i; }; // ambig
317 struct J : virtual I { int j; };
318 struct K : virtual J { int k; }; // ambig
319 K k;
320 
321 // CHECK-DAG: @"\01??_8K@Test17@@7B01@@" =
322 // CHECK-DAG: @"\01??_8J@Test17@@7B@" =
323 // CHECK-DAG: @"\01??_8I@Test17@@7B01@@" =
324 // CHECK-DAG: @"\01??_8H@Test17@@7B@" =
325 // CHECK-DAG: @"\01??_8G@Test17@@7B01@@" =
326 // CHECK-DAG: @"\01??_8F@Test17@@7B@" =
327 // CHECK-DAG: @"\01??_8E@Test17@@7B01@@" =
328 // CHECK-DAG: @"\01??_8D@Test17@@7B@" =
329 // CHECK-DAG: @"\01??_8C@Test17@@7B01@@" =
330 // CHECK-DAG: @"\01??_8B@Test17@@7B@" =
331 }
332 
333 namespace Test18 {
334 struct A { int a; };
335 struct B : virtual A { int b; };
336 struct C : B { int c; };
337 struct D : C, B { int d; };
338 struct E : D, C, B { int e; };
339 E e;
340 
341 // CHECK-DAG: @"\01??_8E@Test18@@7BC@1@D@1@@" =
342 // CHECK-DAG: @"\01??_8E@Test18@@7BB@1@D@1@@" =
343 // CHECK-DAG: @"\01??_8E@Test18@@7BC@1@@" =
344 // CHECK-DAG: @"\01??_8E@Test18@@7BB@1@@" =
345 // CHECK-DAG: @"\01??_8B@Test18@@7B@" =
346 // CHECK-DAG: @"\01??_8C@Test18@@7B@" =
347 // CHECK-DAG: @"\01??_8D@Test18@@7BC@1@@" =
348 // CHECK-DAG: @"\01??_8D@Test18@@7BB@1@@" =
349 }
350 
351 namespace Test19 {
352 struct A { int a; };
353 struct B : virtual A { int b; };
354 struct C : virtual B { int c; };
355 struct D : virtual C, virtual B { int d; };
356 struct E : virtual D, virtual C, virtual B { int e; };
357 E e;
358 
359 // CHECK-DAG: @"\01??_8E@Test19@@7B01@@" =
360 // CHECK-DAG: @"\01??_8E@Test19@@7BD@1@@" =
361 // CHECK-DAG: @"\01??_8E@Test19@@7BC@1@@" =
362 // CHECK-DAG: @"\01??_8E@Test19@@7BB@1@@" =
363 // CHECK-DAG: @"\01??_8D@Test19@@7B@" =
364 // CHECK-DAG: @"\01??_8D@Test19@@7BC@1@@" =
365 // CHECK-DAG: @"\01??_8D@Test19@@7BB@1@@" =
366 // CHECK-DAG: @"\01??_8C@Test19@@7B01@@" =
367 // CHECK-DAG: @"\01??_8C@Test19@@7BB@1@@" =
368 // CHECK-DAG: @"\01??_8B@Test19@@7B@" =
369 }
370 
371 namespace Test20 {
372 // E has no direct vbases, but it adds to C's vbtable anyway.
373 struct A { int a; };
374 struct B { int b; };
375 struct C : virtual A { int c; };
376 struct D : virtual B { int d; };
377 struct E : C, D { int e; };
378 E f;
379 
380 // CHECK-DAG: @"\01??_8E@Test20@@7BC@1@@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 0, i32 20, i32 24]
381 // CHECK-DAG: @"\01??_8E@Test20@@7BD@1@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 16]
382 // CHECK-DAG: @"\01??_8D@Test20@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]
383 // CHECK-DAG: @"\01??_8C@Test20@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]
384 }
385 
386 namespace Test21 {
387 struct A { int a; };
388 struct B : virtual A { int b; };
389 struct C : B { int c; };
390 struct D : B { int d; };
391 struct E : C, D { int e; };
392 struct F : virtual E { int f; };
393 struct G : E { int g; };
394 struct H : F, G { int h; };
395 H h;
396 
397 // CHECK-DAG: @"\01??_8H@Test21@@7B@" =
398 // CHECK-DAG: @"\01??_8H@Test21@@7BC@1@F@1@@" =
399 // CHECK-DAG: @"\01??_8H@Test21@@7BD@1@F@1@@" =
400 // CHECK-DAG: @"\01??_8H@Test21@@7BC@1@G@1@@" =
401 // CHECK-DAG: @"\01??_8H@Test21@@7BD@1@G@1@@" =
402 // CHECK-DAG: @"\01??_8G@Test21@@7BC@1@@" =
403 // CHECK-DAG: @"\01??_8G@Test21@@7BD@1@@" =
404 // CHECK-DAG: @"\01??_8F@Test21@@7B@" =
405 // CHECK-DAG: @"\01??_8F@Test21@@7BC@1@@" =
406 // CHECK-DAG: @"\01??_8F@Test21@@7BD@1@@" =
407 // CHECK-DAG: @"\01??_8E@Test21@@7BC@1@@" =
408 // CHECK-DAG: @"\01??_8E@Test21@@7BD@1@@" =
409 // CHECK-DAG: @"\01??_8D@Test21@@7B@" =
410 // CHECK-DAG: @"\01??_8B@Test21@@7B@" =
411 // CHECK-DAG: @"\01??_8C@Test21@@7B@" =
412 }
413 
414 namespace Test22 {
415 struct A { int a; };
416 struct B : virtual A { int b; };
417 struct C { int c; };
418 struct D : B, virtual C { int d; };
419 D d;
420 
421 // CHECK-DAG: @"\01??_8D@Test22@@7B@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 0, i32 12, i32 16]
422 // CHECK-DAG: @"\01??_8B@Test22@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]
423 }
424 
425 namespace Test23 {
426 struct A { int a; };
427 struct B : virtual A { int b; };
428 struct C { int c; };
429 // Note the unusual order of bases. It forces C to be laid out before A.
430 struct D : virtual C, B { int d; };
431 D d;
432 
433 // CHECK-DAG: @"\01??_8D@Test23@@7B@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 0, i32 16, i32 12]
434 // CHECK-DAG: @"\01??_8B@Test23@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]
435 }
436 
437 namespace Test24 {
438 struct A { int a; };
439 struct B : virtual A { int b; };
440 struct C { int c; };
441 struct D : virtual C, B {
442   virtual void f();  // Issues a vfptr, but the vbptr is still shared with B.
443   int d;
444 };
445 D d;
446 
447 // CHECK-DAG: @"\01??_8D@Test24@@7B@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 0, i32 16, i32 12]
448 // CHECK-DAG: @"\01??_8B@Test24@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]
449 }
450 
451 namespace Test25 {
452 struct A { int a; };
453 struct B : virtual A {
454   virtual void f();  // Issues a vfptr.
455   int b;
456 };
457 struct C { int c; };
458 struct D : virtual C, B { int d; };
459 D d;
460 
461 // CHECK-DAG: @"\01??_8D@Test25@@7B@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 -4, i32 16, i32 12]
462 // CHECK-DAG: @"\01??_8B@Test25@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 -4, i32 8]
463 }
464 
465 namespace Test26 {
466 struct A { int a; };
467 struct B { int b; };
468 struct C { int c; };
469 struct D : virtual A { int d; };
470 struct E : virtual B {
471   virtual void foo();  // Issues a vfptr.
472   int e;
473 };
474 struct F: virtual C, D, E { int f; };
475 F f;
476 // F reuses the D's vbptr, even though D is laid out after E.
477 // CHECK-DAG: @"\01??_8F@Test26@@7BD@1@@" = linkonce_odr unnamed_addr constant [4 x i32] [i32 0, i32 16, i32 12, i32 20]
478 // CHECK-DAG: @"\01??_8F@Test26@@7BE@1@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 -4, i32 28]
479 }
480 
481 namespace Test27 {
482 // PR17748
483 struct A {};
484 struct B : virtual A {};
485 struct C : virtual B {};
486 struct D : C, B {};
487 struct E : D {};
488 struct F : C, E {};
489 struct G : F, D, C, B {};
490 G x;
491 
492 // CHECK-DAG: @"\01??_8G@Test27@@7BB@1@@" =
493 // CHECK-DAG: @"\01??_8G@Test27@@7BB@1@F@1@@" =
494 // CHECK-DAG: @"\01??_8G@Test27@@7BC@1@@" =
495 // CHECK-DAG: @"\01??_8G@Test27@@7BC@1@D@1@@" =
496 // CHECK-DAG: @"\01??_8G@Test27@@7BC@1@E@1@@" =
497 // CHECK-DAG: @"\01??_8G@Test27@@7BC@1@F@1@@" =
498 // CHECK-DAG: @"\01??_8G@Test27@@7BD@1@@" =
499 // CHECK-DAG: @"\01??_8G@Test27@@7BF@1@@" =
500 }
501 
502 namespace Test28 {
503 // PR17748
504 struct A {};
505 struct B : virtual A {};
506 struct C : virtual B {};
507 struct D : C, B {};
508 struct E : C, D {};
509 struct F : virtual E, virtual D, virtual C {};
510 F x;
511 
512 // CHECK-DAG: @"\01??_8F@Test28@@7B01@@" =
513 // CHECK-DAG: @"\01??_8F@Test28@@7BB@1@@" =
514 // CHECK-DAG: @"\01??_8F@Test28@@7BC@1@@" =
515 // CHECK-DAG: @"\01??_8F@Test28@@7BC@1@D@1@@" =
516 // CHECK-DAG: @"\01??_8F@Test28@@7BC@1@D@1@E@1@@" =
517 // CHECK-DAG: @"\01??_8F@Test28@@7BC@1@E@1@@" =
518 // CHECK-DAG: @"\01??_8F@Test28@@7BD@1@@" =
519 // CHECK-DAG: @"\01??_8F@Test28@@7BE@1@@" =
520 }
521 
522 namespace Test29 {
523 struct A {};
524 struct B : virtual A {};
525 struct C : virtual B {};
526 struct D : C {};
527 D d;
528 
529 // CHECK-DAG: @"\01??_8D@Test29@@7BB@1@@" = linkonce_odr unnamed_addr constant [2 x i32] zeroinitializer
530 }
531 
532 namespace Test30 {
533 struct A {};
534 template <class> struct B : virtual A {
BTest30::B535   B() {}
536 };
537 
538 extern template class B<int>;
539 template B<int>::B();
540 // CHECK-DAG: @"\01??_8?$B@H@Test30@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 4], comdat
541 }
542