Updated the patch according to comments.

http://reviews.llvm.org/D5775

Files:
  lib/AST/RecordLayoutBuilder.cpp
  test/Layout/itanium-union-bitfield.cpp
Index: lib/AST/RecordLayoutBuilder.cpp
===================================================================
--- lib/AST/RecordLayoutBuilder.cpp
+++ lib/AST/RecordLayoutBuilder.cpp
@@ -1345,6 +1345,14 @@
     LayoutField(Field);
 }
 
+// Rounds the specified size to have it a multiple of the char size.
+static uint64_t
+roundUpSizeToCharAlignment(uint64_t Size,
+                           const ASTContext &Context) {
+  uint64_t CharAlignment = Context.getTargetInfo().getCharAlign();
+  return llvm::RoundUpToAlignment(Size, CharAlignment);
+}
+
 void RecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize,
                                              uint64_t TypeSize,
                                              bool FieldPacked,
@@ -1382,7 +1390,9 @@
   uint64_t UnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastUnit;
 
   if (IsUnion) {
-    setDataSize(std::max(getDataSizeInBits(), FieldSize));
+    uint64_t RoundedFieldSize = roundUpSizeToCharAlignment(FieldSize,
+                                                           Context);
+    setDataSize(std::max(getDataSizeInBits(), RoundedFieldSize));
     FieldOffset = 0;
   } else {
     // The bitfield is allocated starting at the next offset aligned 
@@ -1607,9 +1617,9 @@
 
   // For unions, this is just a max operation, as usual.
   if (IsUnion) {
-    // FIXME: I think FieldSize should be TypeSize here.
-    setDataSize(std::max(getDataSizeInBits(), FieldSize));
-
+    uint64_t RoundedFieldSize = roundUpSizeToCharAlignment(FieldSize,
+                                                           Context);
+    setDataSize(std::max(getDataSizeInBits(), RoundedFieldSize));
   // For non-zero-width bitfields in ms_struct structs, allocate a new
   // storage unit if necessary.
   } else if (IsMsStruct && FieldSize) {
Index: test/Layout/itanium-union-bitfield.cpp
===================================================================
--- /dev/null
+++ test/Layout/itanium-union-bitfield.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple %itanium_abi_triple -fdump-record-layouts %s 2>/dev/null \
+// RUN:            | FileCheck %s
+
+union A {
+  int f1: 3;
+  A();
+};
+
+A::A() {}
+
+union B {
+  int f1: 69;
+  B();
+};
+
+B::B() {}
+
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:   0 | union A
+// CHECK-NEXT:   0 |   int f1
+// CHECK-NEXT:     | [sizeof=4, dsize=1, align=4
+// CHECK-NEXT:     |  nvsize=1, nvalign=4]
+
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:   0 | union B
+// CHECK-NEXT:   0 |   int f1
+// CHECK-NEXT:     | [sizeof=16, dsize=9, align=8
+// CHECK-NEXT:     |  nvsize=9, nvalign=8]
+
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to