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 #pragma pack(pop) 71 72 // This needs only for building layouts. 73 // Without this clang doesn`t dump record layouts. 74 int main() { 75 // This avoid "Can't yet mangle constructors!" for MS ABI. 76 C* c; 77 c->foo(); 78 DerivedStruct* v; 79 H* g; 80 BaseStruct* u; 81 I* i; 82 return 0; 83 } 84 85 // CHECK: 0 | class D 86 // CHECK-NEXT: 0 | (D vftable pointer) 87 // CHECK-NEXT: 8 | double a 88 89 // CHECK-NEXT: sizeof=16, dsize=16, align=8 90 // CHECK-NEXT: nvsize=16, nvalign=8 91 92 // CHECK: %class.D = type { [8 x i8], double } 93 94 // CHECK: 0 | class B 95 // CHECK-NEXT: 0 | (B vftable pointer) 96 // CHECK-NEXT: 4 | int b_field 97 98 // CHECK-NEXT: sizeof=8, dsize=8, align=4 99 // CHECK-NEXT: nvsize=8, nvalign=4 100 101 // CHECK: %class.B = type { [4 x i8], i32 } 102 103 // CHECK: 0 | class A 104 // CHECK-NEXT: 0 | class B (primary base) 105 // CHECK-NEXT: 0 | (B vftable pointer) 106 // CHECK-NEXT: 4 | int b_field 107 // CHECK-NEXT: 8 | int a_field 108 // CHECK-NEXT: 12 | char one 109 110 // CHECK-NEXT: sizeof=16, dsize=16, align=4 111 // CHECK-NEXT: nvsize=16, nvalign=4 112 113 // CHECK: 0 | class C 114 // CHECK-NEXT: 0 | class D (primary base) 115 // CHECK-NEXT: 0 | (D vftable pointer) 116 // CHECK-NEXT: 8 | double a 117 // CHECK-NEXT: 16 | class B (base) 118 // CHECK-NEXT: 16 | (B vftable pointer) 119 // CHECK-NEXT: 20 | int b_field 120 // CHECK-NEXT: 24 | (C vbtable pointer) 121 // CHECK-NEXT: 32 | double c1_field 122 // CHECK-NEXT: 40 | int c2_field 123 // CHECK-NEXT: 48 | double c3_field 124 // CHECK-NEXT: 56 | int c4_field 125 // CHECK-NEXT: 64 | class A (virtual base) 126 // CHECK-NEXT: 64 | class B (primary base) 127 // CHECK-NEXT: 64 | (B vftable pointer) 128 // CHECK-NEXT: 68 | int b_field 129 // CHECK-NEXT: 72 | int a_field 130 // CHECK-NEXT: 76 | char one 131 132 // CHECK-NEXT: sizeof=80, dsize=80, align=8 133 // CHECK-NEXT: nvsize=64, nvalign=8 134 135 // CHECK: %class.A = type { %class.B, i32, i8 } 136 137 // CHECK: %class.C = type { %class.D, %class.B, [8 x i8], double, i32, double, i32, [4 x i8], %class.A } 138 // CHECK: %class.C.base = type { %class.D, %class.B, [8 x i8], double, i32, double, i32 } 139 140 // CHECK: 0 | struct BaseStruct 141 // CHECK-NEXT: 0 | double v0 142 // CHECK-NEXT: 8 | float v1 143 // CHECK-NEXT: 16 | class C fg 144 // CHECK-NEXT: 16 | class D (primary base) 145 // CHECK-NEXT: 16 | (D vftable pointer) 146 // CHECK-NEXT: 24 | double a 147 // CHECK-NEXT: 32 | class B (base) 148 // CHECK-NEXT: 32 | (B vftable pointer) 149 // CHECK-NEXT: 36 | int b_field 150 // CHECK-NEXT: 40 | (C vbtable pointer) 151 // CHECK-NEXT: 48 | double c1_field 152 // CHECK-NEXT: 56 | int c2_field 153 // CHECK-NEXT: 64 | double c3_field 154 // CHECK-NEXT: 72 | int c4_field 155 // CHECK-NEXT: 80 | class A (virtual base) 156 // CHECK-NEXT: 80 | class B (primary base) 157 // CHECK-NEXT: 80 | (B vftable pointer) 158 // CHECK-NEXT: 84 | int b_field 159 // CHECK-NEXT: 88 | int a_field 160 // CHECK-NEXT: 92 | char one 161 162 // CHECK-NEXT: sizeof=80, dsize=80, align=8 163 // CHECK-NEXT: nvsize=64, nvalign=8 164 165 // CHECK: sizeof=96, dsize=96, align=8 166 // CHECK-NEXT: nvsize=96, nvalign=8 167 168 // CHECK: %struct.BaseStruct = type { double, float, %class.C } 169 170 // CHECK: 0 | struct DerivedStruct 171 // CHECK-NEXT: 0 | struct BaseStruct (base) 172 // CHECK-NEXT: 0 | double v0 173 // CHECK-NEXT: 8 | float v1 174 // CHECK-NEXT: 16 | class C fg 175 // CHECK-NEXT: 16 | class D (primary base) 176 // CHECK-NEXT: 16 | (D vftable pointer) 177 // CHECK-NEXT: 24 | double a 178 // CHECK-NEXT: 32 | class B (base) 179 // CHECK-NEXT: 32 | (B vftable pointer) 180 // CHECK-NEXT: 36 | int b_field 181 // CHECK-NEXT: 40 | (C vbtable pointer) 182 // CHECK-NEXT: 48 | double c1_field 183 // CHECK-NEXT: 56 | int c2_field 184 // CHECK-NEXT: 64 | double c3_field 185 // CHECK-NEXT: 72 | int c4_field 186 // CHECK-NEXT: 80 | class A (virtual base) 187 // CHECK-NEXT: 80 | class B (primary base) 188 // CHECK-NEXT: 80 | (B vftable pointer) 189 // CHECK-NEXT: 84 | int b_field 190 // CHECK-NEXT: 88 | int a_field 191 // CHECK-NEXT: 92 | char one 192 // CHECK-NEXT: sizeof=80, dsize=80, align=8 193 // CHECK-NEXT: nvsize=64, nvalign=8 194 195 // CHECK: 96 | int x 196 // CHECK-NEXT: sizeof=104, dsize=104, align=8 197 // CHECK-NEXT: nvsize=104, nvalign=8 198 199 // CHECK: %struct.DerivedStruct = type { %struct.BaseStruct, i32 } 200 201 // CHECK: 0 | struct G 202 // CHECK-NEXT: 0 | int g_field 203 // CHECK-NEXT: sizeof=4, dsize=4, align=4 204 // CHECK-NEXT: nvsize=4, nvalign=4 205 206 // CHECK: 0 | struct H 207 // CHECK-NEXT: 0 | struct G (base) 208 // CHECK-NEXT: 0 | int g_field 209 // CHECK-NEXT: 4 | (H vbtable pointer) 210 // CHECK-NEXT: 8 | class D (virtual base) 211 // CHECK-NEXT: 8 | (D vftable pointer) 212 // CHECK-NEXT: 16 | double a 213 // CHECK-NEXT: sizeof=24, dsize=24, align=8 214 // CHECK-NEXT: nvsize=8, nvalign=4 215 216 // CHECK: %struct.H = type { %struct.G, [4 x i8], %class.D } 217 218 // CHECK: 0 | struct I 219 // CHECK-NEXT: 0 | (I vftable pointer) 220 // CHECK-NEXT: 8 | (I vbtable pointer) 221 // CHECK-NEXT: 16 | double q 222 // CHECK-NEXT: 24 | class D (virtual base) 223 // CHECK-NEXT: 24 | (D vftable pointer) 224 // CHECK-NEXT: 32 | double a 225 // CHECK-NEXT: sizeof=40, dsize=40, align=8 226 // CHECK-NEXT: nvsize=24, nvalign=8 227 228 // CHECK: %struct.I = type { [16 x i8], double, %class.D } 229 // CHECK: %struct.I.base = type { [16 x i8], double } 230