Index: include/clang/AST/RecordLayout.h
===================================================================
--- include/clang/AST/RecordLayout.h	(revision 139691)
+++ include/clang/AST/RecordLayout.h	(working copy)
@@ -63,6 +63,9 @@
     /// any empty subobjects.
     CharUnits SizeOfLargestEmptySubobject;
     
+    /// VBPtrOffset - Virtual base table offset.
+    CharUnits VBPtrOffset;
+    
     /// PrimaryBase - The primary base info for this record.
     llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> PrimaryBase;
     
@@ -89,7 +92,8 @@
   // Constructor for C++ records.
   typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy;
   ASTRecordLayout(const ASTContext &Ctx,
-                  CharUnits size, CharUnits alignment, CharUnits datasize,
+                  CharUnits size, CharUnits alignment, CharUnits vbptroffset,
+                  CharUnits datasize,
                   const uint64_t *fieldoffsets, unsigned fieldcount,
                   CharUnits nonvirtualsize, CharUnits nonvirtualalign,
                   CharUnits SizeOfLargestEmptySubobject,
@@ -199,6 +203,10 @@
     assert(CXXInfo && "Record layout does not have C++ specific info!");
     return CXXInfo->SizeOfLargestEmptySubobject;
   }
+
+  CharUnits getVBPtrOffset() const {
+    return CXXInfo->VBPtrOffset;
+  }
 };
 
 }  // end namespace clang
Index: lib/AST/RecordLayout.cpp
===================================================================
--- lib/AST/RecordLayout.cpp	(revision 139691)
+++ lib/AST/RecordLayout.cpp	(working copy)
@@ -13,6 +13,7 @@
 
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/RecordLayout.h"
+#include "clang/Basic/TargetInfo.h"
 
 using namespace clang;
 
@@ -42,7 +43,7 @@
 // Constructor for C++ records.
 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
                                  CharUnits size, CharUnits alignment,
-                                 CharUnits datasize,
+                                 CharUnits vbptroffset, CharUnits datasize,
                                  const uint64_t *fieldoffsets,
                                  unsigned fieldcount,
                                  CharUnits nonvirtualsize,
@@ -67,15 +68,20 @@
   CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
   CXXInfo->BaseOffsets = BaseOffsets;
   CXXInfo->VBaseOffsets = VBaseOffsets;
+  CXXInfo->VBPtrOffset = vbptroffset;
 
 #ifndef NDEBUG
     if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
-      if (isPrimaryBaseVirtual())
+      if (isPrimaryBaseVirtual()) {
+        // Microsoft ABI doesn't have primary virtual base
+        if (Ctx.getTargetInfo().getCXXABI() != CXXABI_Microsoft) {
         assert(getVBaseClassOffset(PrimaryBase).isZero() &&
                "Primary virtual base must be at offset 0!");
-      else
+        }
+      } else {
         assert(getBaseClassOffsetInBits(PrimaryBase) == 0 &&
                "Primary base must be at offset 0!");
     }
+    }
 #endif        
 }
Index: lib/AST/RecordLayoutBuilder.cpp
===================================================================
--- lib/AST/RecordLayoutBuilder.cpp	(revision 139691)
+++ lib/AST/RecordLayoutBuilder.cpp	(working copy)
@@ -592,6 +592,13 @@
   /// out is virtual.
   bool PrimaryBaseIsVirtual;
 
+  /// HasVirtualBasePointer - Flag indicates that class has virtual base table.
+  /// This flag needs only for build MS layout.
+  bool IsVBPtrPersist;
+
+  /// VBPtrOffset - Virtual base table offset. Only for MS layout.
+  CharUnits VBPtrOffset;
+
   typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
 
   /// Bases - base classes and their offsets in the record.
@@ -622,7 +629,8 @@
       DataSize(0), NonVirtualSize(CharUnits::Zero()), 
       NonVirtualAlignment(CharUnits::One()), 
       ZeroLengthBitfield(0), PrimaryBase(0), 
-      PrimaryBaseIsVirtual(false), FirstNearlyEmptyVBase(0) { }
+      PrimaryBaseIsVirtual(false), FirstNearlyEmptyVBase(0),
+      IsVBPtrPersist(false), VBPtrOffset(CharUnits::fromQuantity(-1)){ }
 
   void Layout(const RecordDecl *D);
   void Layout(const CXXRecordDecl *D);
@@ -633,6 +641,8 @@
   void LayoutWideBitField(uint64_t FieldSize, uint64_t TypeSize,
                           bool FieldPacked, const FieldDecl *D);
   void LayoutBitField(const FieldDecl *D);
+  void MSLayoutVirtualBases(const CXXRecordDecl *RD);
+  void MSLayout(const CXXRecordDecl *RD);
 
   /// BaseSubobjectInfoAllocator - Allocator for BaseSubobjectInfo objects.
   llvm::SpecificBumpPtrAllocator<BaseSubobjectInfo> BaseSubobjectInfoAllocator;
@@ -663,7 +673,7 @@
 
   void SelectPrimaryVBase(const CXXRecordDecl *RD);
 
-  virtual CharUnits GetVirtualPointersSize(const CXXRecordDecl *RD) const;
+  CharUnits GetVirtualPointersSize(const CXXRecordDecl *RD) const;
 
   /// LayoutNonVirtualBases - Determines the primary base class (if any) and
   /// lays it out. Will then proceed to lay out all non-virtual base clasess.
@@ -723,12 +733,20 @@
   void setDataSize(uint64_t NewSize) { DataSize = NewSize; }
 
 
+  bool HasNewVirtualFunction(const CXXRecordDecl *RD) const;
+
+  /// Add vbptr or vfptr to layout.
+  void AddVPointer();
+
   RecordLayoutBuilder(const RecordLayoutBuilder&);   // DO NOT IMPLEMENT
   void operator=(const RecordLayoutBuilder&); // DO NOT IMPLEMENT
 public:
   static const CXXMethodDecl *ComputeKeyFunction(const CXXRecordDecl *RD);
 
   virtual ~RecordLayoutBuilder() { }
+
+  bool HasVirtualBasePointer() const { return IsVBPtrPersist; }
+  CharUnits GetVBPtrOffset() const { return VBPtrOffset; }
 };
 } // end anonymous namespace
 
@@ -1046,6 +1064,39 @@
   }
 }
 
+void RecordLayoutBuilder::AddVPointer() {
+  CharUnits PtrWidth = 
+    Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
+  setSize(getSize() + PtrWidth);
+  setDataSize(getSize());
+  CharUnits UnpackedBaseAlign = 
+    Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerAlign(0));
+  CharUnits BaseAlign = (Packed) ? CharUnits::One() : UnpackedBaseAlign;
+
+  // The maximum field alignment overrides base align.
+  if (!MaxFieldAlignment.isZero()) {
+    BaseAlign = std::min(BaseAlign, MaxFieldAlignment);
+    UnpackedBaseAlign = std::min(UnpackedBaseAlign, MaxFieldAlignment);
+  }
+
+  // Update the alignment.
+  UpdateAlignment(BaseAlign, UnpackedBaseAlign);
+}
+
+bool 
+RecordLayoutBuilder::HasNewVirtualFunction(const CXXRecordDecl *RD) const {
+  for (CXXRecordDecl::method_iterator method = RD->method_begin();
+       method != RD->method_end();
+       ++method) {
+    if (method->isVirtual() &&
+      !method->size_overridden_methods()) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
 void
 RecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD,
                                         const CXXRecordDecl *MostDerivedClass) {
@@ -1184,6 +1235,11 @@
 }
 
 void RecordLayoutBuilder::Layout(const CXXRecordDecl *RD) {
+  if (Context.getTargetInfo().getCXXABI() == CXXABI_Microsoft) {
+    MSLayout(RD);
+    return ;
+  }
+
   InitializeLayout(RD);
 
   // Lay out the vtable and the non-virtual bases.
@@ -1674,6 +1730,100 @@
   UpdateAlignment(FieldAlign, UnpackedFieldAlign);
 }
 
+void RecordLayoutBuilder::MSLayoutVirtualBases(const CXXRecordDecl *RD) {
+  for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
+       E = RD->vbases_end(); I != E; ++I) {
+
+    const CXXRecordDecl* BaseDecl = I->getType()->getAsCXXRecordDecl();
+    const BaseSubobjectInfo* BaseInfo = VirtualBaseInfo.lookup(BaseDecl);
+
+    assert(BaseInfo && "Did not find virtual base info!");
+    
+    LayoutVirtualBase(BaseInfo);
+  }
+}
+
+// r4start
+// I don`t think that this approach is a good.
+static bool AllBasesVirtual(const CXXRecordDecl* RD) {
+  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 RecordLayoutBuilder::MSLayout(const CXXRecordDecl *RD) {
+  InitializeLayout(RD);
+
+  if (AllBasesVirtual(RD) &&
+      RD->getNumBases()) {
+    // If all bases are virtual and
+    // in class declare new virtual function 
+    // in this case MSVS build vfptr.
+    if (HasNewVirtualFunction(RD)) {
+      AddVPointer();
+    }
+
+    VBPtrOffset = getSize();
+    AddVPointer();
+    IsVBPtrPersist = true;
+
+    ComputeBaseSubobjectInfo(RD);
+  } else {
+    LayoutNonVirtualBases(RD);
+  }
+
+  if (RD->getNumVBases() &&
+      !IsVBPtrPersist) {
+    // Add vbptr.
+    VBPtrOffset = getSize();
+    AddVPointer();
+    IsVBPtrPersist = true;
+  }
+
+  LayoutFields(RD);
+
+  NonVirtualSize = Context.toCharUnitsFromBits(
+    llvm::RoundUpToAlignment(getSizeInBits(), 
+    Context.getTargetInfo().getCharAlign()));
+  NonVirtualAlignment = Alignment;
+
+  // Lay out the virtual bases and add the primary virtual base offsets.
+  MSLayoutVirtualBases(RD);
+
+  VisitedVirtualBases.clear();
+
+  // Finally, round the size of the total struct up to the alignment of the
+  // struct itself.
+  FinishLayout(RD);
+
+#ifndef NDEBUG
+  // Check that we have base offsets for all bases.
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+    E = RD->bases_end(); I != E; ++I) {
+      if (I->isVirtual())
+        continue;
+
+      const CXXRecordDecl *BaseDecl =
+        cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+      assert(Bases.count(BaseDecl) && "Did not find base offset!");
+  }
+
+  // And all virtual bases.
+  for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
+    E = RD->vbases_end(); I != E; ++I) {
+      const CXXRecordDecl *BaseDecl =
+        cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+      assert(VBases.count(BaseDecl) && "Did not find base offset!");
+  }
+#endif
+}
+
 void RecordLayoutBuilder::FinishLayout(const NamedDecl *D) {
   // In C++, records cannot be of size 0.
   if (Context.getLangOptions().CPlusPlus && getSizeInBits() == 0) {
@@ -1883,19 +2033,22 @@
     EmptySubobjectMap EmptySubobjects(*this, RD);
 
     // When compiling for Microsoft, use the special MS builder.
-    llvm::OwningPtr<RecordLayoutBuilder> Builder;
+    /*llvm::OwningPtr<RecordLayoutBuilder> Builder;
     switch (Target->getCXXABI()) {
     default:
       Builder.reset(new RecordLayoutBuilder(*this, &EmptySubobjects));
       break;
     case CXXABI_Microsoft:
       Builder.reset(new MSRecordLayoutBuilder(*this, &EmptySubobjects));
-    }
+    }*/
+
+    RecordLayoutBuilder Builder(*this, &EmptySubobjects);
+
     // Recover resources if we crash before exiting this method.
-    llvm::CrashRecoveryContextCleanupRegistrar<RecordLayoutBuilder>
-      RecordBuilderCleanup(Builder.get());
+    /*llvm::CrashRecoveryContextCleanupRegistrar<RecordLayoutBuilder>
+      RecordBuilderCleanup(Builder.get());*/
     
-    Builder->Layout(RD);
+    Builder.Layout(RD);
 
     // FIXME: This is not always correct. See the part about bitfields at
     // http://www.codesourcery.com/public/cxx-abi/abi.html#POD for more info.
@@ -1904,22 +2057,23 @@
 
     // FIXME: This should be done in FinalizeLayout.
     CharUnits DataSize =
-      IsPODForThePurposeOfLayout ? Builder->getSize() : Builder->getDataSize();
+      IsPODForThePurposeOfLayout ? Builder.getSize() : Builder.getDataSize();
     CharUnits NonVirtualSize = 
-      IsPODForThePurposeOfLayout ? DataSize : Builder->NonVirtualSize;
+      IsPODForThePurposeOfLayout ? DataSize : Builder.NonVirtualSize;
 
     NewEntry =
-      new (*this) ASTRecordLayout(*this, Builder->getSize(), 
-                                  Builder->Alignment,
+      new (*this) ASTRecordLayout(*this, Builder.getSize(), 
+                                  Builder.Alignment,
+                                  Builder.GetVBPtrOffset(),
                                   DataSize, 
-                                  Builder->FieldOffsets.data(),
-                                  Builder->FieldOffsets.size(),
+                                  Builder.FieldOffsets.data(),
+                                  Builder.FieldOffsets.size(),
                                   NonVirtualSize,
-                                  Builder->NonVirtualAlignment,
+                                  Builder.NonVirtualAlignment,
                                   EmptySubobjects.SizeOfLargestEmptySubobject,
-                                  Builder->PrimaryBase,
-                                  Builder->PrimaryBaseIsVirtual,
-                                  Builder->Bases, Builder->VBases);
+                                  Builder.PrimaryBase,
+                                  Builder.PrimaryBaseIsVirtual,
+                                  Builder.Bases, Builder.VBases);
   } else {
     RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0);
     Builder.Layout(D);
@@ -2020,13 +2174,24 @@
   IndentLevel++;
 
   const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
+  bool HasVbptr = Layout.getVBPtrOffset() != CharUnits::fromQuantity(-1);
 
   // Vtable pointer.
   if (RD->isDynamicClass() && !PrimaryBase) {
     PrintOffset(OS, Offset, IndentLevel);
     OS << '(' << RD << " vtable pointer)\n";
   }
+  
+  if (HasVbptr && !PrimaryBase) {
+    PrintOffset(OS, Offset + Layout.getVBPtrOffset(), IndentLevel);
+    OS << '(' << RD << " vbtable pointer)\n";
+
+    // one vbtable per class
+    HasVbptr = false;
+  }
   // Dump (non-virtual) bases
+  CharUnits BaseOffset = CharUnits::Zero();
+  const CXXRecordDecl *Base = 0;
   for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
          E = RD->bases_end(); I != E; ++I) {
     assert(!I->getType()->isDependentType() &&
@@ -2034,15 +2199,22 @@
     if (I->isVirtual())
       continue;
 
-    const CXXRecordDecl *Base =
+    BaseOffset = CharUnits::Zero();
+
+    Base =
       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
 
-    CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base);
+    BaseOffset = Offset + Layout.getBaseClassOffset(Base);
 
     DumpCXXRecordLayout(OS, Base, C, BaseOffset, IndentLevel,
                         Base == PrimaryBase ? "(primary base)" : "(base)",
                         /*IncludeVirtualBases=*/false);
   }
+  // vbptr
+  if (HasVbptr) {
+    PrintOffset(OS, Offset + Layout.getVBPtrOffset(), IndentLevel);
+    OS << '(' << RD << " vbtable pointer)\n";
+  }
 
   // Dump fields.
   uint64_t FieldNo = 0;
