// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -fdump-record-layouts \ // RUN: -fsyntax-only -fxl-pragma-pack %s | \ // RUN: FileCheck %s // RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -fdump-record-layouts \ // RUN: -fsyntax-only -fxl-pragma-pack %s | \ // RUN: FileCheck %s namespace test1 { // Test the class layout when having a double which is/is not the first struct // member. struct D { double d1; int i1; }; struct DoubleFirst { struct D d2; int i2; }; struct IntFirst { int i3; struct D d3; }; int a = sizeof(DoubleFirst); int b = sizeof(IntFirst); // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test1::D // CHECK-NEXT: 0 | double d1 // CHECK-NEXT: 8 | int i1 // CHECK-NEXT: | [sizeof=16, dsize=16, align=4, preferredalign=8, // CHECK-NEXT: | nvsize=16, nvalign=4, preferrednvalign=8] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test1::DoubleFirst // CHECK-NEXT: 0 | struct test1::D d2 // CHECK-NEXT: 0 | double d1 // CHECK-NEXT: 8 | int i1 // CHECK-NEXT: 16 | int i2 // CHECK-NEXT: | [sizeof=24, dsize=24, align=4, preferredalign=8, // CHECK-NEXT: | nvsize=24, nvalign=4, preferrednvalign=8] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test1::IntFirst // CHECK-NEXT: 0 | int i3 // CHECK-NEXT: 4 | struct test1::D d3 // CHECK-NEXT: 4 | double d1 // CHECK-NEXT: 12 | int i1 // CHECK-NEXT: | [sizeof=20, dsize=20, align=4, preferredalign=4, // CHECK-NEXT: | nvsize=20, nvalign=4, preferrednvalign=4] } // namespace test1 namespace test2 { // Test the class layout when having a zero-sized bitfield followed by double. struct Double { int : 0; double d; }; int a = sizeof(Double); // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test2::Double // CHECK-NEXT: 0:- | int // CHECK-NEXT: 0 | double d // CHECK-NEXT: | [sizeof=8, dsize=8, align=4, preferredalign=4, // CHECK-NEXT: | nvsize=8, nvalign=4, preferrednvalign=4] } // namespace test2 namespace test3 { // Test the class layout when having a double member in union. union A { int b; double d; }; struct UnionStruct { union A a; int i; }; int a = sizeof(UnionStruct); // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | union test3::A // CHECK-NEXT: 0 | int b // CHECK-NEXT: 0 | double d // CHECK-NEXT: | [sizeof=8, dsize=8, align=4, preferredalign=8, // CHECK-NEXT: | nvsize=8, nvalign=4, preferrednvalign=8] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test3::UnionStruct // CHECK-NEXT: 0 | union test3::A a // CHECK-NEXT: 0 | int b // CHECK-NEXT: 0 | double d // CHECK-NEXT: 8 | int i // CHECK-NEXT: | [sizeof=16, dsize=16, align=4, preferredalign=8, // CHECK-NEXT: | nvsize=16, nvalign=4, preferrednvalign=8] } // namespace test3 namespace test4 { // Test the class layout when having multiple base classes. struct A { int a; }; struct B { double d; }; class S : A, B { }; int a = sizeof(S); // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test4::A // CHECK-NEXT: 0 | int a // CHECK-NEXT: | [sizeof=4, dsize=4, align=4, preferredalign=4, // CHECK-NEXT: | nvsize=4, nvalign=4, preferrednvalign=4] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test4::B // CHECK-NEXT: 0 | double d // CHECK-NEXT: | [sizeof=8, dsize=8, align=4, preferredalign=8, // CHECK-NEXT: | nvsize=8, nvalign=4, preferrednvalign=8] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | class test4::S // CHECK-NEXT: 0 | struct test4::A (base) // CHECK-NEXT: 0 | int a // CHECK-NEXT: 4 | struct test4::B (base) // CHECK-NEXT: 4 | double d // CHECK-NEXT: | [sizeof=12, dsize=12, align=4, preferredalign=4, // CHECK-NEXT: | nvsize=12, nvalign=4, preferrednvalign=4] } // namespace test4 namespace test5 { struct Empty { }; struct EmptyDer : Empty { double d; }; struct NonEmpty { int i; }; struct NonEmptyDer : NonEmpty { double d; }; int a = sizeof(EmptyDer); int b = sizeof(NonEmptyDer); // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test5::Empty (empty) // CHECK-NEXT: | [sizeof=1, dsize=1, align=1, preferredalign=1, // CHECK-NEXT: | nvsize=1, nvalign=1, preferrednvalign=1] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test5::EmptyDer // CHECK-NEXT: 0 | struct test5::Empty (base) (empty) // CHECK-NEXT: 0 | double d // CHECK-NEXT: | [sizeof=8, dsize=8, align=4, preferredalign=8, // CHECK-NEXT: | nvsize=8, nvalign=4, preferrednvalign=8] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test5::NonEmpty // CHECK-NEXT: 0 | int i // CHECK-NEXT: | [sizeof=4, dsize=4, align=4, preferredalign=4, // CHECK-NEXT: | nvsize=4, nvalign=4, preferrednvalign=4] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test5::NonEmptyDer // CHECK-NEXT: 0 | struct test5::NonEmpty (base) // CHECK-NEXT: 0 | int i // CHECK-NEXT: 4 | double d // CHECK-NEXT: | [sizeof=12, dsize=12, align=4, preferredalign=4, // CHECK-NEXT: | nvsize=12, nvalign=4, preferrednvalign=4] } // namespace test5 namespace test6 { struct A { struct B { double d[3]; } b; }; int a = sizeof(A); // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test6::A::B // CHECK-NEXT: 0 | double [3] d // CHECK-NEXT: | [sizeof=24, dsize=24, align=4, preferredalign=8, // CHECK-NEXT: | nvsize=24, nvalign=4, preferrednvalign=8] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test6::A // CHECK-NEXT: 0 | struct test6::A::B b // CHECK-NEXT: 0 | double [3] d // CHECK-NEXT: | [sizeof=24, dsize=24, align=4, preferredalign=8, // CHECK-NEXT: | nvsize=24, nvalign=4, preferrednvalign=8] } // namespace test6 namespace test7 { struct A { struct B { long double _Complex d[3]; } b; }; int a = sizeof(A); // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test7::A::B // CHECK-NEXT: 0 | _Complex long double [3] d // CHECK-NEXT: | [sizeof=48, dsize=48, align=4, preferredalign=8, // CHECK-NEXT: | nvsize=48, nvalign=4, preferrednvalign=8] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test7::A // CHECK-NEXT: 0 | struct test7::A::B b // CHECK-NEXT: 0 | _Complex long double [3] d // CHECK-NEXT: | [sizeof=48, dsize=48, align=4, preferredalign=8, // CHECK-NEXT: | nvsize=48, nvalign=4, preferrednvalign=8] } // namespace test7 namespace test8 { struct Emp {}; struct Y : Emp { double d; }; struct Z : Emp { Y y; }; int a = sizeof(Z); // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test8::Emp (empty) // CHECK-NEXT: | [sizeof=1, dsize=1, align=1, preferredalign=1, // CHECK-NEXT: | nvsize=1, nvalign=1, preferrednvalign=1] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test8::Y // CHECK-NEXT: 0 | struct test8::Emp (base) (empty) // CHECK-NEXT: 0 | double d // CHECK-NEXT: | [sizeof=8, dsize=8, align=4, preferredalign=8, // CHECK-NEXT: | nvsize=8, nvalign=4, preferrednvalign=8] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test8::Z // CHECK-NEXT: 0 | struct test8::Emp (base) (empty) // CHECK-NEXT: 8 | struct test8::Y y // CHECK-NEXT: 8 | struct test8::Emp (base) (empty) // CHECK-NEXT: 8 | double d // CHECK-NEXT: | [sizeof=16, dsize=16, align=4, preferredalign=8, // CHECK-NEXT: | nvsize=16, nvalign=4, preferrednvalign=8] } // namespace test8 namespace test9 { // Test the class layout when having a zero-extent array in a base class, which // renders the base class not empty. struct A { char zea[0]; }; struct B : A { double d; }; struct C { double d; }; struct D : A, C { char x; }; int a = sizeof(B); int b = sizeof(D); // CHECK: 0 | struct test9::B // CHECK-NEXT: 0 | struct test9::A (base) // CHECK-NEXT: 0 | char [0] zea // CHECK-NEXT: 0 | double d // CHECK-NEXT: | [sizeof=8, dsize=8, align=4, preferredalign=4, // CHECK-NEXT: | nvsize=8, nvalign=4, preferrednvalign=4] // CHECK: 0 | struct test9::D // CHECK-NEXT: 0 | struct test9::A (base) // CHECK-NEXT: 0 | char [0] zea // CHECK-NEXT: 0 | struct test9::C (base) // CHECK-NEXT: 0 | double d // CHECK-NEXT: 8 | char x // CHECK-NEXT: | [sizeof=12, dsize=9, align=4, preferredalign=4, // CHECK-NEXT: | nvsize=9, nvalign=4, preferrednvalign=4] } // namespace test9 namespace test10 { struct A { double x; }; struct B : A {}; int a = sizeof(B); // CHECK: 0 | struct test10::B // CHECK-NEXT: 0 | struct test10::A (base) // CHECK-NEXT: 0 | double x // CHECK-NEXT: | [sizeof=8, dsize=8, align=4, preferredalign=8, // CHECK-NEXT: | nvsize=8, nvalign=4, preferrednvalign=8] } // namespace test10 namespace test11 { // Test how #pragma pack and align attribute interacts with AIX `power` // alignment rules. struct A { char a; double __attribute__((aligned(16))) d; int i; }; struct B { double __attribute__((aligned(4))) d1; char a; double d2; }; #pragma pack(2) struct C { int i; short j; double k; }; #pragma pack(pop) #pragma pack(2) struct D { double d; short j; int i; }; #pragma pack(pop) #pragma pack(8) struct E { double __attribute__((aligned(4))) d; short s; }; #pragma pack(pop) #pragma pack(4) struct F : public D { double d; }; #pragma pack(pop) #pragma pack(2) struct G : public E { int i; }; #pragma pack(pop) int a = sizeof(A); int b = sizeof(B); int c = sizeof(C); int d = sizeof(D); int e = sizeof(E); int f = sizeof(F); int g = sizeof(G); // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test11::A // CHECK-NEXT: 0 | char a // CHECK-NEXT: 16 | double d // CHECK-NEXT: 24 | int i // CHECK-NEXT: | [sizeof=32, dsize=32, align=16, preferredalign=16, // CHECK-NEXT: | nvsize=32, nvalign=16, preferrednvalign=16] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test11::B // CHECK-NEXT: 0 | double d1 // CHECK-NEXT: 8 | char a // CHECK-NEXT: 12 | double d2 // CHECK-NEXT: | [sizeof=24, dsize=24, align=4, preferredalign=8, // CHECK-NEXT: | nvsize=24, nvalign=4, preferrednvalign=8] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test11::C // CHECK-NEXT: 0 | int i // CHECK-NEXT: 4 | short j // CHECK-NEXT: 6 | double k // CHECK-NEXT: | [sizeof=14, dsize=14, align=2, preferredalign=2, // CHECK-NEXT: | nvsize=14, nvalign=2, preferrednvalign=2] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test11::D // CHECK-NEXT: 0 | double d // CHECK-NEXT: 8 | short j // CHECK-NEXT: 10 | int i // CHECK-NEXT: | [sizeof=14, dsize=14, align=2, preferredalign=2, // CHECK-NEXT: | nvsize=14, nvalign=2, preferrednvalign=2] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test11::E // CHECK-NEXT: 0 | double d // CHECK-NEXT: 8 | short s // CHECK-NEXT: | [sizeof=16, dsize=16, align=4, preferredalign=8, // CHECK-NEXT: | nvsize=16, nvalign=4, preferrednvalign=8] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test11::F // CHECK-NEXT: 0 | struct test11::D (base) // CHECK-NEXT: 0 | double d // CHECK-NEXT: 8 | short j // CHECK-NEXT: 10 | int i // CHECK-NEXT: 16 | double d // CHECK-NEXT: | [sizeof=24, dsize=24, align=4, preferredalign=4, // CHECK-NEXT: | nvsize=24, nvalign=4, preferrednvalign=4] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct test11::G // CHECK-NEXT: 0 | struct test11::E (base) // CHECK-NEXT: 0 | double d // CHECK-NEXT: 8 | short s // CHECK-NEXT: 16 | int i // CHECK-NEXT: | [sizeof=20, dsize=20, align=2, preferredalign=2, // CHECK-NEXT: | nvsize=20, nvalign=2, preferrednvalign=2] } // namespace test11