diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 143758f0866a..4ed031f97499 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -815,8 +815,8 @@ void RecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) { assert(DataSize == 0 && "Vtable pointer must be at offset zero!"); // Update the size. - setSize(getSize() + Context.toCharUnitsFromBits(GetVirtualPointersSize(RD))); - setDataSize(getSize()); + setSize(getSizeInBits() + GetVirtualPointersSize(RD)); + setDataSize(getSizeInBits()); CharUnits UnpackedBaseAlign = Context.toCharUnitsFromBits(Context.Target.getPointerAlign(0)); @@ -1108,7 +1108,8 @@ CharUnits RecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) { // If we have an empty base class, try to place it at offset 0. if (Base->Class->isEmpty() && EmptySubobjects->CanPlaceBaseAtOffset(Base, CharUnits::Zero())) { - setSize(std::max(getSize(), Layout.getSize())); + uint64_t RecordSizeInBits = Context.toBits(Layout.getSize()); + setSize(std::max(getSizeInBits(), RecordSizeInBits)); return CharUnits::Zero(); } @@ -1123,24 +1124,27 @@ CharUnits RecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) { } // Round up the current record size to the base's alignment boundary. - CharUnits Offset = getDataSize().RoundUpToAlignment(BaseAlign); + uint64_t Offset = + llvm::RoundUpToAlignment(getDataSizeInBits(), Context.toBits(BaseAlign)); // Try to place the base. - while (!EmptySubobjects->CanPlaceBaseAtOffset(Base, Offset)) - Offset += BaseAlign; + while (!EmptySubobjects->CanPlaceBaseAtOffset(Base, + Context.toCharUnitsFromBits(Offset))) + Offset += Context.toBits(BaseAlign); if (!Base->Class->isEmpty()) { // Update the data size. - setDataSize(Offset + Layout.getNonVirtualSize()); + setDataSize(Offset + Context.toBits(Layout.getNonVirtualSize())); - setSize(std::max(getSize(), getDataSize())); + setSize(std::max(getSizeInBits(), getDataSizeInBits())); } else - setSize(std::max(getSize(), Offset + Layout.getSize())); + setSize(std::max(getSizeInBits(), + Offset + Context.toBits(Layout.getSize()))); // Remember max struct/class alignment. UpdateAlignment(BaseAlign, UnpackedBaseAlign); - return Offset; + return Context.toCharUnitsFromBits(Offset); } void RecordLayoutBuilder::InitializeLayout(const Decl *D) { @@ -1229,7 +1233,7 @@ void RecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D) { // We start laying out ivars not at the end of the superclass // structure, but at the next byte following the last field. setSize(SL.getDataSize()); - setDataSize(getSize()); + setDataSize(getSizeInBits()); } InitializeLayout(D); @@ -1479,13 +1483,14 @@ void RecordLayoutBuilder::LayoutField(const FieldDecl *D) { Context.toBits(UnpackedFieldAlign), FieldPacked, D); // Reserve space for this field. + uint64_t FieldSizeInBits = Context.toBits(FieldSize); if (IsUnion) - setSize(std::max(getSize(), FieldSize)); + setSize(std::max(getSizeInBits(), FieldSizeInBits)); else - setSize(FieldOffset + FieldSize); + setSize(Context.toBits(FieldOffset) + FieldSizeInBits); // Update the data size. - setDataSize(getSize()); + setDataSize(getSizeInBits()); // Remember max struct/class alignment. UpdateAlignment(FieldAlign, UnpackedFieldAlign); @@ -1499,18 +1504,17 @@ void RecordLayoutBuilder::FinishLayout(const NamedDecl *D) { // which is not empty but of size 0; such as having fields of // array of zero-length, remains of Size 0 if (RD->isEmpty()) - setSize(CharUnits::One()); + setSize(8); } else - setSize(CharUnits::One()); + setSize(8); } // Finally, round the size of the record up to the alignment of the // record itself. uint64_t UnpaddedSize = getSizeInBits() - UnfilledBitsInLastByte; - uint64_t UnpackedSizeInBits = + uint64_t UnpackedSize = llvm::RoundUpToAlignment(getSizeInBits(), Context.toBits(UnpackedAlignment)); - CharUnits UnpackedSize = Context.toCharUnitsFromBits(UnpackedSizeInBits); setSize(llvm::RoundUpToAlignment(getSizeInBits(), Context.toBits(Alignment))); unsigned CharBitNum = Context.Target.getCharWidth(); @@ -1532,7 +1536,7 @@ void RecordLayoutBuilder::FinishLayout(const NamedDecl *D) { // Warn if we packed it unnecessarily. If the alignment is 1 byte don't // bother since there won't be alignment issues. if (Packed && UnpackedAlignment > CharUnits::One() && - getSize() == UnpackedSize) + getSizeInBits() == UnpackedSize) Diag(D->getLocation(), diag::warn_unnecessary_packed) << Context.getTypeDeclType(RD); }