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 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 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: *** Dumping AST Record Layout 19 // CHECK: *** Dumping AST Record Layout 20 // CHECK-NEXT: 0 | struct A 21 // CHECK-NEXT: 0 | (A vbtable pointer) 22 // CHECK-NEXT: 4 | struct B0 (virtual base) 23 // CHECK-NEXT: 4 | (B0 vftable pointer) 24 // CHECK-NEXT: 8 | int a 25 // CHECK-NEXT: | [sizeof=12, align=4 26 // CHECK-NEXT: | nvsize=4, nvalign=4] 27 // CHECK-X64: *** Dumping AST Record Layout 28 // CHECK-X64: *** Dumping AST Record Layout 29 // CHECK-X64-NEXT: 0 | struct A 30 // CHECK-X64-NEXT: 0 | (A vbtable pointer) 31 // CHECK-X64-NEXT: 8 | struct B0 (virtual base) 32 // CHECK-X64-NEXT: 8 | (B0 vftable pointer) 33 // CHECK-X64-NEXT: 16 | int a 34 // CHECK-X64-NEXT: | [sizeof=24, align=8 35 // CHECK-X64-NEXT: | nvsize=8, nvalign=8] 36 37 struct B : virtual B0 { 38 virtual void f() { printf("B"); } 39 }; 40 41 // CHECK: *** Dumping AST Record Layout 42 // CHECK-NEXT: 0 | struct B 43 // CHECK-NEXT: 0 | (B vbtable pointer) 44 // CHECK-NEXT: 4 | struct B0 (virtual base) 45 // CHECK-NEXT: 4 | (B0 vftable pointer) 46 // CHECK-NEXT: 8 | int a 47 // CHECK-NEXT: | [sizeof=12, align=4 48 // CHECK-NEXT: | nvsize=4, nvalign=4] 49 // CHECK-X64: *** Dumping AST Record Layout 50 // CHECK-X64-NEXT: 0 | struct B 51 // CHECK-X64-NEXT: 0 | (B vbtable pointer) 52 // CHECK-X64-NEXT: 8 | struct B0 (virtual base) 53 // CHECK-X64-NEXT: 8 | (B0 vftable pointer) 54 // CHECK-X64-NEXT: 16 | int a 55 // CHECK-X64-NEXT: | [sizeof=24, align=8 56 // CHECK-X64-NEXT: | nvsize=8, nvalign=8] 57 58 struct C : virtual B0 { 59 virtual void g() { printf("A"); } 60 }; 61 62 // CHECK: *** Dumping AST Record Layout 63 // CHECK-NEXT: 0 | struct C 64 // CHECK-NEXT: 0 | (C vftable pointer) 65 // CHECK-NEXT: 4 | (C vbtable pointer) 66 // CHECK-NEXT: 8 | struct B0 (virtual base) 67 // CHECK-NEXT: 8 | (B0 vftable pointer) 68 // CHECK-NEXT: 12 | int a 69 // CHECK-NEXT: | [sizeof=16, align=4 70 // CHECK-NEXT: | nvsize=8, nvalign=4] 71 // CHECK-X64: *** Dumping AST Record Layout 72 // CHECK-X64-NEXT: 0 | struct C 73 // CHECK-X64-NEXT: 0 | (C vftable pointer) 74 // CHECK-X64-NEXT: 8 | (C vbtable pointer) 75 // CHECK-X64-NEXT: 16 | struct B0 (virtual base) 76 // CHECK-X64-NEXT: 16 | (B0 vftable pointer) 77 // CHECK-X64-NEXT: 24 | int a 78 // CHECK-X64-NEXT: | [sizeof=32, align=8 79 // CHECK-X64-NEXT: | nvsize=16, nvalign=8] 80 81 struct D : virtual B2, virtual B0 { 82 virtual void f() { printf("D"); } 83 virtual void g() { printf("D"); } 84 }; 85 86 // CHECK: *** Dumping AST Record Layout 87 // CHECK: *** Dumping AST Record Layout 88 // CHECK-NEXT: 0 | struct D 89 // CHECK-NEXT: 0 | (D vftable pointer) 90 // CHECK-NEXT: 4 | (D vbtable pointer) 91 // CHECK-NEXT: 8 | struct B2 (virtual base) 92 // CHECK-NEXT: 8 | int a 93 // CHECK-NEXT: 12 | struct B0 (virtual base) 94 // CHECK-NEXT: 12 | (B0 vftable pointer) 95 // CHECK-NEXT: 16 | int a 96 // CHECK-NEXT: | [sizeof=20, align=4 97 // CHECK-NEXT: | nvsize=8, nvalign=4] 98 // CHECK-X64: *** Dumping AST Record Layout 99 // CHECK-X64: *** Dumping AST Record Layout 100 // CHECK-X64-NEXT: 0 | struct D 101 // CHECK-X64-NEXT: 0 | (D vftable pointer) 102 // CHECK-X64-NEXT: 8 | (D vbtable pointer) 103 // CHECK-X64-NEXT: 16 | struct B2 (virtual base) 104 // CHECK-X64-NEXT: 16 | int a 105 // CHECK-X64-NEXT: 24 | struct B0 (virtual base) 106 // CHECK-X64-NEXT: 24 | (B0 vftable pointer) 107 // CHECK-X64-NEXT: 32 | int a 108 // CHECK-X64-NEXT: | [sizeof=40, align=8 109 // CHECK-X64-NEXT: | nvsize=16, nvalign=8] 110 111 struct E : B0, virtual B1 { 112 virtual void f() { printf("E"); } 113 virtual void g() { printf("E"); } 114 }; 115 116 // CHECK: *** Dumping AST Record Layout 117 // CHECK: *** Dumping AST Record Layout 118 // CHECK-NEXT: 0 | struct E 119 // CHECK-NEXT: 0 | struct B0 (primary base) 120 // CHECK-NEXT: 0 | (B0 vftable pointer) 121 // CHECK-NEXT: 4 | int a 122 // CHECK-NEXT: 8 | (E vbtable pointer) 123 // CHECK-NEXT: 12 | struct B1 (virtual base) 124 // CHECK-NEXT: 12 | (B1 vftable pointer) 125 // CHECK-NEXT: 16 | int a 126 // CHECK-NEXT: | [sizeof=20, align=4 127 // CHECK-NEXT: | nvsize=12, nvalign=4] 128 // CHECK-X64: *** Dumping AST Record Layout 129 // CHECK-X64: *** Dumping AST Record Layout 130 // CHECK-X64-NEXT: 0 | struct E 131 // CHECK-X64-NEXT: 0 | struct B0 (primary base) 132 // CHECK-X64-NEXT: 0 | (B0 vftable pointer) 133 // CHECK-X64-NEXT: 8 | int a 134 // CHECK-X64-NEXT: 16 | (E vbtable pointer) 135 // CHECK-X64-NEXT: 24 | struct B1 (virtual base) 136 // CHECK-X64-NEXT: 24 | (B1 vftable pointer) 137 // CHECK-X64-NEXT: 32 | int a 138 // CHECK-X64-NEXT: | [sizeof=40, align=8 139 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 140 141 struct F : virtual B0, virtual B1 { 142 }; 143 144 // CHECK: *** Dumping AST Record Layout 145 // CHECK-NEXT: 0 | struct F 146 // CHECK-NEXT: 0 | (F vbtable pointer) 147 // CHECK-NEXT: 4 | struct B0 (virtual base) 148 // CHECK-NEXT: 4 | (B0 vftable pointer) 149 // CHECK-NEXT: 8 | int a 150 // CHECK-NEXT: 12 | struct B1 (virtual base) 151 // CHECK-NEXT: 12 | (B1 vftable pointer) 152 // CHECK-NEXT: 16 | int a 153 // CHECK-NEXT: | [sizeof=20, align=4 154 // CHECK-NEXT: | nvsize=4, nvalign=4] 155 // CHECK-X64: *** Dumping AST Record Layout 156 // CHECK-X64-NEXT: 0 | struct F 157 // CHECK-X64-NEXT: 0 | (F vbtable pointer) 158 // CHECK-X64-NEXT: 8 | struct B0 (virtual base) 159 // CHECK-X64-NEXT: 8 | (B0 vftable pointer) 160 // CHECK-X64-NEXT: 16 | int a 161 // CHECK-X64-NEXT: 24 | struct B1 (virtual base) 162 // CHECK-X64-NEXT: 24 | (B1 vftable pointer) 163 // CHECK-X64-NEXT: 32 | int a 164 // CHECK-X64-NEXT: | [sizeof=40, align=8 165 // CHECK-X64-NEXT: | nvsize=8, nvalign=8] 166 167 struct AX : B0X, B1X { int a; AX() : a(0xf000000A) {} virtual void f() { printf("A"); } }; 168 169 // CHECK: *** Dumping AST Record Layout 170 // CHECK: *** Dumping AST Record Layout 171 // CHECK: *** Dumping AST Record Layout 172 // CHECK-NEXT: 0 | struct AX 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: *** Dumping AST Record Layout 182 // CHECK-X64: *** Dumping AST Record Layout 183 // CHECK-X64: *** Dumping AST Record Layout 184 // CHECK-X64-NEXT: 0 | struct AX 185 // CHECK-X64-NEXT: 0 | struct B1X (primary base) 186 // CHECK-X64-NEXT: 0 | (B1X vftable pointer) 187 // CHECK-X64-NEXT: 8 | int a 188 // CHECK-X64-NEXT: 16 | struct B0X (base) 189 // CHECK-X64-NEXT: 16 | int a 190 // CHECK-X64-NEXT: 20 | int a 191 // CHECK-X64-NEXT: | [sizeof=24, align=8 192 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 193 194 struct BX : B0X, B1X { int a; BX() : a(0xf000000B) {} virtual void g() { printf("B"); } }; 195 196 // CHECK: *** Dumping AST Record Layout 197 // CHECK-NEXT: 0 | struct BX 198 // CHECK-NEXT: 0 | struct B1X (primary base) 199 // CHECK-NEXT: 0 | (B1X vftable pointer) 200 // CHECK-NEXT: 4 | int a 201 // CHECK-NEXT: 8 | struct B0X (base) 202 // CHECK-NEXT: 8 | int a 203 // CHECK-NEXT: 12 | int a 204 // CHECK-NEXT: | [sizeof=16, align=4 205 // CHECK-NEXT: | nvsize=16, nvalign=4] 206 // CHECK-X64: *** Dumping AST Record Layout 207 // CHECK-X64-NEXT: 0 | struct BX 208 // CHECK-X64-NEXT: 0 | struct B1X (primary base) 209 // CHECK-X64-NEXT: 0 | (B1X vftable pointer) 210 // CHECK-X64-NEXT: 8 | int a 211 // CHECK-X64-NEXT: 16 | struct B0X (base) 212 // CHECK-X64-NEXT: 16 | int a 213 // CHECK-X64-NEXT: 20 | int a 214 // CHECK-X64-NEXT: | [sizeof=24, align=8 215 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 216 217 struct CX : B0X, B2X { int a; CX() : a(0xf000000C) {} virtual void g() { printf("C"); } }; 218 219 // CHECK: *** Dumping AST Record Layout 220 // CHECK: *** Dumping AST Record Layout 221 // CHECK-NEXT: 0 | struct CX 222 // CHECK-NEXT: 0 | (CX vftable pointer) 223 // CHECK-NEXT: 4 | struct B0X (base) 224 // CHECK-NEXT: 4 | int a 225 // CHECK-NEXT: 8 | struct B2X (base) 226 // CHECK-NEXT: 8 | (B2X vbtable pointer) 227 // CHECK-NEXT: 12 | int a 228 // CHECK-NEXT: 16 | int a 229 // CHECK-NEXT: 20 | struct B1X (virtual base) 230 // CHECK-NEXT: 20 | (B1X vftable pointer) 231 // CHECK-NEXT: 24 | int a 232 // CHECK-NEXT: | [sizeof=28, align=4 233 // CHECK-NEXT: | nvsize=20, nvalign=4] 234 // CHECK-X64: *** Dumping AST Record Layout 235 // CHECK-X64: *** Dumping AST Record Layout 236 // CHECK-X64-NEXT: 0 | struct CX 237 // CHECK-X64-NEXT: 0 | (CX vftable pointer) 238 // CHECK-X64-NEXT: 8 | struct B0X (base) 239 // CHECK-X64-NEXT: 8 | int a 240 // CHECK-X64-NEXT: 16 | struct B2X (base) 241 // CHECK-X64-NEXT: 16 | (B2X vbtable pointer) 242 // CHECK-X64-NEXT: 24 | int a 243 // CHECK-X64-NEXT: 32 | int a 244 // CHECK-X64-NEXT: 40 | struct B1X (virtual base) 245 // CHECK-X64-NEXT: 40 | (B1X vftable pointer) 246 // CHECK-X64-NEXT: 48 | int a 247 // CHECK-X64-NEXT: | [sizeof=56, align=8 248 // CHECK-X64-NEXT: | nvsize=40, nvalign=8] 249 250 struct DX : virtual B1X { int a; DX() : a(0xf000000D) {} virtual void f() { printf("D"); } }; 251 252 // CHECK: *** Dumping AST Record Layout 253 // CHECK-NEXT: 0 | struct DX 254 // CHECK-NEXT: 0 | (DX vbtable pointer) 255 // CHECK-NEXT: 4 | int a 256 // CHECK-NEXT: 8 | (vtordisp for vbase B1X) 257 // CHECK-NEXT: 12 | struct B1X (virtual base) 258 // CHECK-NEXT: 12 | (B1X vftable pointer) 259 // CHECK-NEXT: 16 | int a 260 // CHECK-NEXT: | [sizeof=20, align=4 261 // CHECK-NEXT: | nvsize=8, nvalign=4] 262 // CHECK-X64: *** Dumping AST Record Layout 263 // CHECK-X64-NEXT: 0 | struct DX 264 // CHECK-X64-NEXT: 0 | (DX vbtable pointer) 265 // CHECK-X64-NEXT: 8 | int a 266 // CHECK-X64-NEXT: 20 | (vtordisp for vbase B1X) 267 // CHECK-X64-NEXT: 24 | struct B1X (virtual base) 268 // CHECK-X64-NEXT: 24 | (B1X vftable pointer) 269 // CHECK-X64-NEXT: 32 | int a 270 // CHECK-X64-NEXT: | [sizeof=40, align=8 271 // CHECK-X64-NEXT: | nvsize=16, nvalign=8] 272 273 struct EX : virtual B1X { int a; EX() : a(0xf000000E) {} virtual void g() { printf("E"); } }; 274 275 // CHECK: *** Dumping AST Record Layout 276 // CHECK-NEXT: 0 | struct EX 277 // CHECK-NEXT: 0 | (EX vftable pointer) 278 // CHECK-NEXT: 4 | (EX vbtable pointer) 279 // CHECK-NEXT: 8 | int a 280 // CHECK-NEXT: 12 | struct B1X (virtual base) 281 // CHECK-NEXT: 12 | (B1X vftable pointer) 282 // CHECK-NEXT: 16 | int a 283 // CHECK-NEXT: | [sizeof=20, align=4 284 // CHECK-NEXT: | nvsize=12, nvalign=4] 285 // CHECK-X64: *** Dumping AST Record Layout 286 // CHECK-X64-NEXT: 0 | struct EX 287 // CHECK-X64-NEXT: 0 | (EX vftable pointer) 288 // CHECK-X64-NEXT: 8 | (EX vbtable pointer) 289 // CHECK-X64-NEXT: 16 | int a 290 // CHECK-X64-NEXT: 24 | struct B1X (virtual base) 291 // CHECK-X64-NEXT: 24 | (B1X vftable pointer) 292 // CHECK-X64-NEXT: 32 | int a 293 // CHECK-X64-NEXT: | [sizeof=40, align=8 294 // CHECK-X64-NEXT: | nvsize=24, nvalign=8] 295 296 struct FX : virtual B1X { int a; FX() : a(0xf000000F) {} }; 297 298 // CHECK: *** Dumping AST Record Layout 299 // CHECK-NEXT: 0 | struct FX 300 // CHECK-NEXT: 0 | (FX vbtable pointer) 301 // CHECK-NEXT: 4 | int a 302 // CHECK-NEXT: 8 | struct B1X (virtual base) 303 // CHECK-NEXT: 8 | (B1X vftable pointer) 304 // CHECK-NEXT: 12 | int a 305 // CHECK-NEXT: | [sizeof=16, align=4 306 // CHECK-NEXT: | nvsize=8, nvalign=4] 307 // CHECK-X64: *** Dumping AST Record Layout 308 // CHECK-X64-NEXT: 0 | struct FX 309 // CHECK-X64-NEXT: 0 | (FX vbtable pointer) 310 // CHECK-X64-NEXT: 8 | int a 311 // CHECK-X64-NEXT: 16 | struct B1X (virtual base) 312 // CHECK-X64-NEXT: 16 | (B1X vftable pointer) 313 // CHECK-X64-NEXT: 24 | int a 314 // CHECK-X64-NEXT: | [sizeof=32, align=8 315 // CHECK-X64-NEXT: | nvsize=16, nvalign=8] 316 317 int a[ 318 sizeof(A)+ 319 sizeof(B)+ 320 sizeof(C)+ 321 sizeof(D)+ 322 sizeof(E)+ 323 sizeof(F)+ 324 sizeof(AX)+ 325 sizeof(BX)+ 326 sizeof(CX)+ 327 sizeof(DX)+ 328 sizeof(EX)+ 329 sizeof(FX)]; 330