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

llvm-svn: 136858
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index bb5b334..19a762c 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -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;
     }