initializeLayout(RD);
layoutFields(RD);
DataSize = Size = Size.RoundUpToAlignment(Alignment);
+ RequiredAlignment = std::max(
+ RequiredAlignment, Context.toCharUnitsFromBits(RD->getMaxAlignment()));
finalizeLayout(RD);
}
layoutFields(RD);
injectVPtrs(RD);
DataSize = Size = Size.RoundUpToAlignment(Alignment);
+ RequiredAlignment = std::max(
+ RequiredAlignment, Context.toCharUnitsFromBits(RD->getMaxAlignment()));
layoutVirtualBases(RD);
finalizeLayout(RD);
}
// In 32-bit mode we do not. The check to see if we need to perform alignment
// checks the RequiredAlignment field and performs alignment if it isn't 0.
RequiredAlignment = Is64BitMode ? CharUnits::One() : CharUnits::Zero();
- RequiredAlignment = std::max(RequiredAlignment,
- Context.toCharUnitsFromBits(RD->getMaxAlignment()));
// Compute the maximum field alignment.
MaxFieldAlignment = CharUnits::Zero();
// Honor the default struct packing maximum alignment flag.
i != e; ++i) {
const CXXRecordDecl *BaseDecl = i->getType()->getAsCXXRecordDecl();
const ASTRecordLayout &BaseLayout = Context.getASTRecordLayout(BaseDecl);
- // Track RequiredAlignment for all bases in this pass.
- RequiredAlignment = std::max(RequiredAlignment,
- BaseLayout.getRequiredAlignment());
// Mark and skip virtual bases.
if (i->isVirtual()) {
HasVBPtr = true;
continue;
}
+ // Track RequiredAlignment for all bases in this pass.
+ RequiredAlignment = std::max(RequiredAlignment,
+ BaseLayout.getRequiredAlignment());
// Check fo a base to share a VBPtr with.
if (!SharedVBPtrBase && BaseLayout.hasVBPtr()) {
SharedVBPtrBase = BaseDecl;
CharUnits FieldStart = VBPtrOffset + PointerInfo.Size;
// Make sure that the amount we push the fields back by is a multiple of the
// alignment.
- CharUnits Offset = (FieldStart - InjectionSite).RoundUpToAlignment(Alignment);
+ CharUnits Offset = (FieldStart - InjectionSite).RoundUpToAlignment(
+ std::max(RequiredAlignment, Alignment));
// Increase the size of the object and push back all fields by the offset
// amount.
Size += Offset;
return;
// Make sure that the amount we push the struct back by is a multiple of the
// alignment.
- CharUnits Offset = PointerInfo.Size.RoundUpToAlignment(Alignment);
+ CharUnits Offset = PointerInfo.Size.RoundUpToAlignment(
+ std::max(RequiredAlignment, Alignment));
// Increase the size of the object and push back all fields, the vbptr and all
// bases by the offset amount.
Size += Offset;
- for (SmallVector<uint64_t, 16>::iterator i = FieldOffsets.begin(),
+ for (SmallVectorImpl<uint64_t>::iterator i = FieldOffsets.begin(),
e = FieldOffsets.end();
i != e; ++i)
*i += Context.toBits(Offset);
// The alignment of the vtordisp is at least the required alignment of the
// entire record. This requirement may be present to support vtordisp
// injection.
+ for (CXXRecordDecl::base_class_const_iterator i = RD->vbases_begin(),
+ e = RD->vbases_end();
+ i != e; ++i) {
+ const CXXRecordDecl *BaseDecl = i->getType()->getAsCXXRecordDecl();
+ const ASTRecordLayout &BaseLayout = Context.getASTRecordLayout(BaseDecl);
+ RequiredAlignment =
+ std::max(RequiredAlignment, BaseLayout.getRequiredAlignment());
+ }
VtorDispAlignment = std::max(VtorDispAlignment, RequiredAlignment);
// Compute the vtordisp set.
llvm::SmallPtrSet<const CXXRecordDecl *, 2> HasVtordispSet =
// CHECK-X64-NEXT: | [sizeof=4, align=2
// CHECK-X64-NEXT: | nvsize=3, nvalign=2]
+#pragma pack(1)
+struct L {
+ virtual void fun() {}
+ __declspec(align(256)) int Field;
+};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT: 0 | struct L
+// CHECK-NEXT: 0 | (L vftable pointer)
+// CHECK-NEXT: 256 | int Field
+// CHECK-NEXT: | [sizeof=512, align=256
+// CHECK-NEXT: | nvsize=260, nvalign=256]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT: 0 | struct L
+// CHECK-X64-NEXT: 0 | (L vftable pointer)
+// CHECK-X64-NEXT: 256 | int Field
+// CHECK-X64-NEXT: | [sizeof=512, align=256
+// CHECK-X64-NEXT: | nvsize=260, nvalign=256]
+
+#pragma pack()
+struct MA {};
+#pragma pack(1)
+struct MB : virtual MA {
+ __declspec(align(256)) int Field;
+};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT: 0 | struct MB
+// CHECK-NEXT: 0 | (MB vbtable pointer)
+// CHECK-NEXT: 256 | int Field
+// CHECK-NEXT: 260 | struct MA (virtual base) (empty)
+// CHECK-NEXT: | [sizeof=512, align=256
+// CHECK-NEXT: | nvsize=260, nvalign=256]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT: 0 | struct MB
+// CHECK-X64-NEXT: 0 | (MB vbtable pointer)
+// CHECK-X64-NEXT: 256 | int Field
+// CHECK-X64-NEXT: 260 | struct MA (virtual base) (empty)
+// CHECK-X64-NEXT: | [sizeof=512, align=256
+// CHECK-X64-NEXT: | nvsize=260, nvalign=256]
+
int a[
sizeof(X)+
sizeof(Y)+
sizeof(D2)+
sizeof(JC)+
sizeof(KB)+
+sizeof(L)+
+sizeof(MB)+
0];