// 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;