Home | History | Annotate | Download | only in CodeGenCXX
      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 {
    535   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