Index: include/clang/AST/RecordLayout.h
===================================================================
--- include/clang/AST/RecordLayout.h	(revision 142340)
+++ include/clang/AST/RecordLayout.h	(working copy)
@@ -66,6 +66,9 @@
     /// VBPtrOffset - Virtual base table offset.
     CharUnits VBPtrOffset;
     
+    /// HasNewVirtualFunction - In Microsoft mode this info is very helpful.
+    bool HasNewVirtualFunction;
+    
     /// PrimaryBase - The primary base info for this record.
     llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> PrimaryBase;
     
@@ -99,6 +102,7 @@
                   CharUnits SizeOfLargestEmptySubobject,
                   const CXXRecordDecl *PrimaryBase,
                   bool IsPrimaryBaseVirtual,
+                  bool HasNewVirtualFunction,
                   const BaseOffsetsMapTy& BaseOffsets,
                   const BaseOffsetsMapTy& VBaseOffsets);
 
@@ -204,9 +208,16 @@
     return CXXInfo->SizeOfLargestEmptySubobject;
   }
 
+  /// getVBPtrOffset - Get the offset for virtual base table pointer.
   CharUnits getVBPtrOffset() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
     return CXXInfo->VBPtrOffset;
   }
+
+  bool hasNewVirtualFunction() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+    return CXXInfo->HasNewVirtualFunction;
+  }
 };
 
 }  // end namespace clang
Index: lib/AST/RecordLayout.cpp
===================================================================
--- lib/AST/RecordLayout.cpp	(revision 142340)
+++ lib/AST/RecordLayout.cpp	(working copy)
@@ -51,6 +51,7 @@
                                  CharUnits SizeOfLargestEmptySubobject,
                                  const CXXRecordDecl *PrimaryBase,
                                  bool IsPrimaryBaseVirtual,
+                                 bool HasNewVirtualFunction,
                                  const BaseOffsetsMapTy& BaseOffsets,
                                  const BaseOffsetsMapTy& VBaseOffsets)
   : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
@@ -69,6 +70,7 @@
   CXXInfo->BaseOffsets = BaseOffsets;
   CXXInfo->VBaseOffsets = VBaseOffsets;
   CXXInfo->VBPtrOffset = vbptroffset;
+  CXXInfo->HasNewVirtualFunction = HasNewVirtualFunction;
 
 #ifndef NDEBUG
     if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
Index: lib/AST/RecordLayoutBuilder.cpp
===================================================================
--- lib/AST/RecordLayoutBuilder.cpp	(revision 142340)
+++ lib/AST/RecordLayoutBuilder.cpp	(working copy)
@@ -785,6 +785,8 @@
   // indirect bases, and record all their primary virtual base classes.
   RD->getIndirectPrimaryBases(IndirectPrimaryBases);
 
+  bool HasNonVirtBases = false;
+
   // If the record has a dynamic base class, attempt to choose a primary base
   // class. It is the first (in direct base class order) non-virtual dynamic
   // base class, if one exists.
@@ -796,6 +798,7 @@
 
     const CXXRecordDecl *Base =
       cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+    HasNonVirtBases = true;
 
     if (Base->isDynamicClass()) {
       // We found it.
@@ -807,7 +810,17 @@
 
   // The Microsoft ABI doesn't have primary virtual bases.
   if (Context.getTargetInfo().getCXXABI() == CXXABI_Microsoft) {
-    assert(!PrimaryBase && "Should not get here with a primary base!");
+    if (HasNewVirtualFunction(RD)) {
+      CharUnits PtrWidth = 
+       Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
+      setSize(getSize() + PtrWidth);
+      setDataSize(getSize());
+
+      if (!HasNonVirtBases) {
+        setSize(getSize().RoundUpToAlignment(Alignment));
+        setDataSize(getSize());
+      }
+    }
     return;
   }
 
@@ -1032,15 +1045,8 @@
     // after any base classes.
     CharUnits PtrWidth = 
       Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
-    if (HasNewVirtualFunction(RD) &&
-        (!PrimaryBase || !BaseHasVFPtr(PrimaryBase))) {
-      EnsureVTablePointerAlignment();
-      setSize(getSize() + PtrWidth);
-      setDataSize(getSize());
-    }
     if (RD->getNumVBases() &&
         (!PrimaryBase || !PrimaryBase->getNumVBases())) {
-      EnsureVTablePointerAlignment();
       VBPtrOffset = getSize();
       setSize(getSize() + PtrWidth);
       setDataSize(getSize());
@@ -2074,6 +2080,7 @@
                                   EmptySubobjects.SizeOfLargestEmptySubobject,
                                   Builder->PrimaryBase,
                                   Builder->PrimaryBaseIsVirtual,
+                                  Builder->HasNewVirtualFunction(RD),
                                   Builder->Bases, Builder->VBases);
   } else {
     RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0, CharUnits::One());
Index: lib/CodeGen/CGRecordLayoutBuilder.cpp
===================================================================
--- lib/CodeGen/CGRecordLayoutBuilder.cpp	(revision 142340)
+++ lib/CodeGen/CGRecordLayoutBuilder.cpp	(working copy)
@@ -18,6 +18,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/RecordLayout.h"
+#include "clang/Basic/TargetInfo.h"
 #include "clang/Frontend/CodeGenOptions.h"
 #include "CodeGenTypes.h"
 #include "CGCXXABI.h"
@@ -184,6 +185,16 @@
   /// to data member.
   void CheckZeroInitializable(QualType T);
 
+  bool IsVBPtrPlaceAtStart(const CXXRecordDecl *RD,
+                           const ASTRecordLayout &Layout) const;
+  bool MSComputeNonVirtualBaseType(const CXXRecordDecl *RD);
+  void AddVFPtr(CharUnits Offset, CharUnits Alignment);
+  void AddVBPtr(const ASTRecordLayout &Layout);
+  void AddAlignBytes();
+  void MSLayoutNonVirtualBases(const CXXRecordDecl *RD,
+                               const ASTRecordLayout &Layout);
+  bool MSLayoutFields(const RecordDecl *D);
+
 public:
   CGRecordLayoutBuilder(CodeGenTypes &Types)
     : BaseSubobjectType(0),
@@ -197,6 +208,165 @@
 
 }
 
+bool CGRecordLayoutBuilder::IsVBPtrPlaceAtStart(const CXXRecordDecl *RD,
+                                         const ASTRecordLayout &Layout) const {
+  // If we have at least one non-virtual base class, 
+  // vbptr must be placed after primary base.
+  if (!RD->getNumBases())
+    return false;
+
+  if (Layout.getVBPtrOffset().isZero())
+    return true;
+
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    if (!I->isVirtual()) {
+      return false;
+    }
+  }
+  return true;
+}
+
+void CGRecordLayoutBuilder::AddVFPtr(CharUnits Offset, CharUnits Alignment) {
+  llvm::Type* Ty = 
+    llvm::FunctionType::get(llvm::Type::getInt32Ty(Types.getLLVMContext()),
+                            true);
+  llvm::Type* VfptrTy = Ty->getPointerTo();
+
+  AppendField(Offset, VfptrTy->getPointerTo());
+}
+
+void CGRecordLayoutBuilder::AddAlignBytes() {
+  CharUnits AlignMemberSize = 
+    NextFieldOffset.RoundUpToAlignment(Alignment) - NextFieldOffset;
+
+  if (!AlignMemberSize.isZero()) {
+    AppendBytes(AlignMemberSize);
+  }
+}
+
+void CGRecordLayoutBuilder::AddVBPtr(const ASTRecordLayout &Layout) {
+  llvm::Type *Vbptr = llvm::Type::getInt32PtrTy(Types.getLLVMContext());
+  AppendField(Layout.getVBPtrOffset(), Vbptr);
+}
+
+void
+CGRecordLayoutBuilder::MSLayoutNonVirtualBases(const CXXRecordDecl *RD,
+                                               const ASTRecordLayout &Layout) {
+  const CXXRecordDecl* PrimaryBase = Layout.getPrimaryBase();
+
+  if (RD->isDynamicClass()) {
+    if (!PrimaryBase) {
+      if (Layout.hasNewVirtualFunction())
+        AddVFPtr(CharUnits::Zero(), Layout.getAlignment());
+    } else {
+      if (!Layout.isPrimaryBaseVirtual()) {
+        LayoutNonVirtualBase(PrimaryBase, CharUnits::Zero());
+      }
+    }
+  }
+
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    const CXXRecordDecl* BaseDecl = I->getType()->getAsCXXRecordDecl();
+
+    if (BaseDecl == PrimaryBase ||
+        I->isVirtual()) {
+      continue;
+    }
+
+    LayoutNonVirtualBase(BaseDecl, Layout.getBaseClassOffset(BaseDecl));
+  }
+}
+
+bool
+CGRecordLayoutBuilder::MSLayoutFields(const RecordDecl* D) {
+  assert(!D->isUnion() && "Can't call LayoutFields on a union!");
+  assert(!Alignment.isZero() && "Did not set alignment!");
+
+  const CXXRecordDecl* RD = dyn_cast_or_null<CXXRecordDecl>(D);
+
+  const ASTRecordLayout &Layout = Types.getContext().getASTRecordLayout(D);
+  bool IsVBPtrPlaced = false;
+
+  if (RD) {
+    // FIXME: This code must be replace to MSLayoutNonVirtualBases.
+    if (IsVBPtrPlaceAtStart(RD, Layout)) {
+      if (Layout.hasNewVirtualFunction()) {
+        AddVFPtr(CharUnits::Zero(), Layout.getAlignment());
+
+        ASTContext& Ctx = Types.getContext();
+        CharUnits PtrWidth = 
+          Ctx.toCharUnitsFromBits(Ctx.getTargetInfo().getPointerWidth(0));
+
+        if (Alignment > PtrWidth &&
+            Alignment.getQuantity() > 4) {
+          AppendBytes(PtrWidth);
+        }
+      }
+
+      AddVBPtr(Layout);
+      IsVBPtrPlaced = true;
+    } else {
+      MSLayoutNonVirtualBases(RD, Layout);
+    }
+  
+    if (RD->getNumVBases() &&
+        !IsVBPtrPlaced) {
+      AddVBPtr(Layout);
+    }
+  }
+  unsigned FieldNo = 0;
+
+  for (CXXRecordDecl::field_iterator Field = D->field_begin(),
+       FieldEnd = D->field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
+    AddAlignBytes();
+    if (!LayoutField(*Field, Layout.getFieldOffset(FieldNo))) {
+      return false;
+    }
+  }
+  
+  AddAlignBytes();
+
+  if (RD) {
+    if (!MSComputeNonVirtualBaseType(RD))
+      return false;
+
+    LayoutVirtualBases(RD, Layout);
+  }
+  return true;
+}
+
+bool
+CGRecordLayoutBuilder::MSComputeNonVirtualBaseType(const CXXRecordDecl *RD) {
+  const ASTRecordLayout &Layout = Types.getContext().getASTRecordLayout(RD);
+
+  CharUnits NonVirtualSize  = Layout.getNonVirtualSize();
+  CharUnits NonVirtualAlign = Layout.getNonVirtualAlign();
+  CharUnits AlignedNonVirtualTypeSize =
+      NonVirtualSize.RoundUpToAlignment(NonVirtualAlign);
+  
+  // First check if we can use the same fields as for the complete class.
+  CharUnits RecordSize = Layout.getSize();
+  if (AlignedNonVirtualTypeSize == RecordSize)
+    return true;
+
+  // Check if we need padding.
+  CharUnits AlignedNextFieldOffset =
+    NextFieldOffset.RoundUpToAlignment(getAlignmentAsLLVMStruct());
+
+  if (AlignedNextFieldOffset > AlignedNonVirtualTypeSize) {
+    assert(!Packed && "cannot layout even as packed struct");
+    return false; // Needs packing.
+  }
+
+  BaseSubobjectType = llvm::StructType::create(Types.getLLVMContext(),
+                                               FieldTypes, "", Packed);
+  Types.addRecordTypeName(RD, BaseSubobjectType, ".base");
+
+  return true;
+}
+
 void CGRecordLayoutBuilder::Layout(const RecordDecl *D) {
   Alignment = Types.getContext().getASTRecordLayout(D).getAlignment();
   Packed = D->hasAttr<PackedAttr>();
@@ -208,7 +378,10 @@
     return;
   }
 
-  if (LayoutFields(D))
+  if (Types.getContext().getTargetInfo().getCXXABI() == CXXABI_Microsoft) {
+    if (MSLayoutFields(D))
+      return;
+  } else if (LayoutFields(D))
     return;
 
   // We weren't able to layout the struct. Try again with a packed struct
@@ -221,6 +394,9 @@
   NonVirtualBases.clear();
   VirtualBases.clear();
 
+  if (Types.getContext().getTargetInfo().getCXXABI() == CXXABI_Microsoft)
+    MSLayoutFields(D);
+  else
   LayoutFields(D);
 }
 
@@ -581,7 +757,11 @@
                                        CharUnits baseOffset) {
   ResizeLastBaseFieldIfNecessary(baseOffset);
 
+  if (Types.getContext().getTargetInfo().getCXXABI() != CXXABI_Microsoft) {
   AppendPadding(baseOffset, CharUnits::One());
+  } else {
+    AppendPadding(baseOffset, Alignment);
+  }
 
   const ASTRecordLayout &baseASTLayout
     = Types.getContext().getASTRecordLayout(base);
Index: test/Sema/ms_class_layout.cpp
===================================================================
--- test/Sema/ms_class_layout.cpp	(revision 142340)
+++ test/Sema/ms_class_layout.cpp	(working copy)
@@ -61,6 +61,12 @@
 {
 };
 
+struct I : public virtual D
+{
+  virtual ~I(){}
+  double q;
+};
+
 #pragma pack(pop)
 
 // This needs only for building layouts. 
@@ -72,6 +78,7 @@
   DerivedStruct* v;
   H* g;
   BaseStruct* u;
+  I* i;
   return 0;
 }
 
@@ -82,6 +89,8 @@
 // CHECK-NEXT: sizeof=16, dsize=16, align=8
 // CHECK-NEXT: nvsize=16, nvalign=8
 
+// CHECK: %class.D = type { i32 (...)**, [4 x i8], double }
+
 // CHECK:       0 | class B
 // CHECK-NEXT:  0 |   (B vtable pointer)
 // CHECK-NEXT:  4 |   int b_field
@@ -89,6 +98,8 @@
 // CHECK-NEXT: sizeof=8, dsize=8, align=4
 // CHECK-NEXT: nvsize=8, nvalign=4
 
+// CHECK: %class.B = type { i32 (...)**, i32 }
+
 // CHECK:       0 | class A
 // CHECK-NEXT:  0 |   class B (primary base)
 // CHECK-NEXT:  0 |     (B vtable pointer)
@@ -121,6 +132,9 @@
 // CHECK-NEXT: sizeof=80, dsize=80, align=8
 // CHECK-NEXT: nvsize=80, nvalign=8
  
+// CHECK: %class.A = type { %class.B, i32, i8, [3 x i8] }
+// CHECK: %class.C = type { %class.D, %class.B, i32*, [4 x i8], double, i32, [4 x i8], double, i32, [4 x i8], %class.A }
+ 
 // CHECK:       0 | struct BaseStruct
 // CHECK-NEXT:  0 |   double v0
 // CHECK-NEXT:  8 |   float v1
@@ -149,6 +163,8 @@
 // CHECK: sizeof=96, dsize=96, align=8
 // CHECK-NEXT: nvsize=96, nvalign=8
 
+// CHECK: %struct.BaseStruct = type { double, float, [4 x i8], %class.C }
+
 // CHECK:       0 | struct DerivedStruct
 // CHECK-NEXT:  0 |   struct BaseStruct (base)
 // CHECK-NEXT:  0 |     double v0
@@ -178,11 +194,15 @@
 // CHECK-NEXT: sizeof=104, dsize=104, align=8
 // CHECK-NEXT: nvsize=104, nvalign=8
 
+// CHECK: %struct.DerivedStruct = type { %struct.BaseStruct, i32, [4 x i8] 
+
 // CHECK:      0 | struct G
 // CHECK-NEXT: 0 |   int g_field
 // CHECK-NEXT: sizeof=4, dsize=4, align=4
 // CHECK-NEXT: nvsize=4, nvalign=4
 
+// CHECK: %struct.G = type { i32 }
+
 // FIXME: Dump should not be showing vfptr, and vbptr is in the wrong order.
 // CHECK:       0 | struct H
 // CHECK-NEXT:  0 |   (H vtable pointer)
@@ -194,3 +214,17 @@
 // CHECK-NEXT: 16 |     double a
 // CHECK-NEXT: sizeof=24, dsize=24, align=8
 // CHECK-NEXT: nvsize=24, nvalign=8
+
+// CHECK: %struct.H = type { %struct.G, i32*, %class.D }
+
+// CHECK:       0 | struct I
+// CHECK-NEXT:  0 |   (I vtable pointer)
+// CHECK-NEXT:  8 |   (I vbtable pointer)
+// CHECK-NEXT: 16 |   double q
+// CHECK-NEXT: 24 |   class D (virtual base)
+// CHECK-NEXT: 24 |     (D vtable pointer)
+// CHECK-NEXT: 32 |     double a
+// CHECK-NEXT: sizeof=40, dsize=40, align=8
+// CHECK-NEXT: nvsize=40, nvalign=8
+
+// CHECK: %struct.I = type { i32 (...)**, [4 x i8], i32*, [4 x i8], double, %class.D }
