Fix the layout of bitfields in ms_struct unions: their
alignment is ignored, and they always allocate a complete
storage unit.

Also, change the dumping of AST record layouts: use the more
readable C++-style dumping even in C, include bitfield offset
information in the dump, and don't print sizeof/alignof
information for fields of record type, since we don't do so
for bases or other kinds of field.

rdar://22275433

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@245514 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CodeGen/ms_struct-pack.c b/test/CodeGen/ms_struct-pack.c
index 6486f29..6382f3b 100644
--- a/test/CodeGen/ms_struct-pack.c
+++ b/test/CodeGen/ms_struct-pack.c
@@ -133,12 +133,12 @@
   unsigned long e : 1;
 } __attribute__((__ms_struct__));
 
-// CHECK:      Type: struct test0
-// CHECK-NEXT: Record:
-// CHECK-NEXT: Layout:
-// CHECK-NEXT:   Size:64
-// CHECK-NEXT:   DataSize:64
-// CHECK-NEXT:   Alignment:16
-// CHECK-NEXT:   FieldOffsets: [0, 8, 16, 32, 42]>
+// CHECK:             0 | struct test0
+// CHECK-NEXT:    0:0-7 |   unsigned long a
+// CHECK-NEXT:    1:0-7 |   unsigned long b
+// CHECK-NEXT:    2:0-7 |   unsigned long c
+// CHECK-NEXT:    4:0-9 |   unsigned long d
+// CHECK-NEXT:    5:2-2 |   unsigned long e
+// CHECK-NEXT:          | [sizeof=8, align=2]
 
 static int test0[(sizeof(struct test0) == 8) ? 1 : -1];
diff --git a/test/CodeGen/override-layout.c b/test/CodeGen/override-layout.c
index 57de8b5..9907fec 100644
--- a/test/CodeGen/override-layout.c
+++ b/test/CodeGen/override-layout.c
@@ -1,7 +1,6 @@
-// RUN: %clang_cc1 -w -fdump-record-layouts %s > %t.layouts
-// RUN: %clang_cc1 -w -fdump-record-layouts-simple %s > %t.before
+// RUN: %clang_cc1 -w -fdump-record-layouts-simple %s > %t.layouts
 // RUN: %clang_cc1 -w -DPACKED= -DALIGNED16= -fdump-record-layouts-simple -foverride-record-layout=%t.layouts %s > %t.after
-// RUN: diff %t.before %t.after
+// RUN: diff %t.layouts %t.after
 // RUN: FileCheck %s < %t.after
 
 // If not explicitly disabled, set PACKED to the packed attribute.
diff --git a/test/Layout/itanium-union-bitfield.cpp b/test/Layout/itanium-union-bitfield.cpp
index b06fd36..289a565 100644
--- a/test/Layout/itanium-union-bitfield.cpp
+++ b/test/Layout/itanium-union-bitfield.cpp
@@ -16,14 +16,14 @@
 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-NEXT:     0 | union A
+// CHECK-NEXT: 0:0-2 |   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 |   char f1
-// CHECK-NEXT:     | [sizeof=8, dsize=5, align=4
-// CHECK-NEXT:     |  nvsize=5, nvalign=4]
+// CHECK-NEXT:      0 | union B
+// CHECK-NEXT: 0:0-34 |   char f1
+// CHECK-NEXT:        | [sizeof=8, dsize=5, align=4
+// CHECK-NEXT:        |  nvsize=5, nvalign=4]
 
diff --git a/test/Layout/ms-x86-alias-avoidance-padding.cpp b/test/Layout/ms-x86-alias-avoidance-padding.cpp
index 1d77bf9..203927b 100644
--- a/test/Layout/ms-x86-alias-avoidance-padding.cpp
+++ b/test/Layout/ms-x86-alias-avoidance-padding.cpp
@@ -391,8 +391,6 @@
 // CHECK-NEXT:    0 |     struct RA (base) (empty)
 // CHECK-NEXT:    0 |     struct RB a
 // CHECK-NEXT:    0 |       char c
-// CHECK-NEXT:      |     [sizeof=1, align=1
-// CHECK-NEXT:      |      nvsize=1, nvalign=1]
 // CHECK-NEXT:    1 |   struct RY (base) (empty)
 // CHECK-NEXT:      | [sizeof=1, align=1
 // CHECK-NEXT:      |  nvsize=1, nvalign=1]
@@ -403,8 +401,6 @@
 // CHECK-X64-NEXT:    0 |     struct RA (base) (empty)
 // CHECK-X64-NEXT:    0 |     struct RB a
 // CHECK-X64-NEXT:    0 |       char c
-// CHECK-X64-NEXT:      |     [sizeof=1, align=1
-// CHECK-X64-NEXT:      |      nvsize=1, nvalign=1]
 // CHECK-X64-NEXT:    1 |   struct RY (base) (empty)
 // CHECK-X64-NEXT:      | [sizeof=1, align=1
 // CHECK-X64-NEXT:      |  nvsize=1, nvalign=1]
@@ -415,8 +411,6 @@
 // CHECK-NEXT:    0 | struct RZ4
 // CHECK-NEXT:    0 |   struct RX4 (base)
 // CHECK-NEXT:    0 |     struct RA a (empty)
-// CHECK-NEXT:      |     [sizeof=1, align=1
-// CHECK-NEXT:      |      nvsize=0, nvalign=1]
 // CHECK-NEXT:    1 |     char b
 // CHECK-NEXT:    3 |   struct RY (base) (empty)
 // CHECK-NEXT:      | [sizeof=3, align=1
@@ -426,8 +420,6 @@
 // CHECK-X64-NEXT:    0 | struct RZ4
 // CHECK-X64-NEXT:    0 |   struct RX4 (base)
 // CHECK-X64-NEXT:    0 |     struct RA a (empty)
-// CHECK-X64-NEXT:      |     [sizeof=1, align=1
-// CHECK-X64-NEXT:      |      nvsize=0, nvalign=1]
 // CHECK-X64-NEXT:    1 |     char b
 // CHECK-X64-NEXT:    3 |   struct RY (base) (empty)
 // CHECK-X64-NEXT:      | [sizeof=3, align=1
@@ -439,12 +431,8 @@
 // CHECK-NEXT:    0 | struct RZ5
 // CHECK-NEXT:    0 |   struct RX5 (base)
 // CHECK-NEXT:    0 |     struct RA a (empty)
-// CHECK-NEXT:      |     [sizeof=1, align=1
-// CHECK-NEXT:      |      nvsize=0, nvalign=1]
 // CHECK-NEXT:    1 |     struct RB b
 // CHECK-NEXT:    1 |       char c
-// CHECK-NEXT:      |     [sizeof=1, align=1
-// CHECK-NEXT:      |      nvsize=1, nvalign=1]
 // CHECK-NEXT:    2 |   struct RY (base) (empty)
 // CHECK-NEXT:      | [sizeof=2, align=1
 // CHECK-NEXT:      |  nvsize=2, nvalign=1]
@@ -453,12 +441,8 @@
 // CHECK-X64-NEXT:    0 | struct RZ5
 // CHECK-X64-NEXT:    0 |   struct RX5 (base)
 // CHECK-X64-NEXT:    0 |     struct RA a (empty)
-// CHECK-X64-NEXT:      |     [sizeof=1, align=1
-// CHECK-X64-NEXT:      |      nvsize=0, nvalign=1]
 // CHECK-X64-NEXT:    1 |     struct RB b
 // CHECK-X64-NEXT:    1 |       char c
-// CHECK-X64-NEXT:      |     [sizeof=1, align=1
-// CHECK-X64-NEXT:      |      nvsize=1, nvalign=1]
 // CHECK-X64-NEXT:    2 |   struct RY (base) (empty)
 // CHECK-X64-NEXT:      | [sizeof=2, align=1
 // CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
@@ -472,8 +456,6 @@
 // CHECK-NEXT:    0 |     (RX6 vbtable pointer)
 // CHECK-NEXT:    4 |     struct RB a
 // CHECK-NEXT:    4 |       char c
-// CHECK-NEXT:      |     [sizeof=1, align=1
-// CHECK-NEXT:      |      nvsize=1, nvalign=1]
 // CHECK-NEXT:    9 |   struct RY (base) (empty)
 // CHECK-NEXT:   12 |   struct RV (virtual base) (empty)
 // CHECK-NEXT:      | [sizeof=12, align=4
@@ -486,8 +468,6 @@
 // CHECK-X64-NEXT:    0 |     (RX6 vbtable pointer)
 // CHECK-X64-NEXT:    8 |     struct RB a
 // CHECK-X64-NEXT:    8 |       char c
-// CHECK-X64-NEXT:      |     [sizeof=1, align=1
-// CHECK-X64-NEXT:      |      nvsize=1, nvalign=1]
 // CHECK-X64-NEXT:   17 |   struct RY (base) (empty)
 // CHECK-X64-NEXT:   24 |   struct RV (virtual base) (empty)
 // CHECK-X64-NEXT:      | [sizeof=24, align=8
@@ -501,8 +481,6 @@
 // CHECK-NEXT:    0 |   struct RX7 (base)
 // CHECK-NEXT:    0 |     (RX7 vbtable pointer)
 // CHECK-NEXT:    4 |     struct RA a (empty)
-// CHECK-NEXT:      |     [sizeof=1, align=1
-// CHECK-NEXT:      |      nvsize=0, nvalign=1]
 // CHECK-NEXT:    8 |   struct RY (base) (empty)
 // CHECK-NEXT:    8 |   struct RW (virtual base)
 // CHECK-NEXT:    8 |     char c
@@ -515,8 +493,6 @@
 // CHECK-X64-NEXT:    0 |   struct RX7 (base)
 // CHECK-X64-NEXT:    0 |     (RX7 vbtable pointer)
 // CHECK-X64-NEXT:    8 |     struct RA a (empty)
-// CHECK-X64-NEXT:      |     [sizeof=1, align=1
-// CHECK-X64-NEXT:      |      nvsize=0, nvalign=1]
 // CHECK-X64-NEXT:   16 |   struct RY (base) (empty)
 // CHECK-X64-NEXT:   16 |   struct RW (virtual base)
 // CHECK-X64-NEXT:   16 |     char c
diff --git a/test/Layout/ms-x86-bitfields-vbases.cpp b/test/Layout/ms-x86-bitfields-vbases.cpp
index 5b54596..a78fdad 100644
--- a/test/Layout/ms-x86-bitfields-vbases.cpp
+++ b/test/Layout/ms-x86-bitfields-vbases.cpp
@@ -12,7 +12,7 @@
 // CHECK: *** Dumping AST Record Layout
 // CHECK-NEXT:    0 | struct A
 // CHECK-NEXT:    0 |   (A vbtable pointer)
-// CHECK-NEXT:    4 |   char a
+// CHECK-NEXT:    4:0-0 |   char a
 // CHECK-NEXT:    8 |   struct B0 (virtual base)
 // CHECK-NEXT:    8 |     int a
 // CHECK-NEXT:      | [sizeof=12, align=4
@@ -21,7 +21,7 @@
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64-NEXT:    0 | struct A
 // CHECK-X64-NEXT:    0 |   (A vbtable pointer)
-// CHECK-X64-NEXT:    8 |   char a
+// CHECK-X64-NEXT:    8:0-0 |   char a
 // CHECK-X64-NEXT:   16 |   struct B0 (virtual base)
 // CHECK-X64-NEXT:   16 |     int a
 // CHECK-X64-NEXT:      | [sizeof=24, align=8
@@ -32,7 +32,7 @@
 // CHECK: *** Dumping AST Record Layout
 // CHECK-NEXT:    0 | struct B
 // CHECK-NEXT:    0 |   (B vbtable pointer)
-// CHECK-NEXT:    4 |   short a
+// CHECK-NEXT:    4:0-0 |   short a
 // CHECK-NEXT:    8 |   struct B0 (virtual base)
 // CHECK-NEXT:    8 |     int a
 // CHECK-NEXT:      | [sizeof=12, align=4
@@ -40,7 +40,7 @@
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64-NEXT:    0 | struct B
 // CHECK-X64-NEXT:    0 |   (B vbtable pointer)
-// CHECK-X64-NEXT:    8 |   short a
+// CHECK-X64-NEXT:    8:0-0 |   short a
 // CHECK-X64-NEXT:   16 |   struct B0 (virtual base)
 // CHECK-X64-NEXT:   16 |     int a
 // CHECK-X64-NEXT:      | [sizeof=24, align=8
@@ -51,8 +51,8 @@
 // CHECK: *** Dumping AST Record Layout
 // CHECK-NEXT:    0 | struct C
 // CHECK-NEXT:    0 |   (C vbtable pointer)
-// CHECK-NEXT:    4 |   char a
-// CHECK-NEXT:    5 |   char
+// CHECK-NEXT:    4:0-0 |   char a
+// CHECK-NEXT:    5:- |   char
 // CHECK-NEXT:    8 |   struct B0 (virtual base)
 // CHECK-NEXT:    8 |     int a
 // CHECK-NEXT:      | [sizeof=12, align=4
@@ -60,8 +60,8 @@
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64-NEXT:    0 | struct C
 // CHECK-X64-NEXT:    0 |   (C vbtable pointer)
-// CHECK-X64-NEXT:    8 |   char a
-// CHECK-X64-NEXT:    9 |   char
+// CHECK-X64-NEXT:    8:0-0 |   char a
+// CHECK-X64-NEXT:    9:- |   char
 // CHECK-X64-NEXT:   16 |   struct B0 (virtual base)
 // CHECK-X64-NEXT:   16 |     int a
 // CHECK-X64-NEXT:      | [sizeof=24, align=8
@@ -72,7 +72,7 @@
 // CHECK: *** Dumping AST Record Layout
 // CHECK-NEXT:    0 | struct D
 // CHECK-NEXT:    0 |   (D vbtable pointer)
-// CHECK-NEXT:    4 |   char a
+// CHECK-NEXT:    4:0-0 |   char a
 // CHECK-NEXT:    5 |   char b
 // CHECK-NEXT:    8 |   struct B0 (virtual base)
 // CHECK-NEXT:    8 |     int a
@@ -81,7 +81,7 @@
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64-NEXT:    0 | struct D
 // CHECK-X64-NEXT:    0 |   (D vbtable pointer)
-// CHECK-X64-NEXT:    8 |   char a
+// CHECK-X64-NEXT:    8:0-0 |   char a
 // CHECK-X64-NEXT:    9 |   char b
 // CHECK-X64-NEXT:   16 |   struct B0 (virtual base)
 // CHECK-X64-NEXT:   16 |     int a
@@ -93,7 +93,7 @@
 // CHECK: *** Dumping AST Record Layout
 // CHECK-NEXT:    0 | struct E
 // CHECK-NEXT:    0 |   (E vbtable pointer)
-// CHECK-NEXT:    8 |   long long
+// CHECK-NEXT:    8:0-0 |   long long
 // CHECK-NEXT:   16 |   struct B0 (virtual base)
 // CHECK-NEXT:   16 |     int a
 // CHECK-NEXT:   20 |   struct B1 (virtual base)
@@ -104,7 +104,7 @@
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64-NEXT:    0 | struct E
 // CHECK-X64-NEXT:    0 |   (E vbtable pointer)
-// CHECK-X64-NEXT:    8 |   long long
+// CHECK-X64-NEXT:    8:0-0 |   long long
 // CHECK-X64-NEXT:   16 |   struct B0 (virtual base)
 // CHECK-X64-NEXT:   16 |     int a
 // CHECK-X64-NEXT:   20 |   struct B1 (virtual base)
diff --git a/test/Layout/ms-x86-empty-layout.c b/test/Layout/ms-x86-empty-layout.c
index 3554baf..5dbd844 100644
--- a/test/Layout/ms-x86-empty-layout.c
+++ b/test/Layout/ms-x86-empty-layout.c
@@ -6,48 +6,36 @@
 struct EmptyIntMemb {
   int FlexArrayMemb[0];
 };
-// CHECK: *** Dumping AST Record Layout
-// CHECK: Type: struct EmptyIntMemb
-// CHECK: Record: 
-// CHECK: Layout: <ASTRecordLayout
-// CHECK:     Size:32
-// CHECK:     Alignment:32
-// CHECK:     FieldOffsets: [0]>
+// CHECK:       *** Dumping AST Record Layout
+// CHECK-NEXT:  0 | struct EmptyIntMemb
+// CHECK-NEXT:  0 | int [0] FlexArrayMemb
+// CHECK-NEXT:    | [sizeof=4, align=4
 
 struct EmptyLongLongMemb {
   long long FlexArrayMemb[0];
 };
 // CHECK: *** Dumping AST Record Layout
-// CHECK: Type: struct EmptyLongLongMemb
-// CHECK: Record: 
-// CHECK: Layout: <ASTRecordLayout
-// CHECK:     Size:32
-// CHECK:     Alignment:64
-// CHECK:     FieldOffsets: [0]>
+// CHECK-NEXT:  0 | struct EmptyLongLongMemb
+// CHECK-NEXT:  0 | long long [0] FlexArrayMemb
+// CHECK-NEXT:    | [sizeof=4, align=8
 
 struct EmptyAligned2LongLongMemb {
   long long __declspec(align(2)) FlexArrayMemb[0];
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK: Type: struct EmptyAligned2LongLongMemb
-// CHECK: Record: 
-// CHECK: Layout: <ASTRecordLayout
-// CHECK:     Size:32
-// CHECK:     Alignment:64
-// CHECK:     FieldOffsets: [0]>
+// CHECK-NEXT:  0 | struct EmptyAligned2LongLongMemb
+// CHECK-NEXT:  0 | long long [0] FlexArrayMemb
+// CHECK-NEXT:    | [sizeof=4, align=8
 
 struct EmptyAligned8LongLongMemb {
   long long __declspec(align(8)) FlexArrayMemb[0];
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK: Type: struct EmptyAligned8LongLongMemb
-// CHECK: Record: 
-// CHECK: Layout: <ASTRecordLayout
-// CHECK:     Size:64
-// CHECK:     Alignment:64
-// CHECK:     FieldOffsets: [0]>
+// CHECK-NEXT:  0 | struct EmptyAligned8LongLongMemb
+// CHECK-NEXT:  0 | long long [0] FlexArrayMemb
+// CHECK-NEXT:    | [sizeof=8, align=8
 
 #pragma pack(1)
 struct __declspec(align(4)) EmptyPackedAligned4LongLongMemb {
@@ -56,12 +44,9 @@
 #pragma pack()
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK: Type: struct EmptyPackedAligned4LongLongMemb
-// CHECK: Record: 
-// CHECK: Layout: <ASTRecordLayout
-// CHECK:     Size:32
-// CHECK:     Alignment:32
-// CHECK:     FieldOffsets: [0]>
+// CHECK-NEXT:  0 | struct EmptyPackedAligned4LongLongMemb
+// CHECK-NEXT:  0 | long long [0] FlexArrayMemb
+// CHECK-NEXT:    | [sizeof=4, align=4
 
 #pragma pack(1)
 struct EmptyPackedAligned8LongLongMemb {
@@ -70,12 +55,9 @@
 #pragma pack()
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK: Type: struct EmptyPackedAligned8LongLongMemb
-// CHECK: Record: 
-// CHECK: Layout: <ASTRecordLayout
-// CHECK:     Size:64
-// CHECK:     Alignment:64
-// CHECK:     FieldOffsets: [0]>
+// CHECK-NEXT:  0 | struct EmptyPackedAligned8LongLongMemb
+// CHECK-NEXT:  0 | long long [0] FlexArrayMemb
+// CHECK-NEXT:    | [sizeof=8, align=8
 
 
 int a[
diff --git a/test/Layout/ms-x86-empty-nonvirtual-bases.cpp b/test/Layout/ms-x86-empty-nonvirtual-bases.cpp
index 3fca324..00906e9 100644
--- a/test/Layout/ms-x86-empty-nonvirtual-bases.cpp
+++ b/test/Layout/ms-x86-empty-nonvirtual-bases.cpp
@@ -40,8 +40,6 @@
 // CHECK-NEXT:    0 | struct B
 // CHECK-NEXT:    0 |   struct B0 (base) (empty)
 // CHECK-NEXT:    0 |   struct B0 b0 (empty)
-// CHECK-NEXT:      |   [sizeof=8, align=8
-// CHECK-NEXT:      |    nvsize=0, nvalign=8]
 // CHECK:         8 |   int a
 // CHECK-NEXT:      | [sizeof=16, align=8
 // CHECK-NEXT:      |  nvsize=16, nvalign=8]
@@ -82,23 +80,13 @@
 // CHECK: *** Dumping AST Record Layout
 // CHECK-NEXT:    0 | struct D
 // CHECK-NEXT:    0 |   struct B0 b0 (empty)
-// CHECK-NEXT:      |   [sizeof=8, align=8
-// CHECK-NEXT:      |    nvsize=0, nvalign=8]
 // CHECK:         8 |   struct C0 c0
 // CHECK-NEXT:    8 |     int a
-// CHECK-NEXT:      |   [sizeof=4, align=4
-// CHECK-NEXT:      |    nvsize=4, nvalign=4]
 // CHECK:        12 |   struct C1 c1
 // CHECK-NEXT:   12 |     int a
-// CHECK-NEXT:      |   [sizeof=4, align=4
-// CHECK-NEXT:      |    nvsize=4, nvalign=4]
 // CHECK:        16 |   struct C2 c2
 // CHECK-NEXT:   16 |     int a
-// CHECK-NEXT:      |   [sizeof=4, align=4
-// CHECK-NEXT:      |    nvsize=4, nvalign=4]
 // CHECK:        24 |   struct B1 b1 (empty)
-// CHECK-NEXT:      |   [sizeof=8, align=8
-// CHECK-NEXT:      |    nvsize=0, nvalign=8]
 // CHECK:        32 |   int a
 // CHECK-NEXT:      | [sizeof=40, align=8
 // CHECK-NEXT:      |  nvsize=40, nvalign=8]
diff --git a/test/Layout/ms-x86-empty-virtual-base.cpp b/test/Layout/ms-x86-empty-virtual-base.cpp
index 2d0e55a..b732415 100644
--- a/test/Layout/ms-x86-empty-virtual-base.cpp
+++ b/test/Layout/ms-x86-empty-virtual-base.cpp
@@ -53,8 +53,6 @@
 // CHECK-NEXT:    0 | struct B
 // CHECK-NEXT:    0 |   (B vbtable pointer)
 // CHECK-NEXT:    8 |   struct B0 b0 (empty)
-// CHECK-NEXT:      |   [sizeof=8, align=8
-// CHECK-NEXT:      |    nvsize=0, nvalign=8]
 // CHECK:        16 |   int a
 // CHECK-NEXT:   24 |   struct B0 (virtual base) (empty)
 // CHECK-NEXT:      | [sizeof=24, align=8
@@ -63,8 +61,6 @@
 // CHECK-X64-NEXT:    0 | struct B
 // CHECK-X64-NEXT:    0 |   (B vbtable pointer)
 // CHECK-X64-NEXT:    8 |   struct B0 b0 (empty)
-// CHECK-X64-NEXT:      |   [sizeof=8, align=8
-// CHECK-X64-NEXT:      |    nvsize=0, nvalign=8]
 // CHECK-X64:        16 |   int a
 // CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
 // CHECK-X64-NEXT:      | [sizeof=24, align=8
diff --git a/test/Layout/ms-x86-pack-and-align.cpp b/test/Layout/ms-x86-pack-and-align.cpp
index 9ded22e..958ee19 100644
--- a/test/Layout/ms-x86-pack-and-align.cpp
+++ b/test/Layout/ms-x86-pack-and-align.cpp
@@ -40,8 +40,6 @@
 // CHECK-NEXT:    0 | struct X
 // CHECK-NEXT:    0 |   struct B a
 // CHECK-NEXT:    0 |     long long a
-// CHECK-NEXT:      |   [sizeof=8, align=8
-// CHECK-NEXT:      |    nvsize=8, nvalign=8]
 // CHECK-NEXT:    8 |   char b
 // CHECK-NEXT:   10 |   int c
 // CHECK-NEXT:      | [sizeof=16, align=4
@@ -51,8 +49,6 @@
 // CHECK-X64-NEXT:    0 | struct X
 // CHECK-X64-NEXT:    0 |   struct B a
 // CHECK-X64-NEXT:    0 |     long long a
-// CHECK-X64-NEXT:      |   [sizeof=8, align=8
-// CHECK-X64-NEXT:      |    nvsize=8, nvalign=8]
 // CHECK-X64-NEXT:    8 |   char b
 // CHECK-X64-NEXT:   10 |   int c
 // CHECK-X64-NEXT:      | [sizeof=16, align=4
@@ -193,12 +189,12 @@
 };
 // CHECK: *** Dumping AST Record Layout
 // CHECK-NEXT:    0 | struct YA (empty)
-// CHECK-NEXT:    0 |   char
+// CHECK-NEXT:0:0-0 |   char
 // CHECK-NEXT:      | [sizeof=32, align=32
 // CHECK-NEXT:      |  nvsize=32, nvalign=32]
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64-NEXT:    0 | struct YA (empty)
-// CHECK-X64-NEXT:    0 |   char
+// CHECK-X64-NEXT:0:0-0 |   char
 // CHECK-X64-NEXT:      | [sizeof=32, align=32
 // CHECK-X64-NEXT:      |  nvsize=32, nvalign=32]
 
@@ -211,18 +207,14 @@
 // CHECK-NEXT:    0 | struct YB
 // CHECK-NEXT:    0 |   char a
 // CHECK-NEXT:    1 |   struct YA b (empty)
-// CHECK-NEXT:    1 |     char
-// CHECK-NEXT:      |   [sizeof=32, align=32
-// CHECK-NEXT:      |    nvsize=32, nvalign=32]
+// CHECK-NEXT:1:0-0 |     char
 // CHECK-NEXT:      | [sizeof=33, align=1
 // CHECK-NEXT:      |  nvsize=33, nvalign=1]
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64-NEXT:    0 | struct YB
 // CHECK-X64-NEXT:    0 |   char a
 // CHECK-X64-NEXT:    1 |   struct YA b (empty)
-// CHECK-X64-NEXT:    1 |     char
-// CHECK-X64-NEXT:      |   [sizeof=32, align=32
-// CHECK-X64-NEXT:      |    nvsize=32, nvalign=32]
+// CHECK-X64-NEXT:1:0-0 |     char
 // CHECK-X64-NEXT:      | [sizeof=33, align=1
 // CHECK-X64-NEXT:      |  nvsize=33, nvalign=1]
 
@@ -232,12 +224,12 @@
 };
 // CHECK: *** Dumping AST Record Layout
 // CHECK-NEXT:    0 | struct YC (empty)
-// CHECK-NEXT:    0 |   char
+// CHECK-NEXT:0:0-0 |   char
 // CHECK-NEXT:      | [sizeof=32, align=32
 // CHECK-NEXT:      |  nvsize=32, nvalign=32]
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64-NEXT:    0 | struct YC (empty)
-// CHECK-X64-NEXT:    0 |   char
+// CHECK-X64-NEXT:    0:0-0 |   char
 // CHECK-X64-NEXT:      | [sizeof=8, align=32
 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=32]
 
@@ -250,18 +242,14 @@
 // CHECK-NEXT:    0 | struct YD
 // CHECK-NEXT:    0 |   char a
 // CHECK-NEXT:    1 |   struct YC b (empty)
-// CHECK-NEXT:    1 |     char
-// CHECK-NEXT:      |   [sizeof=32, align=32
-// CHECK-NEXT:      |    nvsize=32, nvalign=32]
+// CHECK-NEXT:1:0-0 |     char
 // CHECK-NEXT:      | [sizeof=33, align=1
 // CHECK-NEXT:      |  nvsize=33, nvalign=1]
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64-NEXT:    0 | struct YD
 // CHECK-X64-NEXT:    0 |   char a
 // CHECK-X64-NEXT:    1 |   struct YC b (empty)
-// CHECK-X64-NEXT:    1 |     char
-// CHECK-X64-NEXT:      |   [sizeof=8, align=32
-// CHECK-X64-NEXT:      |    nvsize=8, nvalign=32]
+// CHECK-X64-NEXT:1:0-0 |     char
 // CHECK-X64-NEXT:      | [sizeof=9, align=1
 // CHECK-X64-NEXT:      |  nvsize=9, nvalign=1]
 
@@ -271,12 +259,12 @@
 };
 // CHECK: *** Dumping AST Record Layout
 // CHECK-NEXT:    0 | struct YE (empty)
-// CHECK-NEXT:    0 |   char
+// CHECK-NEXT:    0:0-0 |   char
 // CHECK-NEXT:      | [sizeof=4, align=32
 // CHECK-NEXT:      |  nvsize=4, nvalign=32]
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64-NEXT:    0 | struct YE (empty)
-// CHECK-X64-NEXT:    0 |   char
+// CHECK-X64-NEXT:    0:0-0 |   char
 // CHECK-X64-NEXT:      | [sizeof=4, align=32
 // CHECK-X64-NEXT:      |  nvsize=4, nvalign=32]
 
@@ -289,18 +277,14 @@
 // CHECK-NEXT:    0 | struct YF
 // CHECK-NEXT:    0 |   char a
 // CHECK-NEXT:    1 |   struct YE b (empty)
-// CHECK-NEXT:    1 |     char
-// CHECK-NEXT:      |   [sizeof=4, align=32
-// CHECK-NEXT:      |    nvsize=4, nvalign=32]
+// CHECK-NEXT:1:0-0 |     char
 // CHECK-NEXT:      | [sizeof=5, align=1
 // CHECK-NEXT:      |  nvsize=5, nvalign=1]
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64-NEXT:    0 | struct YF
 // CHECK-X64-NEXT:    0 |   char a
 // CHECK-X64-NEXT:    1 |   struct YE b (empty)
-// CHECK-X64-NEXT:    1 |     char
-// CHECK-X64-NEXT:      |   [sizeof=4, align=32
-// CHECK-X64-NEXT:      |    nvsize=4, nvalign=32]
+// CHECK-X64-NEXT:1:0-0 |     char
 // CHECK-X64-NEXT:      | [sizeof=5, align=1
 // CHECK-X64-NEXT:      |  nvsize=5, nvalign=1]
 
@@ -459,20 +443,20 @@
 
 // CHECK: *** Dumping AST Record Layout
 // CHECK-NEXT:    0 | struct RB0
-// CHECK-NEXT:    0 |   int b
+// CHECK-NEXT:0:0-2 |   int b
 // CHECK-NEXT:      | [sizeof=8, align=1024
 // CHECK-NEXT:      |  nvsize=4, nvalign=1024]
 // CHECK: *** Dumping AST Record Layout
 // CHECK-NEXT:    0 | struct RB1
 // CHECK-NEXT:    0 |   (RB1 vftable pointer)
-// CHECK-NEXT: 1024 |   int b
+// CHECK-NEXT: 1024:0-2 |   int b
 // CHECK-NEXT:      | [sizeof=1032, align=1024
 // CHECK-NEXT:      |  nvsize=1028, nvalign=1024]
 // CHECK: *** Dumping AST Record Layout
 // CHECK: *** Dumping AST Record Layout
 // CHECK-NEXT:    0 | struct RB2
 // CHECK-NEXT:    0 |   (RB2 vbtable pointer)
-// CHECK-NEXT: 1024 |   int b
+// CHECK-NEXT: 1024:0-2 |   int b
 // CHECK-NEXT: 1028 |   struct RA (virtual base) (empty)
 // CHECK-NEXT:      | [sizeof=1032, align=1024
 // CHECK-NEXT:      |  nvsize=1028, nvalign=1024]
@@ -480,14 +464,14 @@
 // CHECK-NEXT:    0 | struct RB3
 // CHECK-NEXT:    0 |   (RB3 vftable pointer)
 // CHECK-NEXT: 1024 |   (RB3 vbtable pointer)
-// CHECK-NEXT: 2048 |   int b
+// CHECK-NEXT: 2048:0-2 |   int b
 // CHECK-NEXT: 2052 |   struct RA (virtual base) (empty)
 // CHECK-NEXT:      | [sizeof=2056, align=1024
 // CHECK-NEXT:      |  nvsize=2052, nvalign=1024]
 // CHECK: *** Dumping AST Record Layout
 // CHECK-NEXT:    0 | struct RC
 // CHECK-NEXT:    0 |   char _
-// CHECK-NEXT: 1024 |   int c
+// CHECK-NEXT: 1024:0-2 |   int c
 // CHECK-NEXT:      | [sizeof=1028, align=1024
 // CHECK-NEXT:      |  nvsize=1028, nvalign=1024]
 // CHECK: *** Dumping AST Record Layout
@@ -495,27 +479,25 @@
 // CHECK-NEXT:    0 |   char _
 // CHECK-NEXT:    1 |   struct RC c
 // CHECK-NEXT:    1 |     char _
-// CHECK-NEXT: 1025 |     int c
-// CHECK-NEXT:      |   [sizeof=1028, align=1024
-// CHECK-NEXT:      |    nvsize=1028, nvalign=1024]
+// CHECK-NEXT: 1025:0-2 |     int c
 // CHECK-NEXT:      | [sizeof=1029, align=1
 // CHECK-NEXT:      |  nvsize=1029, nvalign=1]
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64-NEXT:    0 | struct RB0
-// CHECK-X64-NEXT:    0 |   int b
+// CHECK-X64-NEXT:    0:0-2 |   int b
 // CHECK-X64-NEXT:      | [sizeof=8, align=1024
 // CHECK-X64-NEXT:      |  nvsize=4, nvalign=1024]
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64-NEXT:    0 | struct RB1
 // CHECK-X64-NEXT:    0 |   (RB1 vftable pointer)
-// CHECK-X64-NEXT: 1024 |   int b
+// CHECK-X64-NEXT: 1024:0-2 |   int b
 // CHECK-X64-NEXT:      | [sizeof=1032, align=1024
 // CHECK-X64-NEXT:      |  nvsize=1028, nvalign=1024]
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64-NEXT:    0 | struct RB2
 // CHECK-X64-NEXT:    0 |   (RB2 vbtable pointer)
-// CHECK-X64-NEXT: 1024 |   int b
+// CHECK-X64-NEXT: 1024:0-2 |   int b
 // CHECK-X64-NEXT: 1028 |   struct RA (virtual base) (empty)
 // CHECK-X64-NEXT:      | [sizeof=1032, align=1024
 // CHECK-X64-NEXT:      |  nvsize=1028, nvalign=1024]
@@ -523,14 +505,14 @@
 // CHECK-X64-NEXT:    0 | struct RB3
 // CHECK-X64-NEXT:    0 |   (RB3 vftable pointer)
 // CHECK-X64-NEXT: 1024 |   (RB3 vbtable pointer)
-// CHECK-X64-NEXT: 2048 |   int b
+// CHECK-X64-NEXT: 2048:0-2 |   int b
 // CHECK-X64-NEXT: 2052 |   struct RA (virtual base) (empty)
 // CHECK-X64-NEXT:      | [sizeof=2056, align=1024
 // CHECK-X64-NEXT:      |  nvsize=2052, nvalign=1024]
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64-NEXT:    0 | struct RC
 // CHECK-X64-NEXT:    0 |   char _
-// CHECK-X64-NEXT: 1024 |   int c
+// CHECK-X64-NEXT: 1024:0-2 |   int c
 // CHECK-X64-NEXT:      | [sizeof=1028, align=1024
 // CHECK-X64-NEXT:      |  nvsize=1028, nvalign=1024]
 // CHECK-X64: *** Dumping AST Record Layout
@@ -538,9 +520,7 @@
 // CHECK-X64-NEXT:    0 |   char _
 // CHECK-X64-NEXT:    1 |   struct RC c
 // CHECK-X64-NEXT:    1 |     char _
-// CHECK-X64-NEXT: 1025 |     int c
-// CHECK-X64-NEXT:      |   [sizeof=1028, align=1024
-// CHECK-X64-NEXT:      |    nvsize=1028, nvalign=1024]
+// CHECK-X64-NEXT: 1025:0-2 |     int c
 // CHECK-X64-NEXT:      | [sizeof=1029, align=1
 // CHECK-X64-NEXT:      |  nvsize=1029, nvalign=1]
 
@@ -670,8 +650,6 @@
 // CHECK-NEXT:    0 |   char a
 // CHECK-NEXT:    8 |   struct PA x
 // CHECK-NEXT:    8 |     int c
-// CHECK-NEXT:      |   [sizeof=4, align=4
-// CHECK-NEXT:      |    nvsize=4, nvalign=4]
 // CHECK-NEXT:      | [sizeof=16, align=8
 // CHECK-NEXT:      |  nvsize=12, nvalign=8]
 // CHECK-X64: *** Dumping AST Record Layout
@@ -679,8 +657,6 @@
 // CHECK-X64-NEXT:    0 |   char a
 // CHECK-X64-NEXT:    8 |   struct PA x
 // CHECK-X64-NEXT:    8 |     int c
-// CHECK-X64-NEXT:      |   [sizeof=4, align=4
-// CHECK-X64-NEXT:      |    nvsize=4, nvalign=4]
 // CHECK-X64-NEXT:      | [sizeof=16, align=8
 // CHECK-X64-NEXT:      |  nvsize=12, nvalign=8]
 
@@ -698,8 +674,6 @@
 // CHECK-NEXT:    0 |   char a
 // CHECK-NEXT:    8 |   struct PA x
 // CHECK-NEXT:    8 |     int c
-// CHECK-NEXT:      |   [sizeof=4, align=4
-// CHECK-NEXT:      |    nvsize=4, nvalign=4]
 // CHECK-NEXT:      | [sizeof=16, align=8
 // CHECK-NEXT:      |  nvsize=12, nvalign=8]
 // CHECK-X64: *** Dumping AST Record Layout
@@ -707,8 +681,6 @@
 // CHECK-X64-NEXT:    0 |   char a
 // CHECK-X64-NEXT:    8 |   struct PA x
 // CHECK-X64-NEXT:    8 |     int c
-// CHECK-X64-NEXT:      |   [sizeof=4, align=4
-// CHECK-X64-NEXT:      |    nvsize=4, nvalign=4]
 // CHECK-X64-NEXT:      | [sizeof=16, align=8
 // CHECK-X64-NEXT:      |  nvsize=12, nvalign=8]
 
@@ -759,13 +731,13 @@
 // CHECK: *** Dumping AST Record Layout
 // CHECK-NEXT:    0 | struct QD
 // CHECK-NEXT:    0 |   char a
-// CHECK-NEXT:    4 |   QA b
+// CHECK-NEXT:4:0-2 |   QA b
 // CHECK-NEXT:      | [sizeof=8, align=4
 // CHECK-NEXT:      |  nvsize=8, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
 // CHECK-X64-NEXT:    0 | struct QD
 // CHECK-X64-NEXT:    0 |   char a
-// CHECK-X64-NEXT:    4 |   QA b
+// CHECK-X64-NEXT:4:0-2 |   QA b
 // CHECK-X64-NEXT:      | [sizeof=8, align=4
 // CHECK-X64-NEXT:      |  nvsize=8, nvalign=4]
 
diff --git a/test/Layout/ms_struct-bitfields.c b/test/Layout/ms_struct-bitfields.c
new file mode 100644
index 0000000..9cb455b
--- /dev/null
+++ b/test/Layout/ms_struct-bitfields.c
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple armv7-apple-darwin -fdump-record-layouts %s 2>/dev/null \
+// RUN:            | FileCheck %s
+
+// rdar://22275433
+
+#pragma ms_struct on
+
+union A {
+  unsigned long long x : 32;
+  unsigned long long y : 32;
+} a;
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:        0 | union A
+// CHECK-NEXT:   0:0-31 |   unsigned long long x
+// CHECK-NEXT:   0:0-31 |   unsigned long long y
+// CHECK-NEXT:          | [sizeof=8, align=1]
+
+union B {
+  __attribute__((aligned(4)))
+  unsigned long long x : 32;
+  unsigned long long y : 32;
+} b;
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:       0 | union B
+// CHECK-NEXT:  0:0-31 |   unsigned long long x
+// CHECK-NEXT:  0:0-31 |   unsigned long long y
+// CHECK-NEXT:         | [sizeof=8, align=1]
+
+union C {
+  unsigned long long : 0;
+  unsigned short y : 8;
+} c;
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:       0 | union C
+// CHECK-NEXT:     0:- |   unsigned long long
+// CHECK-NEXT:   0:0-7 |   unsigned short y
+// CHECK-NEXT:         | [sizeof=2, align=1]
+
+union D {
+  unsigned long long : 0;
+  unsigned short : 0;
+} d;
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:       0 | union D
+// CHECK-NEXT:     0:- |   unsigned long long
+// CHECK-NEXT:     0:- |   unsigned short
+// CHECK-NEXT:         | [sizeof=1, align=1]
+
diff --git a/test/Sema/ms_bitfield_layout.c b/test/Sema/ms_bitfield_layout.c
index 293df77..8d377bc 100644
--- a/test/Sema/ms_bitfield_layout.c
+++ b/test/Sema/ms_bitfield_layout.c
@@ -13,10 +13,16 @@
 	short y;
 } A;
 
-// CHECK: Type: struct A
-// CHECK:   Size:128
-// CHECK:   Alignment:32
-// CHECK:   FieldOffsets: [0, 32, 64, 64, 96, 99, 112]>
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:      0 | struct A
+// CHECK-NEXT:      0 |   char x
+// CHECK-NEXT: 4:0-21 |   int a
+// CHECK-NEXT:    8:- |   int
+// CHECK-NEXT:  8:0-9 |   int c
+// CHECK-NEXT: 12:0-2 |   char b
+// CHECK-NEXT: 12:3-6 |   char d
+// CHECK-NEXT:     14 |   short y
+// CHECK-NEXT:        | [sizeof=16, align=4]
 
 typedef struct B {
 	char x;
@@ -25,10 +31,13 @@
 	char y;
 } B;
 
-// CHECK: Type: struct B
-// CHECK:   Size:48
-// CHECK:   Alignment:16
-// CHECK:   FieldOffsets: [0, 8, 16, 32]>
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:      0 | struct B
+// CHECK-NEXT:      0 |   char x
+// CHECK-NEXT:    1:- |   int
+// CHECK-NEXT:  2:0-3 |   short a
+// CHECK-NEXT:      4 |   char y
+// CHECK-NEXT:        | [sizeof=6, align=2]
 
 typedef struct C {
 	char x;
@@ -37,10 +46,13 @@
 	char y;
 } C;
 
-// CHECK: Type: struct C
-// CHECK:   Size:64
-// CHECK:   Alignment:32
-// CHECK:   FieldOffsets: [0, 16, 32, 32]>
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:      0 | struct C
+// CHECK-NEXT:      0 |   char x
+// CHECK-NEXT:  2:0-3 |   short a
+// CHECK-NEXT:    4:- |   int
+// CHECK-NEXT:      4 |   char y
+// CHECK-NEXT:        | [sizeof=8, align=4]
 
 typedef struct D {
 	char x;
@@ -49,10 +61,13 @@
 	char y;
 } D;
 
-// CHECK: Type: struct D
-// CHECK:   Size:16
-// CHECK:   Alignment:8
-// CHECK:   FieldOffsets: [0, 8, 8, 8]>
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:      0 | struct D
+// CHECK-NEXT:      0 |   char x
+// CHECK-NEXT:    1:- |   short
+// CHECK-NEXT:    1:- |   int
+// CHECK-NEXT:      1 |   char y
+// CHECK-NEXT:        | [sizeof=2, align=1]
 
 typedef union E {
 	char x;
@@ -62,10 +77,15 @@
 	short y;
 } E;
 
-// CHECK: Type: union E
-// CHECK:   Size:64
-// CHECK:   Alignment:16
-// CHECK:   FieldOffsets: [0, 0, 0, 0, 0]>
+
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:      0 | union E
+// CHECK-NEXT:      0 |   char x
+// CHECK-NEXT:  0:0-2 |   long long a
+// CHECK-NEXT:  0:0-2 |   int b
+// CHECK-NEXT:    0:- |   long long
+// CHECK-NEXT:      0 |   short
+// CHECK-NEXT:        | [sizeof=8, align=2]
 
 typedef struct F {
 	char x;
@@ -81,10 +101,20 @@
 	short y;
 } F;
 
-// CHECK: Type: struct F
-// CHECK:   Size:128
-// CHECK:   Alignment:16
-// CHECK:   FieldOffsets: [0, 8, 11, 16, 32, 38, 48, 64, 80, 96, 112]>
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:      0 | struct F
+// CHECK-NEXT:      0 |   char x
+// CHECK-NEXT:  1:0-2 |   char a
+// CHECK-NEXT:  1:3-5 |   char b
+// CHECK-NEXT:  2:0-2 |   char c
+// CHECK-NEXT:  4:0-5 |   short d
+// CHECK-NEXT: 4:6-11 |   short e
+// CHECK-NEXT:  6:0-5 |   short f
+// CHECK-NEXT: 8:0-10 |   short g
+// CHECK-NEXT:10:0-10 |   short h
+// CHECK-NEXT:12:0-10 |   short i
+// CHECK-NEXT:     14 |   short y
+// CHECK-NEXT:        | [sizeof=16, align=2]
 
 typedef union G {
 	char x;
@@ -94,10 +124,14 @@
 	short y;
 } G;
 
-// CHECK: Type: union G
-// CHECK:   Size:32
-// CHECK:   Alignment:16
-// CHECK:   FieldOffsets: [0, 0, 0, 0, 0]>
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:      0 | union G
+// CHECK-NEXT:      0 |   char x
+// CHECK-NEXT:  0:0-2 |   int a
+// CHECK-NEXT:    0:- |   int
+// CHECK-NEXT:    0:- |   long long
+// CHECK-NEXT:      0 |   short y
+// CHECK-NEXT:        | [sizeof=4, align=2]
 
 typedef struct H {
 	unsigned short a : 1;
@@ -106,20 +140,25 @@
 	unsigned short c : 1;
 } H;
 
-// CHECK: Type: struct H
-// CHECK:   Size:32
-// CHECK:   Alignment:16
-// CHECK:   FieldOffsets: [0, 16, 16, 16]>
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:      0 | struct H
+// CHECK-NEXT:  0:0-0 |   unsigned short a
+// CHECK-NEXT:    2:- |   unsigned char
+// CHECK-NEXT:    2:- |   unsigned long
+// CHECK-NEXT:  2:0-0 |   unsigned short c
+// CHECK-NEXT:        | [sizeof=4, align=2]
 
 typedef struct I {
 	short : 8;
 	__declspec(align(16)) short : 8;
 } I;
 
-// CHECK: Type: struct I
-// CHECK:   Size:16
-// CHECK:   Alignment:16
-// CHECK:   FieldOffsets: [0, 8]
+
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:      0 | struct I
+// CHECK-NEXT:  0:0-7 |   short
+// CHECK-NEXT:  1:0-7 |   short
+// CHECK-NEXT:        | [sizeof=2, align=2]
 
 #pragma pack(push, 1)
 
@@ -133,10 +172,16 @@
 	short y;
 } A1;
 
-// CHECK: Type: struct A1
-// CHECK:   Size:96
-// CHECK:   Alignment:8
-// CHECK:   FieldOffsets: [0, 8, 40, 40, 72, 75, 80]>
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:      0 | struct A1
+// CHECK-NEXT:      0 |   char x
+// CHECK-NEXT: 1:0-21 |   int a
+// CHECK-NEXT:    5:- |   int
+// CHECK-NEXT:  5:0-9 |   int c
+// CHECK-NEXT:  9:0-2 |   char b
+// CHECK-NEXT:  9:3-6 |   char d
+// CHECK-NEXT:     10 |   short y
+// CHECK-NEXT:        | [sizeof=12, align=1]
 
 typedef struct B1 {
 	char x;
@@ -145,10 +190,13 @@
 	char y;
 } B1;
 
-// CHECK: Type: struct B1
-// CHECK:   Size:32
-// CHECK:   Alignment:8
-// CHECK:   FieldOffsets: [0, 8, 8, 24]>
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:      0 | struct B1
+// CHECK-NEXT:      0 |   char x
+// CHECK-NEXT:    1:- |   int
+// CHECK-NEXT:  1:0-3 |   short
+// CHECK-NEXT:      3 |   char y
+// CHECK-NEXT:        | [sizeof=4, align=1]
 
 typedef struct C1 {
 	char x;
@@ -157,10 +205,13 @@
 	char y;
 } C1;
 
-// CHECK: Type: struct C1
-// CHECK:   Size:32
-// CHECK:   Alignment:8
-// CHECK:   FieldOffsets: [0, 8, 24, 24]>
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:      0 | struct C1
+// CHECK-NEXT:      0 |   char x
+// CHECK-NEXT:  1:0-3 |   short
+// CHECK-NEXT:    3:- |   int
+// CHECK-NEXT:      3 |   char y
+// CHECK-NEXT:        | [sizeof=4, align=1]
 
 typedef struct D1 {
 	char x;
@@ -169,10 +220,13 @@
 	char y;
 } D1;
 
-// CHECK: Type: struct D1
-// CHECK:   Size:16
-// CHECK:   Alignment:8
-// CHECK:   FieldOffsets: [0, 8, 8, 8]>
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:      0 | struct D1
+// CHECK-NEXT:      0 |   char x
+// CHECK-NEXT:    1:- |   short
+// CHECK-NEXT:    1:- |   int
+// CHECK-NEXT:      1 |   char y
+// CHECK-NEXT:        | [sizeof=2, align=1]
 
 typedef union E1 {
 	char x;
@@ -182,10 +236,14 @@
 	short y;
 } E1;
 
-// CHECK: Type: union E1
-// CHECK:   Size:64
-// CHECK:   Alignment:8
-// CHECK:   FieldOffsets: [0, 0, 0, 0, 0]>
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:      0 | union E1
+// CHECK-NEXT:      0 |   char x
+// CHECK-NEXT:  0:0-2 |   long long a
+// CHECK-NEXT:  0:0-2 |   int b
+// CHECK-NEXT:    0:- |   long long
+// CHECK-NEXT:      0 |   short y
+// CHECK-NEXT:        | [sizeof=8, align=1]
 
 typedef struct F1 {
 	char x;
@@ -201,10 +259,20 @@
 	short y;
 } F1;
 
-// CHECK: Type: struct F1
-// CHECK:   Size:120
-// CHECK:   Alignment:8
-// CHECK:   FieldOffsets: [0, 8, 11, 16, 24, 30, 40, 56, 72, 88, 104]>
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:      0 | struct F1
+// CHECK-NEXT:      0 |   char x
+// CHECK-NEXT:  1:0-2 |   char a
+// CHECK-NEXT:  1:3-5 |   char b
+// CHECK-NEXT:  2:0-2 |   char c
+// CHECK-NEXT:  3:0-5 |   short d
+// CHECK-NEXT: 3:6-11 |   short e
+// CHECK-NEXT:  5:0-5 |   short f
+// CHECK-NEXT: 7:0-10 |   short g
+// CHECK-NEXT: 9:0-10 |   short h
+// CHECK-NEXT:11:0-10 |   short i
+// CHECK-NEXT:     13 |   short y
+// CHECK-NEXT:        | [sizeof=15, align=1]
 
 typedef union G1 {
 	char x;
@@ -214,10 +282,14 @@
 	short y;
 } G1;
 
-// CHECK: Type: union G1
-// CHECK:   Size:32
-// CHECK:   Alignment:8
-// CHECK:   FieldOffsets: [0, 0, 0, 0, 0]>
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:      0 | union G1
+// CHECK-NEXT:      0 |   char x
+// CHECK-NEXT:  0:0-2 |   int a
+// CHECK-NEXT:    0:- |   int
+// CHECK-NEXT:    0:- |   long long
+// CHECK-NEXT:      0 |   short y
+// CHECK-NEXT:        | [sizeof=4, align=1]
 
 typedef struct H1 {
 	unsigned long a : 1;
@@ -226,20 +298,24 @@
 	unsigned long c : 1;
 } H1;
 
-// CHECK: Type: struct H1
-// CHECK:   Size:64
-// CHECK:   Alignment:8
-// CHECK:   FieldOffsets: [0, 32, 32, 32]>
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:      0 | struct H1
+// CHECK-NEXT:  0:0-0 |   unsigned long a
+// CHECK-NEXT:    4:- |   unsigned char
+// CHECK-NEXT:    4:- |   unsigned long
+// CHECK-NEXT:  4:0-0 |   unsigned long c
+// CHECK-NEXT:        | [sizeof=8, align=1]
 
 typedef struct I1 {
 	short : 8;
 	__declspec(align(16)) short : 8;
 } I1;
 
-// CHECK: Type: struct I1
-// CHECK:   Size:16
-// CHECK:   Alignment:8
-// CHECK:   FieldOffsets: [0, 8]
+// CHECK:*** Dumping AST Record Layout
+// CHECK-NEXT:      0 | struct I1
+// CHECK-NEXT:  0:0-7 |   short
+// CHECK-NEXT:  1:0-7 |   short
+// CHECK-NEXT:        | [sizeof=2, align=1]
 
 #pragma pack(pop)
 
diff --git a/test/Sema/ms_class_layout.cpp b/test/Sema/ms_class_layout.cpp
index 896d3ed..8638972 100644
--- a/test/Sema/ms_class_layout.cpp
+++ b/test/Sema/ms_class_layout.cpp
@@ -236,11 +236,7 @@
 // CHECK-NEXT: 84 |         int b_field
 // CHECK-NEXT: 88 |       int a_field
 // CHECK-NEXT: 92 |       char one
-
-// CHECK-NEXT: sizeof=80, align=8
-// CHECK-NEXT: nvsize=64, nvalign=8
-
-// CHECK: sizeof=96, align=8
+// CHECK-NEXT: sizeof=96, align=8
 // CHECK-NEXT: nvsize=96, nvalign=8
 
 // CHECK: %struct.BaseStruct = type { double, float, %class.C }
@@ -267,10 +263,7 @@
 // CHECK-NEXT: 84 |           int b_field
 // CHECK-NEXT: 88 |         int a_field
 // CHECK-NEXT: 92 |         char one
-// CHECK-NEXT: sizeof=80, align=8
-// CHECK-NEXT: nvsize=64, nvalign=8
-
-// CHECK: 96 |   int x
+// CHECK-NEXT: 96 |   int x
 // CHECK-NEXT: sizeof=104, align=8
 // CHECK-NEXT: nvsize=104, nvalign=8