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 #pragma pack(pop) 65 66 // This needs only for building layouts. 67 // Without this clang doesn`t dump record layouts. 68 int main() { 69 // This avoid "Can't yet mangle constructors!" for MS ABI. 70 C* c; 71 c->foo(); 72 DerivedStruct* v; 73 H* g; 74 BaseStruct* u; 75 return 0; 76 } 77 78 // CHECK: 0 | class D 79 // CHECK-NEXT: 0 | (D vtable pointer) 80 // CHECK-NEXT: 8 | double a 81 82 // CHECK-NEXT: sizeof=16, dsize=16, align=8 83 // CHECK-NEXT: nvsize=16, nvalign=8 84 85 // CHECK: 0 | class B 86 // CHECK-NEXT: 0 | (B vtable pointer) 87 // CHECK-NEXT: 4 | int b_field 88 89 // CHECK-NEXT: sizeof=8, dsize=8, align=4 90 // CHECK-NEXT: nvsize=8, nvalign=4 91 92 // CHECK: 0 | class A 93 // CHECK-NEXT: 0 | class B (primary base) 94 // CHECK-NEXT: 0 | (B vtable pointer) 95 // CHECK-NEXT: 4 | int b_field 96 // CHECK-NEXT: 8 | int a_field 97 // CHECK-NEXT: 12 | char one 98 99 // CHECK-NEXT: sizeof=16, dsize=16, align=4 100 // CHECK-NEXT: nvsize=16, nvalign=4 101 102 // CHECK: 0 | class C 103 // CHECK-NEXT: 0 | class D (primary base) 104 // CHECK-NEXT: 0 | (D vtable pointer) 105 // CHECK-NEXT: 8 | double a 106 // CHECK-NEXT: 16 | class B (base) 107 // CHECK-NEXT: 16 | (B vtable pointer) 108 // CHECK-NEXT: 20 | int b_field 109 // CHECK-NEXT: 24 | (C vbtable pointer) 110 // CHECK-NEXT: 32 | double c1_field 111 // CHECK-NEXT: 40 | int c2_field 112 // CHECK-NEXT: 48 | double c3_field 113 // CHECK-NEXT: 56 | int c4_field 114 // CHECK-NEXT: 64 | class A (virtual base) 115 // CHECK-NEXT: 64 | class B (primary base) 116 // CHECK-NEXT: 64 | (B vtable pointer) 117 // CHECK-NEXT: 68 | int b_field 118 // CHECK-NEXT: 72 | int a_field 119 // CHECK-NEXT: 76 | char one 120 121 // CHECK-NEXT: sizeof=80, dsize=80, align=8 122 // CHECK-NEXT: nvsize=80, nvalign=8 123 124 // CHECK: 0 | struct BaseStruct 125 // CHECK-NEXT: 0 | double v0 126 // CHECK-NEXT: 8 | float v1 127 // CHECK-NEXT: 16 | class C fg 128 // CHECK-NEXT: 16 | class D (primary base) 129 // CHECK-NEXT: 16 | (D vtable pointer) 130 // CHECK-NEXT: 24 | double a 131 // CHECK-NEXT: 32 | class B (base) 132 // CHECK-NEXT: 32 | (B vtable pointer) 133 // CHECK-NEXT: 36 | int b_field 134 // CHECK-NEXT: 40 | (C vbtable pointer) 135 // CHECK-NEXT: 48 | double c1_field 136 // CHECK-NEXT: 56 | int c2_field 137 // CHECK-NEXT: 64 | double c3_field 138 // CHECK-NEXT: 72 | int c4_field 139 // CHECK-NEXT: 80 | class A (virtual base) 140 // CHECK-NEXT: 80 | class B (primary base) 141 // CHECK-NEXT: 80 | (B vtable pointer) 142 // CHECK-NEXT: 84 | int b_field 143 // CHECK-NEXT: 88 | int a_field 144 // CHECK-NEXT: 92 | char one 145 146 // CHECK-NEXT: sizeof=80, dsize=80, align=8 147 // CHECK-NEXT: nvsize=80, nvalign=8 148 149 // CHECK: sizeof=96, dsize=96, align=8 150 // CHECK-NEXT: nvsize=96, nvalign=8 151 152 // CHECK: 0 | struct DerivedStruct 153 // CHECK-NEXT: 0 | struct BaseStruct (base) 154 // CHECK-NEXT: 0 | double v0 155 // CHECK-NEXT: 8 | float v1 156 // CHECK-NEXT: 16 | class C fg 157 // CHECK-NEXT: 16 | class D (primary base) 158 // CHECK-NEXT: 16 | (D vtable pointer) 159 // CHECK-NEXT: 24 | double a 160 // CHECK-NEXT: 32 | class B (base) 161 // CHECK-NEXT: 32 | (B vtable pointer) 162 // CHECK-NEXT: 36 | int b_field 163 // CHECK-NEXT: 40 | (C vbtable pointer) 164 // CHECK-NEXT: 48 | double c1_field 165 // CHECK-NEXT: 56 | int c2_field 166 // CHECK-NEXT: 64 | double c3_field 167 // CHECK-NEXT: 72 | int c4_field 168 // CHECK-NEXT: 80 | class A (virtual base) 169 // CHECK-NEXT: 80 | class B (primary base) 170 // CHECK-NEXT: 80 | (B vtable pointer) 171 // CHECK-NEXT: 84 | int b_field 172 // CHECK-NEXT: 88 | int a_field 173 // CHECK-NEXT: 92 | char one 174 // CHECK-NEXT: sizeof=80, dsize=80, align=8 175 // CHECK-NEXT: nvsize=80, nvalign=8 176 177 // CHECK: 96 | int x 178 // CHECK-NEXT: sizeof=104, dsize=104, align=8 179 // CHECK-NEXT: nvsize=104, nvalign=8 180 181 // CHECK: 0 | struct G 182 // CHECK-NEXT: 0 | int g_field 183 // CHECK-NEXT: sizeof=4, dsize=4, align=4 184 // CHECK-NEXT: nvsize=4, nvalign=4 185 186 // FIXME: Dump should not be showing vfptr, and vbptr is in the wrong order. 187 // CHECK: 0 | struct H 188 // CHECK-NEXT: 0 | (H vtable pointer) 189 // CHECK-NEXT: 4 | (H vbtable pointer) 190 // CHECK-NEXT: 0 | struct G (base) 191 // CHECK-NEXT: 0 | int g_field 192 // CHECK-NEXT: 8 | class D (virtual base) 193 // CHECK-NEXT: 8 | (D vtable pointer) 194 // CHECK-NEXT: 16 | double a 195 // CHECK-NEXT: sizeof=24, dsize=24, align=8 196 // CHECK-NEXT: nvsize=24, nvalign=8 197