/// \brief Lays out a single zero-width bit-field in the record and handles
/// special cases associated with zero-width bit-fields.
void layoutZeroWidthBitField(const FieldDecl *FD);
+ void fixSizeAndAlignment(const RecordDecl *FD);
void layoutVirtualBases(const CXXRecordDecl *RD);
void layoutVirtualBase(const CXXRecordDecl *RD, bool HasVtordisp);
/// \brief Flushes the lazy virtual base and conditionally rounds up to
/// alignment.
void finalizeCXXLayout(const CXXRecordDecl *RD);
- void honorDeclspecAlign(const RecordDecl *RD);
+ void finalizeLayout(const RecordDecl *RD);
/// \brief Updates the alignment of the type. This function doesn't take any
/// properties (such as packedness) into account. getAdjustedFieldInfo()
void MicrosoftRecordLayoutBuilder::layout(const RecordDecl *RD) {
initializeLayout(RD);
layoutFields(RD);
- honorDeclspecAlign(RD);
+ fixSizeAndAlignment(RD);
+ finalizeLayout(RD);
}
void MicrosoftRecordLayoutBuilder::cxxLayout(const CXXRecordDecl *RD) {
layoutNonVirtualBases(RD);
layoutVBPtr(RD);
layoutFields(RD);
- DataSize = Size;
- NonVirtualAlignment = Alignment;
+ fixSizeAndAlignment(RD);
layoutVirtualBases(RD);
finalizeCXXLayout(RD);
- honorDeclspecAlign(RD);
+ finalizeLayout(RD);
}
void
}
}
+void MicrosoftRecordLayoutBuilder::fixSizeAndAlignment(const RecordDecl *RD) {
+ DataSize = Size;
+ NonVirtualAlignment = Alignment;
+ RequiredAlignment = std::max(RequiredAlignment,
+ Context.toCharUnitsFromBits(RD->getMaxAlignment()));
+}
+
void MicrosoftRecordLayoutBuilder::layoutVirtualBases(const CXXRecordDecl *RD) {
if (!HasVBPtr)
return;
// bytes (in both 32 and 64 bits modes), we don't know why.
if (PreviousBaseLayout && PreviousBaseLayout->hasZeroSizedSubObject() &&
Layout.leadsWithZeroSizedBase())
- Size = Size.RoundUpToAlignment(Alignment) +
- std::max(CharUnits::fromQuantity(4), Layout.getAlignment());
+ Size = Size.RoundUpToAlignment(std::max(CharUnits::fromQuantity(4),
+ RequiredAlignment)) +
+ CharUnits::fromQuantity(4);
CharUnits BaseNVSize = Layout.getNonVirtualSize();
CharUnits BaseAlign = getBaseAlignment(Layout);
}
}
-void MicrosoftRecordLayoutBuilder::honorDeclspecAlign(const RecordDecl *RD) {
- RequiredAlignment = std::max(RequiredAlignment,
- Context.toCharUnitsFromBits(RD->getMaxAlignment()));
+void MicrosoftRecordLayoutBuilder::finalizeLayout(const RecordDecl *RD) {
if (!RequiredAlignment.isZero()) {
updateAlignment(RequiredAlignment);
Size = Size.RoundUpToAlignment(Alignment);
// CHECK-X64: 8 | struct T0 (base) (empty)
// CHECK-X64: 8 | struct AT (base) (empty)
// CHECK-X64: 8 | char a
-// CHECK-X64: 20 | struct T2 (virtual base)
-// CHECK-X64: 20 | struct AT (base) (empty)
-// CHECK-X64: 20 | char a
+// CHECK-X64: 16 | struct T2 (virtual base)
+// CHECK-X64: 16 | struct AT (base) (empty)
+// CHECK-X64: 16 | char a
// CHECK-X64: | [sizeof=24, align=8
// CHECK-X64: | nvsize=8, nvalign=8]
// CHECK-X64: | [sizeof=32, align=32
// CHECK-X64: | nvsize=16, nvalign=8]
+struct T0 {};
+struct T1 : T0 { char a; };
+struct T3 : virtual T1, virtual T0 { long long a; };
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: 0 | struct T3
+// CHECK: 0 | (T3 vbtable pointer)
+// CHECK: 8 | long long a
+// CHECK: 16 | struct T1 (virtual base)
+// CHECK: 16 | struct T0 (base) (empty)
+// CHECK: 16 | char a
+// CHECK: 24 | struct T0 (virtual base) (empty)
+// CHECK: | [sizeof=24, align=8
+// CHECK: | nvsize=16, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: 0 | struct T3
+// CHECK-X64: 0 | (T3 vbtable pointer)
+// CHECK-X64: 8 | long long a
+// CHECK-X64: 16 | struct T1 (virtual base)
+// CHECK-X64: 16 | struct T0 (base) (empty)
+// CHECK-X64: 16 | char a
+// CHECK-X64: 24 | struct T0 (virtual base) (empty)
+// CHECK-X64: | [sizeof=24, align=8
+// CHECK-X64: | nvsize=16, nvalign=8]
+
int a[
sizeof(A)+
sizeof(B)+
sizeof(S)+
sizeof(T)+
sizeof(U)+
-sizeof(V)];
\ No newline at end of file
+sizeof(V)+
+sizeof(T3)];
\ No newline at end of file