[cfe-commits] r136858 - in /cfe/trunk: include/clang/Basic/TargetInfo.h lib/AST/RecordLayoutBuilder.cpp lib/Basic/TargetInfo.cpp lib/Basic/Targets.cpp test/CodeGen/arm-apcs-zerolength-bitfield.c

Chad Rosier mcrosier at apple.com
Wed Aug 3 18:21:14 PDT 2011


Author: mcrosier
Date: Wed Aug  3 20:21:14 2011
New Revision: 136858

URL: http://llvm.org/viewvc/llvm-project?rev=136858&view=rev
Log:
Add partial support for using anonymous bitfields (e.g., int : 0) to enforce 
alignment.  This fixes cases where the anonymous bitfield is followed by a 
non-bitfield member.  E.g.,

struct t4
{
  int foo : 1;
  long : 0;
  char bar;
};

Part of rdar://9859156

Modified:
    cfe/trunk/include/clang/Basic/TargetInfo.h
    cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
    cfe/trunk/lib/Basic/TargetInfo.cpp
    cfe/trunk/lib/Basic/Targets.cpp
    cfe/trunk/test/CodeGen/arm-apcs-zerolength-bitfield.c

Modified: cfe/trunk/include/clang/Basic/TargetInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TargetInfo.h?rev=136858&r1=136857&r2=136858&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TargetInfo.h (original)
+++ cfe/trunk/include/clang/Basic/TargetInfo.h Wed Aug  3 20:21:14 2011
@@ -132,6 +132,16 @@
   /// boundary.
   unsigned UseBitFieldTypeAlignment : 1;
 
+  /// Control whether zero length bitfields (e.g., int : 0;) force alignment of
+  /// the next bitfield.  If 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.
+  unsigned UseZeroLengthBitfieldAlignment : 1;
+
+  /// If non-zero, specifies a fixed alignment value for bitfields that follow
+  /// zero length bitfield, regardless of the zero length bitfield type.
+  unsigned ZeroLengthBitfieldBoundary;
+
 public:
   IntType getSizeType() const { return SizeType; }
   IntType getIntMaxType() const { return IntMaxType; }
@@ -266,6 +276,18 @@
     return UseBitFieldTypeAlignment;
   }
 
+  /// useZeroLengthBitfieldAlignment() - Check whether zero length bitfields 
+  /// should force alignment of the next member.
+  bool useZeroLengthBitfieldAlignment() const {
+    return UseZeroLengthBitfieldAlignment;
+  }
+
+  /// getZeroLengthBitfieldBoundary() - Get the fixed alignment value in
+  /// bits for a member that follows zero length bitfield.
+  unsigned getZeroLengthBitfieldBoundary() const {
+    return ZeroLengthBitfieldBoundary;
+  }
+
   /// hasAlignMac68kSupport - Check whether this target support '#pragma options
   /// align=mac68k'.
   bool hasAlignMac68kSupport() const {

Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=136858&r1=136857&r2=136858&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Wed Aug  3 20:21:14 2011
@@ -1348,6 +1348,13 @@
       }
       LastFD = FD;
     }
+    else if (Context.Target.useZeroLengthBitfieldAlignment() &&
+             !Context.Target.useBitFieldTypeAlignment()) {
+      FieldDecl *FD =  (*Field);
+      if (Context.ZeroBitfieldFollowsBitfield(FD, LastFD))
+        ZeroLengthBitfield = FD;
+      LastFD = FD;
+    }
     LayoutField(*Field);
   }
   if (IsMsStruct && RemainingInAlignment &&
@@ -1442,7 +1449,7 @@
   // This check is needed for 'long long' in -m32 mode.
   if (IsMsStruct && (TypeSize > FieldAlign))
     FieldAlign = TypeSize;
-  
+
   if (ZeroLengthBitfield) {
     // If a zero-length bitfield is inserted after a bitfield,
     // and the alignment of the zero-length bitfield is
@@ -1559,17 +1566,29 @@
       Context.getTypeInfoInChars(D->getType());
     FieldSize = FieldInfo.first;
     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.
-      std::pair<CharUnits, CharUnits> FieldInfo = 
-        Context.getTypeInfoInChars(ZeroLengthBitfield->getType());
-      CharUnits ZeroLengthBitfieldAlignment = FieldInfo.second;
-      if (ZeroLengthBitfieldAlignment > FieldAlign)
-        FieldAlign = ZeroLengthBitfieldAlignment;
+      CharUnits ZeroLengthBitfieldBoundary = 
+        Context.toCharUnitsFromBits(
+          Context.Target.getZeroLengthBitfieldBoundary());
+      if (ZeroLengthBitfieldBoundary == CharUnits::Zero()) {
+        // 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;
+      }
+      else if (ZeroLengthBitfieldBoundary > FieldAlign) {
+        // Align 'bar' based on a fixed alignment specified by the target.
+        assert (Context.Target.useZeroLengthBitfieldAlignment() &&
+                "ZeroLengthBitfieldBoundary should only be used in conjunction"
+                "with useZeroLengthBitfieldAlignment.");
+        FieldAlign = ZeroLengthBitfieldBoundary;
+      }
       ZeroLengthBitfield = 0;
     }
 

Modified: cfe/trunk/lib/Basic/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/TargetInfo.cpp?rev=136858&r1=136857&r2=136858&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/TargetInfo.cpp (original)
+++ cfe/trunk/lib/Basic/TargetInfo.cpp Wed Aug  3 20:21:14 2011
@@ -53,6 +53,8 @@
   Int64Type = SignedLongLong;
   SigAtomicType = SignedInt;
   UseBitFieldTypeAlignment = true;
+  UseZeroLengthBitfieldAlignment = false;
+  ZeroLengthBitfieldBoundary = 0;
   FloatFormat = &llvm::APFloat::IEEEsingle;
   DoubleFormat = &llvm::APFloat::IEEEdouble;
   LongDoubleFormat = &llvm::APFloat::IEEEdouble;

Modified: cfe/trunk/lib/Basic/Targets.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=136858&r1=136857&r2=136858&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/Targets.cpp (original)
+++ cfe/trunk/lib/Basic/Targets.cpp Wed Aug  3 20:21:14 2011
@@ -1963,6 +1963,16 @@
       // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
       UseBitFieldTypeAlignment = false;
 
+      /// Do force alignment of members that follow zero length bitfields.  If
+      /// 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.
+      UseZeroLengthBitfieldAlignment = true;
+
+      /// gcc forces the alignment to 4 bytes, regardless of the type of the
+      /// zero length bitfield.
+      ZeroLengthBitfieldBoundary = 32;
+
       if (IsThumb) {
         // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
         // so set preferred for small types to 32.

Modified: cfe/trunk/test/CodeGen/arm-apcs-zerolength-bitfield.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/arm-apcs-zerolength-bitfield.c?rev=136858&r1=136857&r2=136858&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/arm-apcs-zerolength-bitfield.c (original)
+++ cfe/trunk/test/CodeGen/arm-apcs-zerolength-bitfield.c Wed Aug  3 20:21:14 2011
@@ -1,4 +1,8 @@
 // RUN: %clang_cc1 -target-abi apcs-gnu -triple armv7-apple-darwin10 %s -verify
+//
+// Note: gcc forces the alignment to 4 bytes, regardless of the type of the
+// zero length bitfield.
+// rdar://9859156
 
 #include <stddef.h>
 
@@ -8,8 +12,8 @@
   char : 0;
   char bar;
 };
-static int arr1_offset[(offsetof(struct t1, bar) == 1) ? 0 : -1];
-static int arr1_sizeof[(sizeof(struct t1) == 2) ? 0 : -1];
+static int arr1_offset[(offsetof(struct t1, bar) == 4) ? 0 : -1];
+static int arr1_sizeof[(sizeof(struct t1) == 8) ? 0 : -1];
 
 struct t2
 {
@@ -17,8 +21,8 @@
   short : 0;
   char bar;
 };
-static int arr2_offset[(offsetof(struct t2, bar) == 1) ? 0 : -1];
-static int arr2_sizeof[(sizeof(struct t2) == 2) ? 0 : -1];
+static int arr2_offset[(offsetof(struct t2, bar) == 4) ? 0 : -1];
+static int arr2_sizeof[(sizeof(struct t2) == 8) ? 0 : -1];
 
 struct t3
 {
@@ -26,8 +30,8 @@
   int : 0;
   char bar;
 };
-static int arr3_offset[(offsetof(struct t3, bar) == 1) ? 0 : -1];
-static int arr3_sizeof[(sizeof(struct t3) == 2) ? 0 : -1];
+static int arr3_offset[(offsetof(struct t3, bar) == 4) ? 0 : -1];
+static int arr3_sizeof[(sizeof(struct t3) == 8) ? 0 : -1];
 
 struct t4
 {
@@ -35,8 +39,8 @@
   long : 0;
   char bar;
 };
-static int arr4_offset[(offsetof(struct t4, bar) == 1) ? 0 : -1];
-static int arr4_sizeof[(sizeof(struct t4) == 2) ? 0 : -1];
+static int arr4_offset[(offsetof(struct t4, bar) == 4) ? 0 : -1];
+static int arr4_sizeof[(sizeof(struct t4) == 8) ? 0 : -1];
 
 struct t5
 {
@@ -44,8 +48,8 @@
   long long : 0;
   char bar;
 };
-static int arr5_offset[(offsetof(struct t5, bar) == 1) ? 0 : -1];
-static int arr5_sizeof[(sizeof(struct t5) == 2) ? 0 : -1];
+static int arr5_offset[(offsetof(struct t5, bar) == 4) ? 0 : -1];
+static int arr5_sizeof[(sizeof(struct t5) == 8) ? 0 : -1];
 
 struct t6
 {
@@ -109,6 +113,17 @@
 static int arr11_offset[(offsetof(struct t11, bar2) == 1) ? 0 : -1];
 static int arr11_sizeof[(sizeof(struct t11) == 2) ? 0 : -1];
 
+struct t12
+{
+  int foo : 1;
+  char : 0;
+  long long : 0;
+  char : 0;
+  char bar;
+};
+static int arr12_offset[(offsetof(struct t12, bar) == 4) ? 0 : -1];
+static int arr12_sizeof[(sizeof(struct t12) == 8) ? 0 : -1];
+
 int main() {
   return 0;
 }





More information about the cfe-commits mailing list