================
@@ -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

Reply via email to