[cfe-commits] r130783 - in /cfe/trunk: lib/AST/Decl.cpp lib/AST/RecordLayoutBuilder.cpp lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGExprConstant.cpp lib/CodeGen/CGRecordLayoutBuilder.cpp test/CodeGen/ms_struct-bitfield-1.c

Fariborz Jahanian fjahanian at apple.com
Tue May 3 13:21:05 PDT 2011


Author: fjahanian
Date: Tue May  3 15:21:04 2011
New Revision: 130783

URL: http://llvm.org/viewvc/llvm-project?rev=130783&view=rev
Log:
Finish off rules for z-length bitfields in ms_struct
structs. // rdar://8823265

Added:
    cfe/trunk/test/CodeGen/ms_struct-bitfield-1.c
Modified:
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp
    cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=130783&r1=130782&r2=130783&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Tue May  3 15:21:04 2011
@@ -2059,8 +2059,7 @@
 
     if (IsMsStruct) {
       // Zero-length bitfields following non-bitfield members are ignored.
-      if (getASTContext().ZeroBitfieldFollowsNonBitfield((*i), LastFD) ||
-          getASTContext().ZeroBitfieldFollowsBitfield((*i), LastFD)) {
+      if (getASTContext().ZeroBitfieldFollowsNonBitfield((*i), LastFD)) {
         ++i;
         continue;
       }

Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=130783&r1=130782&r2=130783&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Tue May  3 15:21:04 2011
@@ -582,7 +582,7 @@
   CharUnits NonVirtualSize;
   CharUnits NonVirtualAlignment;
 
-  CharUnits ZeroLengthBitfieldAlignment;
+  FieldDecl *ZeroLengthBitfield;
 
   /// PrimaryBase - the primary base class (if one exists) of the class
   /// we're laying out.
@@ -621,7 +621,7 @@
       UnfilledBitsInLastByte(0), MaxFieldAlignment(CharUnits::Zero()), 
       DataSize(0), NonVirtualSize(CharUnits::Zero()), 
       NonVirtualAlignment(CharUnits::One()), 
-      ZeroLengthBitfieldAlignment(CharUnits::Zero()), PrimaryBase(0), 
+      ZeroLengthBitfield(0), PrimaryBase(0), 
       PrimaryBaseIsVirtual(false), FirstNearlyEmptyVBase(0) { }
 
   void Layout(const RecordDecl *D);
@@ -1258,22 +1258,16 @@
   // Layout each field, for now, just sequentially, respecting alignment.  In
   // the future, this will need to be tweakable by targets.
   const FieldDecl *LastFD = 0;
+  ZeroLengthBitfield = 0;
   for (RecordDecl::field_iterator Field = D->field_begin(),
        FieldEnd = D->field_end(); Field != FieldEnd; ++Field) {
     if (IsMsStruct) {
-      const FieldDecl *FD =  (*Field);
-      if (Context.ZeroBitfieldFollowsBitfield(FD, LastFD)) {
-        // FIXME. Multiple zero bitfields may follow a bitfield.
-        // set ZeroLengthBitfieldAlignment to max. of its
-        // currrent and alignment of 'FD'.
-        std::pair<CharUnits, CharUnits> FieldInfo = 
-          Context.getTypeInfoInChars(FD->getType());
-        ZeroLengthBitfieldAlignment = FieldInfo.second;
-        continue;
-      }
+      FieldDecl *FD =  (*Field);
+      if (Context.ZeroBitfieldFollowsBitfield(FD, LastFD))
+        ZeroLengthBitfield = FD;
       // Zero-length bitfields following non-bitfield members are
       // ignored:
-      if (Context.ZeroBitfieldFollowsNonBitfield(FD, LastFD))
+      else if (Context.ZeroBitfieldFollowsNonBitfield(FD, LastFD))
         continue;
       LastFD = FD;
     }
@@ -1355,6 +1349,21 @@
   std::pair<uint64_t, unsigned> FieldInfo = Context.getTypeInfo(D->getType());
   uint64_t TypeSize = FieldInfo.first;
   unsigned FieldAlign = FieldInfo.second;
+  
+  if (ZeroLengthBitfield) {
+    // If a zero-length bitfield is inserted after a bitfield,
+    // and the alignment of the zero-length bitfield is
+    // greater than the member that follows it, `bar', `bar' 
+    // will be aligned as the type of the zero-length bitfield.
+    if (ZeroLengthBitfield != D) {
+      std::pair<uint64_t, unsigned> FieldInfo = 
+        Context.getTypeInfo(ZeroLengthBitfield->getType());
+      unsigned ZeroLengthBitfieldAlignment = FieldInfo.second;
+      if (ZeroLengthBitfieldAlignment > FieldAlign)
+        FieldAlign = ZeroLengthBitfieldAlignment;
+      ZeroLengthBitfield = 0;
+    }
+  }
 
   if (FieldSize > TypeSize) {
     LayoutWideBitField(FieldSize, TypeSize, FieldPacked, D);
@@ -1455,9 +1464,19 @@
       Context.getTypeInfoInChars(D->getType());
     FieldSize = FieldInfo.first;
     FieldAlign = FieldInfo.second;
-    if (ZeroLengthBitfieldAlignment > FieldAlign)
-      FieldAlign = ZeroLengthBitfieldAlignment;
-    ZeroLengthBitfieldAlignment = CharUnits::Zero();
+    
+    if (ZeroLengthBitfield) {
+      // If a zero-length bitfield is inserted after a bitfield,
+      // and the alignment of the zero-length bitfield is
+      // greater than the member that follows it, `bar', `bar' 
+      // will be aligned as the type of the zero-length bitfield.
+      std::pair<CharUnits, CharUnits> FieldInfo = 
+        Context.getTypeInfoInChars(ZeroLengthBitfield->getType());
+      CharUnits ZeroLengthBitfieldAlignment = FieldInfo.second;
+      if (ZeroLengthBitfieldAlignment > FieldAlign)
+        FieldAlign = ZeroLengthBitfieldAlignment;
+      ZeroLengthBitfield = 0;
+    }
 
     if (Context.getLangOptions().MSBitfields) {
       // If MS bitfield layout is required, figure out what type is being

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=130783&r1=130782&r2=130783&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Tue May  3 15:21:04 2011
@@ -628,8 +628,7 @@
     FieldDecl *field = *I;
     if (IsMsStruct) {
       // Zero-length bitfields following non-bitfield members are ignored
-      if (CGM.getContext().ZeroBitfieldFollowsNonBitfield((field), LastFD) ||
-          CGM.getContext().ZeroBitfieldFollowsBitfield((field), LastFD)) {
+      if (CGM.getContext().ZeroBitfieldFollowsNonBitfield((field), LastFD)) {
         --fieldNo;
         continue;
       }

Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=130783&r1=130782&r2=130783&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Tue May  3 15:21:04 2011
@@ -352,8 +352,7 @@
     if (IsMsStruct) {
       // Zero-length bitfields following non-bitfield members are
       // ignored:
-      if (CGM.getContext().ZeroBitfieldFollowsNonBitfield((*Field), LastFD) ||
-          CGM.getContext().ZeroBitfieldFollowsBitfield((*Field), LastFD)) {
+      if (CGM.getContext().ZeroBitfieldFollowsNonBitfield((*Field), LastFD)) {
         --FieldNo;
         continue;
       }

Modified: cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp?rev=130783&r1=130782&r2=130783&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp Tue May  3 15:21:04 2011
@@ -753,8 +753,7 @@
       // Zero-length bitfields following non-bitfield members are
       // ignored:
       const FieldDecl *FD =  (*Field);
-      if (Types.getContext().ZeroBitfieldFollowsNonBitfield(FD, LastFD) ||
-          Types.getContext().ZeroBitfieldFollowsBitfield(FD, LastFD)) {
+      if (Types.getContext().ZeroBitfieldFollowsNonBitfield(FD, LastFD)) {
         --FieldNo;
         continue;
       }
@@ -997,8 +996,7 @@
     if (IsMsStruct) {
       // Zero-length bitfields following non-bitfield members are
       // ignored:
-      if (getContext().ZeroBitfieldFollowsNonBitfield(FD, LastFD) ||
-          getContext().ZeroBitfieldFollowsBitfield(FD, LastFD)) {
+      if (getContext().ZeroBitfieldFollowsNonBitfield(FD, LastFD)) {
         --i;
         continue;
       }

Added: cfe/trunk/test/CodeGen/ms_struct-bitfield-1.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms_struct-bitfield-1.c?rev=130783&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/ms_struct-bitfield-1.c (added)
+++ cfe/trunk/test/CodeGen/ms_struct-bitfield-1.c Tue May  3 15:21:04 2011
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -emit-llvm-only  -triple x86_64-apple-darwin9 %s
+// rdar://8823265
+
+#define ATTR __attribute__((__ms_struct__))
+
+struct {
+                   unsigned int bf_1 : 12;
+                   unsigned int : 0;
+                   unsigned int bf_2 : 12;
+} ATTR t1;
+static int a1[(sizeof(t1) == 8) -1];
+
+struct
+{
+                   char foo : 4;
+                   short : 0;
+                   char bar;
+} ATTR t2;
+static int a2[(sizeof(t2) == 4) -1];
+
+#pragma ms_struct on
+struct
+{
+                   char foo : 4;
+                   short : 0;
+                   char bar;
+} t3;
+#pragma ms_struct off
+static int a3[(sizeof(t3) == 4) -1];
+
+struct
+{
+  char foo : 6;
+  long : 0;
+} ATTR t4;
+static int a4[(sizeof(t4) == 8) -1];
+
+struct
+{
+  char foo : 4;
+  short : 0;
+  char bar : 8;
+} ATTR t5;
+static int a5[(sizeof(t5) == 4) -1];
+





More information about the cfe-commits mailing list