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
5namespace Test1 {
6// Classic diamond, fully virtual.
7struct A { int a; };
8struct B : virtual A { int b; };
9struct C : virtual A { int c; };
10struct D : virtual B, virtual C { int d; };
11D 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
29namespace Test2 {
30// Classic diamond, only A is virtual.
31struct A { int a; };
32struct B : virtual A { int b; };
33struct C : virtual A { int c; };
34struct D : B, C { int d; };
35D 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
51namespace Test3 {
52struct A { int a; };
53struct B { int b; };
54struct C : virtual A, virtual B { int c; };
55C c;
56
57// CHECK-DAG: @"\01??_8C@Test3@@7B@" = {{.*}} [3 x i32] [i32 0, i32 8, i32 12]
58}
59
60namespace Test4 {
61// Test reusing a vbptr from a non-virtual base.
62struct A { int a; };
63struct B : virtual A { int b; };
64struct C : B, virtual A { int c; };
65C 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
71namespace Test5 {
72// Test multiple base subobjects of the same type when that type has a virtual
73// base.
74struct A { int a; };
75struct B : virtual A { int b; };
76struct C : B { int c; };
77struct D : B, C { int d; };
78D 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
86namespace Test6 {
87// Test that we skip unneeded base path component names.
88struct A { int a; };
89struct B : virtual A { int b; };
90struct C : B { int c; };
91struct D : B, C { int d; };
92struct E : D { int e; };
93struct F : E, B, C { int f; };
94struct G : F, virtual E { int g; };
95G 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
115namespace Test7 {
116// Test a non-virtual base which reuses the vbptr of another base.
117struct A { int a; };
118struct B { int b; };
119struct C { int c; };
120struct D : virtual A { int d; };
121struct E : B, D, virtual A, virtual C { int e; };
122E 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
128namespace Test8 {
129// Test a virtual base which reuses the vbptr of another base.
130struct A { int a; };
131struct B : virtual A { int b; };
132struct C : B { int c; };
133struct D : virtual C { int d; };
134D 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
142namespace 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.
145struct A { int a; };
146struct B : virtual A { int b; };
147struct C : virtual B { int c; };
148struct BB : B { int bb; };  // Indirection =/
149struct D : BB, C { int d; };
150struct E : virtual D { };
151E 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
166namespace Test10 {
167struct A { int a; };
168struct B { int b; };
169struct C : virtual A { int c; };
170struct D : B, C { int d; };
171D d;
172
173// CHECK-DAG: @"\01??_8D@Test10@@7B@" =
174// CHECK-DAG: @"\01??_8C@Test10@@7B@" =
175
176}
177
178namespace Test11 {
179// Typical diamond with an extra single inheritance indirection for B and C.
180struct A { int a; };
181struct B : virtual A { int b; };
182struct C : virtual A { int c; };
183struct D : B { int d; };
184struct E : C { int e; };
185struct F : D, E { int f; };
186F 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
197namespace Test12 {
198// Another vbptr inside a virtual base.
199struct A { int a; };
200struct B : virtual A { int b; };
201struct C : virtual B { int c; };
202struct D : C, B { int d; };
203struct E : D, C, B { int e; };
204E 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
219namespace Test13 {
220struct A { int a; };
221struct B : virtual A { int b; };
222struct C : virtual B { int c; };
223struct D : virtual C { int d; };
224struct E : D, C, B { int e; };
225E 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
240namespace Test14 {
241struct A { int a; };
242struct B : virtual A { int b; };
243struct C : virtual B { int c; };
244struct D : virtual C { int d; };
245struct E : D, virtual C, virtual B { int e; };
246E 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
259namespace Test15 {
260struct A { int a; };
261struct B : virtual A { int b; };
262struct C : virtual A { int c; };
263struct D : virtual B { int d; };
264struct E : D, C, B { int e; };
265E 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
277namespace Test16 {
278struct A { int a; };
279struct B : virtual A { int b; };
280struct C : virtual B { int c; }; // ambig
281struct D : virtual C { int d; };
282struct E : virtual D { int e; }; // ambig
283struct F : E, D, C, B { int f; };  // ambig
284F 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
305namespace 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.
308struct A { int a; };
309struct B : virtual A { int b; };
310struct C : virtual B { int c; }; // ambig
311struct D : virtual C { int d; };
312struct E : virtual D { int e; }; // ambig
313struct F : virtual E { int f; };
314struct G : virtual F { int g; }; // ambig
315struct H : virtual G { int h; };
316struct I : virtual H { int i; }; // ambig
317struct J : virtual I { int j; };
318struct K : virtual J { int k; }; // ambig
319K 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
333namespace Test18 {
334struct A { int a; };
335struct B : virtual A { int b; };
336struct C : B { int c; };
337struct D : C, B { int d; };
338struct E : D, C, B { int e; };
339E 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
351namespace Test19 {
352struct A { int a; };
353struct B : virtual A { int b; };
354struct C : virtual B { int c; };
355struct D : virtual C, virtual B { int d; };
356struct E : virtual D, virtual C, virtual B { int e; };
357E 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
371namespace Test20 {
372// E has no direct vbases, but it adds to C's vbtable anyway.
373struct A { int a; };
374struct B { int b; };
375struct C : virtual A { int c; };
376struct D : virtual B { int d; };
377struct E : C, D { int e; };
378E 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
386namespace Test21 {
387struct A { int a; };
388struct B : virtual A { int b; };
389struct C : B { int c; };
390struct D : B { int d; };
391struct E : C, D { int e; };
392struct F : virtual E { int f; };
393struct G : E { int g; };
394struct H : F, G { int h; };
395H 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
414namespace Test22 {
415struct A { int a; };
416struct B : virtual A { int b; };
417struct C { int c; };
418struct D : B, virtual C { int d; };
419D 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
425namespace Test23 {
426struct A { int a; };
427struct B : virtual A { int b; };
428struct C { int c; };
429// Note the unusual order of bases. It forces C to be laid out before A.
430struct D : virtual C, B { int d; };
431D 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
437namespace Test24 {
438struct A { int a; };
439struct B : virtual A { int b; };
440struct C { int c; };
441struct D : virtual C, B {
442  virtual void f();  // Issues a vfptr, but the vbptr is still shared with B.
443  int d;
444};
445D 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
451namespace Test25 {
452struct A { int a; };
453struct B : virtual A {
454  virtual void f();  // Issues a vfptr.
455  int b;
456};
457struct C { int c; };
458struct D : virtual C, B { int d; };
459D 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
465namespace Test26 {
466struct A { int a; };
467struct B { int b; };
468struct C { int c; };
469struct D : virtual A { int d; };
470struct E : virtual B {
471  virtual void foo();  // Issues a vfptr.
472  int e;
473};
474struct F: virtual C, D, E { int f; };
475F 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
481namespace Test27 {
482// PR17748
483struct A {};
484struct B : virtual A {};
485struct C : virtual B {};
486struct D : C, B {};
487struct E : D {};
488struct F : C, E {};
489struct G : F, D, C, B {};
490G 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
502namespace Test28 {
503// PR17748
504struct A {};
505struct B : virtual A {};
506struct C : virtual B {};
507struct D : C, B {};
508struct E : C, D {};
509struct F : virtual E, virtual D, virtual C {};
510F 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
522namespace Test29 {
523struct A {};
524struct B : virtual A {};
525struct C : virtual B {};
526struct D : C {};
527D d;
528
529// CHECK-DAG: @"\01??_8D@Test29@@7BB@1@@" = linkonce_odr unnamed_addr constant [2 x i32] zeroinitializer
530}
531
532namespace Test30 {
533struct A {};
534template <class> struct B : virtual A {
535  B() {}
536};
537
538extern template class B<int>;
539template 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