Addressing first round of feedback.

Hi rnk, rsmith,

http://llvm-reviews.chandlerc.com/D1026

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D1026?vs=2535&id=2536#toc

Files:
  include/clang/AST/ASTContext.h
  lib/AST/CMakeLists.txt
  lib/AST/MicrosoftRecordLayoutBuilder.cpp
  lib/AST/RecordLayoutBuilder.cpp
  lib/Makefile
  test/Driver/Inputs/B_opt_tree/dir1/i386-unknown-linux-ld
  test/Driver/Inputs/B_opt_tree/dir1/ld
  test/Driver/Inputs/B_opt_tree/dir2/ld
  test/Driver/Inputs/B_opt_tree/dir3/prefix-ld
  test/Driver/Inputs/hexagon_tree/gnu/bin/hexagon-as
  test/Driver/Inputs/hexagon_tree/gnu/bin/hexagon-gcc
  test/Driver/Inputs/hexagon_tree/gnu/bin/hexagon-ld
  test/Driver/Inputs/prefixed_tools_tree/x86_64--linux-as
  test/Driver/Inputs/prefixed_tools_tree/x86_64--linux-ld
  test/Rewriter/rewrite-nested-property-in-blocks.mm
  test/Sema/ms_bitfield_layout.c
  test/TestRunner.sh
  test/make_test_dirs.pl
  tools/clang-format/clang-format-diff.py
  tools/clang-format/git-clang-format
  tools/diag-build/diag-build.sh
  tools/scan-build/c++-analyzer
  tools/scan-build/ccc-analyzer
  tools/scan-build/scan-build
  tools/scan-build/set-xcode-analyzer
  tools/scan-view/scan-view
  utils/ABITest/ABITestGen.py
  utils/ABITest/build-and-summarize-all.sh
  utils/ABITest/build-and-summarize.sh
  utils/ABITest/build.sh
  utils/ABITest/summarize.sh
  utils/CIndex/completion_logger_server.py
  utils/CaptureCmd
  utils/CmpDriver
  utils/FindSpecRefs
  utils/FuzzTest
  utils/TestUtils/deep-stack.py
  utils/TestUtils/pch-test.pl
  utils/VtableTest/check-zti
  utils/VtableTest/check-ztt
  utils/VtableTest/check-zvt
  utils/analyzer/CmpRuns.py
  utils/analyzer/SATestAdd.py
  utils/analyzer/SATestBuild.py
  utils/analyzer/reducer.pl
  utils/analyzer/ubiviz
  utils/analyzer/update_plist_test.pl
  utils/find-unused-diagnostics.sh
  utils/token-delta.py
  www/builtins.py
  www/make_cxx_dr_status
Index: include/clang/AST/ASTContext.h
===================================================================
--- include/clang/AST/ASTContext.h
+++ include/clang/AST/ASTContext.h
@@ -1618,6 +1618,7 @@
   /// record (struct/union/class) \p D, which indicates its size and field
   /// position information.
   const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D) const;
+  const ASTRecordLayout *BuildMicrosoftASTRecordLayout(const RecordDecl *D) const;
 
   /// \brief Get or compute information about the layout of the specified
   /// Objective-C interface.
Index: lib/AST/CMakeLists.txt
===================================================================
--- lib/AST/CMakeLists.txt
+++ lib/AST/CMakeLists.txt
@@ -39,6 +39,7 @@
   Mangle.cpp
   MicrosoftCXXABI.cpp
   MicrosoftMangle.cpp
+  MicrosoftRecordLayoutBuilder.cpp
   NestedNameSpecifier.cpp
   NSAPI.cpp
   ParentMap.cpp
Index: lib/AST/MicrosoftRecordLayoutBuilder.cpp
===================================================================
--- /dev/null
+++ lib/AST/MicrosoftRecordLayoutBuilder.cpp
@@ -0,0 +1,300 @@
+//=== MicrosoftRecordLayoutBuilder.cpp - Microsoft record layout helpers ---==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Expr.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Sema/SemaDiagnostic.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/Support/CrashRecoveryContext.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/MathExtras.h"
+
+using namespace clang;
+
+namespace {
+struct MicrosoftRecordLayoutBuilder {
+  const ASTContext &Context;
+
+  MicrosoftRecordLayoutBuilder(const ASTContext &Context)
+    : Context(Context) { }
+
+  MicrosoftRecordLayoutBuilder(
+      const MicrosoftRecordLayoutBuilder &) LLVM_DELETED_FUNCTION;
+  void operator=(const MicrosoftRecordLayoutBuilder &) LLVM_DELETED_FUNCTION;
+
+  void Layout(const RecordDecl *RD);
+  void InitializeLayout(const RecordDecl *RD);
+  void FinalizeLayout(const RecordDecl *RD);
+
+  void LayoutField(const FieldDecl *FD);
+  void LayoutBitField(const FieldDecl *FD);
+  void LayoutZeroWidthBitField(const FieldDecl *FD);
+
+  CharUnits getSize() const { return Size; }
+  void setSize(CharUnits NewSize) { Size = NewSize; }
+
+  void UpdateAlignment(CharUnits NewAlignment);
+  CharUnits getAlignment() const { return Alignment; }
+
+  const uint64_t* getFieldOffsets() const { return FieldOffsets.data(); }
+  size_t getNumFieldOffsets() const { return FieldOffsets.size(); }
+
+  /// \brief Gets the size and alignment taking attributes into account.
+  std::pair<CharUnits, CharUnits> getAdjustedFieldInfo(
+      const FieldDecl *FD) const;
+
+  void PlaceFieldAtZero() {
+    FieldOffsets.push_back(0);
+  }
+  void PlaceFieldAtOffset(CharUnits FieldOffset) {
+    FieldOffsets.push_back(Context.toBits(FieldOffset));
+  }
+  void PlaceFieldAtBitOffset(uint64_t FieldOffset) {
+    FieldOffsets.push_back(FieldOffset);
+  }
+
+  void WarnIgnoredBitfieldAndAlignment();
+  void WarnUnionedBitfieldAndAlignment();
+  void ErrorBitfieldIsTooWide();
+
+private:
+  // ------ Output Values ------
+  /// \brief The size of the record being laid out.
+  CharUnits Size;
+  /// \brief The current alignment of the record layout.
+  CharUnits Alignment;
+  /// \brief The collection of field offsets.
+  SmallVector<uint64_t, 16> FieldOffsets;
+
+  // ------ Layout Properties ------
+  bool IsUnion;
+  /// \brief The maximum allowed field alignment. This is set by #pragma pack.
+  CharUnits MaxFieldAlignment;
+
+  // ------ Intermediate state ------
+  // Bit-Field intermediate state
+  /// \brief True if the last field layed out was a bitfield and was not 0
+  /// width.
+  bool LastFieldIsNonZeroWidthBitfield;
+  /// \brief The size of the allocation of the currently active bitfield.
+  /// This value isn't meaningful unless LastFieldIsNonZeroWidthBitfield
+  /// is true.
+  CharUnits CurrentBitfieldSize;
+  /// \brief The number of remaining bits in our last bitfield allocation.
+  /// This value isn't meaningful unless LastFieldIsNonZeroWidthBitfield is
+  /// true.
+  unsigned RemainingBitsInField;
+};
+} // end anonymous namespace
+
+std::pair<CharUnits, CharUnits>
+MicrosoftRecordLayoutBuilder::getAdjustedFieldInfo(const FieldDecl *FD) const {
+  std::pair<CharUnits, CharUnits> FieldInfo;
+  if (FD->getType()->isIncompleteArrayType()) {
+    // This is a flexible array member; we can't directly
+    // query getTypeInfo about these, so we figure it out here.
+    // Flexible array members don't have any size, but they
+    // have to be aligned appropriately for their element type.
+    FieldInfo.first = CharUnits::Zero();
+    const ArrayType* ATy = Context.getAsArrayType(FD->getType());
+    FieldInfo.second = Context.getTypeAlignInChars(ATy->getElementType());
+  } else
+    FieldInfo = Context.getTypeInfoInChars(FD->getType());
+
+  // Respect alignment attributes.
+  FieldInfo.second = std::max(FieldInfo.second, 
+    Context.toCharUnitsFromBits(FD->getMaxAlignment()));
+  // Respect packed attribute.
+  if (FD->hasAttr<PackedAttr>())
+    FieldInfo.second = CharUnits::One();
+  // Respect pack pragma.
+  else if (!MaxFieldAlignment.isZero())
+      FieldInfo.second = std::min(FieldInfo.second, MaxFieldAlignment);
+  return FieldInfo;
+}
+
+void MicrosoftRecordLayoutBuilder::UpdateAlignment(CharUnits NewAlignment) {
+  if (NewAlignment > Alignment) {
+    assert(llvm::isPowerOf2_32(NewAlignment.getQuantity() &&
+           "Alignment not a power of 2"));
+    Alignment = NewAlignment;
+  }
+}
+
+void MicrosoftRecordLayoutBuilder::InitializeLayout(const RecordDecl *RD) {
+  // Read layout properties
+  IsUnion = RD->isUnion();
+
+  // Initalize Output State.
+  Alignment = CharUnits::One();
+  Size = CharUnits::Zero();
+  FieldOffsets.erase(FieldOffsets.begin(), FieldOffsets.end());
+
+  // Clear our bit-fild related temporaries.
+  LastFieldIsNonZeroWidthBitfield = false;
+
+  // Honor the default struct packing maximum alignment flag.
+  MaxFieldAlignment = CharUnits::Zero();
+  if (unsigned DefaultMaxFieldAlignment = Context.getLangOpts().PackStruct)
+    MaxFieldAlignment = CharUnits::fromQuantity(DefaultMaxFieldAlignment);
+  if (const MaxFieldAlignmentAttr *MFAA = RD->getAttr<MaxFieldAlignmentAttr>())
+    MaxFieldAlignment = Context.toCharUnitsFromBits(MFAA->getAlignment());
+  // Packed attribute forces max field alignment to be 1.
+  if (RD->hasAttr<PackedAttr>())
+    MaxFieldAlignment = CharUnits::One();
+
+  // Set the alignment to the maximum alignment set by any attribute.
+  if (unsigned MaxAlign = RD->getMaxAlignment())
+    UpdateAlignment(Context.toCharUnitsFromBits(MaxAlign));
+}
+
+void MicrosoftRecordLayoutBuilder::FinalizeLayout(const RecordDecl *RD) {
+  Size = Size.RoundUpToAlignment(Alignment);
+}
+
+void MicrosoftRecordLayoutBuilder::Layout(const RecordDecl *RD) {
+  InitializeLayout(RD);
+  for (RecordDecl::field_iterator Field = RD->field_begin(),
+       FieldEnd = RD->field_end(); Field != FieldEnd; ++Field)
+      LayoutField(*Field);
+  FinalizeLayout(RD);
+}
+
+void MicrosoftRecordLayoutBuilder::LayoutField(const FieldDecl *FD) {
+  if (FD->isBitField()) {
+    LayoutBitField(FD);
+    return;
+  }
+
+  std::pair<CharUnits, CharUnits> FieldInfo = getAdjustedFieldInfo(FD);
+  CharUnits FieldSize = FieldInfo.first;
+  CharUnits FieldAlign = FieldInfo.second;
+
+  LastFieldIsNonZeroWidthBitfield = false;
+  UpdateAlignment(FieldAlign);
+  if (IsUnion) {
+    PlaceFieldAtZero();
+    setSize(std::max(getSize(), FieldSize));
+  } else {
+    // Round up the current record size to the field's alignment boundary.
+    CharUnits FieldOffset = getSize().RoundUpToAlignment(FieldAlign);
+    PlaceFieldAtOffset(FieldOffset);
+    setSize(FieldOffset + FieldSize);
+  }
+}
+
+void MicrosoftRecordLayoutBuilder::LayoutBitField(const FieldDecl *FD) {
+  unsigned Width = FD->getBitWidthValue(Context);
+  if (Width == 0) {
+    LayoutZeroWidthBitField(FD);
+    return;
+  }
+
+  std::pair<CharUnits, CharUnits> FieldInfo = getAdjustedFieldInfo(FD);
+  CharUnits FieldSize = FieldInfo.first;
+  CharUnits FieldAlign = FieldInfo.second;
+
+  // Check for bitfields that are wider than their storage type.
+  if (Width > Context.toBits(FieldSize))
+    ErrorBitfieldIsTooWide();
+
+  // Check to see if this bitfield fits into an existing allocation.
+  if (!IsUnion &&
+      LastFieldIsNonZeroWidthBitfield &&
+      CurrentBitfieldSize == FieldSize &&
+      Width <= RemainingBitsInField) {
+    PlaceFieldAtBitOffset(Context.toBits(getSize()) - RemainingBitsInField);
+    RemainingBitsInField -= Width;
+    return;
+  }
+
+  LastFieldIsNonZeroWidthBitfield = true;
+  CurrentBitfieldSize = FieldSize;
+  if (IsUnion) {
+    PlaceFieldAtZero();
+    setSize(std::max(getSize(), FieldSize));
+    if (FieldAlign > Alignment)
+      WarnUnionedBitfieldAndAlignment();
+  } else {
+    // Allocate a new block of memory and place the bitfield in it.
+    CharUnits FieldOffset = getSize().RoundUpToAlignment(FieldAlign);
+    PlaceFieldAtOffset(FieldOffset);
+    setSize(FieldOffset + FieldSize);
+    UpdateAlignment(FieldAlign);
+    RemainingBitsInField = Context.toBits(FieldSize) - Width;
+  }
+}
+
+void
+MicrosoftRecordLayoutBuilder::LayoutZeroWidthBitField(const FieldDecl *FD) {
+  // Zero-width bitfields are ignored unless they follow a non-zero-width
+  // bitfield.
+  std::pair<CharUnits, CharUnits> FieldInfo = getAdjustedFieldInfo(FD);
+  CharUnits FieldSize = FieldInfo.first;
+  CharUnits FieldAlign = FieldInfo.second;
+
+  if (!LastFieldIsNonZeroWidthBitfield) {
+    PlaceFieldAtOffset(IsUnion ? CharUnits::Zero() : Size);
+    if (FieldAlign > Alignment)
+      WarnIgnoredBitfieldAndAlignment();
+    return;
+  }
+
+  LastFieldIsNonZeroWidthBitfield = false;
+  if (IsUnion) {
+    PlaceFieldAtZero();
+    setSize(std::max(getSize(), FieldSize));
+    if (FieldAlign > Alignment)
+      WarnUnionedBitfieldAndAlignment();
+  } else {
+    // Round up the current record size to the field's alignment boundary.
+    CharUnits FieldOffset = getSize().RoundUpToAlignment(FieldAlign);
+    PlaceFieldAtOffset(FieldOffset);
+    setSize(FieldOffset);
+    UpdateAlignment(FieldAlign);
+  }
+}
+
+void MicrosoftRecordLayoutBuilder::WarnIgnoredBitfieldAndAlignment() {
+}
+
+void MicrosoftRecordLayoutBuilder::WarnUnionedBitfieldAndAlignment() {
+}
+
+void MicrosoftRecordLayoutBuilder::ErrorBitfieldIsTooWide() {
+  assert(false && "TODO(whunt): throw the correct error here");
+}
+
+/// \brief Get or compute information about the layout of the specified record
+/// (struct/union/class), which indicates its size and field position
+/// information.
+const ASTRecordLayout *
+ASTContext::BuildMicrosoftASTRecordLayout(const RecordDecl *D) const {
+  if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
+    assert(false && "we don't yet support C++ struct layout");
+    return 0;
+  } else {
+    MicrosoftRecordLayoutBuilder Builder(*this);
+    Builder.Layout(D);
+    return new (*this) ASTRecordLayout(
+        *this,
+        Builder.getSize(),
+        Builder.getAlignment(),
+        Builder.getSize(),
+        Builder.getFieldOffsets(),
+        Builder.getNumFieldOffsets());
+  }
+}
Index: lib/AST/RecordLayoutBuilder.cpp
===================================================================
--- lib/AST/RecordLayoutBuilder.cpp
+++ lib/AST/RecordLayoutBuilder.cpp
@@ -2524,15 +2524,21 @@
                                   Builder.PrimaryBaseIsVirtual,
                                   Builder.Bases, Builder.VBases);
   } else {
-    RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0);
-    Builder.Layout(D);
-
-    NewEntry =
-      new (*this) ASTRecordLayout(*this, Builder.getSize(), 
-                                  Builder.Alignment,
-                                  Builder.getSize(),
-                                  Builder.FieldOffsets.data(),
-                                  Builder.FieldOffsets.size());
+    if (getTargetInfo().getPointerWidth(0) == 32 &&
+        getTargetInfo().getCXXABI().isMicrosoft() &&
+        !D->isMsStruct(*this))
+      NewEntry = BuildMicrosoftASTRecordLayout(D);
+    else {
+      RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0);
+      Builder.Layout(D);
+
+      NewEntry =
+        new (*this) ASTRecordLayout(*this, Builder.getSize(), 
+                                    Builder.Alignment,
+                                    Builder.getSize(),
+                                    Builder.FieldOffsets.data(),
+                                    Builder.FieldOffsets.size());
+    }
   }
 
   ASTRecordLayouts[D] = NewEntry;
Index: test/Sema/ms_bitfield_layout.c
===================================================================
--- /dev/null
+++ test/Sema/ms_bitfield_layout.c
@@ -0,0 +1,259 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -cxx-abi microsoft %s 2>&1 \
+// RUN:            | FileCheck %s
+
+typedef __SIZE_TYPE__ size_t;
+int printf(const char *fmt, ...);
+void* memset(void* ptr, int value, size_t num);
+
+typedef struct A {
+	char x;
+	int a : 22;
+	int : 0;
+	int c : 10;
+	char b : 3;
+	char d: 4;
+	short y;
+} A;
+
+// CHECK: Type: struct A
+// CHECK:   Size:128
+// CHECK:   DataSize:128
+// CHECK:   Alignment:32
+// CHECK:   FieldOffsets: [0, 32, 64, 64, 96, 99, 112]>
+
+typedef struct B {
+	char x;
+	int : 0;
+	short a : 4;
+	char y;
+} B;
+
+// CHECK: Type: struct B
+// CHECK:   Size:48
+// CHECK:   DataSize:48
+// CHECK:   Alignment:16
+// CHECK:   FieldOffsets: [0, 8, 16, 32]>
+
+typedef struct C {
+	char x;
+	short a : 4;
+	int : 0;
+	char y;
+} C;
+
+// CHECK: Type: struct C
+// CHECK:   Size:64
+// CHECK:   DataSize:64
+// CHECK:   Alignment:32
+// CHECK:   FieldOffsets: [0, 16, 32, 32]>
+
+typedef struct D {
+	char x;
+	short : 0;
+	int : 0;
+	char y;
+} D;
+
+// CHECK: Type: struct D
+// CHECK:   Size:16
+// CHECK:   DataSize:16
+// CHECK:   Alignment:8
+// CHECK:   FieldOffsets: [0, 8, 8, 8]>
+
+typedef union E {
+	char x;
+	long long a : 3;
+	int b : 3;
+	long long : 0;
+	short y;
+} E;
+
+// CHECK: Type: union E
+// CHECK:   Size:64
+// CHECK:   DataSize:64
+// CHECK:   Alignment:16
+// CHECK:   FieldOffsets: [0, 0, 0, 0, 0]>
+
+typedef struct F {
+	char x;
+	char a : 3;
+	char b : 3;
+	char c : 3;
+	short d : 6;
+	short e : 6;
+	short f : 6;
+	short g : 11;
+	short h : 11;
+	short i : 11;
+	short y;
+} F;
+
+// CHECK: Type: struct F
+// CHECK:   Size:128
+// CHECK:   DataSize:128
+// CHECK:   Alignment:16
+// CHECK:   FieldOffsets: [0, 8, 11, 16, 32, 38, 48, 64, 80, 96, 112]>
+
+typedef union G {
+	char x;
+	int a : 3;
+	int : 0;
+	long long : 0;
+	short y;
+} G;
+
+// CHECK: Type: union G
+// CHECK:   Size:32
+// CHECK:   DataSize:32
+// CHECK:   Alignment:16
+// CHECK:   FieldOffsets: [0, 0, 0, 0, 0]>
+
+typedef struct H {
+	unsigned short a : 1;
+	unsigned char : 0;
+	unsigned long : 0;
+	unsigned short c : 1;
+} H;
+
+// CHECK: Type: struct H
+// CHECK:   Size:32
+// CHECK:   DataSize:32
+// CHECK:   Alignment:16
+// CHECK:   FieldOffsets: [0, 16, 16, 16]>
+
+#pragma pack(push, 1)
+
+typedef struct A1 {
+	char x;
+	int a : 22;
+	int : 0;
+	int c : 10;
+	char b : 3;
+	char d: 4;
+	short y;
+} A1;
+
+// CHECK: Type: struct A1
+// CHECK:   Size:96
+// CHECK:   DataSize:96
+// CHECK:   Alignment:8
+// CHECK:   FieldOffsets: [0, 8, 40, 40, 72, 75, 80]>
+
+typedef struct B1 {
+	char x;
+	int : 0;
+	short a : 4;
+	char y;
+} B1;
+
+// CHECK: Type: struct B1
+// CHECK:   Size:32
+// CHECK:   DataSize:32
+// CHECK:   Alignment:8
+// CHECK:   FieldOffsets: [0, 8, 8, 24]>
+
+typedef struct C1 {
+	char x;
+	short a : 4;
+	int : 0;
+	char y;
+} C1;
+
+// CHECK: Type: struct C1
+// CHECK:   Size:32
+// CHECK:   DataSize:32
+// CHECK:   Alignment:8
+// CHECK:   FieldOffsets: [0, 8, 24, 24]>
+
+typedef struct D1 {
+	char x;
+	short : 0;
+	int : 0;
+	char y;
+} D1;
+
+// CHECK: Type: struct D1
+// CHECK:   Size:16
+// CHECK:   DataSize:16
+// CHECK:   Alignment:8
+// CHECK:   FieldOffsets: [0, 8, 8, 8]>
+
+typedef union E1 {
+	char x;
+	long long a : 3;
+	int b : 3;
+	long long : 0;
+	short y;
+} E1;
+
+// CHECK: Type: union E1
+// CHECK:   Size:64
+// CHECK:   DataSize:64
+// CHECK:   Alignment:8
+// CHECK:   FieldOffsets: [0, 0, 0, 0, 0]>
+
+typedef struct F1 {
+	char x;
+	char a : 3;
+	char b : 3;
+	char c : 3;
+	short d : 6;
+	short e : 6;
+	short f : 6;
+	short g : 11;
+	short h : 11;
+	short i : 11;
+	short y;
+} F1;
+
+// CHECK: Type: struct F1
+// CHECK:   Size:120
+// CHECK:   DataSize:120
+// CHECK:   Alignment:8
+// CHECK:   FieldOffsets: [0, 8, 11, 16, 24, 30, 40, 56, 72, 88, 104]>
+
+typedef union G1 {
+	char x;
+	int a : 3;
+	int : 0;
+	long long : 0;
+	short y;
+} G1;
+
+// CHECK: Type: union G1
+// CHECK:   Size:32
+// CHECK:   DataSize:32
+// CHECK:   Alignment:8
+// CHECK:   FieldOffsets: [0, 0, 0, 0, 0]>
+
+typedef struct H1 {
+	unsigned long a : 1;
+	unsigned char : 0;
+	unsigned long : 0;
+	unsigned long c : 1;
+} H1;
+
+// CHECK: Type: struct H1
+// CHECK:   Size:64
+// CHECK:   DataSize:64
+// CHECK:   Alignment:8
+// CHECK:   FieldOffsets: [0, 32, 32, 32]>
+
+#pragma pack(pop)
+
+A a;
+B b;
+C c;
+D d;
+E e;
+F f;
+G g;
+H h;
+A1 a1;
+B1 b1;
+C1 c1;
+D1 d1;
+E1 e1;
+F1 f1;
+G1 g1;
+H1 h1;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to