[cfe-commits] r130257 - in /cfe/trunk: lib/AST/RecordLayoutBuilder.cpp lib/CodeGen/CGRecordLayoutBuilder.cpp test/CodeGen/ms_struct-bitfield.c

Fariborz Jahanian fjahanian at apple.com
Tue Apr 26 16:52:16 PDT 2011


Author: fjahanian
Date: Tue Apr 26 18:52:16 2011
New Revision: 130257

URL: http://llvm.org/viewvc/llvm-project?rev=130257&view=rev
Log:
With ms_struct attribut, Zero-length bitfields following 
non-bitfield members are ignore. // rdar://8823265 wip

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

Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=130257&r1=130256&r2=130257&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Tue Apr 26 18:52:16 2011
@@ -564,6 +564,8 @@
   unsigned IsUnion : 1;
 
   unsigned IsMac68kAlign : 1;
+  
+  unsigned IsMsStruct : 1;
 
   /// UnfilledBitsInLastByte - If the last field laid out was a bitfield,
   /// this contains the number of bits in the last byte that can be used for
@@ -612,7 +614,8 @@
                       *EmptySubobjects)
     : Context(Context), EmptySubobjects(EmptySubobjects), Size(0), 
       Alignment(CharUnits::One()), UnpackedAlignment(Alignment),
-      Packed(false), IsUnion(false), IsMac68kAlign(false), 
+      Packed(false), IsUnion(false), 
+      IsMac68kAlign(false), IsMsStruct(false),
       UnfilledBitsInLastByte(0), MaxFieldAlignment(CharUnits::Zero()), 
       DataSize(0), NonVirtualSize(CharUnits::Zero()), 
       NonVirtualAlignment(CharUnits::One()), PrimaryBase(0), 
@@ -1148,6 +1151,8 @@
     IsUnion = RD->isUnion();
 
   Packed = D->hasAttr<PackedAttr>();
+  
+  IsMsStruct = D->hasAttr<MsStructAttr>();
 
   // mac68k alignment supersedes maximum field alignment and attribute aligned,
   // and forces all structures to have 2-byte alignment. The IBM docs on it
@@ -1249,9 +1254,21 @@
 void RecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
   // Layout each field, for now, just sequentially, respecting alignment.  In
   // the future, this will need to be tweakable by targets.
+  const FieldDecl *LastFD = 0;
   for (RecordDecl::field_iterator Field = D->field_begin(),
-         FieldEnd = D->field_end(); Field != FieldEnd; ++Field)
+       FieldEnd = D->field_end(); Field != FieldEnd; ++Field) {
+    if (IsMsStruct) {
+      // Zero-length bitfields following non-bitfield members are
+      // ignored:
+      const FieldDecl *FD =  (*Field);
+      if (FD->isBitField() && LastFD && !LastFD->isBitField() &&
+          FD->getBitWidth()->EvaluateAsInt(Context).getZExtValue() == 0) {
+        continue;
+      }
+      LastFD = FD;
+    }
     LayoutField(*Field);
+  }
 }
 
 void RecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize,

Modified: cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp?rev=130257&r1=130256&r2=130257&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp Tue Apr 26 18:52:16 2011
@@ -77,6 +77,9 @@
 
   /// Packed - Whether the resulting LLVM struct will be packed or not.
   bool Packed;
+  
+  /// IsMsStruct - Whether ms_struct is in effect or not
+  bool IsMsStruct;
 
 private:
   CodeGenTypes &Types;
@@ -184,7 +187,8 @@
   CGRecordLayoutBuilder(CodeGenTypes &Types)
     : BaseSubobjectType(0),
       IsZeroInitializable(true), IsZeroInitializableAsBase(true),
-      Packed(false), Types(Types), BitsAvailableInLastField(0) { }
+      Packed(false), IsMsStruct(false),
+      Types(Types), BitsAvailableInLastField(0) { }
 
   /// Layout - Will layout a RecordDecl.
   void Layout(const RecordDecl *D);
@@ -195,6 +199,8 @@
 void CGRecordLayoutBuilder::Layout(const RecordDecl *D) {
   Alignment = Types.getContext().getASTRecordLayout(D).getAlignment();
   Packed = D->hasAttr<PackedAttr>();
+  
+  IsMsStruct = D->hasAttr<MsStructAttr>();
 
   if (D->isUnion()) {
     LayoutUnion(D);
@@ -739,9 +745,24 @@
     LayoutNonVirtualBases(RD, Layout);
 
   unsigned FieldNo = 0;
-
+  const FieldDecl *LastFD = 0;
+  
   for (RecordDecl::field_iterator Field = D->field_begin(),
        FieldEnd = D->field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
+    if (IsMsStruct) {
+      // Zero-length bitfields following non-bitfield members are
+      // ignored:
+      const FieldDecl *FD =  (*Field);
+      // FIXME. Refactor into common code as it is used in several places.
+      if (FD->isBitField() && LastFD && !LastFD->isBitField() &&
+          FD->getBitWidth()->
+            EvaluateAsInt(Types.getContext()).getZExtValue() == 0) {
+        --FieldNo;
+        continue;
+      }
+      LastFD = FD;
+    }
+    
     if (!LayoutField(*Field, Layout.getFieldOffset(FieldNo))) {
       assert(!Packed &&
              "Could not layout fields even with a packed LLVM struct!");
@@ -960,6 +981,8 @@
 
   const ASTRecordLayout &AST_RL = getContext().getASTRecordLayout(D);
   RecordDecl::field_iterator it = D->field_begin();
+  const FieldDecl *LastFD = 0;
+  bool IsMsStruct = D->hasAttr<MsStructAttr>();
   for (unsigned i = 0, e = AST_RL.getFieldCount(); i != e; ++i, ++it) {
     const FieldDecl *FD = *it;
 
@@ -969,13 +992,28 @@
       unsigned FieldNo = RL->getLLVMFieldNo(FD);
       assert(AST_RL.getFieldOffset(i) == SL->getElementOffsetInBits(FieldNo) &&
              "Invalid field offset!");
+      LastFD = FD;
       continue;
     }
 
+    if (IsMsStruct) {
+      // Zero-length bitfields following non-bitfield members are
+      // ignored:
+      if (FD->isBitField() && LastFD && !LastFD->isBitField() &&
+          FD->getBitWidth()->
+          EvaluateAsInt(getContext()).getZExtValue() == 0) {
+        --i;
+        continue;
+      }
+      LastFD = FD;
+    }
+    
     // Ignore unnamed bit-fields.
-    if (!FD->getDeclName())
+    if (!FD->getDeclName()) {
+      LastFD = FD;
       continue;
-
+    }
+    
     const CGBitFieldInfo &Info = RL->getBitFieldInfo(FD);
     for (unsigned i = 0, e = Info.getNumComponents(); i != e; ++i) {
       const CGBitFieldInfo::AccessInfo &AI = Info.getComponent(i);

Added: cfe/trunk/test/CodeGen/ms_struct-bitfield.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms_struct-bitfield.c?rev=130257&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/ms_struct-bitfield.c (added)
+++ cfe/trunk/test/CodeGen/ms_struct-bitfield.c Tue Apr 26 18:52:16 2011
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -emit-llvm-only  -triple x86_64-apple-darwin9 %s
+// rdar://8823265
+
+#define ATTR __attribute__((__ms_struct__))
+
+struct
+{
+   char foo;
+   long : 0;
+   char bar;
+} ATTR t1;
+
+struct
+{
+   char foo;
+   long : 0;
+   char : 0;
+   int : 0;
+   char bar;
+} ATTR t2;
+
+struct
+{
+   char foo;
+   long : 0;
+   char : 0;
+   int : 0;
+   char bar;
+   long : 0;
+   char : 0;
+} ATTR t3;
+
+struct
+{
+   long : 0;
+   char bar;
+} ATTR t4;
+
+struct
+{
+   long : 0;
+   long : 0;
+   char : 0;
+   char bar;
+} ATTR t5;
+
+struct
+{
+   long : 0;
+   long : 0;
+   char : 0;
+   char bar;
+} ATTR t6;
+
+struct
+{
+   char foo;
+   long : 0;
+   int : 0;
+   char bar;
+   char bar1;
+   long : 0;
+   char bar2;
+   char bar3;
+   char : 0;
+   char bar4;
+   char bar5;
+   char : 0;
+   char bar6;
+   char bar7;
+} ATTR t7;
+
+struct
+{
+   long : 0;
+   long : 0;
+   char : 0;
+} ATTR t8;
+
+struct
+{
+   char foo;
+   long : 0;
+   int : 0;
+   char bar;
+   char bar1;
+   long : 0;
+   char bar2;
+   char bar3;
+   char : 0;
+   char bar4;
+   char bar5;
+   char : 0;
+   char bar6;
+   char bar7;
+   int  i1;
+   char : 0;
+   long : 0;
+   char :4;
+   char bar8;
+   char : 0;
+   char bar9;
+   char bar10;
+   int  i2;
+   char : 0;
+   long : 0;
+   char :4;
+} ATTR t9;
+
+static int arr1[(sizeof(t1) == 2) -1];
+static int arr2[(sizeof(t2) == 2) -1];
+static int arr3[(sizeof(t3) == 2) -1];
+static int arr4[(sizeof(t4) == 1) -1];
+static int arr5[(sizeof(t5) == 1) -1];
+static int arr6[(sizeof(t6) == 1) -1];
+static int arr7[(sizeof(t7) == 9) -1];
+static int arr8[(sizeof(t8) == 0) -1];
+static int arr9[(sizeof(t9) == 28) -1];
+
+int main() {
+  return 0;
+}
+





More information about the cfe-commits mailing list