1 // RUN: %clang_cc1 -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -cxx-abi microsoft %s 2>&1 \ 2 // RUN: | FileCheck %s 3 4 #pragma pack(push, 8) 5 6 class B { 7 public: 8 virtual void b(){} 9 int b_field; 10 protected: 11 private: 12 }; 13 14 class A : public B { 15 public: 16 int a_field; 17 virtual void a(){} 18 char one; 19 protected: 20 private: 21 }; 22 23 class D { 24 public: 25 virtual void b(){} 26 double a; 27 }; 28 29 class C : public virtual A, 30 public D, public B { 31 public: 32 double c1_field; 33 int c2_field; 34 double c3_field; 35 int c4_field; 36 virtual void foo(){} 37 virtual void bar(){} 38 protected: 39 private: 40 }; 41 42 struct BaseStruct 43 { 44 BaseStruct(){} 45 double v0; 46 float v1; 47 C fg; 48 }; 49 50 struct DerivedStruct : public BaseStruct { 51 int x; 52 }; 53 54 struct G 55 { 56 int g_field; 57 }; 58 59 struct H : public G, 60 public virtual D 61 { 62 }; 63 64 struct I : public virtual D 65 { 66 virtual ~I(){} 67 double q; 68 }; 69 70 struct K 71 { 72 int k; 73 }; 74 75 struct L 76 { 77 int l; 78 }; 79 80 struct M : public virtual K 81 { 82 int m; 83 }; 84 85 struct N : public L, public M 86 { 87 virtual void f(){} 88 }; 89 90 struct O : public H, public G { 91 virtual void fo(){} 92 }; 93 94 struct P : public M, public virtual L { 95 int p; 96 }; 97 98 struct R {}; 99 100 #pragma pack(pop) 101 102 // This needs only for building layouts. 103 // Without this clang doesn`t dump record layouts. 104 int main() { 105 // This avoid "Can't yet mangle constructors!" for MS ABI. 106 C* c; 107 c->foo(); 108 DerivedStruct* v; 109 H* g; 110 BaseStruct* u; 111 I* i; 112 N* n; 113 O* o; 114 P* p; 115 R* r; 116 return 0; 117 } 118 119 // CHECK: 0 | class D 120 // CHECK-NEXT: 0 | (D vftable pointer) 121 // CHECK-NEXT: 8 | double a 122 123 // CHECK-NEXT: sizeof=16, dsize=16, align=8 124 // CHECK-NEXT: nvsize=16, nvalign=8 125 126 // CHECK: %class.D = type { i32 (...)**, double } 127 128 // CHECK: 0 | class B 129 // CHECK-NEXT: 0 | (B vftable pointer) 130 // CHECK-NEXT: 4 | int b_field 131 132 // CHECK-NEXT: sizeof=8, dsize=8, align=4 133 // CHECK-NEXT: nvsize=8, nvalign=4 134 135 // CHECK: %class.B = type { i32 (...)**, i32 } 136 137 // CHECK: 0 | class A 138 // CHECK-NEXT: 0 | class B (primary base) 139 // CHECK-NEXT: 0 | (B vftable pointer) 140 // CHECK-NEXT: 4 | int b_field 141 // CHECK-NEXT: 8 | int a_field 142 // CHECK-NEXT: 12 | char one 143 144 // CHECK-NEXT: sizeof=16, dsize=16, align=4 145 // CHECK-NEXT: nvsize=16, nvalign=4 146 147 // CHECK: 0 | class C 148 // CHECK-NEXT: 0 | class D (primary base) 149 // CHECK-NEXT: 0 | (D vftable pointer) 150 // CHECK-NEXT: 8 | double a 151 // CHECK-NEXT: 16 | class B (base) 152 // CHECK-NEXT: 16 | (B vftable pointer) 153 // CHECK-NEXT: 20 | int b_field 154 // CHECK-NEXT: 24 | (C vbtable pointer) 155 // CHECK-NEXT: 32 | double c1_field 156 // CHECK-NEXT: 40 | int c2_field 157 // CHECK-NEXT: 48 | double c3_field 158 // CHECK-NEXT: 56 | int c4_field 159 // CHECK-NEXT: 64 | class A (virtual base) 160 // CHECK-NEXT: 64 | class B (primary base) 161 // CHECK-NEXT: 64 | (B vftable pointer) 162 // CHECK-NEXT: 68 | int b_field 163 // CHECK-NEXT: 72 | int a_field 164 // CHECK-NEXT: 76 | char one 165 166 // CHECK-NEXT: sizeof=80, dsize=80, align=8 167 // CHECK-NEXT: nvsize=64, nvalign=8 168 169 // CHECK: %class.A = type { %class.B, i32, i8 } 170 171 // CHECK: %class.C = type { %class.D, %class.B, i32*, double, i32, double, i32, [4 x i8], %class.A } 172 // CHECK: %class.C.base = type { %class.D, %class.B, i32*, double, i32, double, i32 } 173 174 // CHECK: 0 | struct BaseStruct 175 // CHECK-NEXT: 0 | double v0 176 // CHECK-NEXT: 8 | float v1 177 // CHECK-NEXT: 16 | class C fg 178 // CHECK-NEXT: 16 | class D (primary base) 179 // CHECK-NEXT: 16 | (D vftable pointer) 180 // CHECK-NEXT: 24 | double a 181 // CHECK-NEXT: 32 | class B (base) 182 // CHECK-NEXT: 32 | (B vftable pointer) 183 // CHECK-NEXT: 36 | int b_field 184 // CHECK-NEXT: 40 | (C vbtable pointer) 185 // CHECK-NEXT: 48 | double c1_field 186 // CHECK-NEXT: 56 | int c2_field 187 // CHECK-NEXT: 64 | double c3_field 188 // CHECK-NEXT: 72 | int c4_field 189 // CHECK-NEXT: 80 | class A (virtual base) 190 // CHECK-NEXT: 80 | class B (primary base) 191 // CHECK-NEXT: 80 | (B vftable pointer) 192 // CHECK-NEXT: 84 | int b_field 193 // CHECK-NEXT: 88 | int a_field 194 // CHECK-NEXT: 92 | char one 195 196 // CHECK-NEXT: sizeof=80, dsize=80, align=8 197 // CHECK-NEXT: nvsize=64, nvalign=8 198 199 // CHECK: sizeof=96, dsize=96, align=8 200 // CHECK-NEXT: nvsize=96, nvalign=8 201 202 // CHECK: %struct.BaseStruct = type { double, float, %class.C } 203 204 // CHECK: 0 | struct DerivedStruct 205 // CHECK-NEXT: 0 | struct BaseStruct (base) 206 // CHECK-NEXT: 0 | double v0 207 // CHECK-NEXT: 8 | float v1 208 // CHECK-NEXT: 16 | class C fg 209 // CHECK-NEXT: 16 | class D (primary base) 210 // CHECK-NEXT: 16 | (D vftable pointer) 211 // CHECK-NEXT: 24 | double a 212 // CHECK-NEXT: 32 | class B (base) 213 // CHECK-NEXT: 32 | (B vftable pointer) 214 // CHECK-NEXT: 36 | int b_field 215 // CHECK-NEXT: 40 | (C vbtable pointer) 216 // CHECK-NEXT: 48 | double c1_field 217 // CHECK-NEXT: 56 | int c2_field 218 // CHECK-NEXT: 64 | double c3_field 219 // CHECK-NEXT: 72 | int c4_field 220 // CHECK-NEXT: 80 | class A (virtual base) 221 // CHECK-NEXT: 80 | class B (primary base) 222 // CHECK-NEXT: 80 | (B vftable pointer) 223 // CHECK-NEXT: 84 | int b_field 224 // CHECK-NEXT: 88 | int a_field 225 // CHECK-NEXT: 92 | char one 226 // CHECK-NEXT: sizeof=80, dsize=80, align=8 227 // CHECK-NEXT: nvsize=64, nvalign=8 228 229 // CHECK: 96 | int x 230 // CHECK-NEXT: sizeof=104, dsize=104, align=8 231 // CHECK-NEXT: nvsize=104, nvalign=8 232 233 // CHECK: %struct.DerivedStruct = type { %struct.BaseStruct, i32 } 234 235 // CHECK: 0 | struct G 236 // CHECK-NEXT: 0 | int g_field 237 // CHECK-NEXT: sizeof=4, dsize=4, align=4 238 // CHECK-NEXT: nvsize=4, nvalign=4 239 240 // CHECK: 0 | struct H 241 // CHECK-NEXT: 0 | struct G (base) 242 // CHECK-NEXT: 0 | int g_field 243 // CHECK-NEXT: 4 | (H vbtable pointer) 244 // CHECK-NEXT: 8 | class D (virtual base) 245 // CHECK-NEXT: 8 | (D vftable pointer) 246 // CHECK-NEXT: 16 | double a 247 // CHECK-NEXT: sizeof=24, dsize=24, align=8 248 // CHECK-NEXT: nvsize=8, nvalign=4 249 250 // CHECK: %struct.H = type { %struct.G, i32*, %class.D } 251 252 // CHECK: 0 | struct I 253 // CHECK-NEXT: 0 | (I vftable pointer) 254 // CHECK-NEXT: 8 | (I vbtable pointer) 255 // CHECK-NEXT: 16 | double q 256 // CHECK-NEXT: 24 | class D (virtual base) 257 // CHECK-NEXT: 24 | (D vftable pointer) 258 // CHECK-NEXT: 32 | double a 259 // CHECK-NEXT: sizeof=40, dsize=40, align=8 260 // CHECK-NEXT: nvsize=24, nvalign=8 261 262 // CHECK: %struct.I = type { i32 (...)**, [4 x i8], i32*, double, %class.D } 263 // CHECK: %struct.I.base = type { i32 (...)**, [4 x i8], i32*, double } 264 265 // CHECK: 0 | struct L 266 // CHECK-NEXT: 0 | int l 267 // CHECK-NEXT: sizeof=4, dsize=4, align=4 268 // CHECK-NEXT: nvsize=4, nvalign=4 269 270 // CHECK: 0 | struct K 271 // CHECK-NEXT: 0 | int k 272 // CHECK-NEXT: sizeof=4, dsize=4, align=4 273 // CHECK-NEXT: nvsize=4, nvalign=4 274 275 // CHECK: 0 | struct M 276 // CHECK-NEXT: 0 | (M vbtable pointer) 277 // CHECK-NEXT: 4 | int m 278 // CHECK-NEXT: 8 | struct K (virtual base) 279 // CHECK-NEXT: 8 | int k 280 // CHECK-NEXT: sizeof=12, dsize=12, align=4 281 282 //CHECK: %struct.M = type { i32*, i32, %struct.K } 283 //CHECK: %struct.M.base = type { i32*, i32 } 284 285 // CHECK: 0 | struct N 286 // CHECK-NEXT: 4 | struct L (base) 287 // CHECK-NEXT: 4 | int l 288 // CHECK-NEXT: 8 | struct M (base) 289 // CHECK-NEXT: 8 | (M vbtable pointer) 290 // CHECK-NEXT: 12 | int m 291 // CHECK-NEXT: 0 | (N vftable pointer) 292 // CHECK-NEXT: 16 | struct K (virtual base) 293 // CHECK-NEXT: 16 | int k 294 // CHECK-NEXT: sizeof=20, dsize=20, align=4 295 // CHECK-NEXT: nvsize=16, nvalign=4 296 297 //CHECK: %struct.N = type { i32 (...)**, %struct.L, %struct.M.base, %struct.K } 298 299 // FIXME: MSVC place struct H at offset 8. 300 // CHECK: 0 | struct O 301 // CHECK-NEXT: 4 | struct H (base) 302 // CHECK-NEXT: 4 | struct G (base) 303 // CHECK-NEXT: 4 | int g_field 304 // CHECK-NEXT: 8 | (H vbtable pointer) 305 // CHECK-NEXT: 12 | struct G (base) 306 // CHECK-NEXT: 12 | int g_field 307 // CHECK-NEXT: 0 | (O vftable pointer) 308 // CHECK-NEXT: 16 | class D (virtual base) 309 // CHECK-NEXT: 16 | (D vftable pointer) 310 // CHECK-NEXT: 24 | double a 311 // CHECK-NEXT: sizeof=32, dsize=32, align=8 312 // CHECK-NEXT: nvsize=16, nvalign=4 313 314 //CHECK: %struct.O = type { i32 (...)**, %struct.H.base, %struct.G, %class.D } 315 //CHECK: %struct.O.base = type { i32 (...)**, %struct.H.base, %struct.G } 316 317 // CHECK: 0 | struct P 318 // CHECK-NEXT: 0 | struct M (base) 319 // CHECK-NEXT: 0 | (M vbtable pointer) 320 // CHECK-NEXT: 4 | int m 321 // CHECK-NEXT: 8 | int p 322 // CHECK-NEXT: 12 | struct K (virtual base) 323 // CHECK-NEXT: 12 | int k 324 // CHECK-NEXT: 16 | struct L (virtual base) 325 // CHECK-NEXT: 16 | int l 326 // CHECK-NEXT: sizeof=20, dsize=20, align=4 327 // CHECK-NEXT: nvsize=12, nvalign=4 328 329 //CHECK: %struct.P = type { %struct.M.base, i32, %struct.K, %struct.L } 330 331 // CHECK: 0 | struct R (empty) 332 // CHECK-NEXT: sizeof=1, dsize=0, align=1 333 // CHECK-NEXT: nvsize=0, nvalign=1 334 335 //CHECK: %struct.R = type { i8 } 336