1 // RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \ 2 // RUN: | FileCheck %s --strict-whitespace 3 // RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \ 4 // RUN: | FileCheck %s -check-prefix CHECK-X64 --strict-whitespace 5 6 extern "C" int printf(const char *fmt, ...); 7 8 struct B0 { int a; B0() : a(0xf00000B0) { printf("B0 = %p\n", this); } virtual void f() { printf("B0"); } }; 9 struct B1 { int a; B1() : a(0xf00000B1) { printf("B1 = %p\n", this); } virtual void g() { printf("B1"); } }; 10 struct B2 { int a; B2() : a(0xf00000B2) { printf("B1 = %p\n", this); } }; 11 struct B0X { int a; B0X() : a(0xf00000B0) {} }; 12 struct B1X { int a; B1X() : a(0xf00000B1) {} virtual void f() { printf("B0"); } }; 13 struct B2X : virtual B1X { int a; B2X() : a(0xf00000B2) {} }; 14 15 struct A : virtual B0 { 16 }; 17 18 // CHECK-LABEL: 0 | struct A 19 // CHECK-NEXT: 0 | (A vbtable pointer) 20 // CHECK-NEXT: 4 | struct B0 (virtual base) 21 // CHECK-NEXT: 4 | (B0 vftable pointer) 22 // CHECK-NEXT: 8 | int a 23 // CHECK-NEXT: | [sizeof=12, align=4 24 // CHECK-NEXT: | nvsize=4, nvalign=4] 25 // CHECK-X64-LABEL: 0 | struct A 26 // CHECK-X64-NEXT: 0 | (A vbtable pointer) 27 // CHECK-X64-NEXT: 8 | struct B0 (virtual base) 28 // CHECK-X64-NEXT: 8 | (B0 vftable pointer) 29 // CHECK-X64-NEXT: 16 | int a 30 // CHECK-X64-NEXT: | [sizeof=24, align=8 31 // CHECK-X64-NEXT: | nvsize=8, nvalign=8] 32 33 struct B : virtual B0 { 34 virtual void f() { printf("B"); } 35 }; 36 37 // CHECK-LABEL: 0 | struct B 38 // CHECK-NEXT: 0 | (B vbtable pointer) 39 // CHECK-NEXT: 4 | struct B0 (virtual base) 40 // CHECK-NEXT: 4 | (B0 vftable pointer) 41 // CHECK-NEXT: 8 | int a 42 // CHECK-NEXT: | [sizeof=12, align=4 43 // CHECK-NEXT: | nvsize=4, nvalign=4] 44 // CHECK-X64-LABEL: 0 | struct B 45 // CHECK-X64-NEXT: 0 | (B vbtable pointer) 46 // CHECK-X64-NEXT: 8 | struct B0 (virtual base) 47 // CHECK-X64-NEXT: 8 | (B0 vftable pointer) 48 // CHECK-X64-NEXT: 16 | int a 49 // CHECK-X64-NEXT: | [sizeof=24, align=8 50 // CHECK-X64-NEXT: | nvsize=8, nvalign=8] 51 52 struct C : virtual B0 { 53 virtual void g() { printf("A"); } 54 }; 55 56 // CHECK-LABEL: 0 | struct C 57 // CHECK-NEXT: 0 | (C vftable pointer) 58 // CHECK-NEXT: 4 | (C vbtable pointer) 59 // CHECK-NEXT: 8 | struct B0 (virtual base) 60 // CHECK-NEXT: 8 | (B0 vftable pointer) 61 // CHECK-NEXT: 12 | int a 62 // CHECK-NEXT: | [sizeof=16, align=4 63 // CHECK-NEXT: | nvsize=8, nvalign=4] 64 // CHECK-X64-LABEL: 0 | struct C 65 // CHECK-X64-NEXT: 0 | (C vftable pointer) 66 // CHECK-X64-NEXT: 8 | (C vbtable pointer) 67 // CHECK-X64-NEXT: 16 | struct B0 (virtual base) 68 // CHECK-X64-NEXT: 16 | (B0 vftable pointer) 69 // CHECK-X64-NEXT: 24 | int a 70 // CHECK-X64-NEXT: | [sizeof=32, align=8 71 // CHECK-X64-NEXT: | nvsize=16, nvalign=8] 72 73 struct D : virtual B2, virtual B0 { 74 virtual void f() { printf("D"); } 75 virtual void g() { printf("D"); } 76 }; 77 78 // CHECK-LABEL: 0 | struct D 79 // CHECK-NEXT: 0 | (D vftable pointer) 80 // CHECK-NEXT: 4 | (D vbtable pointer) 81 // CHECK-NEXT: 8 | struct B2 (virtual base) 82 // CHECK-NEXT: 8 | int a 83 // CHECK-NEXT: 12 | struct B0 (virtual base) 84 // CHECK-NEXT: 12 | (B0 vftable pointer) 85 // CHECK-NEXT: 16 | int a 86 // CHECK-NEXT: | [sizeof=20, align=4 87 // CHECK-NEXT: | nvsize=8, nvalign=4] 88 // CHECK-X64-LABEL: 0 | struct D 89 // CHECK-X64-NEXT: 0 | (D vftable pointer) 90 // CHECK-X64-NEXT: 8 | (D vbtable pointer) 91 // CHECK-X64-NEXT: 16 | struct B2 (virtual base) 92 // CHECK-X64-NEXT: 16 | int a 93 // CHECK-X64-NEXT: 24 | struct B0 (virtual base) 94 // CHECK-X64-NEXT: 24 | (B0 vftable pointer) 95 // CHECK-X64-NEXT: 32 | int a 96 // CHECK-X64-NEXT: | [sizeof=40, align=8 97 // CHECK-X64-NEXT: | nvsize=16, nvalign=8] 98 99 struct E : B0, virtual B1 { 100 virtual void f() { printf("E"); } 101 virtual void g() { printf("E"); } 102 }; 103 104 // CHECK-LABEL: 0 | struct E 105 // CHECK-NEXT: 0 | struct B0 (primary base) 106 // CHECK-NEXT: 0 | (B0 vftable pointer) 107 // CHECK-NEXT: 4 | int a 108 // CHECK-NEXT: 8 | (E vbtable pointer) 109 // CHECK-NEXT: 12 | struct B1 (virtual base) 110 // CHECK-NEXT: 12 | (B1 vftable pointer) 111 // CHECK-NEXT: 16 | int a 112 // CHECK-NEXT: | [sizeof=20, align=4 113 // CHECK-NEXT: | nvsize=12, nvalign=4] 114 // CHECK-X64-LABEL: 0 | struct E 115 // CHECK-X64-NEXT: 0 | struct B0 (primary base) 116 // CHECK-X64-NEXT: 0 | (B0 vftable pointer) 117 // CHECK-X64-NEXT: 8 | int a 118 // CHECK-X64-NEXT: 16 | (E vbtable pointer) 119 // CHECK-X64-NEXT: 24 | struct B1 (virtual base) 120 // CHECK-X64-NEXT: 24 | (B1 vftable pointer) 121 // CHECK-X64-NEXT: 32 | int a 122 // CHECK-X64-NEXT: | [sizeof=40, align=8 123 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 124 125 struct F : virtual B0, virtual B1 { 126 }; 127 128 // CHECK-LABEL: 0 | struct F 129 // CHECK-NEXT: 0 | (F vbtable pointer) 130 // CHECK-NEXT: 4 | struct B0 (virtual base) 131 // CHECK-NEXT: 4 | (B0 vftable pointer) 132 // CHECK-NEXT: 8 | int a 133 // CHECK-NEXT: 12 | struct B1 (virtual base) 134 // CHECK-NEXT: 12 | (B1 vftable pointer) 135 // CHECK-NEXT: 16 | int a 136 // CHECK-NEXT: | [sizeof=20, align=4 137 // CHECK-NEXT: | nvsize=4, nvalign=4] 138 // CHECK-X64-LABEL: 0 | struct F 139 // CHECK-X64-NEXT: 0 | (F vbtable pointer) 140 // CHECK-X64-NEXT: 8 | struct B0 (virtual base) 141 // CHECK-X64-NEXT: 8 | (B0 vftable pointer) 142 // CHECK-X64-NEXT: 16 | int a 143 // CHECK-X64-NEXT: 24 | struct B1 (virtual base) 144 // CHECK-X64-NEXT: 24 | (B1 vftable pointer) 145 // CHECK-X64-NEXT: 32 | int a 146 // CHECK-X64-NEXT: | [sizeof=40, align=8 147 // CHECK-X64-NEXT: | nvsize=8, nvalign=8] 148 149 struct AX : B0X, B1X { int a; AX() : a(0xf000000A) {} virtual void f() { printf("A"); } }; 150 151 // CHECK-LABEL: 0 | struct AX 152 // CHECK-NEXT: 0 | struct B1X (primary base) 153 // CHECK-NEXT: 0 | (B1X vftable pointer) 154 // CHECK-NEXT: 4 | int a 155 // CHECK-NEXT: 8 | struct B0X (base) 156 // CHECK-NEXT: 8 | int a 157 // CHECK-NEXT: 12 | int a 158 // CHECK-NEXT: | [sizeof=16, align=4 159 // CHECK-NEXT: | nvsize=16, nvalign=4] 160 // CHECK-X64-LABEL: 0 | struct AX 161 // CHECK-X64-NEXT: 0 | struct B1X (primary base) 162 // CHECK-X64-NEXT: 0 | (B1X vftable pointer) 163 // CHECK-X64-NEXT: 8 | int a 164 // CHECK-X64-NEXT: 16 | struct B0X (base) 165 // CHECK-X64-NEXT: 16 | int a 166 // CHECK-X64-NEXT: 20 | int a 167 // CHECK-X64-NEXT: | [sizeof=24, align=8 168 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 169 170 struct BX : B0X, B1X { int a; BX() : a(0xf000000B) {} virtual void g() { printf("B"); } }; 171 172 // CHECK-LABEL: 0 | struct BX 173 // CHECK-NEXT: 0 | struct B1X (primary base) 174 // CHECK-NEXT: 0 | (B1X vftable pointer) 175 // CHECK-NEXT: 4 | int a 176 // CHECK-NEXT: 8 | struct B0X (base) 177 // CHECK-NEXT: 8 | int a 178 // CHECK-NEXT: 12 | int a 179 // CHECK-NEXT: | [sizeof=16, align=4 180 // CHECK-NEXT: | nvsize=16, nvalign=4] 181 // CHECK-X64-LABEL: 0 | struct BX 182 // CHECK-X64-NEXT: 0 | struct B1X (primary base) 183 // CHECK-X64-NEXT: 0 | (B1X vftable pointer) 184 // CHECK-X64-NEXT: 8 | int a 185 // CHECK-X64-NEXT: 16 | struct B0X (base) 186 // CHECK-X64-NEXT: 16 | int a 187 // CHECK-X64-NEXT: 20 | int a 188 // CHECK-X64-NEXT: | [sizeof=24, align=8 189 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 190 191 struct CX : B0X, B2X { int a; CX() : a(0xf000000C) {} virtual void g() { printf("C"); } }; 192 193 // CHECK-LABEL: 0 | struct CX 194 // CHECK-NEXT: 0 | (CX vftable pointer) 195 // CHECK-NEXT: 4 | struct B0X (base) 196 // CHECK-NEXT: 4 | int a 197 // CHECK-NEXT: 8 | struct B2X (base) 198 // CHECK-NEXT: 8 | (B2X vbtable pointer) 199 // CHECK-NEXT: 12 | int a 200 // CHECK-NEXT: 16 | int a 201 // CHECK-NEXT: 20 | struct B1X (virtual base) 202 // CHECK-NEXT: 20 | (B1X vftable pointer) 203 // CHECK-NEXT: 24 | int a 204 // CHECK-NEXT: | [sizeof=28, align=4 205 // CHECK-NEXT: | nvsize=20, nvalign=4] 206 // CHECK-X64-LABEL: 0 | struct CX 207 // CHECK-X64-NEXT: 0 | (CX vftable pointer) 208 // CHECK-X64-NEXT: 8 | struct B0X (base) 209 // CHECK-X64-NEXT: 8 | int a 210 // CHECK-X64-NEXT: 16 | struct B2X (base) 211 // CHECK-X64-NEXT: 16 | (B2X vbtable pointer) 212 // CHECK-X64-NEXT: 24 | int a 213 // CHECK-X64-NEXT: 32 | int a 214 // CHECK-X64-NEXT: 40 | struct B1X (virtual base) 215 // CHECK-X64-NEXT: 40 | (B1X vftable pointer) 216 // CHECK-X64-NEXT: 48 | int a 217 // CHECK-X64-NEXT: | [sizeof=56, align=8 218 // CHECK-X64-NEXT: | nvsize=40, nvalign=8] 219 220 struct DX : virtual B1X { int a; DX() : a(0xf000000D) {} virtual void f() { printf("D"); } }; 221 222 // CHECK-LABEL: 0 | struct DX 223 // CHECK-NEXT: 0 | (DX vbtable pointer) 224 // CHECK-NEXT: 4 | int a 225 // CHECK-NEXT: 8 | (vtordisp for vbase B1X) 226 // CHECK-NEXT: 12 | struct B1X (virtual base) 227 // CHECK-NEXT: 12 | (B1X vftable pointer) 228 // CHECK-NEXT: 16 | int a 229 // CHECK-NEXT: | [sizeof=20, align=4 230 // CHECK-NEXT: | nvsize=8, nvalign=4] 231 // CHECK-X64-LABEL: 0 | struct DX 232 // CHECK-X64-NEXT: 0 | (DX vbtable pointer) 233 // CHECK-X64-NEXT: 8 | int a 234 // CHECK-X64-NEXT: 20 | (vtordisp for vbase B1X) 235 // CHECK-X64-NEXT: 24 | struct B1X (virtual base) 236 // CHECK-X64-NEXT: 24 | (B1X vftable pointer) 237 // CHECK-X64-NEXT: 32 | int a 238 // CHECK-X64-NEXT: | [sizeof=40, align=8 239 // CHECK-X64-NEXT: | nvsize=16, nvalign=8] 240 241 struct EX : virtual B1X { int a; EX() : a(0xf000000E) {} virtual void g() { printf("E"); } }; 242 243 // CHECK-LABEL: 0 | struct EX 244 // CHECK-NEXT: 0 | (EX vftable pointer) 245 // CHECK-NEXT: 4 | (EX vbtable pointer) 246 // CHECK-NEXT: 8 | int a 247 // CHECK-NEXT: 12 | struct B1X (virtual base) 248 // CHECK-NEXT: 12 | (B1X vftable pointer) 249 // CHECK-NEXT: 16 | int a 250 // CHECK-NEXT: | [sizeof=20, align=4 251 // CHECK-NEXT: | nvsize=12, nvalign=4] 252 // CHECK-X64-LABEL: 0 | struct EX 253 // CHECK-X64-NEXT: 0 | (EX vftable pointer) 254 // CHECK-X64-NEXT: 8 | (EX vbtable pointer) 255 // CHECK-X64-NEXT: 16 | int a 256 // CHECK-X64-NEXT: 24 | struct B1X (virtual base) 257 // CHECK-X64-NEXT: 24 | (B1X vftable pointer) 258 // CHECK-X64-NEXT: 32 | int a 259 // CHECK-X64-NEXT: | [sizeof=40, align=8 260 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 261 262 struct FX : virtual B1X { int a; FX() : a(0xf000000F) {} }; 263 264 // CHECK-LABEL: 0 | struct FX 265 // CHECK-NEXT: 0 | (FX vbtable pointer) 266 // CHECK-NEXT: 4 | int a 267 // CHECK-NEXT: 8 | struct B1X (virtual base) 268 // CHECK-NEXT: 8 | (B1X vftable pointer) 269 // CHECK-NEXT: 12 | int a 270 // CHECK-NEXT: | [sizeof=16, align=4 271 // CHECK-NEXT: | nvsize=8, nvalign=4] 272 // CHECK-X64-LABEL: 0 | struct FX 273 // CHECK-X64-NEXT: 0 | (FX vbtable pointer) 274 // CHECK-X64-NEXT: 8 | int a 275 // CHECK-X64-NEXT: 16 | struct B1X (virtual base) 276 // CHECK-X64-NEXT: 16 | (B1X vftable pointer) 277 // CHECK-X64-NEXT: 24 | int a 278 // CHECK-X64-NEXT: | [sizeof=32, align=8 279 // CHECK-X64-NEXT: | nvsize=16, nvalign=8] 280 281 int a[ 282 sizeof(A)+ 283 sizeof(B)+ 284 sizeof(C)+ 285 sizeof(D)+ 286 sizeof(E)+ 287 sizeof(F)+ 288 sizeof(AX)+ 289 sizeof(BX)+ 290 sizeof(CX)+ 291 sizeof(DX)+ 292 sizeof(EX)+ 293 sizeof(FX)]; 294