brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.4 KiB · fd92056 Raw
383 lines · cpp
1// RUN: %clang_cc1 -std=c++2a -fsyntax-only -triple x86_64-windows-msvc -fms-compatibility -fdump-record-layouts %s | FileCheck %s2// RUN: %clang_cc1 -std=c++2a -fsyntax-only -triple x86_64-uefi -fms-compatibility -fdump-record-layouts %s | FileCheck %s3 4namespace Empty {5  struct A {};6  struct A2 {};7  struct A3 { [[msvc::no_unique_address]] A a; };8  struct alignas(8) A4 {};9 10  struct B {11    [[msvc::no_unique_address]] A a;12    char b;13  };14  static_assert(sizeof(B) == 1);15 16  // CHECK:*** Dumping AST Record Layout17  // CHECK:          0 | struct Empty::B18  // CHECK-NEXT:     0 |   struct Empty::A a (empty)19  // CHECK-NEXT:     0 |   char b20  // CHECK-NEXT:       | [sizeof=1, align=1,21  // CHECK-NEXT:       |  nvsize=1, nvalign=1]22 23  struct C {24    [[msvc::no_unique_address]] A a;25    [[msvc::no_unique_address]] A2 a2;26    char c;27  };28  static_assert(sizeof(C) == 1);29 30  // CHECK:*** Dumping AST Record Layout31  // CHECK:          0 | struct Empty::C32  // CHECK-NEXT:     0 |   struct Empty::A a (empty)33  // CHECK-NEXT:     0 |   struct Empty::A2 a2 (empty)34  // CHECK-NEXT:     0 |   char c35  // CHECK-NEXT:       | [sizeof=1, align=1,36  // CHECK-NEXT:       |  nvsize=1, nvalign=1]37 38  struct D {39    [[msvc::no_unique_address]] A3 a;40    int i;41  };42  static_assert(sizeof(D) == 8);43 44  // CHECK:*** Dumping AST Record Layout45  // CHECK:          0 | struct Empty::D46  // CHECK-NEXT:     0 |   struct Empty::A3 a (empty)47  // CHECK-NEXT:     0 |     struct Empty::A a (empty)48  // CHECK-NEXT:     4 |   int i49  // CHECK-NEXT:       | [sizeof=8, align=4,50  // CHECK-NEXT:       |  nvsize=8, nvalign=4]51 52  struct E {53    [[msvc::no_unique_address]] A a1;54    [[msvc::no_unique_address]] A a2;55    char e;56  };57  static_assert(sizeof(E) == 2);58 59  // CHECK:*** Dumping AST Record Layout60  // CHECK:          0 | struct Empty::E61  // CHECK-NEXT:     0 |   struct Empty::A a1 (empty)62  // CHECK-NEXT:     1 |   struct Empty::A a2 (empty)63  // CHECK-NEXT:     0 |   char e64  // CHECK-NEXT:       | [sizeof=2, align=1,65  // CHECK-NEXT:       |  nvsize=2, nvalign=1]66 67  struct F {68    ~F();69    [[msvc::no_unique_address]] A a1;70    [[msvc::no_unique_address]] A a2;71    char f;72  };73  static_assert(sizeof(F) == 2);74 75  // CHECK:*** Dumping AST Record Layout76  // CHECK:          0 | struct Empty::F77  // CHECK-NEXT:     0 |   struct Empty::A a1 (empty)78  // CHECK-NEXT:     1 |   struct Empty::A a2 (empty)79  // CHECK-NEXT:     0 |   char f80  // CHECK-NEXT:       | [sizeof=2, align=1,81  // CHECK-NEXT:       |  nvsize=2, nvalign=1]82 83  struct G { [[msvc::no_unique_address]] A a; ~G(); };84  static_assert(sizeof(G) == 1);85 86  // CHECK:*** Dumping AST Record Layout87  // CHECK:          0 | struct Empty::G88  // CHECK-NEXT:     0 |   struct Empty::A a (empty)89  // CHECK-NEXT:       | [sizeof=1, align=1,90  // CHECK-NEXT:       |  nvsize=1, nvalign=1]91 92  struct H {93    [[msvc::no_unique_address]] A a;94    [[msvc::no_unique_address]] A b;95    ~H();96  };97  static_assert(sizeof(H) == 2);98 99  // CHECK:*** Dumping AST Record Layout100  // CHECK:          0 | struct Empty::H101  // CHECK-NEXT:     0 |   struct Empty::A a (empty)102  // CHECK-NEXT:     1 |   struct Empty::A b (empty)103  // CHECK-NEXT:       | [sizeof=2, align=1,104  // CHECK-NEXT:       |  nvsize=2, nvalign=1]105 106  struct I {107    [[msvc::no_unique_address]] A4 a;108    [[msvc::no_unique_address]] A4 b;109  };110  static_assert(sizeof(I) == 16);111 112  // CHECK:*** Dumping AST Record Layout113  // CHECK:          0 | struct Empty::I114  // CHECK-NEXT:     0 |   struct Empty::A4 a (empty)115  // CHECK-NEXT:     8 |   struct Empty::A4 b (empty)116  // CHECK-NEXT:       | [sizeof=16, align=8,117  // CHECK-NEXT:       |  nvsize=16, nvalign=8]118 119  struct J {120    [[msvc::no_unique_address]] A4 a;121    A4 b;122  };123  static_assert(sizeof(J) == 16);124 125  // MSVC puts a and b at the same offset.126  // CHECK:*** Dumping AST Record Layout127  // CHECK:          0 | struct Empty::J128  // CHECK-NEXT:     0 |   struct Empty::A4 a (empty)129  // CHECK-NEXT:     8 |   struct Empty::A4 b (empty)130  // CHECK-NEXT:       | [sizeof=16, align=8,131  // CHECK-NEXT:       |  nvsize=16, nvalign=8]132 133  struct K {134    [[msvc::no_unique_address]] A4 a;135    [[msvc::no_unique_address]] char c;136    [[msvc::no_unique_address]] A4 b;137  };138  static_assert(sizeof(K) == 16);139 140  // CHECK:*** Dumping AST Record Layout141  // CHECK:          0 | struct Empty::K142  // CHECK-NEXT:     0 |   struct Empty::A4 a (empty)143  // CHECK-NEXT:     0 |   char c144  // CHECK-NEXT:     8 |   struct Empty::A4 b (empty)145  // CHECK-NEXT:       | [sizeof=16, align=8,146  // CHECK-NEXT:       |  nvsize=16, nvalign=8]147 148  struct OversizedEmpty : A {149    ~OversizedEmpty();150    [[msvc::no_unique_address]] A a;151  };152  static_assert(sizeof(OversizedEmpty) == 1);153 154  // CHECK:*** Dumping AST Record Layout155  // CHECK:          0 | struct Empty::OversizedEmpty156  // CHECK-NEXT:     0 |   struct Empty::A (base) (empty)157  // CHECK-NEXT:     0 |   struct Empty::A a (empty)158  // CHECK-NEXT:       | [sizeof=1, align=1,159  // CHECK-NEXT:       |  nvsize=1, nvalign=1]160 161  struct HasOversizedEmpty {162    [[msvc::no_unique_address]] OversizedEmpty m;163  };164  static_assert(sizeof(HasOversizedEmpty) == 1);165 166  // CHECK:*** Dumping AST Record Layout167  // CHECK:          0 | struct Empty::HasOversizedEmpty168  // CHECK-NEXT:     0 |   struct Empty::OversizedEmpty m (empty)169  // CHECK-NEXT:     0 |     struct Empty::A (base) (empty)170  // CHECK-NEXT:     0 |     struct Empty::A a (empty)171  // CHECK-NEXT:       | [sizeof=1, align=1,172  // CHECK-NEXT:       |  nvsize=1, nvalign=1]173 174  struct EmptyWithNonzeroDSize {175    [[msvc::no_unique_address]] A a;176    int x;177    [[msvc::no_unique_address]] A b;178    int y;179    [[msvc::no_unique_address]] A c;180  };181  static_assert(sizeof(EmptyWithNonzeroDSize) == 8);182 183  // CHECK:*** Dumping AST Record Layout184  // CHECK:          0 | struct Empty::EmptyWithNonzeroDSize185  // CHECK-NEXT:     0 |   struct Empty::A a (empty)186  // CHECK-NEXT:     0 |   int x187  // CHECK-NEXT:     1 |   struct Empty::A b (empty)188  // CHECK-NEXT:     4 |   int y189  // CHECK-NEXT:     2 |   struct Empty::A c (empty)190  // CHECK-NEXT:       | [sizeof=8,  align=4,191  // CHECK-NEXT:       |  nvsize=8, nvalign=4]192 193  struct EmptyWithNonzeroDSizeNonPOD {194    ~EmptyWithNonzeroDSizeNonPOD();195    [[msvc::no_unique_address]] A a;196    int x;197    [[msvc::no_unique_address]] A b;198    int y;199    [[msvc::no_unique_address]] A c;200  };201  static_assert(sizeof(EmptyWithNonzeroDSizeNonPOD) == 8);202 203  // CHECK:*** Dumping AST Record Layout204  // CHECK:          0 | struct Empty::EmptyWithNonzeroDSizeNonPOD205  // CHECK-NEXT:     0 |   struct Empty::A a (empty)206  // CHECK-NEXT:     0 |   int x207  // CHECK-NEXT:     1 |   struct Empty::A b (empty)208  // CHECK-NEXT:     4 |   int y209  // CHECK-NEXT:     2 |   struct Empty::A c (empty)210  // CHECK-NEXT:       | [sizeof=8, align=4,211  // CHECK-NEXT:       |  nvsize=8, nvalign=4]212}213 214namespace POD {215  struct A { int n; char c[3]; };216  struct B { [[msvc::no_unique_address]] A a; char d; };217  static_assert(sizeof(B) == 12);218 219  // CHECK:*** Dumping AST Record Layout220  // CHECK:          0 | struct POD::B221  // CHECK-NEXT:     0 |   struct POD::A a222  // CHECK-NEXT:     0 |     int n223  // CHECK-NEXT:     4 |     char[3] c224  // CHECK-NEXT:     8 |   char d225  // CHECK-NEXT:       | [sizeof=12,  align=4,226  // CHECK-NEXT:       |  nvsize=12, nvalign=4]227}228 229namespace NonPOD {230  struct A { int n; char c[3]; ~A(); };231  struct B { [[msvc::no_unique_address]] A a; char d; };232  static_assert(sizeof(B) == 12);233 234  // CHECK:*** Dumping AST Record Layout235  // CHECK:          0 | struct NonPOD::B236  // CHECK-NEXT:     0 |   struct NonPOD::A a237  // CHECK-NEXT:     0 |     int n238  // CHECK-NEXT:     4 |     char[3] c239  // CHECK-NEXT:     8 |   char d240  // CHECK-NEXT:       | [sizeof=12, align=4,241  // CHECK-NEXT:       |  nvsize=12, nvalign=4]242}243 244namespace VBases {245  // The nvsize of an object includes the complete size of its empty subobjects246  // (although it's unclear why). Ensure this corner case is handled properly.247  struct Empty {};248  struct alignas(8) A {}; // dsize 0, nvsize 0, size 8249  struct B : A { char c; }; // dsize 1, nvsize 8, size 8250  static_assert(sizeof(B) == 8);251 252  // CHECK:*** Dumping AST Record Layout253  // CHECK:          0 | struct VBases::B254  // CHECK-NEXT:     0 |   struct VBases::A (base) (empty)255  // CHECK-NEXT:     0 |   char c256  // CHECK-NEXT:       | [sizeof=8, align=8,257  // CHECK-NEXT:       |  nvsize=8, nvalign=8]258 259  struct V { int n; };260 261  struct C : B, virtual V {};262  static_assert(sizeof(C) == 24);263 264  // CHECK:*** Dumping AST Record Layout265  // CHECK:          0 | struct VBases::C266  // CHECK-NEXT:     0 |   struct VBases::B (base)267  // CHECK-NEXT:     0 |     struct VBases::A (base) (empty)268  // CHECK-NEXT:     0 |     char c269  // CHECK-NEXT:     8 |   (C vbtable pointer)270  // CHECK-NEXT:    16 |   struct VBases::V (virtual base)271  // CHECK-NEXT:    16 |     int n272  // CHECK-NEXT:       | [sizeof=24, align=8,273  // CHECK-NEXT:       |  nvsize=16, nvalign=8]274 275  struct D : virtual Empty {276    [[msvc::no_unique_address]] Empty a;277  };278  static_assert(sizeof(D) == 16);279 280  // CHECK:*** Dumping AST Record Layout281  // CHECK:          0 | struct VBases::D282  // CHECK-NEXT:     0 |   (D vbtable pointer)283  // CHECK-NEXT:     8 |   struct VBases::Empty a284  // CHECK-NEXT:    16 |   struct VBases::Empty (virtual base) (empty)285  // CHECK-NEXT:       | [sizeof=16, align=8,286  // CHECK-NEXT:       |  nvsize=16, nvalign=8]287 288  struct E : virtual V {289    [[msvc::no_unique_address]] B b;290  };291  static_assert(sizeof(E) == 24);292 293  // CHECK:*** Dumping AST Record Layout294  // CHECK:          0 | struct VBases::E295  // CHECK-NEXT:     0 |   (E vbtable pointer)296  // CHECK-NEXT:     8 |   struct VBases::B b297  // CHECK-NEXT:     8 |     struct VBases::A (base) (empty)298  // CHECK-NEXT:     8 |     char c299  // CHECK-NEXT:    16 |   struct VBases::V (virtual base)300  // CHECK-NEXT:    16 |     int n301  // CHECK-NEXT:       | [sizeof=24, align=8,302  // CHECK-NEXT:       |  nvsize=16, nvalign=8]303 304  struct X : virtual A { [[msvc::no_unique_address]] A a; };305  struct F : virtual A {306    [[msvc::no_unique_address]] A a;307    [[msvc::no_unique_address]] X x;308  };309  static_assert(sizeof(F) == 24);310 311  // MSVC places x after a and the total size is 48.312  // CHECK:*** Dumping AST Record Layout313  // CHECK:          0 | struct VBases::F314  // CHECK-NEXT:     0 |   (F vbtable pointer)315  // CHECK-NEXT:     8 |   struct VBases::A a (empty)316  // CHECK-NEXT:     8 |   struct VBases::X x317  // CHECK-NEXT:     8 |     (X vbtable pointer)318  // CHECK-NEXT:    16 |     struct VBases::A a (empty)319  // CHECK-NEXT:    24 |     struct VBases::A (virtual base) (empty)320  // CHECK-NEXT:    24 |   struct VBases::A (virtual base) (empty)321  // CHECK-NEXT:       | [sizeof=24, align=8,322  // CHECK-NEXT:       |  nvsize=24, nvalign=8]323 324  struct G : virtual Empty {325    int i;326    [[msvc::no_unique_address]] A a;327  };328  static_assert(sizeof(G) == 16);329 330  // MSVC places a at offset 12.331  // CHECK:*** Dumping AST Record Layout332  // CHECK:         0 | struct VBases::G333  // CHECK-NEXT:    0 |   (G vbtable pointer)334  // CHECK-NEXT:    8 |   int i335  // CHECK-NEXT:    8 |   struct VBases::A a (empty)336  // CHECK-NEXT:   16 | struct VBases::Empty (virtual base) (empty)337  // CHECK-NEXT:      | [sizeof=16, align=8,338  // CHECK-NEXT:      |  nvsize=16, nvalign=8]339}340 341namespace ZeroSize {342  struct empty {};343 344  union empty_union {};345 346  struct empty_union_container {347    [[msvc::no_unique_address]] empty_union x;348  };349 350  union union_of_empty {351    [[msvc::no_unique_address]] empty x;352  };353 354  struct struct_of_empty {355    [[msvc::no_unique_address]] empty x;356  };357 358  struct union_of_empty_container {359    [[msvc::no_unique_address]] union_of_empty x;360  };361  static_assert(sizeof(union_of_empty_container) == 1);362  // CHECK:*** Dumping AST Record Layout363  // CHECK:         0 | struct ZeroSize::union_of_empty_container364  // CHECK-NOT: (empty)365  // CHECK:         0 |   union ZeroSize::union_of_empty x (empty)366  // CHECK:         0 |     struct ZeroSize::empty x (empty)367  // CHECK:           | [sizeof=1, align=1,368  // CHECK:           |  nvsize=1, nvalign=1] 369 370  struct struct_of_empty_container {371    [[msvc::no_unique_address]] struct_of_empty x;372  }; 373  static_assert(sizeof(struct_of_empty_container) == 1);374  // CHECK:*** Dumping AST Record Layout375  // CHECK:         0 | struct ZeroSize::struct_of_empty_container376  // CHECK-NOT: (empty)377  // CHECK:         0 |   struct ZeroSize::struct_of_empty x (empty)378  // CHECK:         0 |     struct ZeroSize::empty x (empty)379  // CHECK:           | [sizeof=1, align=1,380  // CHECK:           |  nvsize=1, nvalign=1] 381 382}383