From 944691f0b7fa8d99790a4544545e55f014c37295 Mon Sep 17 00:00:00 2001 From: Xiangling Liao Date: Wed, 30 Sep 2020 09:52:41 -0400 Subject: [PATCH] [NFC][FE] Replace TypeSize with StorageUnitSize On some targets like AIX, last bitfield size is not always equal to last bitfield type size. Some bitfield like bool will have the same alignment as [unsigned]. So we'd like to use a more general term `StorageUnit` to replace type in this field. Differential Revision: https://reviews.llvm.org/D88260 --- clang/lib/AST/RecordLayoutBuilder.cpp | 60 ++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 715b629..1c185bb 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -622,9 +622,10 @@ protected: /// an adjacent bitfield if necessary. The unit in question is usually /// a byte, but larger units are used if IsMsStruct. unsigned char UnfilledBitsInLastUnit; - /// LastBitfieldTypeSize - If IsMsStruct, represents the size of the type - /// of the previous field if it was a bitfield. - unsigned char LastBitfieldTypeSize; + + /// LastBitfieldStorageUnitSize - If IsMsStruct, represents the size of the + /// storage unit of the previous field if it was a bitfield. + unsigned char LastBitfieldStorageUnitSize; /// MaxFieldAlignment - The maximum allowed field alignment. This is set by /// #pragma pack. @@ -693,7 +694,7 @@ protected: UnadjustedAlignment(CharUnits::One()), UseExternalLayout(false), InferAlignment(false), Packed(false), IsUnion(false), IsMac68kAlign(false), IsMsStruct(false), UnfilledBitsInLastUnit(0), - LastBitfieldTypeSize(0), MaxFieldAlignment(CharUnits::Zero()), + LastBitfieldStorageUnitSize(0), MaxFieldAlignment(CharUnits::Zero()), DataSize(0), NonVirtualSize(CharUnits::Zero()), NonVirtualAlignment(CharUnits::One()), PreferredNVAlignment(CharUnits::One()), @@ -708,7 +709,7 @@ protected: void LayoutFields(const RecordDecl *D); void LayoutField(const FieldDecl *D, bool InsertExtraPadding); - void LayoutWideBitField(uint64_t FieldSize, uint64_t TypeSize, + void LayoutWideBitField(uint64_t FieldSize, uint64_t StorageUnitSize, bool FieldPacked, const FieldDecl *D); void LayoutBitField(const FieldDecl *D); @@ -1451,7 +1452,7 @@ roundUpSizeToCharAlignment(uint64_t Size, } void ItaniumRecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize, - uint64_t TypeSize, + uint64_t StorageUnitSize, bool FieldPacked, const FieldDecl *D) { assert(Context.getLangOpts().CPlusPlus && @@ -1481,7 +1482,7 @@ void ItaniumRecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize, // We're not going to use any of the unfilled bits in the last byte. UnfilledBitsInLastUnit = 0; - LastBitfieldTypeSize = 0; + LastBitfieldStorageUnitSize = 0; uint64_t FieldOffset; uint64_t UnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastUnit; @@ -1520,7 +1521,7 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { bool FieldPacked = Packed || D->hasAttr(); uint64_t FieldSize = D->getBitWidthValue(Context); TypeInfo FieldInfo = Context.getTypeInfo(D->getType()); - uint64_t TypeSize = FieldInfo.Width; + uint64_t StorageUnitSize = FieldInfo.Width; unsigned FieldAlign = FieldInfo.Align; // UnfilledBitsInLastUnit is the difference between the end of the @@ -1529,7 +1530,7 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { // first bit offset available for non-bitfields). The current data // size in bits is always a multiple of the char size; additionally, // for ms_struct records it's also a multiple of the - // LastBitfieldTypeSize (if set). + // LastBitfieldStorageUnitSize (if set). // The struct-layout algorithm is dictated by the platform ABI, // which in principle could use almost any rules it likes. In @@ -1583,26 +1584,26 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { // First, some simple bookkeeping to perform for ms_struct structs. if (IsMsStruct) { // The field alignment for integer types is always the size. - FieldAlign = TypeSize; + FieldAlign = StorageUnitSize; // If the previous field was not a bitfield, or was a bitfield // with a different storage unit size, or if this field doesn't fit into // the current storage unit, we're done with that storage unit. - if (LastBitfieldTypeSize != TypeSize || + if (LastBitfieldStorageUnitSize != StorageUnitSize || UnfilledBitsInLastUnit < FieldSize) { // Also, ignore zero-length bitfields after non-bitfields. - if (!LastBitfieldTypeSize && !FieldSize) + if (!LastBitfieldStorageUnitSize && !FieldSize) FieldAlign = 1; UnfilledBitsInLastUnit = 0; - LastBitfieldTypeSize = 0; + LastBitfieldStorageUnitSize = 0; } } // If the field is wider than its declared type, it follows // different rules in all cases. - if (FieldSize > TypeSize) { - LayoutWideBitField(FieldSize, TypeSize, FieldPacked, D); + if (FieldSize > StorageUnitSize) { + LayoutWideBitField(FieldSize, StorageUnitSize, FieldPacked, D); return; } @@ -1686,7 +1687,7 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { // Compute the real offset. if (FieldSize == 0 || (AllowPadding && - (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)) { + (FieldOffset & (FieldAlign - 1)) + FieldSize > StorageUnitSize)) { FieldOffset = llvm::alignTo(FieldOffset, FieldAlign); } else if (ExplicitFieldAlign && (MaxFieldAlignmentInBits == 0 || @@ -1700,7 +1701,8 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { // Repeat the computation for diagnostic purposes. if (FieldSize == 0 || (AllowPadding && - (UnpackedFieldOffset & (UnpackedFieldAlign-1)) + FieldSize > TypeSize)) + (UnpackedFieldOffset & (UnpackedFieldAlign - 1)) + FieldSize > + StorageUnitSize)) UnpackedFieldOffset = llvm::alignTo(UnpackedFieldOffset, UnpackedFieldAlign); else if (ExplicitFieldAlign && @@ -1741,11 +1743,11 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { // is a zero-width bitfield, in which case just use a size of 1. uint64_t RoundedFieldSize; if (IsMsStruct) { - RoundedFieldSize = - (FieldSize ? TypeSize : Context.getTargetInfo().getCharWidth()); + RoundedFieldSize = (FieldSize ? StorageUnitSize + : Context.getTargetInfo().getCharWidth()); - // Otherwise, allocate just the number of bytes required to store - // the bitfield. + // Otherwise, allocate just the number of bytes required to store + // the bitfield. } else { RoundedFieldSize = roundUpSizeToCharAlignment(FieldSize, Context); } @@ -1757,15 +1759,15 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { // We should have cleared UnfilledBitsInLastUnit in every case // where we changed storage units. if (!UnfilledBitsInLastUnit) { - setDataSize(FieldOffset + TypeSize); - UnfilledBitsInLastUnit = TypeSize; + setDataSize(FieldOffset + StorageUnitSize); + UnfilledBitsInLastUnit = StorageUnitSize; } UnfilledBitsInLastUnit -= FieldSize; - LastBitfieldTypeSize = TypeSize; + LastBitfieldStorageUnitSize = StorageUnitSize; - // Otherwise, bump the data size up to include the bitfield, - // including padding up to char alignment, and then remember how - // bits we didn't use. + // Otherwise, bump the data size up to include the bitfield, + // including padding up to char alignment, and then remember how + // bits we didn't use. } else { uint64_t NewSizeInBits = FieldOffset + FieldSize; uint64_t CharAlignment = Context.getTargetInfo().getCharAlign(); @@ -1775,7 +1777,7 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { // The only time we can get here for an ms_struct is if this is a // zero-width bitfield, which doesn't count as anything for the // purposes of unfilled bits. - LastBitfieldTypeSize = 0; + LastBitfieldStorageUnitSize = 0; } // Update the size. @@ -1825,7 +1827,7 @@ void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D, uint64_t UnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastUnit; // Reset the unfilled bits. UnfilledBitsInLastUnit = 0; - LastBitfieldTypeSize = 0; + LastBitfieldStorageUnitSize = 0; bool FieldPacked = Packed || D->hasAttr(); -- 2.7.4