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