================
@@ -15871,6 +15869,80 @@ struct PaddingCalculator {
}
}
+ void VisitBitfield(const FieldDecl *Field, uint64_t StartBitOffset) {
+ assert(Field->isBitField() && !Field->isUnnamedBitField());
+ if (Field->isZeroLengthBitField())
+ return;
+
+ const uint64_t DeclaredSizeInBits = Field->getBitWidthValue();
+
+ // Handle over-sized bitfields:
+ // unsigned char a : 12;
+ // In this case, DeclaredSizeInBits is 12, but the actually occupied bit
+ // size is 8, while the remaining 4 bits are padding.
+ const uint64_t OccupiedSizeInBits =
+ std::min(DeclaredSizeInBits,
+ static_cast<uint64_t>(Ctx.getIntWidth(Field->getType())));
+
+ if (Ctx.getTargetInfo().isLittleEndian()) {
+ OccuppiedIntervals.push_back(
+ {StartBitOffset, StartBitOffset + OccupiedSizeInBits});
+ return;
+ }
+
+ // In big endian mode, the sequence of occupied bits traverses bytes in
+ // increasing address order, just like in little endian. However, within
+ // each byte, the traversal starts from the most significant bit. This is
+ // where it differs from little endian.
+ //
+ // If the interval contains whole bytes in the middle, then for these
+ // nothing changes, and they constitute a contiguous interval. However for
+ // the partially occupied bytes in either end, if present, their bit
+ // intervals need to be adjusted so that they count from the MSB instead.
+ //
+ // FIXME: For over-sized bitfields in BE, Clang allocates padding bits
+ // before the occupied bits. This violates the ABI rules, which say that
----------------
vhscampos wrote:
Added a citation to the comment. The issue can be seen on this example:
https://godbolt.org/z/qM46djnx1
https://github.com/llvm/llvm-project/pull/216063
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits