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