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