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