|  | // RUN: %clang_cc1 -triple aarch64-unknown-linux-gnu -emit-llvm -fdump-record-layouts -std=c++17 %s -o %t | FileCheck %s | 
|  |  | 
|  | // CHECK-LABEL:          0 | class Empty (empty) | 
|  | // CHECK-NEXT:             | [sizeof=1, dsize=1, align=1, | 
|  | // CHECK-NEXT:             |  nvsize=1, nvalign=1] | 
|  | // CHECK-LABEL:          0 | class Second | 
|  | // CHECK-NEXT:           0 |   class Empty (base) (empty) | 
|  | // CHECK-NEXT:       0:0-0 |   short A | 
|  | // CHECK-NEXT:             | [sizeof=2, dsize=1, align=2, | 
|  | // CHECK-NEXT:             |  nvsize=1, nvalign=2] | 
|  | // CHECK-LABEL:          0 | class Foo | 
|  | // CHECK-NEXT:           0 |   class Empty (base) (empty) | 
|  | // CHECK-NEXT:           2 |   class Second NZNoUnique | 
|  | // CHECK-NEXT:           2 |     class Empty (base) (empty) | 
|  | // CHECK-NEXT:       2:0-0 |     short A | 
|  | // CHECK-NEXT:           3 |   char B | 
|  | // CHECK-NEXT:             | [sizeof=4, dsize=4, align=2, | 
|  | // CHECK-NEXT:             |  nvsize=4, nvalign=2] | 
|  |  | 
|  | class Empty {}; | 
|  |  | 
|  | // CHECK-LABEL: LLVMType:%class.Second = type { i8, i8 } | 
|  | // CHECK-NEXT:  NonVirtualBaseLLVMType:%class.Second.base = type { i8 } | 
|  | class Second : Empty { | 
|  | short A : 1; | 
|  | }; | 
|  |  | 
|  | // CHECK-LABEL:   LLVMType:%class.Foo = type { [2 x i8], %class.Second.base, i8 } | 
|  | // CHECK-NEXT:    NonVirtualBaseLLVMType:%class.Foo = type { [2 x i8], %class.Second.base, i8 } | 
|  | class Foo : Empty { | 
|  | [[no_unique_address]] Second NZNoUnique; | 
|  | char B; | 
|  | }; | 
|  | Foo I; | 
|  |  | 
|  | // CHECK-LABEL:          0 | class SecondEmpty (empty) | 
|  | // CHECK-NEXT:           0 |   class Empty (base) (empty) | 
|  | // CHECK-NEXT:             | [sizeof=1, dsize=0, align=1, | 
|  | // CHECK-NEXT:             |  nvsize=1, nvalign=1] | 
|  | class SecondEmpty: Empty { | 
|  | }; | 
|  |  | 
|  | // CHECK-LABEL:          0 | class Bar | 
|  | // CHECK-NEXT:           0 |   class Empty (base) (empty) | 
|  | // CHECK-NEXT:           1 |   class SecondEmpty ZNoUnique (empty) | 
|  | // CHECK-NEXT:           1 |     class Empty (base) (empty) | 
|  | // CHECK-NEXT:           0 |   char C | 
|  | // CHECK-NEXT:             | [sizeof=2, dsize=1, align=1, | 
|  | // CHECK-NEXT:             |  nvsize=2, nvalign=1] | 
|  |  | 
|  | // CHECK-LABEL:  LLVMType:%class.Bar = type { i8, i8 } | 
|  | // CHECK-NEXT:   NonVirtualBaseLLVMType:%class.Bar = type { i8, i8 } | 
|  | class Bar : Empty { | 
|  | [[no_unique_address]] SecondEmpty ZNoUnique; | 
|  | char C; | 
|  | }; | 
|  | Bar J; | 
|  |  | 
|  | // CHECK-LABEL:          0 | class IntFieldClass | 
|  | // CHECK-NEXT:           0 |   class Empty (base) (empty) | 
|  | // CHECK-NEXT:           2 |   class Second Field | 
|  | // CHECK-NEXT:           2 |     class Empty (base) (empty) | 
|  | // CHECK-NEXT:       2:0-0 |     short A | 
|  | // CHECK-NEXT:           4 |   int C | 
|  | // CHECK-NEXT:             | [sizeof=8, dsize=8, align=4, | 
|  | // CHECK-NEXT:             |  nvsize=8, nvalign=4] | 
|  |  | 
|  | // CHECK-LABEL:   LLVMType:%class.IntFieldClass = type { [2 x i8], %class.Second.base, i32 } | 
|  | // CHECK-NEXT:    NonVirtualBaseLLVMType:%class.IntFieldClass = type { [2 x i8], %class.Second.base, i32 } | 
|  | class IntFieldClass : Empty { | 
|  | [[no_unique_address]] Second Field; | 
|  | int C; | 
|  | }; | 
|  | IntFieldClass K; | 
|  |  | 
|  | // CHECK-LABEL:         0 | class UnionClass | 
|  | // CHECK-NEXT:          0 |   class Empty (base) (empty) | 
|  | // CHECK-NEXT:          0 |   union UnionClass | 
|  | // CHECK-NEXT:          0 |     int I | 
|  | // CHECK-NEXT:          0 |     char C | 
|  | // CHECK-NEXT:          4 |   int C | 
|  | // CHECK-NEXT:            | [sizeof=8, dsize=8, align=4, | 
|  | // CHECK-NEXT:            |  nvsize=8, nvalign=4] | 
|  |  | 
|  | // CHECK-LABEL:  LLVMType:%class.UnionClass = type { %union.anon, i32 } | 
|  | // CHECK-NEXT:   NonVirtualBaseLLVMType:%class.UnionClass = type { %union.anon, i32 } | 
|  | // CHECK-NEXT:   IsZeroInitializable:1 | 
|  | // CHECK-NEXT:   BitFields:[ | 
|  | // CHECK-NEXT: ]> | 
|  | class UnionClass : Empty { | 
|  | [[no_unique_address]] union { | 
|  | int I; | 
|  | char C; | 
|  | } U; | 
|  | int C; | 
|  | }; | 
|  | UnionClass L; | 
|  |  | 
|  | // CHECK-LABEL:         0 | class EnumClass | 
|  | // CHECK-NEXT:          0 |   class Empty (base) (empty) | 
|  | // CHECK-NEXT:          0 |   enum E A | 
|  | // CHECK-NEXT:          4 |   int C | 
|  | // CHECK-NEXT:            | [sizeof=8, dsize=8, align=4, | 
|  | // CHECK-NEXT:            |  nvsize=8, nvalign=4] | 
|  |  | 
|  | // CHECK-LABEL:  LLVMType:%class.EnumClass = type { i32, i32 } | 
|  | // CHECK-NEXT:   NonVirtualBaseLLVMType:%class.EnumClass = type { i32, i32 } | 
|  | // CHECK-NEXT:   IsZeroInitializable:1 | 
|  | // CHECK-NEXT:   BitFields:[ | 
|  | // CHECK-NEXT: ]> | 
|  | class EnumClass : Empty { | 
|  | [[no_unique_address]] enum class E { X, Y, Z } A; | 
|  | int C; | 
|  | }; | 
|  | EnumClass M; | 
|  |  | 
|  | // CHECK-LABEL:         0 | class NoBaseField | 
|  | // CHECK-NEXT:          0 |   class Empty (base) (empty) | 
|  | // CHECK-NEXT:          1 |   class Empty A (empty) | 
|  | // CHECK-NEXT:          0 |   int B | 
|  | // CHECK-NEXT:            | [sizeof=4, dsize=4, align=4, | 
|  | // CHECK-NEXT:            |  nvsize=4, nvalign=4] | 
|  |  | 
|  | // CHECK-LABEL:  LLVMType:%class.NoBaseField = type { i32 } | 
|  | // CHECK-NEXT:   NonVirtualBaseLLVMType:%class.NoBaseField = type { i32 } | 
|  | // CHECK-NEXT:   IsZeroInitializable:1 | 
|  | // CHECK-NEXT:   BitFields:[ | 
|  | // CHECK-NEXT: ]> | 
|  | class NoBaseField : Empty { | 
|  | [[no_unique_address]] Empty A; | 
|  | int B; | 
|  | }; | 
|  | NoBaseField N; | 
|  |  | 
|  | // CHECK-LABEL:        0 | class FinalEmpty (empty) | 
|  | // CHECK-NEXT:           | [sizeof=1, dsize=1, align=1, | 
|  | // CHECK-NEXT:           |  nvsize=1, nvalign=1] | 
|  |  | 
|  | // CHECK-LABEL:        0 | class FinalClass | 
|  | // CHECK-NEXT:         0 |   class Empty (base) (empty) | 
|  | // CHECK-NEXT:         0 |   class FinalEmpty A (empty) | 
|  | // CHECK-NEXT:         0 |   int B | 
|  | // CHECK-NEXT:           | [sizeof=4, dsize=4, align=4, | 
|  | // CHECK-NEXT:           |  nvsize=4, nvalign=4] | 
|  | class FinalEmpty final {}; | 
|  | class FinalClass final : Empty { | 
|  | [[no_unique_address]] FinalEmpty A; | 
|  | int B; | 
|  | } O; | 
|  |  | 
|  |  | 
|  | // CHECK-LABEL:        0 | union Union2Class::PaddedUnion | 
|  | // CHECK-NEXT:         0 |   class Empty A (empty) | 
|  | // CHECK-NEXT:         0 |   char B | 
|  | // CHECK-NEXT:           | [sizeof=2, dsize=1, align=2, | 
|  | // CHECK-NEXT:           |  nvsize=1, nvalign=2] | 
|  |  | 
|  | // CHECK-LABEL:        0 | class Union2Class | 
|  | // CHECK-NEXT:         0 |   class Empty (base) (empty) | 
|  | // CHECK-NEXT:         2 |   union Union2Class::PaddedUnion U | 
|  | // CHECK-NEXT:         2 |     class Empty A (empty) | 
|  | // CHECK-NEXT:         2 |     char B | 
|  | // CHECK-NEXT:         3 |   char C | 
|  | // CHECK-NEXT:           | [sizeof=4, dsize=4, align=2, | 
|  | // CHECK-NEXT:           |  nvsize=4, nvalign=2] | 
|  | class Union2Class : Empty { | 
|  | [[no_unique_address]] union PaddedUnion { | 
|  | private: | 
|  | Empty A; | 
|  | alignas(2) char B; | 
|  | } U; | 
|  | char C; | 
|  | } P; | 
|  |  | 
|  | // CHECK-LABEL:          0 | struct NotEmptyWithBitfield | 
|  | // CHECK-NEXT:           0 |   class Empty (base) (empty) | 
|  | // CHECK-NEXT:           0 |   char[2] A | 
|  | // CHECK-NEXT:       2:0-0 |   int B | 
|  | // CHECK-NEXT:             | [sizeof=4, dsize=3, align=4, | 
|  | // CHECK-NEXT:             |  nvsize=3, nvalign=4] | 
|  |  | 
|  | // CHECK-LABEL:          0 | union C:: | 
|  | // CHECK-NEXT:           0 |   short C | 
|  | // CHECK-NEXT:           0 |   struct NotEmptyWithBitfield A | 
|  | // CHECK-NEXT:           0 |     class Empty (base) (empty) | 
|  | // CHECK-NEXT:           0 |     char[2] A | 
|  | // CHECK-NEXT:       2:0-0 |     int B | 
|  | // CHECK-NEXT:             | [sizeof=4, dsize=3, align=4, | 
|  | // CHECK-NEXT:             |  nvsize=3, nvalign=4] | 
|  |  | 
|  | // CHECK-LABEL:          0 | struct C | 
|  | // CHECK-NEXT:           0 |   union C:: | 
|  | // CHECK-NEXT:           0 |     short C | 
|  | // CHECK-NEXT:           0 |     struct NotEmptyWithBitfield A | 
|  | // CHECK-NEXT:           0 |       class Empty (base) (empty) | 
|  | // CHECK-NEXT:           0 |       char[2] A | 
|  | // CHECK-NEXT:       2:0-0 |       int B | 
|  | // CHECK-NEXT:             | [sizeof=4, dsize=3, align=4, | 
|  | // CHECK-NEXT:             |  nvsize=3, nvalign=4] | 
|  | struct NotEmptyWithBitfield : Empty { | 
|  | char A[2]; | 
|  | int B : 1; | 
|  | }; | 
|  | struct C { | 
|  | [[no_unique_address]] union { | 
|  | short C; | 
|  | [[no_unique_address]] NotEmptyWithBitfield A; | 
|  | } U; | 
|  | } Q; |