[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / clang / test / Layout / ms-no-unique-address.cpp
blob51cfd9a6ae3b77fff75843cde6539eb27cbb21db
1 // RUN: %clang_cc1 -std=c++2a -fsyntax-only -triple x86_64-windows-msvc -fms-compatibility -fdump-record-layouts %s | FileCheck %s
3 namespace Empty {
4 struct A {};
5 struct A2 {};
6 struct A3 { [[msvc::no_unique_address]] A a; };
7 struct alignas(8) A4 {};
9 struct B {
10 [[msvc::no_unique_address]] A a;
11 char b;
13 static_assert(sizeof(B) == 1);
15 // CHECK:*** Dumping AST Record Layout
16 // CHECK: 0 | struct Empty::B
17 // CHECK-NEXT: 0 | struct Empty::A a (empty)
18 // CHECK-NEXT: 0 | char b
19 // CHECK-NEXT: | [sizeof=1, align=1,
20 // CHECK-NEXT: | nvsize=1, nvalign=1]
22 struct C {
23 [[msvc::no_unique_address]] A a;
24 [[msvc::no_unique_address]] A2 a2;
25 char c;
27 static_assert(sizeof(C) == 1);
29 // CHECK:*** Dumping AST Record Layout
30 // CHECK: 0 | struct Empty::C
31 // CHECK-NEXT: 0 | struct Empty::A a (empty)
32 // CHECK-NEXT: 0 | struct Empty::A2 a2 (empty)
33 // CHECK-NEXT: 0 | char c
34 // CHECK-NEXT: | [sizeof=1, align=1,
35 // CHECK-NEXT: | nvsize=1, nvalign=1]
37 struct D {
38 [[msvc::no_unique_address]] A3 a;
39 int i;
41 static_assert(sizeof(D) == 8);
43 // CHECK:*** Dumping AST Record Layout
44 // CHECK: 0 | struct Empty::D
45 // CHECK-NEXT: 0 | struct Empty::A3 a (empty)
46 // CHECK-NEXT: 0 | struct Empty::A a (empty)
47 // CHECK-NEXT: 4 | int i
48 // CHECK-NEXT: | [sizeof=8, align=4,
49 // CHECK-NEXT: | nvsize=8, nvalign=4]
51 struct E {
52 [[msvc::no_unique_address]] A a1;
53 [[msvc::no_unique_address]] A a2;
54 char e;
56 static_assert(sizeof(E) == 2);
58 // CHECK:*** Dumping AST Record Layout
59 // CHECK: 0 | struct Empty::E
60 // CHECK-NEXT: 0 | struct Empty::A a1 (empty)
61 // CHECK-NEXT: 1 | struct Empty::A a2 (empty)
62 // CHECK-NEXT: 0 | char e
63 // CHECK-NEXT: | [sizeof=2, align=1,
64 // CHECK-NEXT: | nvsize=2, nvalign=1]
66 struct F {
67 ~F();
68 [[msvc::no_unique_address]] A a1;
69 [[msvc::no_unique_address]] A a2;
70 char f;
72 static_assert(sizeof(F) == 2);
74 // CHECK:*** Dumping AST Record Layout
75 // CHECK: 0 | struct Empty::F
76 // CHECK-NEXT: 0 | struct Empty::A a1 (empty)
77 // CHECK-NEXT: 1 | struct Empty::A a2 (empty)
78 // CHECK-NEXT: 0 | char f
79 // CHECK-NEXT: | [sizeof=2, align=1,
80 // CHECK-NEXT: | nvsize=2, nvalign=1]
82 struct G { [[msvc::no_unique_address]] A a; ~G(); };
83 static_assert(sizeof(G) == 1);
85 // CHECK:*** Dumping AST Record Layout
86 // CHECK: 0 | struct Empty::G
87 // CHECK-NEXT: 0 | struct Empty::A a (empty)
88 // CHECK-NEXT: | [sizeof=1, align=1,
89 // CHECK-NEXT: | nvsize=1, nvalign=1]
91 struct H {
92 [[msvc::no_unique_address]] A a;
93 [[msvc::no_unique_address]] A b;
94 ~H();
96 static_assert(sizeof(H) == 2);
98 // CHECK:*** Dumping AST Record Layout
99 // CHECK: 0 | struct Empty::H
100 // CHECK-NEXT: 0 | struct Empty::A a (empty)
101 // CHECK-NEXT: 1 | struct Empty::A b (empty)
102 // CHECK-NEXT: | [sizeof=2, align=1,
103 // CHECK-NEXT: | nvsize=2, nvalign=1]
105 struct I {
106 [[msvc::no_unique_address]] A4 a;
107 [[msvc::no_unique_address]] A4 b;
109 static_assert(sizeof(I) == 16);
111 // CHECK:*** Dumping AST Record Layout
112 // CHECK: 0 | struct Empty::I
113 // CHECK-NEXT: 0 | struct Empty::A4 a (empty)
114 // CHECK-NEXT: 8 | struct Empty::A4 b (empty)
115 // CHECK-NEXT: | [sizeof=16, align=8,
116 // CHECK-NEXT: | nvsize=16, nvalign=8]
118 struct J {
119 [[msvc::no_unique_address]] A4 a;
120 A4 b;
122 static_assert(sizeof(J) == 16);
124 // MSVC puts a and b at the same offset.
125 // CHECK:*** Dumping AST Record Layout
126 // CHECK: 0 | struct Empty::J
127 // CHECK-NEXT: 0 | struct Empty::A4 a (empty)
128 // CHECK-NEXT: 8 | struct Empty::A4 b (empty)
129 // CHECK-NEXT: | [sizeof=16, align=8,
130 // CHECK-NEXT: | nvsize=16, nvalign=8]
132 struct K {
133 [[msvc::no_unique_address]] A4 a;
134 [[msvc::no_unique_address]] char c;
135 [[msvc::no_unique_address]] A4 b;
137 static_assert(sizeof(K) == 16);
139 // CHECK:*** Dumping AST Record Layout
140 // CHECK: 0 | struct Empty::K
141 // CHECK-NEXT: 0 | struct Empty::A4 a (empty)
142 // CHECK-NEXT: 0 | char c
143 // CHECK-NEXT: 8 | struct Empty::A4 b (empty)
144 // CHECK-NEXT: | [sizeof=16, align=8,
145 // CHECK-NEXT: | nvsize=16, nvalign=8]
147 struct OversizedEmpty : A {
148 ~OversizedEmpty();
149 [[msvc::no_unique_address]] A a;
151 static_assert(sizeof(OversizedEmpty) == 1);
153 // CHECK:*** Dumping AST Record Layout
154 // CHECK: 0 | struct Empty::OversizedEmpty
155 // CHECK-NEXT: 0 | struct Empty::A (base) (empty)
156 // CHECK-NEXT: 0 | struct Empty::A a (empty)
157 // CHECK-NEXT: | [sizeof=1, align=1,
158 // CHECK-NEXT: | nvsize=1, nvalign=1]
160 struct HasOversizedEmpty {
161 [[msvc::no_unique_address]] OversizedEmpty m;
163 static_assert(sizeof(HasOversizedEmpty) == 1);
165 // CHECK:*** Dumping AST Record Layout
166 // CHECK: 0 | struct Empty::HasOversizedEmpty
167 // CHECK-NEXT: 0 | struct Empty::OversizedEmpty m (empty)
168 // CHECK-NEXT: 0 | struct Empty::A (base) (empty)
169 // CHECK-NEXT: 0 | struct Empty::A a (empty)
170 // CHECK-NEXT: | [sizeof=1, align=1,
171 // CHECK-NEXT: | nvsize=1, nvalign=1]
173 struct EmptyWithNonzeroDSize {
174 [[msvc::no_unique_address]] A a;
175 int x;
176 [[msvc::no_unique_address]] A b;
177 int y;
178 [[msvc::no_unique_address]] A c;
180 static_assert(sizeof(EmptyWithNonzeroDSize) == 8);
182 // CHECK:*** Dumping AST Record Layout
183 // CHECK: 0 | struct Empty::EmptyWithNonzeroDSize
184 // CHECK-NEXT: 0 | struct Empty::A a (empty)
185 // CHECK-NEXT: 0 | int x
186 // CHECK-NEXT: 1 | struct Empty::A b (empty)
187 // CHECK-NEXT: 4 | int y
188 // CHECK-NEXT: 2 | struct Empty::A c (empty)
189 // CHECK-NEXT: | [sizeof=8, align=4,
190 // CHECK-NEXT: | nvsize=8, nvalign=4]
192 struct EmptyWithNonzeroDSizeNonPOD {
193 ~EmptyWithNonzeroDSizeNonPOD();
194 [[msvc::no_unique_address]] A a;
195 int x;
196 [[msvc::no_unique_address]] A b;
197 int y;
198 [[msvc::no_unique_address]] A c;
200 static_assert(sizeof(EmptyWithNonzeroDSizeNonPOD) == 8);
202 // CHECK:*** Dumping AST Record Layout
203 // CHECK: 0 | struct Empty::EmptyWithNonzeroDSizeNonPOD
204 // CHECK-NEXT: 0 | struct Empty::A a (empty)
205 // CHECK-NEXT: 0 | int x
206 // CHECK-NEXT: 1 | struct Empty::A b (empty)
207 // CHECK-NEXT: 4 | int y
208 // CHECK-NEXT: 2 | struct Empty::A c (empty)
209 // CHECK-NEXT: | [sizeof=8, align=4,
210 // CHECK-NEXT: | nvsize=8, nvalign=4]
213 namespace POD {
214 struct A { int n; char c[3]; };
215 struct B { [[msvc::no_unique_address]] A a; char d; };
216 static_assert(sizeof(B) == 12);
218 // CHECK:*** Dumping AST Record Layout
219 // CHECK: 0 | struct POD::B
220 // CHECK-NEXT: 0 | struct POD::A a
221 // CHECK-NEXT: 0 | int n
222 // CHECK-NEXT: 4 | char[3] c
223 // CHECK-NEXT: 8 | char d
224 // CHECK-NEXT: | [sizeof=12, align=4,
225 // CHECK-NEXT: | nvsize=12, nvalign=4]
228 namespace NonPOD {
229 struct A { int n; char c[3]; ~A(); };
230 struct B { [[msvc::no_unique_address]] A a; char d; };
231 static_assert(sizeof(B) == 12);
233 // CHECK:*** Dumping AST Record Layout
234 // CHECK: 0 | struct NonPOD::B
235 // CHECK-NEXT: 0 | struct NonPOD::A a
236 // CHECK-NEXT: 0 | int n
237 // CHECK-NEXT: 4 | char[3] c
238 // CHECK-NEXT: 8 | char d
239 // CHECK-NEXT: | [sizeof=12, align=4,
240 // CHECK-NEXT: | nvsize=12, nvalign=4]
243 namespace VBases {
244 // The nvsize of an object includes the complete size of its empty subobjects
245 // (although it's unclear why). Ensure this corner case is handled properly.
246 struct Empty {};
247 struct alignas(8) A {}; // dsize 0, nvsize 0, size 8
248 struct B : A { char c; }; // dsize 1, nvsize 8, size 8
249 static_assert(sizeof(B) == 8);
251 // CHECK:*** Dumping AST Record Layout
252 // CHECK: 0 | struct VBases::B
253 // CHECK-NEXT: 0 | struct VBases::A (base) (empty)
254 // CHECK-NEXT: 0 | char c
255 // CHECK-NEXT: | [sizeof=8, align=8,
256 // CHECK-NEXT: | nvsize=8, nvalign=8]
258 struct V { int n; };
260 struct C : B, virtual V {};
261 static_assert(sizeof(C) == 24);
263 // CHECK:*** Dumping AST Record Layout
264 // CHECK: 0 | struct VBases::C
265 // CHECK-NEXT: 0 | struct VBases::B (base)
266 // CHECK-NEXT: 0 | struct VBases::A (base) (empty)
267 // CHECK-NEXT: 0 | char c
268 // CHECK-NEXT: 8 | (C vbtable pointer)
269 // CHECK-NEXT: 16 | struct VBases::V (virtual base)
270 // CHECK-NEXT: 16 | int n
271 // CHECK-NEXT: | [sizeof=24, align=8,
272 // CHECK-NEXT: | nvsize=16, nvalign=8]
274 struct D : virtual Empty {
275 [[msvc::no_unique_address]] Empty a;
277 static_assert(sizeof(D) == 16);
279 // CHECK:*** Dumping AST Record Layout
280 // CHECK: 0 | struct VBases::D
281 // CHECK-NEXT: 0 | (D vbtable pointer)
282 // CHECK-NEXT: 8 | struct VBases::Empty a
283 // CHECK-NEXT: 16 | struct VBases::Empty (virtual base) (empty)
284 // CHECK-NEXT: | [sizeof=16, align=8,
285 // CHECK-NEXT: | nvsize=16, nvalign=8]
287 struct E : virtual V {
288 [[msvc::no_unique_address]] B b;
290 static_assert(sizeof(E) == 24);
292 // CHECK:*** Dumping AST Record Layout
293 // CHECK: 0 | struct VBases::E
294 // CHECK-NEXT: 0 | (E vbtable pointer)
295 // CHECK-NEXT: 8 | struct VBases::B b
296 // CHECK-NEXT: 8 | struct VBases::A (base) (empty)
297 // CHECK-NEXT: 8 | char c
298 // CHECK-NEXT: 16 | struct VBases::V (virtual base)
299 // CHECK-NEXT: 16 | int n
300 // CHECK-NEXT: | [sizeof=24, align=8,
301 // CHECK-NEXT: | nvsize=16, nvalign=8]
303 struct X : virtual A { [[msvc::no_unique_address]] A a; };
304 struct F : virtual A {
305 [[msvc::no_unique_address]] A a;
306 [[msvc::no_unique_address]] X x;
308 static_assert(sizeof(F) == 24);
310 // MSVC places x after a and the total size is 48.
311 // CHECK:*** Dumping AST Record Layout
312 // CHECK: 0 | struct VBases::F
313 // CHECK-NEXT: 0 | (F vbtable pointer)
314 // CHECK-NEXT: 8 | struct VBases::A a (empty)
315 // CHECK-NEXT: 8 | struct VBases::X x
316 // CHECK-NEXT: 8 | (X vbtable pointer)
317 // CHECK-NEXT: 16 | struct VBases::A a (empty)
318 // CHECK-NEXT: 24 | struct VBases::A (virtual base) (empty)
319 // CHECK-NEXT: 24 | struct VBases::A (virtual base) (empty)
320 // CHECK-NEXT: | [sizeof=24, align=8,
321 // CHECK-NEXT: | nvsize=24, nvalign=8]
323 struct G : virtual Empty {
324 int i;
325 [[msvc::no_unique_address]] A a;
327 static_assert(sizeof(G) == 16);
329 // MSVC places a at offset 12.
330 // CHECK:*** Dumping AST Record Layout
331 // CHECK: 0 | struct VBases::G
332 // CHECK-NEXT: 0 | (G vbtable pointer)
333 // CHECK-NEXT: 8 | int i
334 // CHECK-NEXT: 8 | struct VBases::A a (empty)
335 // CHECK-NEXT: 16 | struct VBases::Empty (virtual base) (empty)
336 // CHECK-NEXT: | [sizeof=16, align=8,
337 // CHECK-NEXT: | nvsize=16, nvalign=8]
340 namespace ZeroSize {
341 struct empty {};
343 union empty_union {};
345 struct empty_union_container {
346 [[msvc::no_unique_address]] empty_union x;
349 union union_of_empty {
350 [[msvc::no_unique_address]] empty x;
353 struct struct_of_empty {
354 [[msvc::no_unique_address]] empty x;
357 struct union_of_empty_container {
358 [[msvc::no_unique_address]] union_of_empty x;
360 static_assert(sizeof(union_of_empty_container) == 1);
361 // CHECK:*** Dumping AST Record Layout
362 // CHECK: 0 | struct ZeroSize::union_of_empty_container
363 // CHECK-NOT: (empty)
364 // CHECK: 0 | union ZeroSize::union_of_empty x (empty)
365 // CHECK: 0 | struct ZeroSize::empty x (empty)
366 // CHECK: | [sizeof=1, align=1,
367 // CHECK: | nvsize=1, nvalign=1]
369 struct struct_of_empty_container {
370 [[msvc::no_unique_address]] struct_of_empty x;
372 static_assert(sizeof(struct_of_empty_container) == 1);
373 // CHECK:*** Dumping AST Record Layout
374 // CHECK: 0 | struct ZeroSize::struct_of_empty_container
375 // CHECK-NOT: (empty)
376 // CHECK: 0 | struct ZeroSize::struct_of_empty x (empty)
377 // CHECK: 0 | struct ZeroSize::empty x (empty)
378 // CHECK: | [sizeof=1, align=1,
379 // CHECK: | nvsize=1, nvalign=1]