[cfe-dev] -mms_bitfields question
Eli Friedman
eli.friedman at gmail.com
Thu Oct 4 13:26:04 PDT 2012
On Thu, Oct 4, 2012 at 1:14 PM, Jeremiah Zanin
<Jeremiah.Zanin at volition-inc.com> wrote:
> Hello,
>
> We are using Clang for generating reflection data and ran into an issue with how Microsoft lays out bitfields. Here's the structure we were having a problem with:
>
> struct reflected woof
> {
> bool m_b1 : 1 reflected; // Clang bit offset: 0, MS bit offset: 0
> bool m_b2 : 1 reflected; // Clang bit offset: 1, MS bit offset: 1
> bool m_b3 : 1 reflected; // Clang bit offset: 2, MS bit offset: 2
> bool m_b4 : 1 reflected; // Clang bit offset: 3, MS bit offset: 3
> uint m_i1 reflected; // Clang bit offset: 32, MS bit offset: 32
> uint m_i2 : 5 reflected; // Clang bit offset: 64, MS bit offset: 64
> uint m_i3 : 8 reflected; // Clang bit offset: 69, MS bit offset: 69
> uint16 m_i5 : 2 reflected; // Clang bit offset: 77, MS bit offset: 96
> uint8 m_i4 : 2 reflected;
> uint8 m_ix1 : 2;
> uint16 m_i6 : 6 reflected;
> };
>
> When compiling with Clang the bit offset of "m_i5" is 77, while when compiling with VS 2010 the bit offset is 96. We tried compiling with the "-mms-bitfields" command-line parameter but it didn't change the results. We stepped through Clang code and discovered that the "RecordLayoutBuilder::LayoutFields" function is looking for the "IsMsStruct" attribute. So we tried adding __attribute__((ms_struct)) to the structure and that fixed the problem. Adding "#pragma ms_struct on" also worked. We were wondering if the code inside "RecordLayoutBuilder::LayoutFields" should be checking "Context.getLangOpts().MSBitfields" along with "IsMsStruct":
>
> for (RecordDecl::field_iterator Field = D->field_begin(),
> FieldEnd = D->field_end(); Field != FieldEnd; ++Field) {
> if (IsMsStruct) { // <-- Should this check Context.getLangOpts().MSBitfields?
> FieldDecl *FD = *Field;
> if (Context.ZeroBitfieldFollowsBitfield(FD, LastFD))
> ZeroLengthBitfield = FD;
>
> ...
>
> if (IsMsStruct && RemainingInAlignment && // <-- Should this check Context.getLangOpts().MSBitfields?
> LastFD && LastFD->isBitField() && LastFD->getBitWidthValue(Context)) {
Looking at the gcc docs, the computation of IsMsStruct (whether to use
ms_struct layout) should depend on getLangOpts().MSBitfields, and we
shouldn't check getLangOpts().MSBitfields directly anywhere else.
-Eli
More information about the cfe-dev
mailing list