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 __declspec(align(4096)) char buffer[4096]; 8 9 struct AT {}; 10 11 struct V : AT { 12 char c; 13 V() { 14 printf("V - this: %d\n", (int)((char*)this - buffer)); 15 } 16 }; 17 18 struct AT0 { 19 union { struct { int a; AT t; } y; int b; } x; 20 char c; 21 AT0() { 22 printf("AT0 - this: %d\n", (int)((char*)this - buffer)); 23 } 24 }; 25 26 struct AT1 : V { 27 int a; 28 AT1() { 29 printf("AT1 - this: %d\n", (int)((char*)this - buffer)); 30 } 31 }; 32 33 struct AT2 { 34 AT0 t; 35 char AT2FieldName0; 36 AT2() { 37 printf("AT2 - this: %d\n", (int)((char*)this - buffer)); 38 printf("AT2 - Fiel: %d\n", (int)((char*)&AT2FieldName0 - buffer)); 39 } 40 }; 41 42 struct AT3 : AT2, AT1 { 43 AT3() { 44 printf("AT3 - this: %d\n", (int)((char*)this - buffer)); 45 } 46 }; 47 48 // CHECK: *** Dumping AST Record Layout 49 // CHECK: *** Dumping AST Record Layout 50 // CHECK: *** Dumping AST Record Layout 51 // CHECK: *** Dumping AST Record Layout 52 // CHECK: *** Dumping AST Record Layout 53 // CHECK: *** Dumping AST Record Layout 54 // CHECK: *** Dumping AST Record Layout 55 // CHECK: *** Dumping AST Record Layout 56 // CHECK-NEXT: 0 | struct AT3 57 // CHECK-NEXT: 0 | struct AT2 (base) 58 // CHECK-NEXT: 0 | struct AT0 t 59 // CHECK-NEXT: 0 | union AT0::<anonymous at {{.*}} x 60 // CHECK-NEXT: 0 | struct AT0::<anonymous at {{.*}} y 61 // CHECK-NEXT: 0 | int a 62 // CHECK-NEXT: 4 | struct AT t (empty) 63 // CHECK: 0 | int b 64 // CHECK: 8 | char c 65 // CHECK: 12 | char AT2FieldName0 66 // CHECK-NEXT: 20 | struct AT1 (base) 67 // CHECK-NEXT: 20 | struct V (base) 68 // CHECK-NEXT: 20 | struct AT (base) (empty) 69 // CHECK-NEXT: 20 | char c 70 // CHECK-NEXT: 24 | int a 71 // CHECK-NEXT: | [sizeof=28, align=4 72 // CHECK-NEXT: | nvsize=28, nvalign=4] 73 // CHECK-X64: *** Dumping AST Record Layout 74 // CHECK-X64: *** Dumping AST Record Layout 75 // CHECK-X64: *** Dumping AST Record Layout 76 // CHECK-X64: *** Dumping AST Record Layout 77 // CHECK-X64: *** Dumping AST Record Layout 78 // CHECK-X64: *** Dumping AST Record Layout 79 // CHECK-X64: *** Dumping AST Record Layout 80 // CHECK-X64: *** Dumping AST Record Layout 81 // CHECK-X64-NEXT: 0 | struct AT3 82 // CHECK-X64-NEXT: 0 | struct AT2 (base) 83 // CHECK-X64-NEXT: 0 | struct AT0 t 84 // CHECK-X64-NEXT: 0 | union AT0::<anonymous at {{.*}} x 85 // CHECK-X64-NEXT: 0 | struct AT0::<anonymous at {{.*}} y 86 // CHECK-X64-NEXT: 0 | int a 87 // CHECK-X64-NEXT: 4 | struct AT t (empty) 88 // CHECK-X64: 0 | int b 89 // CHECK-X64: 8 | char c 90 // CHECK-X64: 12 | char AT2FieldName0 91 // CHECK-X64-NEXT: 20 | struct AT1 (base) 92 // CHECK-X64-NEXT: 20 | struct V (base) 93 // CHECK-X64-NEXT: 20 | struct AT (base) (empty) 94 // CHECK-X64-NEXT: 20 | char c 95 // CHECK-X64-NEXT: 24 | int a 96 // CHECK-X64-NEXT: | [sizeof=28, align=4 97 // CHECK-X64-NEXT: | nvsize=28, nvalign=4] 98 99 struct BT0 { 100 BT0() { 101 printf("BT0 - this: %d\n", (int)((char*)this - buffer)); 102 } 103 }; 104 105 struct BT2 : BT0 { 106 char BT2FieldName0; 107 BT2() { 108 printf("BT2 - this: %d\n", (int)((char*)this - buffer)); 109 printf("BT2 - Fiel: %d\n", (int)((char*)&BT2FieldName0 - buffer)); 110 } 111 }; 112 113 struct BT3 : BT0, BT2 { 114 BT3() { 115 printf("BT3 - this: %d\n", (int)((char*)this - buffer)); 116 } 117 }; 118 119 // CHECK: *** Dumping AST Record Layout 120 // CHECK: *** Dumping AST Record Layout 121 // CHECK: *** Dumping AST Record Layout 122 // CHECK-NEXT: 0 | struct BT3 123 // CHECK-NEXT: 0 | struct BT0 (base) (empty) 124 // CHECK-NEXT: 1 | struct BT2 (base) 125 // CHECK-NEXT: 1 | struct BT0 (base) (empty) 126 // CHECK-NEXT: 1 | char BT2FieldName0 127 // CHECK-NEXT: | [sizeof=2, align=1 128 // CHECK-NEXT: | nvsize=2, nvalign=1] 129 // CHECK-X64: *** Dumping AST Record Layout 130 // CHECK-X64: *** Dumping AST Record Layout 131 // CHECK-X64: *** Dumping AST Record Layout 132 // CHECK-X64-NEXT: 0 | struct BT3 133 // CHECK-X64-NEXT: 0 | struct BT0 (base) (empty) 134 // CHECK-X64-NEXT: 1 | struct BT2 (base) 135 // CHECK-X64-NEXT: 1 | struct BT0 (base) (empty) 136 // CHECK-X64-NEXT: 1 | char BT2FieldName0 137 // CHECK-X64-NEXT: | [sizeof=2, align=1 138 // CHECK-X64-NEXT: | nvsize=2, nvalign=1] 139 140 struct T0 : AT { 141 T0() { 142 printf("T0 (this) : %d\n", (int)((char*)this - buffer)); 143 } 144 }; 145 146 struct T1 : T0 { 147 char a; 148 T1() { 149 printf("T1 (this) : %d\n", (int)((char*)this - buffer)); 150 printf("T1 (fiel) : %d\n", (int)((char*)&a - buffer)); 151 } 152 }; 153 154 struct T2 : AT { 155 char a; 156 T2() { 157 printf("T2 (this) : %d\n", (int)((char*)this - buffer)); 158 printf("T2 (fiel) : %d\n", (int)((char*)&a - buffer)); 159 } 160 }; 161 162 struct __declspec(align(1)) T3 : virtual T1, virtual T2 { 163 T3() { 164 printf("T3 (this) : %d\n", (int)((char*)this - buffer)); 165 } 166 }; 167 168 // CHECK: *** Dumping AST Record Layout 169 // CHECK: *** Dumping AST Record Layout 170 // CHECK: *** Dumping AST Record Layout 171 // CHECK: *** Dumping AST Record Layout 172 // CHECK-NEXT: 0 | struct T3 173 // CHECK-NEXT: 0 | (T3 vbtable pointer) 174 // CHECK-NEXT: 4 | struct T1 (virtual base) 175 // CHECK-NEXT: 4 | struct T0 (base) (empty) 176 // CHECK-NEXT: 4 | struct AT (base) (empty) 177 // CHECK-NEXT: 4 | char a 178 // CHECK-NEXT: 12 | struct T2 (virtual base) 179 // CHECK-NEXT: 12 | struct AT (base) (empty) 180 // CHECK-NEXT: 12 | char a 181 // CHECK-NEXT: | [sizeof=16, align=4 182 // CHECK-NEXT: | nvsize=4, nvalign=4] 183 // CHECK-X64: *** Dumping AST Record Layout 184 // CHECK-X64: *** Dumping AST Record Layout 185 // CHECK-X64: *** Dumping AST Record Layout 186 // CHECK-X64: *** Dumping AST Record Layout 187 // CHECK-X64-NEXT: 0 | struct T3 188 // CHECK-X64-NEXT: 0 | (T3 vbtable pointer) 189 // CHECK-X64-NEXT: 8 | struct T1 (virtual base) 190 // CHECK-X64-NEXT: 8 | struct T0 (base) (empty) 191 // CHECK-X64-NEXT: 8 | struct AT (base) (empty) 192 // CHECK-X64-NEXT: 8 | char a 193 // CHECK-X64-NEXT: 16 | struct T2 (virtual base) 194 // CHECK-X64-NEXT: 16 | struct AT (base) (empty) 195 // CHECK-X64-NEXT: 16 | char a 196 // CHECK-X64-NEXT: | [sizeof=24, align=8 197 // CHECK-X64-NEXT: | nvsize=8, nvalign=8] 198 199 struct B {}; 200 struct C { int a; }; 201 struct D : B, virtual C { B b; }; 202 struct E : D, B {}; 203 // CHECK: *** Dumping AST Record Layout 204 // CHECK: *** Dumping AST Record Layout 205 // CHECK: *** Dumping AST Record Layout 206 // CHECK: *** Dumping AST Record Layout 207 // CHECK-NEXT: 0 | struct E 208 // CHECK-NEXT: 0 | struct D (base) 209 // CHECK-NEXT: 4 | struct B (base) (empty) 210 // CHECK-NEXT: 0 | (D vbtable pointer) 211 // CHECK-NEXT: 4 | struct B b (empty) 212 // CHECK: 8 | struct B (base) (empty) 213 // CHECK-NEXT: 8 | struct C (virtual base) 214 // CHECK-NEXT: 8 | int a 215 // CHECK-NEXT: | [sizeof=12, align=4 216 // CHECK-NEXT: | nvsize=8, nvalign=4] 217 // CHECK-X64: *** Dumping AST Record Layout 218 // CHECK-X64: *** Dumping AST Record Layout 219 // CHECK-X64: *** Dumping AST Record Layout 220 // CHECK-X64: *** Dumping AST Record Layout 221 // CHECK-X64-NEXT: 0 | struct E 222 // CHECK-X64-NEXT: 0 | struct D (base) 223 // CHECK-X64-NEXT: 8 | struct B (base) (empty) 224 // CHECK-X64-NEXT: 0 | (D vbtable pointer) 225 // CHECK-X64-NEXT: 8 | struct B b (empty) 226 // CHECK-X64: 16 | struct B (base) (empty) 227 // CHECK-X64-NEXT: 16 | struct C (virtual base) 228 // CHECK-X64-NEXT: 16 | int a 229 // CHECK-X64-NEXT: | [sizeof=24, align=8 230 // CHECK-X64-NEXT: | nvsize=16, nvalign=8] 231 232 struct F : virtual D, virtual B {}; 233 // CHECK: *** Dumping AST Record Layout 234 // CHECK-NEXT: 0 | struct F 235 // CHECK-NEXT: 0 | (F vbtable pointer) 236 // CHECK-NEXT: 4 | struct C (virtual base) 237 // CHECK-NEXT: 4 | int a 238 // CHECK-NEXT: 8 | struct D (virtual base) 239 // CHECK-NEXT: 12 | struct B (base) (empty) 240 // CHECK-NEXT: 8 | (D vbtable pointer) 241 // CHECK-NEXT: 12 | struct B b (empty) 242 // CHECK: 16 | struct B (virtual base) (empty) 243 // CHECK-NEXT: | [sizeof=16, align=4 244 // CHECK-NEXT: | nvsize=4, nvalign=4] 245 // CHECK-X64: *** Dumping AST Record Layout 246 // CHECK-X64-NEXT: 0 | struct F 247 // CHECK-X64-NEXT: 0 | (F vbtable pointer) 248 // CHECK-X64-NEXT: 8 | struct C (virtual base) 249 // CHECK-X64-NEXT: 8 | int a 250 // CHECK-X64-NEXT: 16 | struct D (virtual base) 251 // CHECK-X64-NEXT: 24 | struct B (base) (empty) 252 // CHECK-X64-NEXT: 16 | (D vbtable pointer) 253 // CHECK-X64-NEXT: 24 | struct B b (empty) 254 // CHECK-X64: 32 | struct B (virtual base) (empty) 255 // CHECK-X64-NEXT: | [sizeof=32, align=8 256 // CHECK-X64-NEXT: | nvsize=8, nvalign=8] 257 258 struct JC0 { 259 JC0() { printf("JC0 : %d\n", (int)((char*)this - buffer)); } 260 }; 261 struct JC1 : JC0 { 262 virtual void f() {} 263 JC1() { printf("JC1 : %d\n", (int)((char*)this - buffer)); } 264 }; 265 struct JC2 : JC1 { 266 JC2() { printf("JC2 : %d\n", (int)((char*)this - buffer)); } 267 }; 268 struct JC4 : JC1, JC2 { 269 JC4() { printf("JC4 : %d\n", (int)((char*)this - buffer)); } 270 }; 271 272 // CHECK: *** Dumping AST Record Layout 273 // CHECK: *** Dumping AST Record Layout 274 // CHECK: *** Dumping AST Record Layout 275 // CHECK: *** Dumping AST Record Layout 276 // CHECK-NEXT: 0 | struct JC4 277 // CHECK-NEXT: 0 | struct JC1 (primary base) 278 // CHECK-NEXT: 0 | (JC1 vftable pointer) 279 // CHECK-NEXT: 4 | struct JC0 (base) (empty) 280 // CHECK-NEXT: 8 | struct JC2 (base) 281 // CHECK-NEXT: 8 | struct JC1 (primary base) 282 // CHECK-NEXT: 8 | (JC1 vftable pointer) 283 // CHECK-NEXT: 12 | struct JC0 (base) (empty) 284 // CHECK-NEXT: | [sizeof=12, align=4 285 // CHECK-NEXT: | nvsize=12, nvalign=4] 286 // CHECK-x64: *** Dumping AST Record Layout 287 // CHECK-x64: *** Dumping AST Record Layout 288 // CHECK-x64: *** Dumping AST Record Layout 289 // CHECK-x64: *** Dumping AST Record Layout 290 // CHECK-x64-NEXT: 0 | struct JC4 291 // CHECK-x64-NEXT: 0 | struct JC1 (primary base) 292 // CHECK-x64-NEXT: 0 | (JC1 vftable pointer) 293 // CHECK-x64-NEXT: 8 | struct JC0 (base) (empty) 294 // CHECK-x64-NEXT: 16 | struct JC2 (base) 295 // CHECK-x64-NEXT: 16 | struct JC1 (primary base) 296 // CHECK-x64-NEXT: 16 | (JC1 vftable pointer) 297 // CHECK-x64-NEXT: 24 | struct JC0 (base) (empty) 298 // CHECK-x64-NEXT: | [sizeof=24, align=8 299 // CHECK-x64-NEXT: | nvsize=24, nvalign=8] 300 301 int a[ 302 sizeof(AT3) + 303 sizeof(BT3) + 304 sizeof(T3) + 305 sizeof(E) + 306 sizeof(F) + 307 sizeof(JC4) + 308 0]; 309