// one.
// * The last zero size virtual base may be placed at the end of the struct.
// and can potentially alias a zero sized type in the next struct.
-// * If the last field is a non-zero length bitfield and we have any virtual
-// bases then some extra padding is added before the virtual bases for no
-// obvious reason.
+// * If the last field is a non-zero length bitfield, all virtual bases will
+// have extra padding added before them for no obvious reason. The padding
+// has the same number of bits as the type of the bitfield.
// * When laying out empty non-virtual bases, an extra byte of padding is added
// if the non-virtual base before the empty non-virtual base has a vbptr.
// * The ABI attempts to avoid aliasing of zero sized bases by adding padding
llvm::SmallPtrSet<const CXXRecordDecl *, 2> HasVtordisp =
computeVtorDispSet(RD);
- // If the last field we laid out was a non-zero length bitfield then add some
- // extra padding for no obvious reason.
- if (LastFieldIsNonZeroWidthBitfield)
- Size += CurrentBitfieldSize;
-
// Iterate through the virtual bases and lay them out.
for (CXXRecordDecl::base_class_const_iterator i = RD->vbases_begin(),
e = RD->vbases_end();
i != e; ++i) {
const CXXRecordDecl *BaseDecl =
cast<CXXRecordDecl>(i->getType()->castAs<RecordType>()->getDecl());
+ // If the last field we laid out was a non-zero length bitfield then add
+ // some extra padding for no obvious reason.
+ if (LastFieldIsNonZeroWidthBitfield)
+ Size += CurrentBitfieldSize;
layoutVirtualBase(BaseDecl, HasVtordisp.count(BaseDecl));
}
}
// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
// RUN: | FileCheck %s -check-prefix CHECK-X64
-struct B0 { };\r
-\r
-struct A : virtual B0 { char a : 1; };\r
+struct B0 { int a; };
+struct B1 { int a; };
-// CHECK: *** Dumping AST Record Layout\r
-// CHECK: 0 | struct A\r
-// CHECK: 0 | (A vbtable pointer)\r
-// CHECK: 4 | char a\r
-// CHECK: 9 | struct B0 (virtual base) (empty)\r
-// CHECK: | [sizeof=9, align=4\r
-// CHECK: | nvsize=8, nvalign=4]\r
+struct A : virtual B0 { char a : 1; };
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: 0 | struct A
+// CHECK: 0 | (A vbtable pointer)
+// CHECK: 4 | char a
+// CHECK: 12 | struct B0 (virtual base)
+// CHECK: 12 | int a
+// CHECK: | [sizeof=16, align=4
+// CHECK: | nvsize=8, nvalign=4]
// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: 0 | struct A\r
-// CHECK-X64: 0 | (A vbtable pointer)\r
-// CHECK-X64: 8 | char a\r
-// CHECK-X64: 17 | struct B0 (virtual base) (empty)\r
-// CHECK-X64: | [sizeof=24, align=8\r
-// CHECK-X64: | nvsize=16, nvalign=8]\r
+// CHECK-X64: 0 | struct A
+// CHECK-X64: 0 | (A vbtable pointer)
+// CHECK-X64: 8 | char a
+// CHECK-X64: 20 | struct B0 (virtual base)
+// CHECK-X64: 20 | int a
+// CHECK-X64: | [sizeof=24, align=8
+// CHECK-X64: | nvsize=16, nvalign=8]
-struct B : virtual B0 { short a : 1; };\r
+struct B : virtual B0 { short a : 1; };
// CHECK: *** Dumping AST Record Layout
-// CHECK: 0 | struct B\r
-// CHECK: 0 | (B vbtable pointer)\r
-// CHECK: 4 | short a\r
-// CHECK: 10 | struct B0 (virtual base) (empty)\r
-// CHECK: | [sizeof=10, align=4\r
-// CHECK: | nvsize=8, nvalign=4]\r
+// CHECK: 0 | struct B
+// CHECK: 0 | (B vbtable pointer)
+// CHECK: 4 | short a
+// CHECK: 12 | struct B0 (virtual base)
+// CHECK: 12 | int a
+// CHECK: | [sizeof=16, align=4
+// CHECK: | nvsize=8, nvalign=4]
// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: 0 | struct B\r
-// CHECK-X64: 0 | (B vbtable pointer)\r
-// CHECK-X64: 8 | short a\r
-// CHECK-X64: 18 | struct B0 (virtual base) (empty)\r
-// CHECK-X64: | [sizeof=24, align=8\r
-// CHECK-X64: | nvsize=16, nvalign=8]\r
+// CHECK-X64: 0 | struct B
+// CHECK-X64: 0 | (B vbtable pointer)
+// CHECK-X64: 8 | short a
+// CHECK-X64: 20 | struct B0 (virtual base)
+// CHECK-X64: 20 | int a
+// CHECK-X64: | [sizeof=24, align=8
+// CHECK-X64: | nvsize=16, nvalign=8]
-struct C : virtual B0 { char a : 1; char : 0; };\r
+struct C : virtual B0 { char a : 1; char : 0; };
// CHECK: *** Dumping AST Record Layout
-// CHECK: 0 | struct C\r
-// CHECK: 0 | (C vbtable pointer)\r
-// CHECK: 4 | char a\r
-// CHECK: 5 | char\r
-// CHECK: 8 | struct B0 (virtual base) (empty)\r
-// CHECK: | [sizeof=8, align=4\r
-// CHECK: | nvsize=8, nvalign=4]\r
+// CHECK: 0 | struct C
+// CHECK: 0 | (C vbtable pointer)
+// CHECK: 4 | char a
+// CHECK: 5 | char
+// CHECK: 8 | struct B0 (virtual base)
+// CHECK: 8 | int a
+// CHECK: | [sizeof=12, align=4
+// CHECK: | nvsize=8, nvalign=4]
// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: 0 | struct C\r
-// CHECK-X64: 0 | (C vbtable pointer)\r
-// CHECK-X64: 8 | char a\r
-// CHECK-X64: 9 | char\r
-// CHECK-X64: 16 | struct B0 (virtual base) (empty)\r
-// CHECK-X64: | [sizeof=16, align=8\r
-// CHECK-X64: | nvsize=16, nvalign=8]\r
+// CHECK-X64: 0 | struct C
+// CHECK-X64: 0 | (C vbtable pointer)
+// CHECK-X64: 8 | char a
+// CHECK-X64: 9 | char
+// CHECK-X64: 16 | struct B0 (virtual base)
+// CHECK-X64: 16 | int a
+// CHECK-X64: | [sizeof=24, align=8
+// CHECK-X64: | nvsize=16, nvalign=8]
+
+struct D : virtual B0 { char a : 1; char b; };
-struct D : virtual B0 { char a : 1; char b; };\r
+// CHECK: *** Dumping AST Record Layout
+// CHECK: 0 | struct D
+// CHECK: 0 | (D vbtable pointer)
+// CHECK: 4 | char a
+// CHECK: 5 | char b
+// CHECK: 8 | struct B0 (virtual base)
+// CHECK: 8 | int a
+// CHECK: | [sizeof=12, align=4
+// CHECK: | nvsize=8, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: 0 | struct D
+// CHECK-X64: 0 | (D vbtable pointer)
+// CHECK-X64: 8 | char a
+// CHECK-X64: 9 | char b
+// CHECK-X64: 16 | struct B0 (virtual base)
+// CHECK-X64: 16 | int a
+// CHECK-X64: | [sizeof=24, align=8
+// CHECK-X64: | nvsize=16, nvalign=8]
+struct E : virtual B0, virtual B1 { long long : 1; };
// CHECK: *** Dumping AST Record Layout
-// CHECK: 0 | struct D\r
-// CHECK: 0 | (D vbtable pointer)\r
-// CHECK: 4 | char a\r
-// CHECK: 5 | char b\r
-// CHECK: 8 | struct B0 (virtual base) (empty)\r
-// CHECK: | [sizeof=8, align=4\r
-// CHECK: | nvsize=8, nvalign=4]\r
+// CHECK: 0 | struct E
+// CHECK: 0 | (E vbtable pointer)
+// CHECK: 8 | long long
+// CHECK: 24 | struct B0 (virtual base)
+// CHECK: 24 | int a
+// CHECK: 36 | struct B1 (virtual base)
+// CHECK: 36 | int a
+// CHECK: | [sizeof=40, align=8
+// CHECK: | nvsize=16, nvalign=8]
// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64: 0 | struct D\r
-// CHECK-X64: 0 | (D vbtable pointer)\r
-// CHECK-X64: 8 | char a\r
-// CHECK-X64: 9 | char b\r
-// CHECK-X64: 16 | struct B0 (virtual base) (empty)\r
-// CHECK-X64: | [sizeof=16, align=8\r
-// CHECK-X64: | nvsize=16, nvalign=8]\r
+// CHECK-X64: 0 | struct E
+// CHECK-X64: 0 | (E vbtable pointer)
+// CHECK-X64: 8 | long long
+// CHECK-X64: 24 | struct B0 (virtual base)
+// CHECK-X64: 24 | int a
+// CHECK-X64: 36 | struct B1 (virtual base)
+// CHECK-X64: 36 | int a
+// CHECK-X64: | [sizeof=40, align=8
+// CHECK-X64: | nvsize=16, nvalign=8]
int a[
sizeof(A)+
sizeof(B)+
sizeof(C)+
-sizeof(D)];
+sizeof(D)+
+sizeof(E)];