r245514 - Fix the layout of bitfields in ms_struct unions: their

John McCall via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 19 15:42:36 PDT 2015


Author: rjmccall
Date: Wed Aug 19 17:42:36 2015
New Revision: 245514

URL: http://llvm.org/viewvc/llvm-project?rev=245514&view=rev
Log:
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

Added:
    cfe/trunk/test/Layout/ms_struct-bitfields.c
Modified:
    cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
    cfe/trunk/test/CodeGen/ms_struct-pack.c
    cfe/trunk/test/CodeGen/override-layout.c
    cfe/trunk/test/Layout/itanium-union-bitfield.cpp
    cfe/trunk/test/Layout/ms-x86-alias-avoidance-padding.cpp
    cfe/trunk/test/Layout/ms-x86-bitfields-vbases.cpp
    cfe/trunk/test/Layout/ms-x86-empty-layout.c
    cfe/trunk/test/Layout/ms-x86-empty-nonvirtual-bases.cpp
    cfe/trunk/test/Layout/ms-x86-empty-virtual-base.cpp
    cfe/trunk/test/Layout/ms-x86-pack-and-align.cpp
    cfe/trunk/test/Sema/ms_bitfield_layout.c
    cfe/trunk/test/Sema/ms_class_layout.cpp

Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=245514&r1=245513&r2=245514&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Wed Aug 19 17:42:36 2015
@@ -1565,6 +1565,12 @@ void ItaniumRecordLayoutBuilder::LayoutB
     UnpackedFieldAlign = std::min(UnpackedFieldAlign, MaxFieldAlignmentInBits);
   }
 
+  // But, ms_struct just ignores all of that in unions, even explicit
+  // alignment attributes.
+  if (IsMsStruct && IsUnion) {
+    FieldAlign = UnpackedFieldAlign = 1;
+  }
+
   // For purposes of diagnostics, we're going to simultaneously
   // compute the field offsets that we would have used if we weren't
   // adding any alignment padding or if the field weren't packed.
@@ -1631,9 +1637,20 @@ void ItaniumRecordLayoutBuilder::LayoutB
 
   // For unions, this is just a max operation, as usual.
   if (IsUnion) {
-    uint64_t RoundedFieldSize = roundUpSizeToCharAlignment(FieldSize,
-                                                           Context);
+    // For ms_struct, allocate the entire storage unit --- unless this
+    // is a zero-width bitfield, in which case just use a size of 1.
+    uint64_t RoundedFieldSize;
+    if (IsMsStruct) {
+      RoundedFieldSize =
+        (FieldSize ? TypeSize : Context.getTargetInfo().getCharWidth());
+
+    // Otherwise, allocate just the number of bytes required to store
+    // the bitfield.
+    } else {
+      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) {
@@ -3045,144 +3062,189 @@ ASTContext::getObjCLayout(const ObjCInte
 
 static void PrintOffset(raw_ostream &OS,
                         CharUnits Offset, unsigned IndentLevel) {
-  OS << llvm::format("%4" PRId64 " | ", (int64_t)Offset.getQuantity());
+  OS << llvm::format("%10" PRId64 " | ", (int64_t)Offset.getQuantity());
+  OS.indent(IndentLevel * 2);
+}
+
+static void PrintBitFieldOffset(raw_ostream &OS, CharUnits Offset,
+                                unsigned Begin, unsigned Width,
+                                unsigned IndentLevel) {
+  llvm::SmallString<10> Buffer;
+  {
+    llvm::raw_svector_ostream BufferOS(Buffer);
+    BufferOS << Offset.getQuantity() << ':';
+    if (Width == 0) {
+      BufferOS << '-';
+    } else {
+      BufferOS << Begin << '-' << (Begin + Width - 1);
+    }
+  }
+  
+  OS << llvm::right_justify(Buffer, 10) << " | ";
   OS.indent(IndentLevel * 2);
 }
 
 static void PrintIndentNoOffset(raw_ostream &OS, unsigned IndentLevel) {
-  OS << "     | ";
+  OS << "           | ";
   OS.indent(IndentLevel * 2);
 }
 
-static void DumpCXXRecordLayout(raw_ostream &OS,
-                                const CXXRecordDecl *RD, const ASTContext &C,
-                                CharUnits Offset,
-                                unsigned IndentLevel,
-                                const char* Description,
-                                bool IncludeVirtualBases) {
+static void DumpRecordLayout(raw_ostream &OS, const RecordDecl *RD,
+                             const ASTContext &C,
+                             CharUnits Offset,
+                             unsigned IndentLevel,
+                             const char* Description,
+                             bool PrintSizeInfo,
+                             bool IncludeVirtualBases) {
   const ASTRecordLayout &Layout = C.getASTRecordLayout(RD);
+  auto CXXRD = dyn_cast<CXXRecordDecl>(RD);
 
   PrintOffset(OS, Offset, IndentLevel);
-  OS << C.getTypeDeclType(const_cast<CXXRecordDecl *>(RD)).getAsString();
+  OS << C.getTypeDeclType(const_cast<RecordDecl*>(RD)).getAsString();
   if (Description)
     OS << ' ' << Description;
-  if (RD->isEmpty())
+  if (CXXRD && CXXRD->isEmpty())
     OS << " (empty)";
   OS << '\n';
 
   IndentLevel++;
 
-  const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
-  bool HasOwnVFPtr = Layout.hasOwnVFPtr();
-  bool HasOwnVBPtr = Layout.hasOwnVBPtr();
-
-  // Vtable pointer.
-  if (RD->isDynamicClass() && !PrimaryBase && !isMsLayout(C)) {
-    PrintOffset(OS, Offset, IndentLevel);
-    OS << '(' << *RD << " vtable pointer)\n";
-  } else if (HasOwnVFPtr) {
-    PrintOffset(OS, Offset, IndentLevel);
-    // vfptr (for Microsoft C++ ABI)
-    OS << '(' << *RD << " vftable pointer)\n";
-  }
-
-  // Collect nvbases.
-  SmallVector<const CXXRecordDecl *, 4> Bases;
-  for (const CXXBaseSpecifier &Base : RD->bases()) {
-    assert(!Base.getType()->isDependentType() &&
-           "Cannot layout class with dependent bases.");
-    if (!Base.isVirtual())
-      Bases.push_back(Base.getType()->getAsCXXRecordDecl());
-  }
-
-  // Sort nvbases by offset.
-  std::stable_sort(Bases.begin(), Bases.end(),
-                   [&](const CXXRecordDecl *L, const CXXRecordDecl *R) {
-    return Layout.getBaseClassOffset(L) < Layout.getBaseClassOffset(R);
-  });
-
-  // Dump (non-virtual) bases
-  for (const CXXRecordDecl *Base : Bases) {
-    CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base);
-    DumpCXXRecordLayout(OS, Base, C, BaseOffset, IndentLevel,
-                        Base == PrimaryBase ? "(primary base)" : "(base)",
-                        /*IncludeVirtualBases=*/false);
-  }
-
-  // vbptr (for Microsoft C++ ABI)
-  if (HasOwnVBPtr) {
-    PrintOffset(OS, Offset + Layout.getVBPtrOffset(), IndentLevel);
-    OS << '(' << *RD << " vbtable pointer)\n";
+  // Dump bases.
+  if (CXXRD) {
+    const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
+    bool HasOwnVFPtr = Layout.hasOwnVFPtr();
+    bool HasOwnVBPtr = Layout.hasOwnVBPtr();
+
+    // Vtable pointer.
+    if (CXXRD->isDynamicClass() && !PrimaryBase && !isMsLayout(C)) {
+      PrintOffset(OS, Offset, IndentLevel);
+      OS << '(' << *RD << " vtable pointer)\n";
+    } else if (HasOwnVFPtr) {
+      PrintOffset(OS, Offset, IndentLevel);
+      // vfptr (for Microsoft C++ ABI)
+      OS << '(' << *RD << " vftable pointer)\n";
+    }
+
+    // Collect nvbases.
+    SmallVector<const CXXRecordDecl *, 4> Bases;
+    for (const CXXBaseSpecifier &Base : CXXRD->bases()) {
+      assert(!Base.getType()->isDependentType() &&
+             "Cannot layout class with dependent bases.");
+      if (!Base.isVirtual())
+        Bases.push_back(Base.getType()->getAsCXXRecordDecl());
+    }
+
+    // Sort nvbases by offset.
+    std::stable_sort(Bases.begin(), Bases.end(),
+                     [&](const CXXRecordDecl *L, const CXXRecordDecl *R) {
+      return Layout.getBaseClassOffset(L) < Layout.getBaseClassOffset(R);
+    });
+
+    // Dump (non-virtual) bases
+    for (const CXXRecordDecl *Base : Bases) {
+      CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base);
+      DumpRecordLayout(OS, Base, C, BaseOffset, IndentLevel,
+                       Base == PrimaryBase ? "(primary base)" : "(base)",
+                       /*PrintSizeInfo=*/false,
+                       /*IncludeVirtualBases=*/false);
+    }
+
+    // vbptr (for Microsoft C++ ABI)
+    if (HasOwnVBPtr) {
+      PrintOffset(OS, Offset + Layout.getVBPtrOffset(), IndentLevel);
+      OS << '(' << *RD << " vbtable pointer)\n";
+    }
   }
 
   // Dump fields.
   uint64_t FieldNo = 0;
-  for (CXXRecordDecl::field_iterator I = RD->field_begin(),
+  for (RecordDecl::field_iterator I = RD->field_begin(),
          E = RD->field_end(); I != E; ++I, ++FieldNo) {
     const FieldDecl &Field = **I;
-    CharUnits FieldOffset = Offset + 
-      C.toCharUnitsFromBits(Layout.getFieldOffset(FieldNo));
-
-    if (const CXXRecordDecl *D = Field.getType()->getAsCXXRecordDecl()) {
-      DumpCXXRecordLayout(OS, D, C, FieldOffset, IndentLevel,
-                          Field.getName().data(),
-                          /*IncludeVirtualBases=*/true);
+    uint64_t LocalFieldOffsetInBits = Layout.getFieldOffset(FieldNo);
+    CharUnits FieldOffset =
+      Offset + C.toCharUnitsFromBits(LocalFieldOffsetInBits);
+
+    // Recursively dump fields of record type.
+    if (auto RT = Field.getType()->getAs<RecordType>()) {
+      DumpRecordLayout(OS, RT->getDecl(), C, FieldOffset, IndentLevel,
+                       Field.getName().data(),
+                       /*PrintSizeInfo=*/false,
+                       /*IncludeVirtualBases=*/true);
       continue;
     }
 
-    PrintOffset(OS, FieldOffset, IndentLevel);
+    if (Field.isBitField()) {
+      uint64_t LocalFieldByteOffsetInBits = C.toBits(FieldOffset - Offset);
+      unsigned Begin = LocalFieldOffsetInBits - LocalFieldByteOffsetInBits;
+      unsigned Width = Field.getBitWidthValue(C);
+      PrintBitFieldOffset(OS, FieldOffset, Begin, Width, IndentLevel);
+    } else {
+      PrintOffset(OS, FieldOffset, IndentLevel);
+    }
     OS << Field.getType().getAsString() << ' ' << Field << '\n';
   }
 
-  if (!IncludeVirtualBases)
-    return;
-
   // Dump virtual bases.
-  const ASTRecordLayout::VBaseOffsetsMapTy &vtordisps = 
-    Layout.getVBaseOffsetsMap();
-  for (const CXXBaseSpecifier &Base : RD->vbases()) {
-    assert(Base.isVirtual() && "Found non-virtual class!");
-    const CXXRecordDecl *VBase = Base.getType()->getAsCXXRecordDecl();
-
-    CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBase);
+  if (CXXRD && IncludeVirtualBases) {
+    const ASTRecordLayout::VBaseOffsetsMapTy &VtorDisps = 
+      Layout.getVBaseOffsetsMap();
+
+    for (const CXXBaseSpecifier &Base : CXXRD->vbases()) {
+      assert(Base.isVirtual() && "Found non-virtual class!");
+      const CXXRecordDecl *VBase = Base.getType()->getAsCXXRecordDecl();
+
+      CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBase);
+
+      if (VtorDisps.find(VBase)->second.hasVtorDisp()) {
+        PrintOffset(OS, VBaseOffset - CharUnits::fromQuantity(4), IndentLevel);
+        OS << "(vtordisp for vbase " << *VBase << ")\n";
+      }
 
-    if (vtordisps.find(VBase)->second.hasVtorDisp()) {
-      PrintOffset(OS, VBaseOffset - CharUnits::fromQuantity(4), IndentLevel);
-      OS << "(vtordisp for vbase " << *VBase << ")\n";
+      DumpRecordLayout(OS, VBase, C, VBaseOffset, IndentLevel,
+                       VBase == Layout.getPrimaryBase() ?
+                         "(primary virtual base)" : "(virtual base)",
+                       /*PrintSizeInfo=*/false,
+                       /*IncludeVirtualBases=*/false);
     }
-
-    DumpCXXRecordLayout(OS, VBase, C, VBaseOffset, IndentLevel,
-                        VBase == PrimaryBase ?
-                        "(primary virtual base)" : "(virtual base)",
-                        /*IncludeVirtualBases=*/false);
   }
 
+  if (!PrintSizeInfo) return;
+
   PrintIndentNoOffset(OS, IndentLevel - 1);
   OS << "[sizeof=" << Layout.getSize().getQuantity();
-  if (!isMsLayout(C))
+  if (CXXRD && !isMsLayout(C))
     OS << ", dsize=" << Layout.getDataSize().getQuantity();
-  OS << ", align=" << Layout.getAlignment().getQuantity() << '\n';
+  OS << ", align=" << Layout.getAlignment().getQuantity();
 
-  PrintIndentNoOffset(OS, IndentLevel - 1);
-  OS << " nvsize=" << Layout.getNonVirtualSize().getQuantity();
-  OS << ", nvalign=" << Layout.getNonVirtualAlignment().getQuantity() << "]\n";
+  if (CXXRD) {
+    OS << ",\n";
+    PrintIndentNoOffset(OS, IndentLevel - 1);
+    OS << " nvsize=" << Layout.getNonVirtualSize().getQuantity();
+    OS << ", nvalign=" << Layout.getNonVirtualAlignment().getQuantity();
+  }
+  OS << "]\n";
 }
 
 void ASTContext::DumpRecordLayout(const RecordDecl *RD,
                                   raw_ostream &OS,
                                   bool Simple) const {
-  const ASTRecordLayout &Info = getASTRecordLayout(RD);
+  if (!Simple) {
+    ::DumpRecordLayout(OS, RD, *this, CharUnits(), 0, nullptr,
+                       /*PrintSizeInfo*/true,
+                       /*IncludeVirtualBases=*/true);
+    return;
+  }
 
-  if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
-    if (!Simple)
-      return DumpCXXRecordLayout(OS, CXXRD, *this, CharUnits(), 0, nullptr,
-                                 /*IncludeVirtualBases=*/true);
+  // The "simple" format is designed to be parsed by the
+  // layout-override testing code.  There shouldn't be any external
+  // uses of this format --- when LLDB overrides a layout, it sets up
+  // the data structures directly --- so feel free to adjust this as
+  // you like as long as you also update the rudimentary parser for it
+  // in libFrontend.
 
+  const ASTRecordLayout &Info = getASTRecordLayout(RD);
   OS << "Type: " << getTypeDeclType(RD).getAsString() << "\n";
-  if (!Simple) {
-    OS << "Record: ";
-    RD->dump();
-  }
   OS << "\nLayout: ";
   OS << "<ASTRecordLayout\n";
   OS << "  Size:" << toBits(Info.getSize()) << "\n";

Modified: cfe/trunk/test/CodeGen/ms_struct-pack.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms_struct-pack.c?rev=245514&r1=245513&r2=245514&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/ms_struct-pack.c (original)
+++ cfe/trunk/test/CodeGen/ms_struct-pack.c Wed Aug 19 17:42:36 2015
@@ -133,12 +133,12 @@ struct test0 {
   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];

Modified: cfe/trunk/test/CodeGen/override-layout.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/override-layout.c?rev=245514&r1=245513&r2=245514&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/override-layout.c (original)
+++ cfe/trunk/test/CodeGen/override-layout.c Wed Aug 19 17:42:36 2015
@@ -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.

Modified: cfe/trunk/test/Layout/itanium-union-bitfield.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Layout/itanium-union-bitfield.cpp?rev=245514&r1=245513&r2=245514&view=diff
==============================================================================
--- cfe/trunk/test/Layout/itanium-union-bitfield.cpp (original)
+++ cfe/trunk/test/Layout/itanium-union-bitfield.cpp Wed Aug 19 17:42:36 2015
@@ -16,14 +16,14 @@ union 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-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]
 

Modified: cfe/trunk/test/Layout/ms-x86-alias-avoidance-padding.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Layout/ms-x86-alias-avoidance-padding.cpp?rev=245514&r1=245513&r2=245514&view=diff
==============================================================================
--- cfe/trunk/test/Layout/ms-x86-alias-avoidance-padding.cpp (original)
+++ cfe/trunk/test/Layout/ms-x86-alias-avoidance-padding.cpp Wed Aug 19 17:42:36 2015
@@ -391,8 +391,6 @@ struct RZ3 : RX3, RY {};
 // 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 @@ struct RZ3 : RX3, RY {};
 // 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 @@ struct RZ4 : RX4, RY {};
 // 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 @@ struct RZ4 : RX4, RY {};
 // 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 @@ struct RZ5 : RX5, RY {};
 // 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 @@ struct RZ5 : RX5, RY {};
 // 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 @@ struct RZ6 : RX6, RY {};
 // 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 @@ struct RZ6 : RX6, RY {};
 // 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 @@ struct RZ7 : RX7, RY {};
 // 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 @@ struct RZ7 : RX7, RY {};
 // 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

Modified: cfe/trunk/test/Layout/ms-x86-bitfields-vbases.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Layout/ms-x86-bitfields-vbases.cpp?rev=245514&r1=245513&r2=245514&view=diff
==============================================================================
--- cfe/trunk/test/Layout/ms-x86-bitfields-vbases.cpp (original)
+++ cfe/trunk/test/Layout/ms-x86-bitfields-vbases.cpp Wed Aug 19 17:42:36 2015
@@ -12,7 +12,7 @@ struct A : virtual B0 { char a : 1; };
 // 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 @@ struct A : virtual B0 { char a : 1; };
 // 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 @@ struct B : virtual B0 { short a : 1; };
 // 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 @@ struct B : virtual B0 { short a : 1; };
 // 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 @@ struct C : virtual B0 { char a : 1; char
 // 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 @@ struct C : virtual B0 { char a : 1; char
 // 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 @@ struct D : virtual B0 { char a : 1; char
 // 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 @@ struct D : virtual B0 { char a : 1; char
 // 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 @@ struct E : virtual B0, virtual B1 { long
 // 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 @@ struct E : virtual B0, virtual B1 { long
 // 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)

Modified: cfe/trunk/test/Layout/ms-x86-empty-layout.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Layout/ms-x86-empty-layout.c?rev=245514&r1=245513&r2=245514&view=diff
==============================================================================
--- cfe/trunk/test/Layout/ms-x86-empty-layout.c (original)
+++ cfe/trunk/test/Layout/ms-x86-empty-layout.c Wed Aug 19 17:42:36 2015
@@ -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 @@ struct __declspec(align(4)) EmptyPackedA
 #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 @@ struct EmptyPackedAligned8LongLongMemb {
 #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[

Modified: cfe/trunk/test/Layout/ms-x86-empty-nonvirtual-bases.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Layout/ms-x86-empty-nonvirtual-bases.cpp?rev=245514&r1=245513&r2=245514&view=diff
==============================================================================
--- cfe/trunk/test/Layout/ms-x86-empty-nonvirtual-bases.cpp (original)
+++ cfe/trunk/test/Layout/ms-x86-empty-nonvirtual-bases.cpp Wed Aug 19 17:42:36 2015
@@ -40,8 +40,6 @@ struct B : B0 {
 // 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 @@ struct D {
 // 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]

Modified: cfe/trunk/test/Layout/ms-x86-empty-virtual-base.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Layout/ms-x86-empty-virtual-base.cpp?rev=245514&r1=245513&r2=245514&view=diff
==============================================================================
--- cfe/trunk/test/Layout/ms-x86-empty-virtual-base.cpp (original)
+++ cfe/trunk/test/Layout/ms-x86-empty-virtual-base.cpp Wed Aug 19 17:42:36 2015
@@ -53,8 +53,6 @@ struct B : virtual B0 {
 // 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 @@ struct B : virtual B0 {
 // 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

Modified: cfe/trunk/test/Layout/ms-x86-pack-and-align.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Layout/ms-x86-pack-and-align.cpp?rev=245514&r1=245513&r2=245514&view=diff
==============================================================================
--- cfe/trunk/test/Layout/ms-x86-pack-and-align.cpp (original)
+++ cfe/trunk/test/Layout/ms-x86-pack-and-align.cpp Wed Aug 19 17:42:36 2015
@@ -40,8 +40,6 @@ struct X {
 // 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 @@ struct X {
 // 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 @@ struct YA {
 };
 // 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 @@ struct YB {
 // 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 @@ struct YC {
 };
 // 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 @@ struct YD {
 // 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 @@ struct YE {
 };
 // 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 @@ struct YF {
 // 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 @@ struct RE {
 
 // 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 @@ struct RE {
 // 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 @@ struct RE {
 // 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 @@ struct RE {
 // 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 @@ struct RE {
 // 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 @@ struct PC {
 // 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 @@ struct PC {
 // 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 @@ struct PE {
 // 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 @@ struct PE {
 // 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 @@ struct QD {
 // 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]
 

Added: cfe/trunk/test/Layout/ms_struct-bitfields.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Layout/ms_struct-bitfields.c?rev=245514&view=auto
==============================================================================
--- cfe/trunk/test/Layout/ms_struct-bitfields.c (added)
+++ cfe/trunk/test/Layout/ms_struct-bitfields.c Wed Aug 19 17:42:36 2015
@@ -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]
+

Modified: cfe/trunk/test/Sema/ms_bitfield_layout.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/ms_bitfield_layout.c?rev=245514&r1=245513&r2=245514&view=diff
==============================================================================
--- cfe/trunk/test/Sema/ms_bitfield_layout.c (original)
+++ cfe/trunk/test/Sema/ms_bitfield_layout.c Wed Aug 19 17:42:36 2015
@@ -13,10 +13,16 @@ typedef struct A {
 	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 @@ typedef struct B {
 	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 @@ typedef struct C {
 	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 @@ typedef struct D {
 	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 @@ typedef union E {
 	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 @@ typedef struct F {
 	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 @@ typedef union G {
 	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 @@ typedef struct H {
 	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 @@ typedef struct A1 {
 	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 @@ typedef struct B1 {
 	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 @@ typedef struct C1 {
 	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 @@ typedef struct D1 {
 	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 @@ typedef union E1 {
 	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 @@ typedef struct F1 {
 	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 @@ typedef union G1 {
 	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 @@ typedef struct H1 {
 	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)
 

Modified: cfe/trunk/test/Sema/ms_class_layout.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/ms_class_layout.cpp?rev=245514&r1=245513&r2=245514&view=diff
==============================================================================
--- cfe/trunk/test/Sema/ms_class_layout.cpp (original)
+++ cfe/trunk/test/Sema/ms_class_layout.cpp Wed Aug 19 17:42:36 2015
@@ -236,11 +236,7 @@ int main() {
 // 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 @@ int main() {
 // 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
 




More information about the cfe-commits mailing list