[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