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