brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.5 KiB · ae66020 Raw
542 lines · cpp
1// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o - | FileCheck %s2 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 D15//    int d16// A: int a17// B: vbptr B18//    int b19// C: vbptr C20//    int c21 22// CHECK-DAG: @"??_8D@Test1@@7B01@@" = linkonce_odr unnamed_addr constant [4 x i32] [i32 0, i32 8, i32 12, i32 20], comdat, align 423// CHECK-DAG: @"??_8D@Test1@@7BB@1@@" = {{.*}} [2 x i32] [i32 0, i32 -4]24// CHECK-DAG: @"??_8D@Test1@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 -12]25// CHECK-DAG: @"??_8C@Test1@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]26// CHECK-DAG: @"??_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 B39//    int b40// C: vbptr C41//    int c42// D: int d43// A: int a44 45// CHECK-DAG: @"??_8D@Test2@@7BB@1@@" = {{.*}} [2 x i32] [i32 0, i32 20]46// CHECK-DAG: @"??_8D@Test2@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 12]47// CHECK-DAG: @"??_8C@Test2@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]48// CHECK-DAG: @"??_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: @"??_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: @"??_8C@Test4@@7B@" = {{.*}} [2 x i32] [i32 0, i32 12]68// CHECK-DAG: @"??_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 virtual73// 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: @"??_8D@Test5@@7BB@1@@"81// CHECK-DAG: @"??_8D@Test5@@7BC@1@@"82// CHECK-DAG: @"??_8C@Test5@@7B@"83// CHECK-DAG: @"??_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: @"??_8G@Test6@@7BB@1@E@1@F@1@@" =98// CHECK-DAG: @"??_8G@Test6@@7BC@1@E@1@F@1@@" =99// CHECK-DAG: @"??_8G@Test6@@7BB@1@F@1@@" =100// CHECK-DAG: @"??_8G@Test6@@7BC@1@F@1@@" =101// CHECK-DAG: @"??_8G@Test6@@7BB@1@E@1@@" =102// CHECK-DAG: @"??_8G@Test6@@7BC@1@E@1@@" =103// CHECK-DAG: @"??_8F@Test6@@7BB@1@E@1@@" = {{.*}} [2 x i32] [i32 0, i32 52]104// CHECK-DAG: @"??_8F@Test6@@7BC@1@E@1@@" = {{.*}} [2 x i32] [i32 0, i32 44]105// CHECK-DAG: @"??_8F@Test6@@7BB@1@@" = {{.*}} [2 x i32] [i32 0, i32 24]106// CHECK-DAG: @"??_8F@Test6@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 16]107// CHECK-DAG: @"??_8C@Test6@@7B@" = {{.*}} [2 x i32] [i32 0, i32 12]108// CHECK-DAG: @"??_8B@Test6@@7B@" = {{.*}} [2 x i32] [i32 0, i32 8]109// CHECK-DAG: @"??_8E@Test6@@7BB@1@@" = {{.*}} [2 x i32] [i32 0, i32 28]110// CHECK-DAG: @"??_8E@Test6@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 20]111// CHECK-DAG: @"??_8D@Test6@@7BB@1@@" = {{.*}} [2 x i32] [i32 0, i32 24]112// CHECK-DAG: @"??_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: @"??_8E@Test7@@7B@" = {{.*}} [3 x i32] [i32 0, i32 12, i32 16]125// CHECK-DAG: @"??_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: @"??_8D@Test8@@7B01@@" = {{.*}} [3 x i32] [i32 0, i32 8, i32 12]137// CHECK-DAG: @"??_8D@Test8@@7BC@1@@" = {{.*}} [2 x i32] [i32 0, i32 -4]138// CHECK-DAG: @"??_8C@Test8@@7B@" = {{.*}} [2 x i32] [i32 0, i32 12]139// CHECK-DAG: @"??_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: @"??_8E@Test9@@7B01@@" =154// CHECK-DAG: @"??_8E@Test9@@7BD@1@@" =155// CHECK-DAG: @"??_8E@Test9@@7BC@1@@" =156// CHECK-DAG: @"??_8E@Test9@@7BB@1@@" =157// CHECK-DAG: @"??_8D@Test9@@7B@" =158// CHECK-DAG: @"??_8D@Test9@@7BC@1@@" =159// CHECK-DAG: @"??_8D@Test9@@7BB@1@@" =160// CHECK-DAG: @"??_8C@Test9@@7B01@@" =161// CHECK-DAG: @"??_8C@Test9@@7BB@1@@" =162// CHECK-DAG: @"??_8BB@Test9@@7B@" =163// CHECK-DAG: @"??_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: @"??_8D@Test10@@7B@" =174// CHECK-DAG: @"??_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: @"??_8F@Test11@@7BD@1@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 28]189// CHECK-DAG: @"??_8F@Test11@@7BE@1@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 16]190// CHECK-DAG: @"??_8E@Test11@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 12]191// CHECK-DAG: @"??_8C@Test11@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]192// CHECK-DAG: @"??_8D@Test11@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 12]193// CHECK-DAG: @"??_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: @"??_8E@Test12@@7BC@1@D@1@@" =207// CHECK-DAG: @"??_8E@Test12@@7BB@1@D@1@@" =208// CHECK-DAG: @"??_8E@Test12@@7BD@1@@" =209// CHECK-DAG: @"??_8E@Test12@@7BC@1@@" =210// CHECK-DAG: @"??_8E@Test12@@7BB@1@@" =211// CHECK-DAG: @"??_8C@Test12@@7B01@@" =212// CHECK-DAG: @"??_8C@Test12@@7BB@1@@" =213// CHECK-DAG: @"??_8D@Test12@@7BC@1@@" =214// CHECK-DAG: @"??_8D@Test12@@7BB@1@@" =215// CHECK-DAG: @"??_8D@Test12@@7B@" =216// CHECK-DAG: @"??_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: @"??_8E@Test13@@7BD@1@@" =228// CHECK-DAG: @"??_8E@Test13@@7BC@1@D@1@@" =229// CHECK-DAG: @"??_8E@Test13@@7BB@1@D@1@@" =230// CHECK-DAG: @"??_8E@Test13@@7BC@1@@" =231// CHECK-DAG: @"??_8E@Test13@@7BB@1@@" =232// CHECK-DAG: @"??_8D@Test13@@7B@" =233// CHECK-DAG: @"??_8D@Test13@@7BC@1@@" =234// CHECK-DAG: @"??_8D@Test13@@7BB@1@@" =235// CHECK-DAG: @"??_8C@Test13@@7B01@@" =236// CHECK-DAG: @"??_8C@Test13@@7BB@1@@" =237// CHECK-DAG: @"??_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: @"??_8E@Test14@@7B@" =249// CHECK-DAG: @"??_8E@Test14@@7BC@1@@" =250// CHECK-DAG: @"??_8E@Test14@@7BB@1@@" =251// CHECK-DAG: @"??_8D@Test14@@7B@" =252// CHECK-DAG: @"??_8D@Test14@@7BC@1@@" =253// CHECK-DAG: @"??_8D@Test14@@7BB@1@@" =254// CHECK-DAG: @"??_8C@Test14@@7B01@@" =255// CHECK-DAG: @"??_8C@Test14@@7BB@1@@" =256// CHECK-DAG: @"??_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: @"??_8E@Test15@@7BD@1@@" =268// CHECK-DAG: @"??_8E@Test15@@7BB@1@D@1@@" =269// CHECK-DAG: @"??_8E@Test15@@7BC@1@@" =270// CHECK-DAG: @"??_8E@Test15@@7BB@1@@" =271// CHECK-DAG: @"??_8C@Test15@@7B@" =272// CHECK-DAG: @"??_8D@Test15@@7B01@@" =273// CHECK-DAG: @"??_8D@Test15@@7BB@1@@" =274// CHECK-DAG: @"??_8B@Test15@@7B@" =275}276 277namespace Test16 {278struct A { int a; };279struct B : virtual A { int b; };280struct C : virtual B { int c; }; // ambig281struct D : virtual C { int d; };282struct E : virtual D { int e; }; // ambig283struct F : E, D, C, B { int f; };  // ambig284F f;285 286// CHECK-DAG: @"??_8F@Test16@@7BE@1@@" =287// CHECK-DAG: @"??_8F@Test16@@7BD@1@E@1@@" =288// CHECK-DAG: @"??_8F@Test16@@7BC@1@E@1@@" =289// CHECK-DAG: @"??_8F@Test16@@7BB@1@E@1@@" =290// CHECK-DAG: @"??_8F@Test16@@7BD@1@@" =291// CHECK-DAG: @"??_8F@Test16@@7BC@1@@" =292// CHECK-DAG: @"??_8F@Test16@@7BB@1@@" =293// CHECK-DAG: @"??_8E@Test16@@7B01@@" =294// CHECK-DAG: @"??_8E@Test16@@7BD@1@@" =295// CHECK-DAG: @"??_8E@Test16@@7BC@1@@" =296// CHECK-DAG: @"??_8E@Test16@@7BB@1@@" =297// CHECK-DAG: @"??_8D@Test16@@7B@" =298// CHECK-DAG: @"??_8D@Test16@@7BC@1@@" =299// CHECK-DAG: @"??_8D@Test16@@7BB@1@@" =300// CHECK-DAG: @"??_8C@Test16@@7B01@@" =301// CHECK-DAG: @"??_8C@Test16@@7BB@1@@" =302// CHECK-DAG: @"??_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; }; // ambig311struct D : virtual C { int d; };312struct E : virtual D { int e; }; // ambig313struct F : virtual E { int f; };314struct G : virtual F { int g; }; // ambig315struct H : virtual G { int h; };316struct I : virtual H { int i; }; // ambig317struct J : virtual I { int j; };318struct K : virtual J { int k; }; // ambig319K k;320 321// CHECK-DAG: @"??_8K@Test17@@7B01@@" =322// CHECK-DAG: @"??_8J@Test17@@7B@" =323// CHECK-DAG: @"??_8I@Test17@@7B01@@" =324// CHECK-DAG: @"??_8H@Test17@@7B@" =325// CHECK-DAG: @"??_8G@Test17@@7B01@@" =326// CHECK-DAG: @"??_8F@Test17@@7B@" =327// CHECK-DAG: @"??_8E@Test17@@7B01@@" =328// CHECK-DAG: @"??_8D@Test17@@7B@" =329// CHECK-DAG: @"??_8C@Test17@@7B01@@" =330// CHECK-DAG: @"??_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: @"??_8E@Test18@@7BC@1@D@1@@" =342// CHECK-DAG: @"??_8E@Test18@@7BB@1@D@1@@" =343// CHECK-DAG: @"??_8E@Test18@@7BC@1@@" =344// CHECK-DAG: @"??_8E@Test18@@7BB@1@@" =345// CHECK-DAG: @"??_8B@Test18@@7B@" =346// CHECK-DAG: @"??_8C@Test18@@7B@" =347// CHECK-DAG: @"??_8D@Test18@@7BC@1@@" =348// CHECK-DAG: @"??_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: @"??_8E@Test19@@7B01@@" =360// CHECK-DAG: @"??_8E@Test19@@7BD@1@@" =361// CHECK-DAG: @"??_8E@Test19@@7BC@1@@" =362// CHECK-DAG: @"??_8E@Test19@@7BB@1@@" =363// CHECK-DAG: @"??_8D@Test19@@7B@" =364// CHECK-DAG: @"??_8D@Test19@@7BC@1@@" =365// CHECK-DAG: @"??_8D@Test19@@7BB@1@@" =366// CHECK-DAG: @"??_8C@Test19@@7B01@@" =367// CHECK-DAG: @"??_8C@Test19@@7BB@1@@" =368// CHECK-DAG: @"??_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: @"??_8E@Test20@@7BC@1@@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 0, i32 20, i32 24]381// CHECK-DAG: @"??_8E@Test20@@7BD@1@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 16]382// CHECK-DAG: @"??_8D@Test20@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8]383// CHECK-DAG: @"??_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: @"??_8H@Test21@@7B@" =398// CHECK-DAG: @"??_8H@Test21@@7BC@1@F@1@@" =399// CHECK-DAG: @"??_8H@Test21@@7BD@1@F@1@@" =400// CHECK-DAG: @"??_8H@Test21@@7BC@1@G@1@@" =401// CHECK-DAG: @"??_8H@Test21@@7BD@1@G@1@@" =402// CHECK-DAG: @"??_8G@Test21@@7BC@1@@" =403// CHECK-DAG: @"??_8G@Test21@@7BD@1@@" =404// CHECK-DAG: @"??_8F@Test21@@7B@" =405// CHECK-DAG: @"??_8F@Test21@@7BC@1@@" =406// CHECK-DAG: @"??_8F@Test21@@7BD@1@@" =407// CHECK-DAG: @"??_8E@Test21@@7BC@1@@" =408// CHECK-DAG: @"??_8E@Test21@@7BD@1@@" =409// CHECK-DAG: @"??_8D@Test21@@7B@" =410// CHECK-DAG: @"??_8B@Test21@@7B@" =411// CHECK-DAG: @"??_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: @"??_8D@Test22@@7B@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 0, i32 12, i32 16]422// CHECK-DAG: @"??_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: @"??_8D@Test23@@7B@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 0, i32 16, i32 12]434// CHECK-DAG: @"??_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: @"??_8D@Test24@@7B@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 0, i32 16, i32 12]448// CHECK-DAG: @"??_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: @"??_8D@Test25@@7B@" = linkonce_odr unnamed_addr constant [3 x i32] [i32 -4, i32 16, i32 12]462// CHECK-DAG: @"??_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: @"??_8F@Test26@@7BD@1@@" = linkonce_odr unnamed_addr constant [4 x i32] [i32 0, i32 16, i32 12, i32 20]478// CHECK-DAG: @"??_8F@Test26@@7BE@1@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 -4, i32 28]479}480 481namespace Test27 {482// PR17748483struct 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: @"??_8G@Test27@@7BB@1@@" =493// CHECK-DAG: @"??_8G@Test27@@7BB@1@F@1@@" =494// CHECK-DAG: @"??_8G@Test27@@7BC@1@@" =495// CHECK-DAG: @"??_8G@Test27@@7BC@1@D@1@@" =496// CHECK-DAG: @"??_8G@Test27@@7BC@1@E@1@@" =497// CHECK-DAG: @"??_8G@Test27@@7BC@1@F@1@@" =498// CHECK-DAG: @"??_8G@Test27@@7BD@1@@" =499// CHECK-DAG: @"??_8G@Test27@@7BF@1@@" =500}501 502namespace Test28 {503// PR17748504struct 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: @"??_8F@Test28@@7B01@@" =513// CHECK-DAG: @"??_8F@Test28@@7BB@1@@" =514// CHECK-DAG: @"??_8F@Test28@@7BC@1@@" =515// CHECK-DAG: @"??_8F@Test28@@7BC@1@D@1@@" =516// CHECK-DAG: @"??_8F@Test28@@7BC@1@D@1@E@1@@" =517// CHECK-DAG: @"??_8F@Test28@@7BC@1@E@1@@" =518// CHECK-DAG: @"??_8F@Test28@@7BD@1@@" =519// CHECK-DAG: @"??_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: @"??_8D@Test29@@7BB@1@@" = linkonce_odr unnamed_addr constant [2 x i32] zeroinitializer530}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: @"??_8?$B@H@Test30@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 4], comdat541}542