Index: include/clang/AST/Mangle.h
===================================================================
--- include/clang/AST/Mangle.h	(revision 154277)
+++ include/clang/AST/Mangle.h	(working copy)
@@ -61,6 +61,39 @@
   SmallString<256> Buffer;
 };
 
+// r4start
+class MSMangleContextExtensions
+{
+public:
+  virtual void mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *,
+                                                  const CXXRecordDecl *,
+                                                  raw_ostream &) = 0;
+
+  virtual void mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *,
+                                                  StringRef ,
+                                                  raw_ostream &) = 0;
+
+  virtual void mangleCXXRTTITypeDescriptor(const CXXRecordDecl *,
+                                           raw_ostream &) = 0;
+
+  virtual void mangleCXXRTTIClassHierarhyDescriptor(const CXXRecordDecl *,
+                                                    raw_ostream &) = 0;
+
+  virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *,
+                                           raw_ostream &) = 0;
+
+  virtual void mangleCXXRTTIBaseClassDescriptor(const CXXRecordDecl *RD,
+                                                int64_t MemberOffset,
+                                                int64_t OffsetInVBTable,
+                                                int64_t IndexInVBTable,
+                                                int64_t Attributes,
+                                                raw_ostream &Out) = 0;
+
+  virtual void mangleCXXVBTable(const CXXRecordDecl *,
+                                const CXXRecordDecl *,
+                                raw_ostream &) = 0;
+};
+
 /// MangleContext - Context for tracking state which persists across multiple
 /// calls to the C++ name mangler.
 class MangleContext {
@@ -107,10 +140,12 @@
   virtual void mangleReferenceTemporary(const VarDecl *D,
                                         raw_ostream &) = 0;
   virtual void mangleCXXVTable(const CXXRecordDecl *RD,
+                               const CXXRecordDecl *BaseClass,
                                raw_ostream &) = 0;
   virtual void mangleCXXVTT(const CXXRecordDecl *RD,
                             raw_ostream &) = 0;
-  virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
+  virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, 
+                                   int64_t Offset,
                                    const CXXRecordDecl *Type,
                                    raw_ostream &) = 0;
   virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
@@ -134,6 +169,9 @@
   void mangleObjCMethodName(const ObjCMethodDecl *MD,
                             raw_ostream &);
 
+  // r4start
+  virtual MSMangleContextExtensions* getMsExtensions() = 0;
+
   // This is pretty lame.
   virtual void mangleItaniumGuardVariable(const VarDecl *D,
                                           raw_ostream &) {
Index: include/clang/AST/RecordLayout.h
===================================================================
--- include/clang/AST/RecordLayout.h	(revision 154277)
+++ include/clang/AST/RecordLayout.h	(working copy)
@@ -16,6 +16,7 @@
 
 #include "llvm/Support/DataTypes.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/DeclCXX.h"
 
@@ -33,6 +34,22 @@
 /// ObjCInterfaceDecl. FIXME - Find appropriate name.
 /// These objects are managed by ASTContext.
 class ASTRecordLayout {
+public:
+  struct VBaseInfo {
+    CharUnits VBaseOffset;
+    bool IsVtordispPresent;
+
+    VBaseInfo() :
+     IsVtordispPresent(false), VBaseOffset(CharUnits::fromQuantity(-1)) {}
+
+    VBaseInfo(CharUnits VBaseOffset, bool IsVtordispNeed) :
+     VBaseOffset(VBaseOffset), IsVtordispPresent(IsVtordispNeed) {}
+  };
+
+  typedef llvm::DenseMap<const CXXRecordDecl *, VBaseInfo>
+    VBaseOffsetsMapTy;
+
+private:
   /// Size - Size of record in characters.
   CharUnits Size;
 
@@ -66,6 +83,9 @@
     /// VFPtrOffset - Virtual function table offset (Microsoft-only).
     CharUnits VFPtrOffset;
 
+    /// r4start
+    bool HasSingleVFPtr;
+
     /// VBPtrOffset - Virtual base table offset (Microsoft-only).
     CharUnits VBPtrOffset;
     
@@ -79,7 +99,7 @@
     BaseOffsetsMapTy BaseOffsets;
 
     /// VBaseOffsets - Contains a map from vbase classes to their offset.
-    BaseOffsetsMapTy VBaseOffsets;
+    VBaseOffsetsMapTy VBaseOffsets;
   };
 
   /// CXXInfo - If the record layout is for a C++ record, this will have
@@ -102,9 +122,9 @@
                   CharUnits nonvirtualsize, CharUnits nonvirtualalign,
                   CharUnits SizeOfLargestEmptySubobject,
                   const CXXRecordDecl *PrimaryBase,
-                  bool IsPrimaryBaseVirtual,
+                  bool IsPrimaryBaseVirtual, bool HasSingleVFPtr,
                   const BaseOffsetsMapTy& BaseOffsets,
-                  const BaseOffsetsMapTy& VBaseOffsets);
+                  const VBaseOffsetsMapTy& VBaseOffsets);
 
   ~ASTRecordLayout() {}
 
@@ -180,7 +200,7 @@
     assert(CXXInfo && "Record layout does not have C++ specific info!");
     assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!");
 
-    return CXXInfo->VBaseOffsets[VBase];
+    return CXXInfo->VBaseOffsets[VBase].VBaseOffset;
   }
 
   /// getBaseClassOffsetInBits - Get the offset, in bits, for the given
@@ -221,6 +241,16 @@
     assert(CXXInfo && "Record layout does not have C++ specific info!");
     return CXXInfo->VBPtrOffset;
   }
+
+  const VBaseOffsetsMapTy &getVBaseOffsetsMap() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+    return CXXInfo->VBaseOffsets;
+  }
+
+  bool hasSingleVFPtr() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+    return CXXInfo->HasSingleVFPtr;
+  }
 };
 
 }  // end namespace clang
Index: include/clang/AST/VBTableBuilder.h
===================================================================
--- include/clang/AST/VBTableBuilder.h	(revision 0)
+++ include/clang/AST/VBTableBuilder.h	(working copy)
@@ -0,0 +1,78 @@
+//===-- VBTableBuilder.h - C++ vbtable layout builder for MS ABI --*- C++ -*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code dealing with generation of the layout of 
+// virtual bases table.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_VBTABLEBUILDER_H
+#define LLVM_CLANG_AST_VBTABLEBUILDER_H
+
+#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/GlobalDecl.h"
+#include "clang/AST/RecordLayout.h"
+#include "llvm/ADT/DenseMap.h"
+
+/// r4start
+namespace clang {
+
+class VBTableContext {
+public:
+  struct VBTableEntry : 
+   public std::binary_function<VBTableEntry, VBTableEntry, bool> {
+    uint32_t index;
+    int32_t offset;
+
+    VBTableEntry() : index(-1), offset(-1) {}
+
+    VBTableEntry(uint32_t Index, int32_t Offest) :
+      index(Index), offset(Offest) {}
+
+    bool operator () (const VBTableEntry &LHS, const VBTableEntry &RHS) {
+      return (LHS.index < RHS.index);
+    }
+  };
+  
+  typedef std::map<VBTableEntry, const CXXRecordDecl *, VBTableEntry> BaseVBTableTy;
+  typedef llvm::DenseMap<const CXXRecordDecl *, BaseVBTableTy > VBTableTy;
+
+  /// We have such table:
+  /// (1)Vbtable holder
+  /// (2)Base class
+  /// (3)Index of base in vbtable
+  /// (4)Base class offset from vbtable position.
+  llvm::DenseMap<const CXXRecordDecl *, VBTableTy > VBTables;
+
+private:
+
+  void ComputeVBTable(const CXXRecordDecl *RD, const CXXRecordDecl *Base);
+  void ComputeVBTables(const CXXRecordDecl *RD);
+
+public:
+
+  const BaseVBTableTy &getVBTable(const CXXRecordDecl *RD,
+                                  const CXXRecordDecl *Base) {
+    ComputeVBTable(RD, Base);
+    return VBTables[RD][Base];
+  }
+
+  const VBTableTy &getVBTables(const CXXRecordDecl *RD) {
+    ComputeVBTables(RD);
+    return VBTables[RD];
+  }
+
+  const VBTableEntry &getEntryFromVBTable(const CXXRecordDecl *RD,
+                                          const CXXRecordDecl *LayoutClass,
+                                          const CXXRecordDecl *Base);
+};
+
+}
+
+#endif 
Index: include/clang/AST/VTableBuilder.h
===================================================================
--- include/clang/AST/VTableBuilder.h	(revision 154277)
+++ include/clang/AST/VTableBuilder.h	(working copy)
@@ -19,6 +19,7 @@
 #include "clang/AST/GlobalDecl.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/Basic/ABI.h"
+#include "clang/Basic/TargetInfo.h"
 #include "llvm/ADT/SetVector.h"
 #include <utility>
 
@@ -279,6 +280,10 @@
     VTableLayoutMapTy;
   VTableLayoutMapTy VTableLayouts;
 
+  /// r4start
+  /// Table for vftable layouts.
+  llvm::DenseMap<const CXXRecordDecl *, VTableLayoutMapTy > VFTablesLayouts;
+
   /// NumVirtualFunctionPointers - Contains the number of virtual function
   /// pointers in the vtable for a given record decl.
   llvm::DenseMap<const CXXRecordDecl *, uint64_t> NumVirtualFunctionPointers;
@@ -305,6 +310,10 @@
   /// given record decl.
   void ComputeVTableRelatedInformation(const CXXRecordDecl *RD);
 
+  /// r4start
+  void ComputeVFTableRelatedInformation(const CXXRecordDecl *RD,
+                                        const CXXRecordDecl *Base);
+
 public:
   VTableContext(ASTContext &Context) : Context(Context) {}
   ~VTableContext();
@@ -316,6 +325,13 @@
     return *VTableLayouts[RD];
   }
 
+  /// r4start
+  const VTableLayout &getVFTableLayout(const CXXRecordDecl *RD,
+                                       const CXXRecordDecl *Base) {
+    ComputeVFTableRelatedInformation(RD, Base);
+    return *VFTablesLayouts[RD][Base];
+  }
+
   VTableLayout *
   createConstructionVTableLayout(const CXXRecordDecl *MostDerivedClass,
                                  CharUnits MostDerivedClassOffset,
@@ -323,6 +339,9 @@
                                  const CXXRecordDecl *LayoutClass);
 
   const ThunkInfoVectorTy *getThunkInfo(const CXXMethodDecl *MD) {
+    // r4start
+    assert(Context.getTargetInfo().getCXXABI() != CXXABI_Microsoft &&
+           "getThunkInfo doesn`t work in MS ABI!");
     ComputeVTableRelatedInformation(MD->getParent());
 
     ThunksMapTy::const_iterator I = Thunks.find(MD);
@@ -334,6 +353,8 @@
     return &I->second;
   }
 
+  const ThunkInfoVectorTy *getThunkInfoMS(const CXXMethodDecl *MD);
+
   /// getNumVirtualFunctionPointers - Return the number of virtual function
   /// pointers in the vtable for a given record decl.
   uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD);
Index: include/clang/Basic/ABI.h
===================================================================
--- include/clang/Basic/ABI.h	(revision 154277)
+++ include/clang/Basic/ABI.h	(working copy)
@@ -102,13 +102,23 @@
   /// Return - The return adjustment.
   ReturnAdjustment Return;
 
-  ThunkInfo() { }
+  /// r4start
+  bool IsVtordispEx;
 
-  ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return)
-    : This(This), Return(Return) { }
+  /// r4start
+  uint32_t VFPtrOffset;
 
+  ThunkInfo() : IsVtordispEx(false), VFPtrOffset(-1) { }
+
+  ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return,
+            bool IsVtordispEx = false, uint32_t VFPtrOffset = -1)
+    : This(This), Return(Return), IsVtordispEx(IsVtordispEx), 
+  VFPtrOffset(VFPtrOffset) { }
+
   friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) {
-    return LHS.This == RHS.This && LHS.Return == RHS.Return;
+    return LHS.This == RHS.This && LHS.Return == RHS.Return &&
+           LHS.IsVtordispEx == RHS.IsVtordispEx && 
+           LHS.VFPtrOffset == RHS.VFPtrOffset;
   }
 
   friend bool operator<(const ThunkInfo &LHS, const ThunkInfo &RHS) {
Index: include/clang/Basic/OperatorKinds.def
===================================================================
--- include/clang/Basic/OperatorKinds.def	(revision 154277)
+++ include/clang/Basic/OperatorKinds.def	(working copy)
@@ -102,5 +102,9 @@
 // resolution machinery for it.
 OVERLOADED_OPERATOR_MULTI(Conditional    , "?"                        , false, true , false)
 
+// r4start
+// Operators for Microsoft.
+OVERLOADED_OPERATOR_MULTI(ScalarDeletingDestructor, ""	              , false, false, true)
+
 #undef OVERLOADED_OPERATOR_MULTI
 #undef OVERLOADED_OPERATOR
Index: lib/AST/CMakeLists.txt
===================================================================
--- lib/AST/CMakeLists.txt	(revision 154277)
+++ lib/AST/CMakeLists.txt	(working copy)
@@ -50,6 +50,7 @@
   TypeLoc.cpp
   TypePrinter.cpp
   VTableBuilder.cpp
+  VBTableBuilder.cpp
   VTTBuilder.cpp
   )
 
Index: lib/AST/ItaniumMangle.cpp
===================================================================
--- lib/AST/ItaniumMangle.cpp	(revision 154277)
+++ lib/AST/ItaniumMangle.cpp	(working copy)
@@ -125,7 +125,9 @@
                           raw_ostream &);
   void mangleReferenceTemporary(const VarDecl *D,
                                 raw_ostream &);
+  // r4start
   void mangleCXXVTable(const CXXRecordDecl *RD,
+                       const CXXRecordDecl *Base,
                        raw_ostream &);
   void mangleCXXVTT(const CXXRecordDecl *RD,
                     raw_ostream &);
@@ -145,6 +147,11 @@
     Discriminator = 0;
   }
 
+  // r4start
+  MSMangleContextExtensions* getMsExtensions() {
+    return 0;
+  }
+
   bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
     // Lambda closure types with external linkage (indicated by a 
     // non-zero lambda mangling number) have their own numbering scheme, so
@@ -3525,6 +3532,7 @@
 }
 
 void ItaniumMangleContext::mangleCXXVTable(const CXXRecordDecl *RD,
+                                           const CXXRecordDecl *Base,
                                            raw_ostream &Out) {
   // <special-name> ::= TV <type>  # virtual table
   CXXNameMangler Mangler(*this, Out);
Index: lib/AST/MicrosoftMangle.cpp
===================================================================
--- lib/AST/MicrosoftMangle.cpp	(revision 154277)
+++ lib/AST/MicrosoftMangle.cpp	(working copy)
@@ -20,9 +20,13 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/Basic/ABI.h"
+// r4start
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/CXXInheritance.h"
 
 using namespace clang;
 
+// r4start
 namespace {
 
 /// MicrosoftCXXNameMangler - Manage the mangling of a single name for the
@@ -43,6 +47,22 @@
   void mangleVariableEncoding(const VarDecl *VD);
   void mangleNumber(int64_t Number);
   void mangleType(QualType T);
+  void mangleClassArryaOrHierarchyDescr(const CXXRecordDecl *RD,
+                                        StringRef FuncName = "??_R2");
+  void mangleCompleteObjLocatorOrVFTable(const CXXRecordDecl *RD,
+                                         const CXXRecordDecl *BaseClass = 0,
+                                         StringRef FuncName = "??_R4");
+  void mangleCXXRTTITypeDescriptor(const CXXRecordDecl *RD, 
+                                   StringRef Prefix = "?");
+  void mangleCXXRTTIBaseClassDescriptor(const CXXRecordDecl *RD,
+                                        int64_t MemberDisplacement,
+                                        int64_t VBTableDisplacement,
+                                        int64_t IndexInVBTable,
+                                        int64_t Attributes,
+                                        StringRef Prefix = "?");
+  void mangleCXXRTTIVBTable(const CXXRecordDecl *RD,
+                            const CXXRecordDecl *BaseClass,
+                            StringRef Prefix = "?");
 
 private:
   void mangleUnqualifiedName(const NamedDecl *ND) {
@@ -75,7 +95,9 @@
 
 /// MicrosoftMangleContext - Overrides the default MangleContext for the
 /// Microsoft Visual C++ ABI.
-class MicrosoftMangleContext : public MangleContext {
+class MicrosoftMangleContext :
+  public MangleContext,
+  public MSMangleContextExtensions {
 public:
   MicrosoftMangleContext(ASTContext &Context,
                    DiagnosticsEngine &Diags) : MangleContext(Context, Diags) { }
@@ -88,6 +110,7 @@
                                   const ThisAdjustment &ThisAdjustment,
                                   raw_ostream &);
   virtual void mangleCXXVTable(const CXXRecordDecl *RD,
+                               const CXXRecordDecl *BaseClass,
                                raw_ostream &);
   virtual void mangleCXXVTT(const CXXRecordDecl *RD,
                             raw_ostream &);
@@ -102,6 +125,38 @@
                              raw_ostream &);
   virtual void mangleReferenceTemporary(const clang::VarDecl *,
                                         raw_ostream &);
+  
+  virtual MSMangleContextExtensions* getMsExtensions();
+
+  /// Microsoft RTTI specific extensions
+
+  virtual void mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *RD,
+                                                  const CXXRecordDecl *BaseClass,
+                                                  raw_ostream &);
+
+  virtual void mangleCXXRTTITypeDescriptor(const CXXRecordDecl *,
+                                           raw_ostream &);
+
+  virtual void mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *RD,
+                                                  StringRef BaseClass,
+                                                  raw_ostream &);
+
+  virtual void mangleCXXRTTIClassHierarhyDescriptor(const CXXRecordDecl *RD,
+                                                    raw_ostream &);
+
+  virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *RD,
+                                           raw_ostream &);
+
+  virtual void mangleCXXRTTIBaseClassDescriptor(const CXXRecordDecl *RD,
+                                                int64_t MemberOffset,
+                                                int64_t OffsetInVBTable,
+                                                int64_t IndexInVBTable,
+                                                int64_t Attributes,
+                                                raw_ostream &Out);
+
+  virtual void mangleCXXVBTable(const CXXRecordDecl *RD,
+                                const CXXRecordDecl *BaseDecl,
+                                raw_ostream &);
 };
 
 }
@@ -179,6 +234,185 @@
   // TODO: Fields? Can MSVC even mangle them?
 }
 
+void MicrosoftCXXNameMangler::mangleClassArryaOrHierarchyDescr(
+                                        const CXXRecordDecl *RD,
+                                        StringRef Prefix ) {
+  Out << '\01';
+  Out << Prefix;
+
+  mangleName(RD);
+
+  Out << "8";
+}
+
+static bool ClassDeclaresNewVirtualFunction(const CXXRecordDecl *RD) {
+  for (CXXRecordDecl::method_iterator M = RD->method_begin(),
+       E = RD->method_end(); M != E; ++M) {
+    if (!M->size_overridden_methods() && M->isVirtual() &&
+        M->getKind() != Decl::CXXDestructor)
+      return true;
+  }
+  return false;
+}
+
+static bool IsPrimaryBase(const ASTContext &Ctx, CXXBasePath &Path) {
+  int primaryBaseCount = 0;
+  for (CXXBasePath::const_iterator I = Path.begin(),
+       E = Path.end(); I != E; ++I) {
+    const CXXRecordDecl *BaseDecl = I->Base->getType()->getAsCXXRecordDecl();
+    const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(I->Class);
+
+    if (BaseDecl == Layout.getPrimaryBase())
+      ++primaryBaseCount;
+  }
+
+  if (primaryBaseCount == Path.size())
+    return true;
+
+  return false;
+}
+
+static uint32_t HasVFPtr(ASTContext &Ctx, const CXXRecordDecl *RD) {
+  const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
+  uint32_t counter = 0;
+
+  if (Layout.getVFPtrOffset() != CharUnits::fromQuantity(-1))
+    counter++;
+
+  for (auto I = RD->bases_begin(), E = RD->bases_end(); I != E; ++I) {
+    const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
+    if (uint32_t count = HasVFPtr(Ctx, Base))
+      counter += count;
+  }
+
+  return counter;
+}
+
+static bool HasOnlyOneVFPtr(ASTContext &Ctx, const CXXRecordDecl *RD) {
+  uint32_t VFPtrsCounter = 0;
+  const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
+
+  if (Layout.getVFPtrOffset() != CharUnits::fromQuantity(-1))
+    VFPtrsCounter++;
+
+  for (auto I = RD->bases_begin(), E = RD->bases_end(); I != E; ++I) {
+    const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
+    if (uint32_t count = HasVFPtr(Ctx, Base))
+      VFPtrsCounter += count;
+  }
+
+  return VFPtrsCounter == 1;
+}
+
+void MicrosoftCXXNameMangler::mangleCompleteObjLocatorOrVFTable(
+                                        const CXXRecordDecl *RD,
+                                        const CXXRecordDecl *BaseClass,
+                                        StringRef Prefix) {
+  Out << '\01';
+  Out << Prefix;
+
+  mangleName(RD);
+
+  Out << "6B";
+
+  const ASTRecordLayout &Layout = 
+    Context.getASTContext().getASTRecordLayout(RD);
+
+  if (BaseClass && RD != BaseClass) {
+    CXXBasePaths Paths;
+    Paths.setOrigin(const_cast<CXXRecordDecl *>(RD));
+    RD->lookupInBases(&CXXRecordDecl::FindBaseClass,
+                    const_cast<CXXRecordDecl *>(BaseClass->getCanonicalDecl()),
+                      Paths);
+
+    if (!IsPrimaryBase(Context.getASTContext(), Paths.front())/* &&
+        !HasOnlyOneVFPtr(Context.getASTContext(), RD)*/) {
+      //CXXBasePathElement *Elem = Paths.front().begin();
+      mangleName(/*Elem->Base->getType()->getAsCXXRecordDecl()*/BaseClass);
+    }
+
+  } else if ((Layout.getVFPtrOffset() != CharUnits::fromQuantity(-1) &&
+             RD->getNumVBases() && RD != BaseClass)/* ||
+           (RD == BaseClass && !HasOnlyOneVFPtr(Context.getASTContext(), RD))*/) {
+    Out << "0@";
+  }
+
+  Out << "@";
+}
+
+void MicrosoftCXXNameMangler::mangleCXXRTTITypeDescriptor(
+                                        const CXXRecordDecl *RD,
+                                        StringRef Prefix) {
+  Out << '\01';
+  Out << Prefix;
+
+  Out << "?_R0";
+  
+  // This is always reference?
+  Out << "?A";
+  mangleType(RD->getASTContext().getRecordType(RD));
+  // End magic number
+  Out << "@8";
+}
+
+void MicrosoftCXXNameMangler::mangleCXXRTTIBaseClassDescriptor(
+                                        const CXXRecordDecl *RD,
+                                        int64_t MemberDisplacement,
+                                        int64_t VBTableDisplacement,
+                                        int64_t IndexInVBTable,
+                                        int64_t Attributes,
+                                        StringRef Prefix)
+{
+  assert(Attributes != 0 && "Class inheritance must be greater 0");
+
+  Out << '\01';
+  Out << Prefix;
+  Out << "?_R1";
+
+  if (MemberDisplacement == 0) {
+    Out << "A@";
+  } else {
+    mangleNumber(MemberDisplacement);
+  }
+
+  if (VBTableDisplacement == -1)
+  {
+    Out << "?0";
+  } else {
+    mangleNumber(VBTableDisplacement);
+  }
+
+  if (IndexInVBTable == 0) {
+    Out << "A@";
+  } else {
+    mangleNumber(IndexInVBTable);
+  }
+    
+  mangleNumber(Attributes);
+  mangleName(RD);
+  Out << "8";
+}
+
+void MicrosoftCXXNameMangler::mangleCXXRTTIVBTable(
+                                        const CXXRecordDecl *RD,
+                                        const CXXRecordDecl *BaseClass,
+                                        StringRef Prefix) {
+  Out << '\01';
+  Out << Prefix;
+
+  Out << "?_8";
+  mangleName(RD);
+
+  Out << "7B";
+
+  if (BaseClass)
+  {
+    mangleName(BaseClass);
+  }
+
+  Out << "@";
+}
+
 void MicrosoftCXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
   // <type-encoding> ::= <function-class> <function-type>
 
@@ -477,6 +711,8 @@
   case OO_PipeEqual: Out << "?_5"; break;
   // <operator-name> ::= ?_6 # ^=
   case OO_CaretEqual: Out << "?_6"; break;
+  // <operator-name> ::= ?_G # scalar deleting destructor
+  case OO_ScalarDeletingDestructor: Out << "?_G"; break;
   //                     ?_7 # vftable
   //                     ?_8 # vbtable
   //                     ?_9 # vcall
@@ -1135,10 +1371,55 @@
   MicrosoftCXXNameMangler Mangler(*this, Out);
   return Mangler.mangle(D);
 }
+
+namespace {
+struct CheckVtordisp : 
+  std::unary_function<const std::pair<const CXXRecordDecl *,
+                                      ASTRecordLayout::VBaseInfo>, bool> {
+
+  bool operator () (const std::pair<const CXXRecordDecl *, 
+                                    ASTRecordLayout::VBaseInfo> &Elem) {
+    return Elem.second.IsVtordispPresent;
+  }
+};
+}
+
 void MicrosoftMangleContext::mangleThunk(const CXXMethodDecl *MD,
                                          const ThunkInfo &Thunk,
-                                         raw_ostream &) {
-  llvm_unreachable("Can't yet mangle thunks!");
+                                         raw_ostream &Out) {
+  MicrosoftCXXNameMangler mangler(*this, Out);
+  Out << '\01' << "?";
+
+  mangler.mangleName(MD);
+
+  const ASTRecordLayout &Layout = 
+    getASTContext().getASTRecordLayout(MD->getParent());
+
+  ASTRecordLayout::VBaseOffsetsMapTy::const_iterator 
+    I = std::find_if(Layout.getVBaseOffsetsMap().begin(),
+                     Layout.getVBaseOffsetsMap().end(),
+                     CheckVtordisp());
+
+  if (I == Layout.getVBaseOffsetsMap().end()) {
+    // Unknown prefix for number.
+    Out << "W";
+    mangler.mangleNumber(uint32_t(-Thunk.This.NonVirtual));
+  } else {
+    // This string right if we have vtordisp.
+    // Unknown prefix.
+    if (Thunk.IsVtordispEx)
+      Out << "$R4";
+    else
+      Out << "$4";
+    Out << "-VTORDISP-";
+    
+    if (Thunk.VFPtrOffset != uint32_t(-1))
+      mangler.mangleNumber(Thunk.VFPtrOffset);
+    // When we have vtordisp thunk, number always is -4.
+    mangler.mangleNumber(uint32_t(-4));
+  }
+
+  mangler.mangleFunctionEncoding(MD);
 }
 void MicrosoftMangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD,
                                                 CXXDtorType Type,
@@ -1147,8 +1428,10 @@
   llvm_unreachable("Can't yet mangle destructor thunks!");
 }
 void MicrosoftMangleContext::mangleCXXVTable(const CXXRecordDecl *RD,
-                                             raw_ostream &) {
-  llvm_unreachable("Can't yet mangle virtual tables!");
+                                             const CXXRecordDecl *Base,
+                                             raw_ostream &Out) {
+  MicrosoftCXXNameMangler mangler(*this, Out);
+  mangler.mangleCompleteObjLocatorOrVFTable(RD, Base, "??_7");
 }
 void MicrosoftMangleContext::mangleCXXVTT(const CXXRecordDecl *RD,
                                           raw_ostream &) {
@@ -1162,12 +1445,95 @@
 }
 void MicrosoftMangleContext::mangleCXXRTTI(QualType T,
                                            raw_ostream &) {
-  llvm_unreachable("Can't yet mangle RTTI!");
+  //llvm_unreachable("Can't yet mangle RTTI!");
 }
+void 
+MicrosoftMangleContext::mangleCXXRTTITypeDescriptor(const CXXRecordDecl *RD,
+                                                    raw_ostream &Out) {
+  MicrosoftCXXNameMangler mangler(*this, Out);
+  mangler.mangleCXXRTTITypeDescriptor(RD);
+}
 void MicrosoftMangleContext::mangleCXXRTTIName(QualType T,
-                                               raw_ostream &) {
-  llvm_unreachable("Can't yet mangle RTTI names!");
+                                               raw_ostream &Out) {
+  MicrosoftCXXNameMangler mangler(*this, Out);
+  mangler.mangleType(T);
 }
+
+MSMangleContextExtensions* MicrosoftMangleContext::getMsExtensions() {
+  return this;
+}
+
+void MicrosoftMangleContext::mangleCXXRTTICompleteObjectLocator(
+                                        const CXXRecordDecl *RD,
+                                        const CXXRecordDecl *Base,
+                                        raw_ostream &Out) {
+  MicrosoftCXXNameMangler mangler(*this, Out);
+  mangler.mangleCompleteObjLocatorOrVFTable(RD, Base, "??_R4");
+}
+
+void MicrosoftMangleContext::mangleCXXRTTICompleteObjectLocator(
+                                        const CXXRecordDecl *RD,
+                                        StringRef BaseClass,
+                                        raw_ostream &Out) {
+
+  Out << '\01';
+  Out << "??_R4";
+  Out << RD->getNameAsString();
+  Out << "@@6B";
+
+  if (BaseClass.size())
+  {
+    Out << BaseClass;
+
+    if (BaseClass == "0")
+    {
+      Out << "@";
+    }
+    else
+    {
+      Out << "@@";
+    }
+    
+  }
+
+  Out << "@";
+}
+
+void MicrosoftMangleContext::mangleCXXRTTIClassHierarhyDescriptor(
+                                        const CXXRecordDecl *RD, 
+                                        raw_ostream &Out) {
+  MicrosoftCXXNameMangler mangler(*this, Out);
+  mangler.mangleClassArryaOrHierarchyDescr(RD, "??_R3");
+}
+
+void MicrosoftMangleContext::mangleCXXRTTIBaseClassArray(
+                                        const CXXRecordDecl *RD, 
+                                        raw_ostream &Out) {
+  MicrosoftCXXNameMangler mangler(*this, Out);
+  mangler.mangleClassArryaOrHierarchyDescr(RD, "??_R2");
+}
+
+void MicrosoftMangleContext::mangleCXXRTTIBaseClassDescriptor(
+                                        const CXXRecordDecl *RD,
+                                        int64_t MemberOffset,
+                                        int64_t OffsetInVBTable,
+                                        int64_t IndexInVBTable,
+                                        int64_t Attributes,
+                                        raw_ostream &Out) {
+  MicrosoftCXXNameMangler mangler(*this, Out);
+
+  mangler.mangleCXXRTTIBaseClassDescriptor(RD, MemberOffset,
+                                           OffsetInVBTable,
+                                           IndexInVBTable,
+                                           Attributes);
+}
+
+void MicrosoftMangleContext::mangleCXXVBTable(const CXXRecordDecl *RD,
+                                              const CXXRecordDecl *BaseDecl,
+                                              raw_ostream &Out) {
+  MicrosoftCXXNameMangler mangler(*this, Out);
+  mangler.mangleCXXRTTIVBTable(RD, BaseDecl);
+}
 void MicrosoftMangleContext::mangleCXXCtor(const CXXConstructorDecl *D,
                                            CXXCtorType Type,
                                            raw_ostream & Out) {
Index: lib/AST/RecordLayout.cpp
===================================================================
--- lib/AST/RecordLayout.cpp	(revision 154277)
+++ lib/AST/RecordLayout.cpp	(working copy)
@@ -40,6 +40,7 @@
   }
 }
 
+// r4start
 // Constructor for C++ records.
 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
                                  CharUnits size, CharUnits alignment,
@@ -52,8 +53,9 @@
                                  CharUnits SizeOfLargestEmptySubobject,
                                  const CXXRecordDecl *PrimaryBase,
                                  bool IsPrimaryBaseVirtual,
+                                 bool HasSingleVFPtr,
                                  const BaseOffsetsMapTy& BaseOffsets,
-                                 const BaseOffsetsMapTy& VBaseOffsets)
+                                 const VBaseOffsetsMapTy& VBaseOffsets)
   : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
     FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
 {
Index: lib/AST/RecordLayoutBuilder.cpp
===================================================================
--- lib/AST/RecordLayoutBuilder.cpp	(revision 154277)
+++ lib/AST/RecordLayoutBuilder.cpp	(working copy)
@@ -603,6 +603,8 @@
   /// VFPtrOffset - Virtual function table offset. Only for MS layout.
   CharUnits VFPtrOffset;
 
+  bool HasSingleVFPtr;
+
   /// VBPtrOffset - Virtual base table offset. Only for MS layout.
   CharUnits VBPtrOffset;
 
@@ -612,7 +614,7 @@
   BaseOffsetsMapTy Bases;
 
   // VBases - virtual base classes and their offsets in the record.
-  BaseOffsetsMapTy VBases;
+  ASTRecordLayout::VBaseOffsetsMapTy VBases;
 
   /// IndirectPrimaryBases - Virtual base classes, direct or indirect, that are
   /// primary base classes for some other direct or indirect base class.
@@ -652,6 +654,7 @@
       NonVirtualAlignment(CharUnits::One()), 
       ZeroLengthBitfield(0), PrimaryBase(0), 
       PrimaryBaseIsVirtual(false),
+      HasSingleVFPtr(false),
       VFPtrOffset(CharUnits::fromQuantity(-1)),
       VBPtrOffset(CharUnits::fromQuantity(-1)),
       FirstNearlyEmptyVBase(0) { }
@@ -725,15 +728,26 @@
                                     CharUnits Offset);
 
   bool needsVFTable(const CXXRecordDecl *RD) const;
-  bool hasNewVirtualFunction(const CXXRecordDecl *RD) const;
+  bool hasNewVirtualFunction(const CXXRecordDecl *RD,
+                             bool IgnoreDestructor = false) const;
   bool isPossiblePrimaryBase(const CXXRecordDecl *Base) const;
 
+  typedef llvm::SmallPtrSet<const CXXRecordDecl*, 4> ClassSetTy;
+
+  bool hasAnyNonVirtualBase(const CXXRecordDecl *RD, 
+                            const ClassSetTy &Overridden,
+                            const ClassSetTy &Vtordisps);
+
+  void fillVtordisps(const CXXRecordDecl *RD, 
+                     ClassSetTy &VtordispVBases);
+
   /// LayoutVirtualBases - Lays out all the virtual bases.
   void LayoutVirtualBases(const CXXRecordDecl *RD,
                           const CXXRecordDecl *MostDerivedClass);
 
   /// LayoutVirtualBase - Lays out a single virtual base.
-  void LayoutVirtualBase(const BaseSubobjectInfo *Base);
+  void LayoutVirtualBase(const BaseSubobjectInfo *Base, 
+                         bool IsVtordispNeed = false);
 
   /// LayoutBase - Will lay out a base and return the offset where it was
   /// placed, in chars.
@@ -1044,8 +1058,10 @@
     CharUnits PtrAlign = 
       Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerAlign(0));
     EnsureVTablePointerAlignment(PtrAlign);
-    if (isMicrosoftCXXABI())
+    if (isMicrosoftCXXABI()) {
+      HasSingleVFPtr = true;
       VFPtrOffset = getSize();
+    }
     setSize(getSize() + PtrWidth);
     setDataSize(getSize());
   }
@@ -1142,7 +1158,7 @@
       assert(!VBases.count(Info->PrimaryVirtualBaseInfo->Class) && 
              "primary vbase offset already exists!");
       VBases.insert(std::make_pair(Info->PrimaryVirtualBaseInfo->Class,
-                                   Offset));
+                                   ASTRecordLayout::VBaseInfo(Offset, false)));
 
       // Traverse the primary virtual base.
       AddPrimaryVirtualBaseOffsets(Info->PrimaryVirtualBaseInfo, Offset);
@@ -1193,19 +1209,182 @@
   return hasNewVirtualFunction(RD);
 }
 
+/*void RecordLayoutBuilder::fillVtordisps(const CXXRecordDecl *RD) {
+  llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedBasesVBases;
+  
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(Base);
+
+    if (I->isVirtual()) {
+      VisitedBasesVBases.insert(Base);
+      
+      if (needsVtorDispDirectBase(RD, Base) && 
+          !VtordispVBases.count(Base))
+        VtordispVBases.insert(Base);
+    }
+
+    VtordispVBases.insert(Layout.getVtordispVBases().begin(),
+                           Layout.getVtordispVBases().end());
+  }
+
+  if (VisitedBasesVBases.size() == RD->getNumVBases())
+    return;
+
+  for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
+       E = RD->vbases_end(); I != E; ++I) {
+    const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
+
+    if (VisitedBasesVBases.count(Base))
+      continue;
+
+    if (needsVtorDispDirectBase(RD, Base, true) &&
+        !VtordispVBases.count(Base))
+      VtordispVBases.insert(Base);
+  }
+}
+
+bool 
+RecordLayoutBuilder::hasAnyNonVirtualBase(const CXXRecordDecl *RD, 
+                const llvm::SmallPtrSet<const CXXRecordDecl*, 4> &Overridden) {
+  if (!RD->hasUserDeclaredConstructor() &&
+      !RD->hasUserDeclaredDestructor())
+    return false;
+
+  for (llvm::SmallPtrSet<const CXXRecordDecl *, 4>::const_iterator
+       I = Overridden.begin(), E = Overridden.end(); I != E; ++I) {
+    const CXXRecordDecl *Base = *I;
+
+    if (!Base->isVirtuallyDerivedFrom(RD))
+      continue;
+
+    for (CXXRecordDecl::method_iterator M = Base->method_begin(),
+         E = Base->method_end(); M != E; ++M) {
+      if (!M->isVirtual() || isa<CXXDestructorDecl>(*M))
+        continue;
+
+      for (CXXMethodDecl::method_iterator O = (*M)->begin_overridden_methods(),
+           E = (*M)->end_overridden_methods(); O != E; ++O) {
+        if ((*O)->getParent() == RD)
+      return true;
+  }
+    }
+  }
+
+  return false;
+}*/
+bool 
+RecordLayoutBuilder::hasAnyNonVirtualBase(const CXXRecordDecl *RD, 
+                                          const ClassSetTy &Overridden,
+                                          const ClassSetTy &Vtordisps) {
+  for (ClassSetTy::const_iterator I = Overridden.begin(),
+       E = Overridden.end(); I != E; ++I) {
+    const CXXRecordDecl *OV = *I;
+    if (RD->isDerivedFrom(OV) && 
+        !RD->isVirtuallyDerivedFrom(const_cast<CXXRecordDecl *>(OV)))
+      return true;
+  }
+
+  return false;
+}
+
+void RecordLayoutBuilder::fillVtordisps(const CXXRecordDecl *RD,
+                                        ClassSetTy &VtordispVBases) {
+  if (!RD->getNumVBases())
+    return;
+
+  // As an optimization, remember the set of
+  // virtual bases that we haven't decided yet.
+  ClassSetTy UndecidedVBases;
+  for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
+       E = RD->vbases_end(); I != E; ++I) {
+    const CXXRecordDecl *VBase = I->getType()->getAsCXXRecordDecl();
+
+    UndecidedVBases.insert(VBase);
+  }
+
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
+    const ASTRecordLayout &BaseLayout = Context.getASTRecordLayout(BaseDecl);
+
+    for (ASTRecordLayout::VBaseOffsetsMapTy::const_iterator
+         VI = BaseLayout.getVBaseOffsetsMap().begin(), 
+         VE = BaseLayout.getVBaseOffsetsMap().end(); VI != VE; ++VI) {
+      if (!VI->second.IsVtordispPresent)
+        continue;
+      if (!UndecidedVBases.erase(VI->first)) 
+        continue;
+
+      VtordispVBases.insert(VI->first);
+
+      if (UndecidedVBases.empty()) 
+        return;
+    }
+  }
+
+  // Otherwise, a virtual base requires a vtor disp if any the non-destructor
+  // virtual methods declared in this class directly override a method provided
+  // by that virtual base.
+
+  // Collect the set of bases directly overridden by any method in this class.
+  // It's possible that some of these classes won't be virtual bases, or won't be
+  // provided by virtual bases, or won't be virtual bases in the overridden
+  // instance but are virtual bases elsewhere.  Only the last matters for what
+  // we're doing, and we can ignore those:  if we don't directly override
+  // a method provided by a virtual copy of a base class, but we do directly
+  // override a method provided by a non-virtual copy of that base class,
+  // then we must indirectly override the method provided by the virtual base,
+  // and so we should already have collected it in the loop above.
+  ClassSetTy OverriddenBases;
+  for (CXXRecordDecl::method_iterator M = RD->method_begin(),
+       E = RD->method_end(); M != E; ++M) {
+    if (!M->isVirtual() || isa<CXXDestructorDecl>(*M)) 
+      continue;
+    
+    for (CXXMethodDecl::method_iterator I = M->begin_overridden_methods(),
+          E = M->end_overridden_methods(); I != E; ++I) {
+      const CXXRecordDecl *OverriddenBase = (*I)->getParent();
+      const CXXMethodDecl *OverriddenMD = *I;
+
+      // As an optimization, check immediately whether we're overriding
+      // something from the undecided set.
+      if (!OverriddenMD->size_overridden_methods()) {
+        if (UndecidedVBases.erase(OverriddenBase)) {
+          VtordispVBases.insert(OverriddenBase);
+          if (UndecidedVBases.empty()) return;
+          continue;
+        }
+      }
+      // Otherwise, just collect it.
+      OverriddenBases.insert(OverriddenBase);
+    }
+  }
+
+  // Walk the undecided v-bases and check whether they (non-virtually)
+  // provide any of the overridden bases.
+  for (ClassSetTy::const_iterator I = UndecidedVBases.begin(),
+       E = UndecidedVBases.end(); I != E; ++I) {
+    if (hasAnyNonVirtualBase(*I, OverriddenBases, VtordispVBases))
+      VtordispVBases.insert(*I);
+  }
+}
+
 /// hasNewVirtualFunction - Does the given polymorphic class declare a
 /// virtual function that does not override a method from any of its
 /// base classes?
 bool 
-RecordLayoutBuilder::hasNewVirtualFunction(const CXXRecordDecl *RD) const {
-  assert(RD->isPolymorphic());
+RecordLayoutBuilder::hasNewVirtualFunction(const CXXRecordDecl *RD, 
+                                           bool IgnoreDestructor) const {
   if (!RD->getNumBases()) 
     return true;
 
   for (CXXRecordDecl::method_iterator method = RD->method_begin();
        method != RD->method_end();
        ++method) {
-    if (method->isVirtual() && !method->size_overridden_methods()) {
+    if (method->isVirtual() && !method->size_overridden_methods() &&
+        !(IgnoreDestructor && method->getKind() == Decl::CXXDestructor)) {
       return true;
     }
   }
@@ -1232,6 +1411,9 @@
 
   // If it has no virtual bases, then everything is at a static offset.
   if (!Base->getNumVBases()) return true;
+  
+  // If class has primary, then it can be primary base.
+  if (Context.getASTRecordLayout(Base).getPrimaryBase()) return true;
 
   // Okay, just ask the base class's layout.
   return (Context.getASTRecordLayout(Base).getVFPtrOffset()
@@ -1288,10 +1470,12 @@
 }
 
 void RecordLayoutBuilder::MSLayoutVirtualBases(const CXXRecordDecl *RD) {
-
   if (!RD->getNumVBases())
     return;
 
+  ClassSetTy VtordispVBases;
+  fillVtordisps(RD, VtordispVBases);
+  
   // This is substantially simplified because there are no virtual
   // primary bases.
   for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
@@ -1299,12 +1483,24 @@
     const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
     const BaseSubobjectInfo *BaseInfo = VirtualBaseInfo.lookup(BaseDecl);
     assert(BaseInfo && "Did not find virtual base info!");
+
+    bool VtordispIsNeed = false;
     
-    LayoutVirtualBase(BaseInfo);
+    if (VtordispVBases.count(BaseDecl)) {
+      CharUnits IntSize = 
+        CharUnits::fromQuantity(Context.getTargetInfo().getIntWidth() / 8);
+
+      setSize(getSize() + IntSize);
+      setDataSize(getSize());
+      VtordispIsNeed = true;
+    }
+
+    LayoutVirtualBase(BaseInfo, VtordispIsNeed);
   }
 }
 
-void RecordLayoutBuilder::LayoutVirtualBase(const BaseSubobjectInfo *Base) {
+void RecordLayoutBuilder::LayoutVirtualBase(const BaseSubobjectInfo *Base,
+                                            bool IsVtordispNeed) {
   assert(!Base->Derived && "Trying to lay out a primary virtual base!");
   
   // Layout the base.
@@ -1312,9 +1508,11 @@
 
   // Add its base class offset.
   assert(!VBases.count(Base->Class) && "vbase offset already exists!");
-  VBases.insert(std::make_pair(Base->Class, Offset));
-  
-  AddPrimaryVirtualBaseOffsets(Base, Offset);
+  VBases.insert(std::make_pair(Base->Class, 
+                       ASTRecordLayout::VBaseInfo(Offset, IsVtordispNeed)));
+
+  if (!isMicrosoftCXXABI())
+    AddPrimaryVirtualBaseOffsets(Base, Offset);
 }
 
 CharUnits RecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) {
@@ -1461,8 +1659,8 @@
                                  Context.getTargetInfo().getCharAlign()));
   NonVirtualAlignment = Alignment;
 
-  if (isMicrosoftCXXABI() &&
-      NonVirtualSize != NonVirtualSize.RoundUpToAlignment(Alignment)) {
+  if (isMicrosoftCXXABI()) {
+    if (NonVirtualSize != NonVirtualSize.RoundUpToAlignment(Alignment)) {
     CharUnits AlignMember = 
       NonVirtualSize.RoundUpToAlignment(Alignment) - NonVirtualSize;
 
@@ -1472,9 +1670,9 @@
     NonVirtualSize = Context.toCharUnitsFromBits(
                              llvm::RoundUpToAlignment(getSizeInBits(),
                              Context.getTargetInfo().getCharAlign()));
+    }
 
     MSLayoutVirtualBases(RD);
-
   } else {
     // Lay out the virtual bases and add the primary virtual base offsets.
     LayoutVirtualBases(RD, RD);
@@ -2248,6 +2446,7 @@
                                   EmptySubobjects.SizeOfLargestEmptySubobject,
                                   Builder.PrimaryBase,
                                   Builder.PrimaryBaseIsVirtual,
+                                  Builder.HasSingleVFPtr,
                                   Builder.Bases, Builder.VBases);
   } else {
     RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0);
@@ -2438,6 +2637,8 @@
     return;
 
   // Dump virtual bases.
+  const ASTRecordLayout::VBaseOffsetsMapTy &vtordisps = 
+    Layout.getVBaseOffsetsMap();
   for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
          E = RD->vbases_end(); I != E; ++I) {
     assert(I->isVirtual() && "Found non-virtual class!");
@@ -2445,6 +2646,12 @@
       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
 
     CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBase);
+
+    if (vtordisps.find(VBase)->second.IsVtordispPresent) {
+      PrintOffset(OS, VBaseOffset - CharUnits::fromQuantity(4), IndentLevel);
+      OS << "(vtordisp for vbase " << *VBase << ")\n";
+    }
+
     DumpCXXRecordLayout(OS, VBase, C, VBaseOffset, IndentLevel,
                         VBase == PrimaryBase ?
                         "(primary virtual base)" : "(virtual base)",
Index: lib/AST/VBTableBuilder.cpp
===================================================================
--- lib/AST/VBTableBuilder.cpp	(revision 0)
+++ lib/AST/VBTableBuilder.cpp	(working copy)
@@ -0,0 +1,229 @@
+//===------ VBTableBuilder.cpp - C++ vbtable layout builder for MS ABI ------=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code dealing with generation of the layout of 
+// virtual bases table.
+//
+//===----------------------------------------------------------------------===//
+
+/// r4start
+#include "clang/AST/VBTableBuilder.h"
+
+using namespace clang;
+
+namespace {
+
+class VBTableBuilder {
+  VBTableContext::BaseVBTableTy VBTable;
+
+  const CXXRecordDecl *MostDerived;
+  const CXXRecordDecl *LayoutClass;
+
+  ASTContext &Ctx;
+
+  void Layout();
+  void LayoutSingleVBTable();
+  void LayoutForMultiplyVBTables();
+
+public:
+  VBTableBuilder(ASTContext &C, const CXXRecordDecl *MostDerived,
+                 const CXXRecordDecl *LayoutClass);
+
+  const VBTableContext::BaseVBTableTy &getVBTable() const {
+    return VBTable;
+  }
+};
+
+}
+
+VBTableBuilder::VBTableBuilder(ASTContext &C, const CXXRecordDecl *MostDerived,
+                               const CXXRecordDecl *LayoutClass)
+  : Ctx(C), MostDerived(MostDerived), LayoutClass(LayoutClass){
+  Layout();
+}
+
+static CharUnits GetClassOffset(const ASTContext &Ctx,
+                                const CXXRecordDecl *RD,
+                                const CXXRecordDecl *Base) {
+  assert(RD != Base && 
+         "GetClassOffset can`t work if RD equal Base");
+
+  CharUnits BaseOffset;
+
+  if (RD->isVirtuallyDerivedFrom(const_cast<CXXRecordDecl *>(Base))) {
+    const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
+    return Layout.getVBaseClassOffset(Base);
+  }
+
+  CXXBasePaths InhPaths;
+  InhPaths.setOrigin(const_cast<CXXRecordDecl *>(RD));
+  RD->lookupInBases(&CXXRecordDecl::FindBaseClass, 
+                 const_cast<CXXRecordDecl *>(Base), InhPaths);
+
+  assert(InhPaths.begin() != InhPaths.end() &&
+         "Can`t find inheritance path from RD to Base!");
+  
+  CXXBasePath& Path = InhPaths.front();
+
+  for (CXXBasePath::const_iterator I = Path.begin(),
+       E = Path.end(); I != E; ++I) {
+    const CXXRecordDecl *BaseElem = I->Base->getType()->getAsCXXRecordDecl();
+    const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(I->Class);
+
+    if (I->Base->isVirtual())
+      BaseOffset += Layout.getVBaseClassOffset(BaseElem);
+    else
+      BaseOffset += Layout.getBaseClassOffset(BaseElem);
+  }
+
+  return BaseOffset;
+}
+
+static uint32_t GetVBTableOffset(ASTContext &C, const CXXRecordDecl *RD,
+                                int64_t StartOffset) {
+  const ASTRecordLayout &Layout = C.getASTRecordLayout(RD);
+
+  if (!RD->getNumVBases())
+    return -1;
+  if (Layout.getVBPtrOffset().getQuantity() != -1)
+    return Layout.getVBPtrOffset().getQuantity() + StartOffset;
+
+  uint32_t Offset = -1;
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+    E = RD->bases_end(); I != E; ++I) {
+      CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
+
+      if (I->isVirtual())
+        StartOffset += Layout.getVBaseClassOffset(Base).getQuantity();
+      else
+        StartOffset += Layout.getBaseClassOffset(Base).getQuantity();
+
+      Offset = GetVBTableOffset(C, Base, StartOffset);
+      if (Offset != -1)
+        return Offset;
+  }
+
+  return Offset;
+}
+
+void VBTableBuilder::LayoutSingleVBTable() {
+  uint32_t Offset = GetVBTableOffset(Ctx, MostDerived, 0);
+
+  VBTable.insert(std::make_pair(VBTableContext::VBTableEntry(0, -Offset),
+                                MostDerived));
+
+  const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(MostDerived);
+
+  int idx = 1;
+  for (CXXRecordDecl::base_class_const_iterator I = MostDerived->vbases_begin(),
+       E = MostDerived->vbases_end(); I != E; ++I, ++idx) {
+    const CXXRecordDecl *VBase = I->getType()->getAsCXXRecordDecl();
+
+    int32_t BaseOffset = Layout.getVBaseClassOffset(VBase).getQuantity();
+
+    VBTable.insert(std::make_pair(
+                      VBTableContext::VBTableEntry(idx, BaseOffset - Offset),
+                      VBase));
+  }
+}
+
+void VBTableBuilder::LayoutForMultiplyVBTables() {
+  uint32_t Offset = GetVBTableOffset(Ctx, LayoutClass, 0);
+  uint32_t ClassOffset = GetClassOffset(MostDerived->getASTContext(),
+                                        MostDerived, LayoutClass).getQuantity();
+
+  VBTable.insert(std::make_pair(VBTableContext::VBTableEntry(0, -Offset),
+                                MostDerived));
+
+  Offset += ClassOffset;
+  const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(MostDerived);
+  int idx = 1;
+  
+  for (CXXRecordDecl::base_class_const_iterator I = LayoutClass->vbases_begin(),
+       E = LayoutClass->vbases_end(); I != E; ++I, ++idx) {
+    const CXXRecordDecl *VBase = I->getType()->getAsCXXRecordDecl();
+
+    int32_t BaseOffset = Layout.getVBaseClassOffset(VBase).getQuantity();
+
+    VBTable.insert(std::make_pair(
+                        VBTableContext::VBTableEntry(idx, BaseOffset - Offset),
+                        VBase));
+  }
+}
+
+void VBTableBuilder::Layout() {
+  if (MostDerived == LayoutClass)
+    LayoutSingleVBTable();
+  else
+    LayoutForMultiplyVBTables();
+}
+
+void VBTableContext::ComputeVBTable(const CXXRecordDecl *RD,
+                                    const CXXRecordDecl *Base) {
+  if (VBTables.count(RD))
+    if (VBTables[RD].count(Base))
+      return;
+  VBTableBuilder Builder(RD->getASTContext(), RD, Base);
+  
+  VBTables.insert(std::make_pair(RD, VBTableTy()));
+  VBTables[RD].insert(std::make_pair(Base, Builder.getVBTable()));
+}
+
+typedef llvm::SmallSet<const CXXRecordDecl *, 8> ClassesContainerTy;
+
+static void TraverseBases(ASTContext &Ctx, const CXXRecordDecl *Class,
+                          ClassesContainerTy &DefferredClasses) {
+  for (auto I = Class->bases_begin(), E = Class->bases_end(); I != E; ++I) {
+    const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
+    const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(BaseDecl);
+    if (Layout.getVBPtrOffset() != CharUnits::fromQuantity(-1))
+      DefferredClasses.insert(BaseDecl);
+    TraverseBases(Ctx, BaseDecl, DefferredClasses);
+  }
+
+  const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Class);
+  if (Layout.getVBPtrOffset() != CharUnits::fromQuantity(-1))
+    DefferredClasses.insert(Class);
+}
+
+void VBTableContext::ComputeVBTables(const CXXRecordDecl *RD) {
+  assert(RD->getNumVBases() && "Class must have virtual bases");
+  if (VBTables.count(RD))
+    return;
+
+  ClassesContainerTy ClassWithVBTables;
+  TraverseBases(RD->getASTContext(), RD, ClassWithVBTables);
+
+  for (auto I = ClassWithVBTables.begin(), 
+       E = ClassWithVBTables.end(); I != E; ++I) {
+    const CXXRecordDecl *Class = *I;
+
+    if (Class == RD)
+      ComputeVBTable(Class, Class);
+    else
+      ComputeVBTable(RD, Class);
+  }
+}
+
+const VBTableContext::VBTableEntry &
+VBTableContext::getEntryFromVBTable(const CXXRecordDecl *RD,
+                                    const CXXRecordDecl *LayoutClass,
+                                    const CXXRecordDecl *Base) {
+  assert(RD->getNumVBases() && "Class must have virtual bases!");
+  ComputeVBTable(RD, LayoutClass);
+  const BaseVBTableTy &Table = VBTables[RD][LayoutClass];
+
+  for (BaseVBTableTy::const_iterator I = Table.begin(),
+       E = Table.end(); I != E; ++I) {
+    if (I->second == Base)
+      return I->first;
+  }
+
+  llvm_unreachable("Can not find entry for base in vbtable!");
+}
Index: lib/AST/VTableBuilder.cpp
===================================================================
--- lib/AST/VTableBuilder.cpp	(revision 154277)
+++ lib/AST/VTableBuilder.cpp	(working copy)
@@ -16,13 +16,9 @@
 #include "clang/AST/RecordLayout.h"
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/Support/Format.h"
-#include <algorithm>
-#include <cstdio>
 
 using namespace clang;
 
-#define DUMP_OVERRIDERS 0
-
 namespace {
 
 /// BaseOffset - Represents an offset from a derived class to a direct or
@@ -789,6 +785,9 @@
   typedef llvm::DenseMap<BaseSubobject, uint64_t> 
     AddressPointsMapTy;
 
+  typedef llvm::DenseMap<const CXXMethodDecl *, const CXXMethodDecl *> 
+    OverriddersMapTy;
+
 private:
   /// VTables - Global vtable information.
   VTableContext &VTables;
@@ -874,6 +873,9 @@
   /// Thunks - A map that contains all the thunks needed for all methods in the
   /// most derived class for which the vtable is currently being built.
   ThunksMapTy Thunks;
+
+  typedef llvm::SmallVector<const CXXMethodDecl *, 8> VFTableTy;
+  VFTableTy VFTable;
   
   /// AddThunk - Add a thunk for the given method.
   void AddThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk);
@@ -905,6 +907,35 @@
                         CharUnits BaseOffsetInLayoutClass,
                         FinalOverriders::OverriderInfo Overrider);
 
+  /// MSComputeThisAdjustmentForThunk - Compute the 'this' pointer adjustment.
+  /// In MS ABI this is sly thing. Microsoft compiler generates general
+  /// function. This function works with 'this' = 'this' + adjustment, but
+  /// this new pointer can point to memory after class.
+  /// For example we have such ierarchy:
+  /// class first{
+  ///   int s;
+  /// public:
+  ///   virtual void asdf() {}
+  /// };
+  /// class second : public virtual first {
+  /// public :
+  ///   int q;
+  ///   virtual void asdf() { q = 90; }
+  /// };
+  /// class third : public virtual second {
+  /// public:
+  /// };
+  /// For second::asdf in third will be generates 
+  /// thunk with adjustor equals 16. When we call
+  /// second::asdf pointer in ecx register will not
+  /// be pointer to second::vbptr.
+  ThisAdjustment
+  MSComputeThisAdjustmentForThunk(const CXXMethodDecl *MD,
+                                  ThunkInfo &Info,
+                                  const ASTRecordLayout::VBaseInfo &VI,
+                                  const CXXBasePath &Path,
+                          FinalOverriders::OverriderInfo Overrider);
+
   /// AddMethod - Add a single virtual member function to the vtable
   /// components vector.
   void AddMethod(const CXXMethodDecl *MD, ReturnAdjustment ReturnAdjustment);
@@ -941,6 +972,26 @@
                   CharUnits FirstBaseOffsetInLayoutClass,
                   PrimaryBasesSetVectorTy &PrimaryBases);
 
+  /// r4start
+  void AddAllVirtualFunctions(const CXXRecordDecl *RD, 
+                              bool IgnoreDestructor = true);
+
+  /// r4start
+  bool IsThunkRequire(const CXXMethodDecl *Overridden, 
+                      const CXXMethodDecl *Overrider,
+                      const ASTRecordLayout::VBaseInfo &VI) const;
+  bool IsVtordispEx(const CXXMethodDecl *Overridden, 
+                    const CXXMethodDecl *Overrider) const;
+
+  void GenerateVFTable(OverriddersMapTy &OverridersMap,
+                       CXXBasePath &Path);
+
+  /// r4start
+  void FillVFTable(CXXBasePath &Path);
+
+  /// r4start
+  void MSAddMethods();
+
   // LayoutVTable - Layout the vtable for the given base class, including its
   // secondary vtables and any vtables for virtual bases.
   void LayoutVTable();
@@ -979,10 +1030,16 @@
 
   /// isBuildingConstructionVTable - Return whether this vtable builder is
   /// building a construction vtable.
-  bool isBuildingConstructorVTable() const { 
+  /// r4start
+  bool isBuildingConstructorVTable() const {
+    if (Context.getTargetInfo().getCXXABI() == CXXABI_Microsoft)
+      return false;
     return MostDerivedClass != LayoutClass;
   }
 
+  /// r4start
+  void MSLayoutVFTable();
+
 public:
   VTableBuilder(VTableContext &VTables, const CXXRecordDecl *MostDerivedClass,
                 CharUnits MostDerivedClassOffset, 
@@ -1286,7 +1343,128 @@
   
   return Adjustment;
 }
+
+static CharUnits GetClassOffset(const ASTContext &Ctx,
+                                const CXXRecordDecl *RD,
+                                const CXXRecordDecl *Base) {
+  assert(RD != Base && 
+         "GetClassOffset can`t work if RD equal Base");
+
+  CharUnits BaseOffset;
+
+  if (RD->isVirtuallyDerivedFrom(const_cast<CXXRecordDecl *>(Base))) {
+    const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
+    return Layout.getVBaseClassOffset(Base);
+  }
+
+  CXXBasePaths InhPaths;
+  InhPaths.setOrigin(const_cast<CXXRecordDecl *>(RD));
+  RD->lookupInBases(&CXXRecordDecl::FindBaseClass, 
+                 const_cast<CXXRecordDecl *>(Base), InhPaths);
+
+  assert(InhPaths.begin() != InhPaths.end() &&
+         "Can`t find inheritance path from RD to Base!");
   
+  CXXBasePath& Path = InhPaths.front();
+
+  for (CXXBasePath::const_iterator I = Path.begin(),
+       E = Path.end(); I != E; ++I) {
+    const CXXRecordDecl *BaseElem = I->Base->getType()->getAsCXXRecordDecl();
+    const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(I->Class);
+
+    if (I->Base->isVirtual())
+      BaseOffset += Layout.getVBaseClassOffset(BaseElem);
+    else
+      BaseOffset += Layout.getBaseClassOffset(BaseElem);
+  }
+
+  return BaseOffset;
+}
+
+static ASTRecordLayout::VBaseOffsetsMapTy::const_iterator
+GetVBaseInfo(ASTContext &Ctx, const CXXRecordDecl *RD,const CXXBasePath &Path) {
+  const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
+  const ASTRecordLayout::VBaseOffsetsMapTy 
+    &VBases = Layout.getVBaseOffsetsMap();
+  ASTRecordLayout::VBaseOffsetsMapTy::const_iterator
+    VBaseInfo = VBases.end();
+
+  for (CXXBasePath::const_iterator I = Path.begin(),
+       E = Path.end(); I != E; ++I) {
+    const CXXRecordDecl *Base = I->Base->getType()->getAsCXXRecordDecl();
+    if ((VBaseInfo = VBases.find(Base)) != VBases.end() && 
+        VBaseInfo->second.IsVtordispPresent)
+      return VBaseInfo;
+  }
+}
+
+ThisAdjustment
+VTableBuilder::MSComputeThisAdjustmentForThunk(const CXXMethodDecl *MD,
+                                               ThunkInfo &Info,
+                                           const ASTRecordLayout::VBaseInfo &VI,
+                                               const CXXBasePath &Path,
+                                    FinalOverriders::OverriderInfo Overrider) {
+  const CXXRecordDecl *Base = MD->getParent();
+  const CXXRecordDecl *RD = Overrider.Method->getParent();
+  
+  const ASTRecordLayout &Layout = Context.getASTRecordLayout(LayoutClass);
+  const ASTRecordLayout &RDLayout = Context.getASTRecordLayout(RD);
+  ThisAdjustment Ret;
+
+  if ((Base == RD || LayoutClass == RD) &&
+      !VI.IsVtordispPresent ||
+      Base == RDLayout.getPrimaryBase())
+    return Ret;
+
+  CharUnits BaseOffsetInRD = GetClassOffset(Context, RD, Base);
+
+  if (LayoutClass == RD) {
+    Ret.NonVirtual = BaseOffsetInRD.getQuantity();
+
+    if (VI.IsVtordispPresent) {
+      Ret.VCallOffsetOffset = 4;
+      Ret.NonVirtual = 0;
+    }
+
+    return Ret;
+  }
+
+  CharUnits BaseOffsetInLayout = GetClassOffset(Context, LayoutClass, Base);
+  CharUnits RDOffsetInLayout = GetClassOffset(Context, LayoutClass, RD);
+
+  // vtordisp
+  if (VI.IsVtordispPresent) {
+    Ret.VCallOffsetOffset = 4;
+  }
+
+  if (BaseOffsetInLayout - RDOffsetInLayout < BaseOffsetInRD) {
+
+    const ASTRecordLayout &BaseLayout = Context.getASTRecordLayout(Base);
+    const ASTRecordLayout::VBaseOffsetsMapTy 
+      &RDVbases = RDLayout.getVBaseOffsetsMap();
+    ASTRecordLayout::VBaseOffsetsMapTy::const_iterator
+      VI = RDVbases.find(Base);
+
+    CharUnits VtordispCorrection;
+    if (VI != RDVbases.end() &&
+        VI->second.IsVtordispPresent)
+      VtordispCorrection = CharUnits::fromQuantity(4);
+
+    Ret.NonVirtual = (RDLayout.getNonVirtualSize() + 
+      BaseLayout.getNonVirtualSize() + VtordispCorrection).getQuantity();
+
+    Info.VFPtrOffset = 
+      (BaseOffsetInLayout + BaseLayout.getVFPtrOffset()).getQuantity();
+
+    if (IsVtordispEx(MD, Overrider.Method)) {
+      Ret.NonVirtual -= 
+        (RDOffsetInLayout - Layout.getVBPtrOffset()).getQuantity();
+    }
+  }
+
+  return Ret;
+}
+
 void 
 VTableBuilder::AddMethod(const CXXMethodDecl *MD,
                          ReturnAdjustment ReturnAdjustment) {
@@ -1563,7 +1741,312 @@
   }
 }
 
+static void ReplaceOverridden(const CXXMethodDecl *MD,
+                              const CXXRecordDecl *Base,
+                              VTableBuilder::OverriddersMapTy &OverridersMap,
+                     llvm::SmallVector<const CXXMethodDecl *, 8> &Methods) {
+  for (CXXMethodDecl::method_iterator Overridden = 
+       MD->begin_overridden_methods(), OverE = MD->end_overridden_methods();
+       Overridden != OverE; ++Overridden) {
+
+    const CXXMethodDecl *OverMD = *Overridden;
+    
+    if (OverMD->getParent() == Base) {
+      auto I = std::find(Methods.begin(), Methods.end(), OverMD);
+
+      assert(I != Methods.end() && 
+             "Can not find overloaded method in vftable!");
+
+      Methods.insert(I, MD);
+
+      if (OverridersMap.count(OverMD)) {
+        const CXXMethodDecl *Parent = OverridersMap[OverMD];
+
+        Methods.erase(std::find(Methods.begin(), Methods.end(), OverMD));
+        Methods.erase(std::find(Methods.begin(), Methods.end(), Parent));
+
+        OverridersMap.erase(OverMD);
+        OverridersMap.insert(std::make_pair(MD, Parent));
+      } else {
+        Methods.erase(std::find(Methods.begin(), Methods.end(), OverMD));
+        OverridersMap.insert(std::make_pair(MD, OverMD));
+      }
+
+      return;
+    }
+  }
+}
+
+static void ReplaceOverriddenDestructor(const CXXMethodDecl *MD,
+                         llvm::SmallVector<const CXXMethodDecl *, 8> &VFTable) {
+  auto I = std::find_if(VFTable.begin(), VFTable.end(),
+          [](const CXXMethodDecl *MD) -> bool {
+            return isa<CXXDestructorDecl>(MD);
+        });
+
+  if (I == VFTable.end()) {
+    return;
+  }
+
+  const CXXMethodDecl *Destructor = *I;
+  VFTable.insert(I, MD);
+  VFTable.erase(std::find(VFTable.begin(), VFTable.end(), Destructor));
+}
+
+void VTableBuilder::AddAllVirtualFunctions(const CXXRecordDecl *RD, 
+                                           bool IgnoreDestructor) {
+  for (CXXRecordDecl::method_iterator M = RD->method_begin(),
+       E = RD->method_end(); M != E; ++M) {
+    const CXXMethodDecl *MD = *M;
+
+    if (!MD->isVirtual())
+      continue;
+
+    if (isa<CXXDestructorDecl>(MD) && !IgnoreDestructor)
+      VFTable.push_back(MD);
+
+    if (MD->size_overridden_methods())
+      continue;
+
+    VFTable.push_back(MD);
+  }
+}
+
+bool VTableBuilder::IsThunkRequire(const CXXMethodDecl *Overridden,
+                                   const CXXMethodDecl *Overrider,
+                                   const ASTRecordLayout::VBaseInfo &VI) const {
+  const ASTRecordLayout &Layout = Context.getASTRecordLayout(LayoutClass);
+
+  const ASTRecordLayout::VBaseOffsetsMapTy 
+    &VBases = Layout.getVBaseOffsetsMap();
+  
+  if (VI.IsVtordispPresent)
+    return true;
+
+  if (MostDerivedClass == LayoutClass ||
+      Overrider->getParent() == LayoutClass)
+    return false;
+
+  const CXXRecordDecl *RD = Overrider->getParent();
+  const CXXRecordDecl *Base = Overridden->getParent();
+
+  CharUnits BaseOffsetInLayout = GetClassOffset(Context, LayoutClass, Base);
+  CharUnits RDOffsetInLayout = GetClassOffset(Context, LayoutClass, RD);
+
+  if (BaseOffsetInLayout < RDOffsetInLayout)
+    return true;
+  
+  CharUnits BaseOffsetInRD = GetClassOffset(Context, RD, Base);
+  const ASTRecordLayout &RDLayout = Context.getASTRecordLayout(RD);
+
+  assert(RDLayout.getFieldCount() && 
+         "IsThunkRequire doesn`t work with classes without fields!");
+  
+  CharUnits FieldOffset = 
+    CharUnits::fromQuantity(RDLayout.getFieldOffset(0) / 8);
+  CharUnits ThisAdjInRD = BaseOffsetInRD - FieldOffset;
+  CharUnits ThisAdjInLayoutClass = 
+    BaseOffsetInLayout - (FieldOffset + RDOffsetInLayout);
+
+  if (ThisAdjInRD != ThisAdjInLayoutClass)
+    return true;
+
+  return false;
+}
+
+namespace {
+class FindFunctionBase : 
+ public std::unary_function<const CXXBaseSpecifier &, bool> {
+  const CXXRecordDecl *OverriderBase;
+public:
+  FindFunctionBase(const CXXRecordDecl *RD) :
+   OverriderBase(RD) {}
+
+  bool operator ()(const CXXBaseSpecifier &Base) {
+    if (Base.getType()->getAsCXXRecordDecl() == OverriderBase &&
+        !Base.isVirtual())
+      return true;
+    return false;
+  }
+};
+
+class FindVBaseInfo : 
+ public std::unary_function<const CXXBasePathElement &, bool> {
+  const ASTRecordLayout::VBaseOffsetsMapTy &VBases;
+  ASTRecordLayout::VBaseInfo VI;
+public:
+  FindVBaseInfo(ASTContext &Ctx, const CXXRecordDecl *Class) :
+   VBases(Ctx.getASTRecordLayout(Class).getVBaseOffsetsMap()) {}
+
+  bool operator () (const CXXBasePathElement &Elem) {
+    const CXXRecordDecl *Base = Elem.Base->getType()->getAsCXXRecordDecl();
+    ASTRecordLayout::VBaseOffsetsMapTy::const_iterator VBaseInfo;
+    if ((VBaseInfo = VBases.find(Base)) != VBases.end() && 
+        VBaseInfo->second.IsVtordispPresent) {
+      VI = VBaseInfo->second;
+      return true;
+    }
+    return false;
+  }
+
+  const ASTRecordLayout::VBaseInfo &getVBaseInfo() const {
+    return VI;
+  }
+};
+}
+
+bool VTableBuilder::IsVtordispEx(const CXXMethodDecl *Overridden,
+                                 const CXXMethodDecl *Overrider) const {
+  if (Overrider->getParent() == LayoutClass)
+    return false;
+
+  const ASTRecordLayout &Layout = Context.getASTRecordLayout(LayoutClass);
+  
+  const ASTRecordLayout::VBaseOffsetsMapTy 
+    &VBases = Layout.getVBaseOffsetsMap();
+  
+  const CXXRecordDecl *OVBase = Overridden->getParent();
+
+  ASTRecordLayout::VBaseOffsetsMapTy::const_iterator 
+    VBaseInfo = VBases.find(OVBase);
+
+  const CXXBaseSpecifier *OverriderBase = 
+    std::find_if(LayoutClass->bases_begin(),
+                 LayoutClass->bases_end(),
+                 FindFunctionBase(Overrider->getParent()));
+
+  if (VBaseInfo != VBases.end() &&
+      VBaseInfo->second.IsVtordispPresent &&
+      OVBase != LayoutClass &&
+      OverriderBase == LayoutClass->bases_end())
+    return true;
+  return false;
+}
+
+void VTableBuilder::GenerateVFTable(OverriddersMapTy &OverriddersMap,
+                                    CXXBasePath &Path) {
+  int idx = 1;
+  FindVBaseInfo vbaseInfoFinder(Context, LayoutClass);
+  CXXBasePathElement *PathPoint = 
+    std::find_if(Path.begin(), Path.end(), vbaseInfoFinder);
+
+  for (auto I = VFTable.begin(), E = VFTable.end();
+       I != E; ++I, ++idx) {
+    if (OverriddersMap.count(*I)){
+      OverriddersMapTy::iterator Elem = OverriddersMap.find(*I);
+
+      if (PathPoint != Path.end() &&
+          IsThunkRequire(Elem->second, Elem->first, 
+                         vbaseInfoFinder.getVBaseInfo())) {
+        
+        FinalOverriders::OverriderInfo Overrider;
+
+        Overrider.Method = Elem->first;
+        ThunkInfo Info;
+        Info.VFPtrOffset = uint32_t(-1);
+
+        ThisAdjustment TA = 
+          MSComputeThisAdjustmentForThunk(Elem->second, Info, 
+                                          vbaseInfoFinder.getVBaseInfo(),
+                                          Path, Overrider);
+
+        Info.This = TA;
+        Info.IsVtordispEx = IsVtordispEx(Elem->second, Elem->first);
+
+        AddThunk(*I, Info);
+        VTableThunks.insert(std::make_pair(idx, Info));
+
+        if (isa<CXXDestructorDecl>(*I))
+          llvm_unreachable("Can not build virtual dtor thunk!");
+        else
+          Components.push_back(VTableComponent::MakeFunction(*I));
+        
+        continue;
+      }
+    }
+
+    if (isa<CXXDestructorDecl>(*I))
+      Components.push_back(
+                VTableComponent::MakeCompleteDtor(cast<CXXDestructorDecl>(*I)));
+    else
+      Components.push_back(VTableComponent::MakeFunction(*I));
+  }
+}
+
+void VTableBuilder::FillVFTable(CXXBasePath &Path) {
+  bool IsPrimary = true;
+  OverriddersMapTy OverridersMap;
+  
+  for (CXXBasePath::reverse_iterator I = Path.rbegin(),
+       E = Path.rend(); I != E; ++I) {
+    const CXXRecordDecl *Decl = I->Base->getType()->getAsCXXRecordDecl();
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(I->Class);
+
+    IsPrimary = (Decl == Layout.getPrimaryBase()) && IsPrimary;
+    
+    for (CXXRecordDecl::method_iterator M = I->Class->method_begin(),
+         ME = I->Class->method_end(); M != ME; ++M) {
+      const CXXMethodDecl *MD = *M;
+
+      if (!MD->isVirtual())
+        continue;
+
+      if (IsPrimary && !MD->size_overridden_methods()) {
+        VFTable.push_back(MD);
+        continue;
+      }
+
+      if (isa<CXXDestructorDecl>(MD)){
+        ReplaceOverriddenDestructor(MD, VFTable);
+      } else if (MD->size_overridden_methods() && 
+                 !isa<CXXDestructorDecl>(MD)) {
+        ReplaceOverridden(MD, Decl, OverridersMap, VFTable);
+      }
+    }
+  }
+
+  GenerateVFTable(OverridersMap, Path);
+}
+
+void VTableBuilder::MSAddMethods() {
+  if (LayoutClass == MostDerivedClass) {
+    AddAllVirtualFunctions(LayoutClass, false);
+
+    OverriddersMapTy EmptyMap;
+    CXXBasePath EmptyPath;
+    GenerateVFTable(EmptyMap, EmptyPath);
+    
+    return;
+  }
+
+  CXXBasePaths Paths;
+  Paths.setOrigin(const_cast<CXXRecordDecl *>(LayoutClass));
+
+  LayoutClass->lookupInBases(&CXXRecordDecl::FindBaseClass, 
+                          const_cast<CXXRecordDecl *>(MostDerivedClass), Paths);
+  
+  AddAllVirtualFunctions(MostDerivedClass);
+
+  FillVFTable(Paths.front());
+}
+
+void VTableBuilder::MSLayoutVFTable() {
+  assert(MostDerivedClass && "MostDerived must not be 0!");
+  assert(LayoutClass && "LayoutClass must not be 0!");
+
+  // Add RTTI
+  Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass));
+
+  MSAddMethods();
+
+  //ComputeThisAdjustments();
+}
+
 void VTableBuilder::LayoutVTable() {
+  // r4start
+  if (Context.getTargetInfo().getCXXABI() == CXXABI_Microsoft) {
+    return MSLayoutVFTable();
+  }
   LayoutPrimaryAndSecondaryVTables(BaseSubobject(MostDerivedClass,
                                                  CharUnits::Zero()),
                                    /*BaseIsMorallyVirtual=*/false,
@@ -2299,7 +2782,7 @@
   assert(I != NumVirtualFunctionPointers.end() && "Did not find entry!");
   return I->second;
 }
-      
+
 uint64_t VTableContext::getMethodVTableIndex(GlobalDecl GD) {
   MethodVTableIndicesTy::iterator I = MethodVTableIndices.find(GD);
   if (I != MethodVTableIndices.end())
@@ -2394,6 +2877,24 @@
   }
 }
 
+// r4start
+void 
+VTableContext::ComputeVFTableRelatedInformation(const CXXRecordDecl *RD,
+                                                const CXXRecordDecl *Base) {
+
+  const VTableLayout *&Entry = VFTablesLayouts[RD][Base];
+
+  // Check if we've computed this information before.
+  if (Entry)
+    return;
+ 
+  VTableBuilder Builder(*this, Base, CharUnits::Zero(), 
+    /*MostDerivedClassIsVirtual=*/0, RD);
+  Entry = CreateVTableLayout(Builder);
+ 
+  Thunks.insert(Builder.thunks_begin(), Builder.thunks_end());
+}
+
 VTableLayout *VTableContext::createConstructionVTableLayout(
                                           const CXXRecordDecl *MostDerivedClass,
                                           CharUnits MostDerivedClassOffset,
@@ -2403,3 +2904,13 @@
                         MostDerivedClassIsVirtual, LayoutClass);
   return CreateVTableLayout(Builder);
 }
+
+const VTableContext::ThunkInfoVectorTy *
+VTableContext::getThunkInfoMS(const CXXMethodDecl *MD) {
+  ThunksMapTy::const_iterator I = Thunks.find(MD);
+  if (I == Thunks.end()) {
+    // We did not find a thunk for this method.
+    return 0;
+  }
+  return &I->second;
+}
Index: lib/CodeGen/CGClass.cpp
===================================================================
--- lib/CodeGen/CGClass.cpp	(revision 154277)
+++ lib/CodeGen/CGClass.cpp	(working copy)
@@ -272,11 +272,13 @@
   return Value;
 }
                              
+/// r4start
 /// GetVTTParameter - Return the VTT parameter that should be passed to a
 /// base constructor/destructor with virtual bases.
 static llvm::Value *GetVTTParameter(CodeGenFunction &CGF, GlobalDecl GD,
                                     bool ForVirtualBase) {
-  if (!CodeGenVTables::needsVTTParameter(GD)) {
+  if (!CodeGenVTables::needsVTTParameter(GD) ||
+      CGF.CGM.getContext().getTargetInfo().getCXXABI() == CXXABI_Microsoft) {
     // This constructor/destructor does not need a VTT parameter.
     return 0;
   }
@@ -368,7 +370,7 @@
 static void EmitBaseInitializer(CodeGenFunction &CGF, 
                                 const CXXRecordDecl *ClassDecl,
                                 CXXCtorInitializer *BaseInit,
-                                CXXCtorType CtorType) {
+                                CXXCtorType CtorType, bool FromCtor = false) {
   assert(BaseInit->isBaseInitializer() &&
          "Must have base initializer!");
 
@@ -403,7 +405,7 @@
                           AggValueSlot::DoesNotNeedGCBarriers,
                           AggValueSlot::IsNotAliased);
 
-  CGF.EmitAggExpr(BaseInit->getInit(), AggSlot);
+  CGF.EmitAggExpr(BaseInit->getInit(), AggSlot, false, FromCtor);
   
   if (CGF.CGM.getLangOpts().Exceptions && 
       !BaseClassDecl->hasTrivialDestructor())
@@ -707,6 +709,7 @@
   return true;
 }
 
+/// r4start
 /// EmitConstructorBody - Emits the body of the current constructor.
 void CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) {
   const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(CurGD.getDecl());
@@ -714,7 +717,9 @@
 
   // Before we go any further, try the complete->base constructor
   // delegation optimization.
-  if (CtorType == Ctor_Complete && IsConstructorDelegationValid(Ctor)) {
+  if (CtorType == Ctor_Complete && 
+      IsConstructorDelegationValid(Ctor) &&
+      CGM.getContext().getTargetInfo().getCXXABI() != CXXABI_Microsoft) {
     if (CGDebugInfo *DI = getDebugInfo()) 
       DI->EmitLocation(Builder, Ctor->getLocEnd());
     EmitDelegateCXXConstructorCall(Ctor, Ctor_Base, Args);
@@ -763,14 +768,58 @@
     return EmitDelegatingCXXConstructorCall(CD, Args);
 
   const CXXRecordDecl *ClassDecl = CD->getParent();
+  llvm::SmallPtrSet<CXXCtorInitializer *, 8> VisitedCtorInitializers;
 
+  // r4start
+  if (CGM.getContext().getTargetInfo().getCXXABI() == CXXABI_Microsoft &&
+      ClassDecl->getNumVBases()) {
+    llvm::Constant *Zero = llvm::ConstantInt::get(CGM.Int32Ty, 0);
+    llvm::Value *FlagParam = 
+      (++(CurFn->arg_begin()))->getValueName()->getValue();
+    llvm::Value *Condition = Builder.CreateICmpEQ(Zero, FlagParam, "spices");
+
+    llvm::BasicBlock *VBTableInit = 
+      llvm::BasicBlock::Create(CGM.getLLVMContext(), "vbtable.init", CurFn);
+    llvm::BasicBlock *VBTableSkipInit = 
+      llvm::BasicBlock::Create(CGM.getLLVMContext(), "skip.vbtable.init");
+
+    Builder.CreateCondBr(Condition, VBTableInit, VBTableSkipInit);
+
+    Builder.SetInsertPoint(VBTableInit);
+
+    MSInitializeVBTablePointers(ClassDecl);
+
+    // In MS ABI we must emit virtual base initializers before vf-table init.
+    for (CXXConstructorDecl::init_const_iterator M = CD->init_begin(),
+         E = CD->init_end(); M != E; ++M) {
+      CXXCtorInitializer *Member = *M;
+      
+      if (Member->isBaseInitializer()) {
+        CXXRecordDecl *BaseClass = 
+          Member->getBaseClass()->getAsCXXRecordDecl();
+        if (ClassDecl->isVirtuallyDerivedFrom(BaseClass)) {
+          VisitedCtorInitializers.insert(Member);
+          EmitBaseInitializer(*this, ClassDecl, Member, CtorType, true);
+        }
+      }
+    }
+
+    Builder.CreateBr(VBTableSkipInit);
+
+    CurFn->getBasicBlockList().push_back(VBTableSkipInit);
+    Builder.SetInsertPoint(VBTableSkipInit);
+  }
+
   SmallVector<CXXCtorInitializer *, 8> MemberInitializers;
   
   for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
        E = CD->init_end();
        B != E; ++B) {
+    if (VisitedCtorInitializers.count(*B))
+      continue;
+
     CXXCtorInitializer *Member = (*B);
-    
+
     if (Member->isBaseInitializer()) {
       EmitBaseInitializer(*this, ClassDecl, Member, CtorType);
     } else {
@@ -1218,7 +1267,8 @@
                                         CXXCtorType Type, bool ForVirtualBase,
                                         llvm::Value *This,
                                         CallExpr::const_arg_iterator ArgBeg,
-                                        CallExpr::const_arg_iterator ArgEnd) {
+                                        CallExpr::const_arg_iterator ArgEnd,
+                                        bool CallFromCtor) {
 
   CGDebugInfo *DI = getDebugInfo();
   if (DI && CGM.getCodeGenOpts().LimitDebugInfo) {
@@ -1251,7 +1301,8 @@
   llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(D, Type), ForVirtualBase);
   llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
 
-  EmitCXXMemberCall(D, Callee, ReturnValueSlot(), This, VTT, ArgBeg, ArgEnd);
+  EmitCXXMemberCall(D, Callee, ReturnValueSlot(), This, VTT, 
+                    ArgBeg, ArgEnd, CallFromCtor);
 }
 
 void
@@ -1469,25 +1520,30 @@
   // Compute the address point.
   llvm::Value *VTableAddressPoint;
 
-  // Check if we need to use a vtable from the VTT.
-  if (CodeGenVTables::needsVTTParameter(CurGD) &&
-      (RD->getNumVBases() || NearestVBase)) {
-    // Get the secondary vpointer index.
-    uint64_t VirtualPointerIndex = 
-     CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);
+  // r4start
+  if (Target.getCXXABI() != CXXABI_Microsoft) {
+    // Check if we need to use a vtable from the VTT.
+    if (CodeGenVTables::needsVTTParameter(CurGD) &&
+        (RD->getNumVBases() || NearestVBase)) {
+      // Get the secondary vpointer index.
+      uint64_t VirtualPointerIndex = 
+       CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);
     
-    /// Load the VTT.
-    llvm::Value *VTT = LoadCXXVTT();
-    if (VirtualPointerIndex)
-      VTT = Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex);
+      /// Load the VTT.
+      llvm::Value *VTT = LoadCXXVTT();
+      if (VirtualPointerIndex)
+        VTT = Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex);
 
-    // And load the address point from the VTT.
-    VTableAddressPoint = Builder.CreateLoad(VTT);
+      // And load the address point from the VTT.
+      VTableAddressPoint = Builder.CreateLoad(VTT);
+    } else {
+      uint64_t AddressPoint =
+        CGM.getVTableContext().getVTableLayout(VTableClass).getAddressPoint(Base);
+      VTableAddressPoint =
+        Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint);
+    }
   } else {
-    uint64_t AddressPoint =
-      CGM.getVTableContext().getVTableLayout(VTableClass).getAddressPoint(Base);
-    VTableAddressPoint =
-      Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint);
+   llvm_unreachable("Use MSInitializeVFTablePointer padawan!");
   }
 
   // Compute where to store the address point.
@@ -1586,6 +1642,11 @@
   if (!RD->isDynamicClass())
     return;
 
+  // r4start
+  if (CGM.getContext().getTargetInfo().getCXXABI() == CXXABI_Microsoft) {
+    return MSInitializeVFTablePointers(RD);
+  }
+
   // Get the VTable.
   llvm::Constant *VTable = CGM.getVTables().GetAddrOfVTable(RD);
 
@@ -1598,6 +1659,173 @@
                            VTable, RD, VBases);
 }
 
+void CodeGenFunction::MSInitializeVBTablePointer(llvm::Constant *VBTable,
+                                                 CharUnits Offset) {
+  llvm::Value *ThisPtr = LoadCXXThis();
+
+  ThisPtr = Builder.CreateBitCast(ThisPtr, Int8PtrTy);
+
+  llvm::Value *VBPtr = 
+    Builder.CreateConstInBoundsGEP1_64(ThisPtr, Offset.getQuantity(), 
+                                       "vbptr.field");
+
+  llvm::Value *VBTableAddressPoint = 
+    Builder.CreateConstInBoundsGEP1_64(VBTable, 0, "vbtable.addr");
+
+  llvm::Type *AddressPointerTy = VBTableAddressPoint->getType()->getPointerTo();
+  VBPtr = Builder.CreateBitCast(VBPtr, AddressPointerTy, "vbptr");
+
+  Builder.CreateStore(VBTableAddressPoint, VBPtr);
+}
+
+// r4start
+void CodeGenFunction::MSInitializeVBTablePointers(const CXXRecordDecl *Class) {
+  assert(Class && "Can not generate vb-table for null class!");
+
+  if (!Class->getNumVBases())
+    return;
+  
+  VBTableContext& Context = CGM.getVBTableContext();
+  auto VBTables = Context.getVBTables(Class);
+  for (auto I = VBTables.begin(), E = VBTables.end(); I != E; ++I) {
+    llvm::GlobalVariable *VBTable = 
+      CGM.getVTables().GetAddrOfVBTable(Class, I->first);
+
+    const VBTableContext::BaseVBTableTy &Table = I->second;
+
+    llvm::SmallVector<llvm::Constant *, 32> Offsets;
+
+    for (VBTableContext::BaseVBTableTy::const_iterator I = Table.begin(),
+         E = Table.end(); I != E; ++I) {
+      VBTableContext::VBTableEntry Entry = I->first;
+
+      Offsets.push_back(llvm::ConstantInt::get(Int32Ty, Entry.offset));
+    }
+
+    llvm::ArrayType *VBTableType = llvm::ArrayType::get(Int32Ty, Table.size());
+    llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets);
+
+    VBTable->setInitializer(Init);
+    MSInitializeVBTablePointer(VBTable, 
+                       CharUnits::fromQuantity(-(Table.begin()->first.offset)));
+  }
+}
+
+// r4start
+void CodeGenFunction::MSInitializeVFTablePointer(llvm::Constant *VFTable,
+                                                 CharUnits Offset) {
+  llvm::Value *ThisPtr = LoadCXXThis();
+
+  ThisPtr = Builder.CreateBitCast(ThisPtr, Int8PtrTy);
+
+  llvm::Value *VFPtr = 
+    Builder.CreateConstInBoundsGEP1_64(ThisPtr, Offset.getQuantity(), 
+                                       "vfptr.field");
+
+  llvm::Value *VTableAddressPoint = 
+    Builder.CreateConstInBoundsGEP2_64(VFTable, 0, 1, "vtable.addr");
+
+  llvm::Type *AddressPointerTy = VTableAddressPoint->getType()->getPointerTo();
+  VFPtr = Builder.CreateBitCast(VFPtr, AddressPointerTy, "vfptr");
+
+  Builder.CreateStore(VTableAddressPoint, VFPtr);
+}
+
+static CharUnits GetClassOffset(const ASTContext &Ctx,
+                                const CXXRecordDecl *RD,
+                                const CXXRecordDecl *Base) {
+  assert(RD != Base && 
+         "GetClassOffset can`t work if RD equal Base");
+
+  CharUnits BaseOffset;
+
+  if (RD->isVirtuallyDerivedFrom(const_cast<CXXRecordDecl *>(Base))) {
+    const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
+    return Layout.getVBaseClassOffset(Base);
+  }
+
+  CXXBasePaths InhPaths;
+  InhPaths.setOrigin(const_cast<CXXRecordDecl *>(RD));
+  RD->lookupInBases(&CXXRecordDecl::FindBaseClass, 
+                 const_cast<CXXRecordDecl *>(Base), InhPaths);
+
+  assert(InhPaths.begin() != InhPaths.end() &&
+         "Can`t find inheritance path from RD to Base!");
+  
+  CXXBasePath& Path = InhPaths.front();
+
+  for (CXXBasePath::const_iterator I = Path.begin(),
+       E = Path.end(); I != E; ++I) {
+    const CXXRecordDecl *BaseElem = I->Base->getType()->getAsCXXRecordDecl();
+    const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(I->Class);
+
+    if (I->Base->isVirtual())
+      BaseOffset += Layout.getVBaseClassOffset(BaseElem);
+    else
+      BaseOffset += Layout.getBaseClassOffset(BaseElem);
+  }
+
+  return BaseOffset;
+}
+
+// r4start
+void CodeGenFunction::MSInitializeVFTablePointers(const CXXRecordDecl *MostDerived, 
+                                                  const CXXRecordDecl *RD, 
+                                                  const CXXRecordDecl *Base) {
+  for (CXXRecordDecl::base_class_const_iterator I = Base->bases_begin(),
+       E = Base->bases_end(); I != E; ++I) {
+    const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
+
+    if (!BaseDecl->isPolymorphic())
+      continue;
+
+    MSInitializeVFTablePointers(MostDerived, Base, BaseDecl);
+  }
+
+  const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(Base);
+  if (Layout.getPrimaryBase() ||
+      Layout.getVFPtrOffset() == CharUnits::fromQuantity(-1))
+    return;
+
+  llvm::Constant *VFTable = 
+    CGM.getVTables().GetAddrOfVFTable(MostDerived, Base);
+
+  CharUnits VFPtrOffset = 
+    GetClassOffset(CGM.getContext(), MostDerived, Base) + 
+                                                        Layout.getVFPtrOffset();
+
+  MSInitializeVFTablePointer(VFTable, VFPtrOffset);
+}
+
+// r4start
+void CodeGenFunction::MSInitializeVFTablePointers(const CXXRecordDecl *RD) {
+  if (!RD->getNumBases()) {
+    // At now only build vftable
+    llvm::Constant *VFTable = CGM.getVTables().GetAddrOfVFTable(RD, 0);
+    MSInitializeVFTablePointer(VFTable, CharUnits::fromQuantity(0));
+    return;
+  }
+
+  const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
+
+  if (Layout.getVFPtrOffset() != CharUnits::fromQuantity(-1)) {
+    llvm::Constant *VFTable = 
+      CGM.getVTables().GetAddrOfVFTable(RD, 0);
+
+    MSInitializeVFTablePointer(VFTable, Layout.getVFPtrOffset());
+  }
+
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
+
+    if (!Base->isPolymorphic())
+      continue;
+
+    MSInitializeVFTablePointers(RD, RD, Base);
+  }
+}
+
 llvm::Value *CodeGenFunction::GetVTablePtr(llvm::Value *This,
                                            llvm::Type *Ty) {
   llvm::Value *VTablePtrSrc = Builder.CreateBitCast(This, Ty->getPointerTo());
Index: lib/CodeGen/CGCXX.cpp
===================================================================
--- lib/CodeGen/CGCXX.cpp	(revision 154277)
+++ lib/CodeGen/CGCXX.cpp	(working copy)
@@ -173,7 +173,9 @@
   return false;
 }
 
-void CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) {
+// r4start
+void CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) 
+{
   // The constructor used for constructing this as a complete class;
   // constucts the virtual bases, then calls the base constructor.
   if (!D->getParent()->isAbstract()) {
@@ -227,16 +229,22 @@
                                                       /*ForVTable=*/false));
 }
 
-void CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) {
-  // The destructor in a virtual table is always a 'deleting'
-  // destructor, which calls the complete destructor and then uses the
-  // appropriate operator delete.
-  if (D->isVirtual())
-    EmitGlobal(GlobalDecl(D, Dtor_Deleting));
+// r4start
+void CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D)
+{
+  if (Context.getTargetInfo().getCXXABI() == CXXABI_Microsoft) {
+    EmitGlobal(GlobalDecl(D, Dtor_Base));
+  } else {
+    // The destructor in a virtual table is always a 'deleting'
+    // destructor, which calls the complete destructor and then uses the
+    // appropriate operator delete.
+    if (D->isVirtual())
+      EmitGlobal(GlobalDecl(D, Dtor_Deleting));
 
-  // The destructor used for destructing this as a most-derived class;
-  // call the base destructor and then destructs any virtual bases.
-  EmitGlobal(GlobalDecl(D, Dtor_Complete));
+    // The destructor used for destructing this as a most-derived class;
+    // call the base destructor and then destructs any virtual bases.
+    EmitGlobal(GlobalDecl(D, Dtor_Complete));
+  }
 
   // The destructor used for destructing this as a base class; ignores
   // virtual bases.
Index: lib/CodeGen/CGExprAgg.cpp
===================================================================
--- lib/CodeGen/CGExprAgg.cpp	(revision 154277)
+++ lib/CodeGen/CGExprAgg.cpp	(working copy)
@@ -35,6 +35,7 @@
   CGBuilderTy &Builder;
   AggValueSlot Dest;
   bool IgnoreResult;
+  bool CallFromCtor;
 
   /// We want to use 'dest' as the return slot except under two
   /// conditions:
@@ -59,9 +60,9 @@
 
 public:
   AggExprEmitter(CodeGenFunction &cgf, AggValueSlot Dest,
-                 bool ignore)
+                 bool ignore, bool CallType = false)
     : CGF(cgf), Builder(CGF.Builder), Dest(Dest),
-      IgnoreResult(ignore) {
+      IgnoreResult(ignore), CallFromCtor(CallType) {
   }
 
   //===--------------------------------------------------------------------===//
@@ -780,7 +781,7 @@
 void
 AggExprEmitter::VisitCXXConstructExpr(const CXXConstructExpr *E) {
   AggValueSlot Slot = EnsureSlot(E->getType());
-  CGF.EmitCXXConstructExpr(E, Slot);
+  CGF.EmitCXXConstructExpr(E, Slot, CallFromCtor);
 }
 
 void
@@ -1168,7 +1169,7 @@
 /// \param IsInitializer - true if this evaluation is initializing an
 /// object whose lifetime is already being managed.
 void CodeGenFunction::EmitAggExpr(const Expr *E, AggValueSlot Slot,
-                                  bool IgnoreResult) {
+                                  bool IgnoreResult, bool IsCallFromCtor) {
   assert(E && hasAggregateLLVMType(E->getType()) &&
          "Invalid aggregate expression to emit");
   assert((Slot.getAddr() != 0 || Slot.isIgnored()) &&
@@ -1177,7 +1178,8 @@
   // Optimize the slot if possible.
   CheckAggExprForMemSetUse(Slot, E, *this);
  
-  AggExprEmitter(*this, Slot, IgnoreResult).Visit(const_cast<Expr*>(E));
+  AggExprEmitter(*this, Slot, IgnoreResult, IsCallFromCtor).
+                                                    Visit(const_cast<Expr*>(E));
 }
 
 LValue CodeGenFunction::EmitAggExprToLValue(const Expr *E) {
Index: lib/CodeGen/CGExprCXX.cpp
===================================================================
--- lib/CodeGen/CGExprCXX.cpp	(revision 154277)
+++ lib/CodeGen/CGExprCXX.cpp	(working copy)
@@ -29,7 +29,8 @@
                                           llvm::Value *This,
                                           llvm::Value *VTT,
                                           CallExpr::const_arg_iterator ArgBeg,
-                                          CallExpr::const_arg_iterator ArgEnd) {
+                                          CallExpr::const_arg_iterator ArgEnd,
+                                          bool CallFromCtor) {
   assert(MD->isInstance() &&
          "Trying to emit a member call expr on a static method!");
 
@@ -40,6 +41,8 @@
 
   // If there is a VTT parameter, emit it.
   if (VTT) {
+    assert(CGM.getContext().getTargetInfo().getCXXABI() != CXXABI_Microsoft &&
+           "MS ABI does not have VTT!");
     QualType T = getContext().getPointerType(getContext().VoidPtrTy);
     Args.add(RValue::get(VTT), T);
   }
@@ -47,6 +50,13 @@
   const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
   RequiredArgs required = RequiredArgs::forPrototypePlus(FPT, Args.size());
   
+  // r4start
+  if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases() &&
+      CGM.getContext().getTargetInfo().getCXXABI() == CXXABI_Microsoft) {
+    llvm::Value *Flag = llvm::ConstantInt::get(CGM.Int32Ty, !CallFromCtor);
+    Args.add(RValue::get(Flag), CGM.getContext().Char32Ty);
+  }
+
   // And the rest of the call args.
   EmitCallArgs(Args, FPT, ArgBeg, ArgEnd);
 
@@ -398,7 +408,7 @@
 
 void
 CodeGenFunction::EmitCXXConstructExpr(const CXXConstructExpr *E,
-                                      AggValueSlot Dest) {
+                                      AggValueSlot Dest, bool CallFromCtor) {
   assert(!Dest.isIgnored() && "Must have a destination!");
   const CXXConstructorDecl *CD = E->getConstructor();
   
@@ -464,7 +474,7 @@
     
     // Call the constructor.
     EmitCXXConstructorCall(CD, Type, ForVirtualBase, Dest.getAddr(),
-                           E->arg_begin(), E->arg_end());
+                           E->arg_begin(), E->arg_end(), CallFromCtor);
   }
 }
 
Index: lib/CodeGen/CGRTTI.cpp
===================================================================
--- lib/CodeGen/CGRTTI.cpp	(revision 154277)
+++ lib/CodeGen/CGRTTI.cpp	(working copy)
@@ -11,6 +11,12 @@
 //
 //===----------------------------------------------------------------------===//
 
+// r4start
+#include <list>
+#include <set>
+#include <deque>
+#include "clang/AST/VBTableBuilder.h"
+
 #include "CodeGenModule.h"
 #include "CGCXXABI.h"
 #include "clang/AST/RecordLayout.h"
@@ -26,9 +32,19 @@
   CodeGenModule &CGM;  // Per-module state.
   llvm::LLVMContext &VMContext;
   
+  llvm::Type *Int8PtrTy;
+  
+  /// r4start
+  llvm::Type* Int32Ty;
+  llvm::GlobalVariable::LinkageTypes CurLinkage;
+  
   /// Fields - The fields of the RTTI descriptor currently being built.
   SmallVector<llvm::Constant *, 16> Fields;
 
+  /// r4start
+  /// AmbiguousBases - Set of bases that in MSVC is ambiguous subobjects.
+  llvm::SmallSet<const CXXRecordDecl *, 8> AmbiguousBases;
+
   /// GetAddrOfTypeName - Returns the mangled type name of the given type.
   llvm::GlobalVariable *
   GetAddrOfTypeName(QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage);
@@ -61,9 +77,119 @@
   /// struct, used for member pointer types.
   void BuildPointerToMemberTypeInfo(const MemberPointerType *Ty);
   
+  /// r4start
+  void GetAmbiguousSubobjects(const CXXRecordDecl *RD);
+
+  /// r4start
+  void BuildVBTable(const CXXRecordDecl *RD);
+
+  /// r4start
+  int32_t GetMemberDisplacement(const CXXRecordDecl *RD, CXXRecordDecl *Base);
+
+  /// r4start
+  uint32_t GetAttributesField(const CXXRecordDecl *RD,
+                              CXXRecordDecl *Base);
+
+  /// r4start
+  VBTableContext::VBTableEntry GetVBaseDisplacement(const CXXRecordDecl *RD,
+                                                    CXXRecordDecl *Base);
+
+  /// r4start
+  /// Microsoft specific.
+  llvm::Constant* 
+  BuildRTTIBaseClassDescriptor(const CXXRecordDecl *RD,
+                               CXXRecordDecl *Base);
+
+  /// r4start
+  /// Build Microsoft specific structure Base Class Array.
+  /// This array consists of RTTIBaseClassDescriptor.
+  /// struct RTTIBaseClassDescriptor
+  /// {
+  ///   //type descriptor of the class
+  ///   struct TypeDescriptor* pTypeDescriptor;
+  ///
+  ///   //number of nested classes following in the Base Class Array
+  ///   DWORD numContainedBases;
+  ///
+  ///   //pointer-to-member displacement info
+  ///   struct PMD where;
+  ///
+  ///   //flags, usually 0
+  ///   DWORD attributes;
+  /// };
+  ///
+  /// struct PMD
+  /// {
+  ///   //member displacement
+  ///   int mdisp;
+  ///
+  ///   //vbtable displacement
+  ///   int pdisp;
+  ///
+  ///   //displacement inside vbtable
+  ///   int vdisp;
+  /// };
+  llvm::Constant *BuildRTTIBaseClassArray(const CXXRecordDecl* RD);
+
+  /// r4start
+  /// Build Microsoft specific structure Class Hierarchy Descriptor.
+  /// struct RTTIClassHierarchyDescriptor
+  /// {
+  ///   always zero?
+  ///   DWORD signature;
+  ///
+  ///   bit 0 set = multiple inheritance;
+  ///   bit 1 set = virtual inheritance, only sets with bit 0.
+  ///   bit 2 set = when we have inheritance like this
+  ///   class B {
+  ///   public:
+  ///     virtual void b(){}
+  ///     double b_field;
+  ///   };
+  ///
+  ///   class C :  B {
+  ///   public:
+  ///     virtual void C_f(){}
+  ///     int y;
+  ///   };
+  ///   
+  ///   struct F{};
+  ///   struct FE : F{};
+  ///
+  ///   class A : public C, B, FE, virtual F{
+  ///   public:
+  ///     int a_field;
+  ///     virtual void a(){}
+  ///   };
+  ///   
+  ///   DWORD attributes;
+  ///
+  ///   number of classes in pBaseClassArray
+  ///   DWORD numBaseClasses;
+  ///
+  ///   struct RTTIBaseClassArray* pBaseClassArray;
+  /// };
+  llvm::Constant *BuildRTTIClassHierarchyDescriptor(const CXXRecordDecl* RD);
+
+  /// r4start
+  /// Build Microsoft specific structure RTTI Type Descriptor.
+  /// struct RTTITypeDescriptor 
+  /// {
+  ///  // pointer to type_info vftable
+  ///  struct type_info* pVFTable;
+  /// 
+  ///   //always null?
+  ///   DWORD spare;
+  /// 
+  ///   char* name;
+  /// };
+  llvm::Constant *BuildRTTITypeDescriptor(QualType Ty);
+
 public:
   RTTIBuilder(CodeGenModule &CGM) : CGM(CGM), 
-    VMContext(CGM.getModule().getContext()) { }
+    VMContext(CGM.getModule().getContext()),
+    Int8PtrTy(llvm::Type::getInt8PtrTy(VMContext)),
+    Int32Ty(llvm::Type::getInt32Ty(VMContext)){ }
 
   // Pointer type info flags.
   enum {
@@ -107,6 +233,29 @@
   /// \param Force - true to force the creation of this RTTI value
   /// \param ForEH - true if this is for exception handling
   llvm::Constant *BuildTypeInfo(QualType Ty, bool Force = false);
+
+  /// r4start
+  /// Build Microsoft specific type info - RTTI Complete Object Locator.
+  /// struct RTTICompleteObjectLocator
+  /// {
+  ///   //always zero ?
+  ///   DWORD signature;
+  ///
+  ///   //offset of this vtable in the complete class
+  ///   DWORD offset;
+  ///   
+  ///   //constructor displacement offset
+  ///   DWORD cdOffset;
+  ///
+  ///   //TypeDescriptor of the complete class
+  ///   struct TypeDescriptor* pTypeDescriptor;
+  ///
+  ///   //describes inheritance hierarchy
+  ///   struct RTTIClassHierarchyDescriptor* ClassDescriptor;
+  /// };
+  llvm::Constant *BuildMSTypeInfo(QualType Ty,
+                                  QualType BaseTy,
+                                  bool Force = false);
 };
 }
 
@@ -376,120 +525,128 @@
 }
 
 void RTTIBuilder::BuildVTablePointer(const Type *Ty) {
-  // abi::__class_type_info.
-  static const char * const ClassTypeInfo =
-    "_ZTVN10__cxxabiv117__class_type_infoE";
-  // abi::__si_class_type_info.
-  static const char * const SIClassTypeInfo =
-    "_ZTVN10__cxxabiv120__si_class_type_infoE";
-  // abi::__vmi_class_type_info.
-  static const char * const VMIClassTypeInfo =
-    "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
 
   const char *VTableName = 0;
+  llvm::Constant *VTable;
 
-  switch (Ty->getTypeClass()) {
+  // r4start
+  if (CGM.getContext().getTargetInfo().getCXXABI() == CXXABI_Microsoft) {
+    VTableName = "\01??_7type_info@@6B@";
+
+    VTable = CGM.getModule().getOrInsertGlobal(VTableName, Int8PtrTy);
+  } else {
+    // abi::__class_type_info.
+    static const char * const ClassTypeInfo =
+      "_ZTVN10__cxxabiv117__class_type_infoE";
+    // abi::__si_class_type_info.
+    static const char * const SIClassTypeInfo =
+      "_ZTVN10__cxxabiv120__si_class_type_infoE";
+    // abi::__vmi_class_type_info.
+    static const char * const VMIClassTypeInfo =
+      "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
+
+    switch (Ty->getTypeClass()) {
 #define TYPE(Class, Base)
 #define ABSTRACT_TYPE(Class, Base)
 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
 #define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
 #define DEPENDENT_TYPE(Class, Base) case Type::Class:
 #include "clang/AST/TypeNodes.def"
-    llvm_unreachable("Non-canonical and dependent types shouldn't get here");
+      llvm_unreachable("Non-canonical and dependent types shouldn't get here");
 
-  case Type::LValueReference:
-  case Type::RValueReference:
-    llvm_unreachable("References shouldn't get here");
+    case Type::LValueReference:
+    case Type::RValueReference:
+      llvm_unreachable("References shouldn't get here");
 
-  case Type::Builtin:
-  // GCC treats vector and complex types as fundamental types.
-  case Type::Vector:
-  case Type::ExtVector:
-  case Type::Complex:
-  case Type::Atomic:
-  // FIXME: GCC treats block pointers as fundamental types?!
-  case Type::BlockPointer:
-    // abi::__fundamental_type_info.
-    VTableName = "_ZTVN10__cxxabiv123__fundamental_type_infoE";
-    break;
+    case Type::Builtin:
+    // GCC treats vector and complex types as fundamental types.
+    case Type::Vector:
+    case Type::ExtVector:
+    case Type::Complex:
+    case Type::Atomic:
+    // FIXME: GCC treats block pointers as fundamental types?!
+    case Type::BlockPointer:
+      // abi::__fundamental_type_info.
+      VTableName = "_ZTVN10__cxxabiv123__fundamental_type_infoE";
+      break;
 
-  case Type::ConstantArray:
-  case Type::IncompleteArray:
-  case Type::VariableArray:
-    // abi::__array_type_info.
-    VTableName = "_ZTVN10__cxxabiv117__array_type_infoE";
-    break;
+    case Type::ConstantArray:
+    case Type::IncompleteArray:
+    case Type::VariableArray:
+      // abi::__array_type_info.
+      VTableName = "_ZTVN10__cxxabiv117__array_type_infoE";
+      break;
 
-  case Type::FunctionNoProto:
-  case Type::FunctionProto:
-    // abi::__function_type_info.
-    VTableName = "_ZTVN10__cxxabiv120__function_type_infoE";
-    break;
+    case Type::FunctionNoProto:
+    case Type::FunctionProto:
+      // abi::__function_type_info.
+      VTableName = "_ZTVN10__cxxabiv120__function_type_infoE";
+      break;
 
-  case Type::Enum:
-    // abi::__enum_type_info.
-    VTableName = "_ZTVN10__cxxabiv116__enum_type_infoE";
-    break;
+    case Type::Enum:
+      // abi::__enum_type_info.
+      VTableName = "_ZTVN10__cxxabiv116__enum_type_infoE";
+      break;
 
-  case Type::Record: {
-    const CXXRecordDecl *RD = 
-      cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
+    case Type::Record: {
+      const CXXRecordDecl *RD = 
+        cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
     
-    if (!RD->hasDefinition() || !RD->getNumBases()) {
-      VTableName = ClassTypeInfo;
-    } else if (CanUseSingleInheritance(RD)) {
-      VTableName = SIClassTypeInfo;
-    } else {
-      VTableName = VMIClassTypeInfo;
+      if (!RD->hasDefinition() || !RD->getNumBases()) {
+        VTableName = ClassTypeInfo;
+      } else if (CanUseSingleInheritance(RD)) {
+        VTableName = SIClassTypeInfo;
+      } else {
+        VTableName = VMIClassTypeInfo;
+      }
+    
+      break;
     }
-    
-    break;
-  }
 
-  case Type::ObjCObject:
-    // Ignore protocol qualifiers.
-    Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
+    case Type::ObjCObject:
+      // Ignore protocol qualifiers.
+      Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
 
-    // Handle id and Class.
-    if (isa<BuiltinType>(Ty)) {
-      VTableName = ClassTypeInfo;
+      // Handle id and Class.
+      if (isa<BuiltinType>(Ty)) {
+        VTableName = ClassTypeInfo;
+        break;
+      }
+
+      assert(isa<ObjCInterfaceType>(Ty));
+      // Fall through.
+
+    case Type::ObjCInterface:
+      if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
+        VTableName = SIClassTypeInfo;
+      } else {
+        VTableName = ClassTypeInfo;
+      }
       break;
-    }
 
-    assert(isa<ObjCInterfaceType>(Ty));
-    // Fall through.
+    case Type::ObjCObjectPointer:
+    case Type::Pointer:
+      // abi::__pointer_type_info.
+      VTableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";
+      break;
 
-  case Type::ObjCInterface:
-    if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
-      VTableName = SIClassTypeInfo;
-    } else {
-      VTableName = ClassTypeInfo;
+    case Type::MemberPointer:
+      // abi::__pointer_to_member_type_info.
+      VTableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
+      break;
     }
-    break;
 
-  case Type::ObjCObjectPointer:
-  case Type::Pointer:
-    // abi::__pointer_type_info.
-    VTableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";
-    break;
+      VTable = 
+      CGM.getModule().getOrInsertGlobal(VTableName, Int8PtrTy);
+    
+    llvm::Type *PtrDiffTy = 
+      CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
 
-  case Type::MemberPointer:
-    // abi::__pointer_to_member_type_info.
-    VTableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
-    break;
+    // The vtable address point is 2.
+    llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
+    VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Two);
+    VTable = llvm::ConstantExpr::getBitCast(VTable, Int8PtrTy);
   }
-
-  llvm::Constant *VTable = 
-    CGM.getModule().getOrInsertGlobal(VTableName, CGM.Int8PtrTy);
-    
-  llvm::Type *PtrDiffTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
-
-  // The vtable address point is 2.
-  llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
-  VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Two);
-  VTable = llvm::ConstantExpr::getBitCast(VTable, CGM.Int8PtrTy);
-
   Fields.push_back(VTable);
 }
 
@@ -547,7 +704,1226 @@
   TypeNameGV->setLinkage(Linkage);
 }
 
+// r4start
+static llvm::StructType* GetBaseClassDescriptorType(CodeGenModule& CGM)
+{
+  llvm::SmallVector<llvm::Type*, 4> BaseClassDescrFieldTypes;
+
+  BaseClassDescrFieldTypes.push_back(llvm::Type::getInt8PtrTy(CGM.getLLVMContext()));
+
+  // Push numContainedBases, PMD fields and attributes.
+  for (int i = 0; i < 5; ++i)
+  {
+    BaseClassDescrFieldTypes.push_back(llvm::Type::getInt32Ty(CGM.getLLVMContext()));
+  }
+
+  return llvm::StructType::get(CGM.getLLVMContext(), BaseClassDescrFieldTypes);
+}
+
+// r4start
+// Need to rewrite this!!!!!!!!!!!!
+static uint32_t GetBasesCount(const CXXRecordDecl *RD) {
+  if (!RD->getNumBases() && !RD->getNumVBases())
+    return 0;
+
+  uint32_t BasesCount = 0;
+  llvm::SmallVector<const CXXRecordDecl *, 16> Bases;
+
+  Bases.push_back(RD);
+
+  while (!Bases.empty()) {
+    
+    const CXXRecordDecl *Derived = Bases.back();
+    Bases.pop_back();
+
+    for (CXXRecordDecl::base_class_const_iterator I = Derived->bases_begin(),
+         E = Derived->bases_end(); I != E; ++I, ++BasesCount) {
+      const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
+
+      if (Base->getNumBases() ||
+          Base->getNumVBases())
+        Bases.push_back(Base);
+    }
+  }
+
+  return BasesCount;
+}
+
+// r4start
+static llvm::StructType* GetTypeDescriptorType(CodeGenModule& CGM,
+                                               llvm::Type* TypeInfoTy,
+                                               uint64_t NameLen) {
+  llvm::SmallVector<llvm::Type*, 3> DescrTy;
+
+  DescrTy.push_back(TypeInfoTy);
+  DescrTy.push_back(llvm::Type::getInt32Ty(CGM.getLLVMContext()));
+  DescrTy.push_back(llvm::ArrayType::get(llvm::Type::getInt8Ty(CGM.getLLVMContext()), NameLen));
+
+  return llvm::StructType::get(CGM.getLLVMContext(), DescrTy);
+}
+
+// r4start
+void
+RTTIBuilder::BuildVBTable(const CXXRecordDecl *RD) {
+  llvm::SmallString<256> Name;
+  llvm::raw_svector_ostream Out(Name);
+
+  CGM.getCXXABI().getMangleContext().
+    getMsExtensions()->mangleCXXVBTable(RD, 0, Out);
+  Out.flush();
+
+  llvm::StringRef VBTableName = Name.str();
+
+  llvm::GlobalVariable *VBTable = 
+    CGM.getModule().getGlobalVariable(VBTableName);
+  if (VBTable)
+    return;
+
+  VBTableContext& Context = CGM.getVBTableContext();
+  const VBTableContext::BaseVBTableTy &Table = Context.getVBTable(RD, RD);
+
+  llvm::ArrayType *VBTableType = llvm::ArrayType::get(Int32Ty, Table.size());
+  llvm::SmallVector<llvm::Constant *, 32> Offsets;
+
+  for (VBTableContext::BaseVBTableTy::const_iterator I = Table.begin(),
+       E = Table.end(); I != E; ++I) {
+    VBTableContext::VBTableEntry Entry = I->first;
+
+    Offsets.push_back(llvm::ConstantInt::get(Int32Ty, Entry.offset));
+  }
+
+  llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets);
+
+  VBTable = 
+    new llvm::GlobalVariable(CGM.getModule(),Init->getType(), true,
+                             CurLinkage, Init, VBTableName);
+}
+
+uint32_t RTTIBuilder::GetAttributesField(const CXXRecordDecl *RD, 
+                                         CXXRecordDecl *Base) {
+  // At now we know that only first byte uses from attr field.
+  // 7 bit sets always (counting from 1).
+  // 5 bit sets if Base is virtually derived from RD.
+  // 4 bit sets always with 1 bit, at now I don`t know this bit meaning.
+  // 3 bit sets if Base is not directly public. 
+  // 2 bit sets if Base ambiguous subobject.
+  // 1 bit sets if down cast not allowed.
+  // Other bits are unknown.
+  uint32_t Attr = 64;
+
+  if (RD == Base)
+    return Attr;
+
+  if (RD->isVirtuallyDerivedFrom(Base))
+    Attr |= 16;
+
+  bool BaseWasVisited = false;
+  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 == Base) {
+      BaseWasVisited = true;
+      if (I->getAccessSpecifier() != AS_public) {
+        Attr |= 4;
+      }
+      break;
+    }
+  }
+
+  CXXBasePaths Paths;
+  Paths.setOrigin(const_cast<CXXRecordDecl *>(RD));
+  RD->lookupInBases(&CXXRecordDecl::FindBaseClass,
+                    Base->getCanonicalDecl(), Paths);
+
+  QualType BaseTy = CGM.getContext().getTagDeclType(Base);
+
+  if (Paths.isAmbiguous(CGM.getContext().getCanonicalType(BaseTy)))
+    Attr |= 2;
+
+  // What we must do with ambiguous subobjects?
+  if (!BaseWasVisited) {
+    CXXBasePath& Path = Paths.front();
+    if (Path.Access != AS_public)
+      Attr |= 4;
+  }
+
+  // Down cast not allowed by default.
+  uint32_t DownCastAllowed = 9;
+
+  if (!(Attr & 4))
+    DownCastAllowed = 0;
+  
+  Attr |= DownCastAllowed;
+
+  return Attr;
+}
+
+int32_t RTTIBuilder::GetMemberDisplacement(const CXXRecordDecl *RD,
+                                           CXXRecordDecl *Base) {
+  assert(!RD->isVirtuallyDerivedFrom(Base) && 
+         "Unable get member displacement for virtual base!");
+
+  CXXBasePaths Paths;
+  Paths.setOrigin(const_cast<CXXRecordDecl *>(RD));
+  RD->lookupInBases(&CXXRecordDecl::FindBaseClass,
+                    Base->getCanonicalDecl(), Paths);
+
+  if (Paths.getDetectedVirtual())
+    return 0;
+
+  QualType BaseTy = CGM.getContext().getTagDeclType(Base);
+  CanQualType BaseCanQualTy = CGM.getContext().getCanonicalType(BaseTy);
+  assert(!Paths.isAmbiguous(BaseCanQualTy) && 
+         "At now we can't work with ambiguous bases!");
+
+  CXXBasePath& Path = Paths.front();
+
+  ASTContext &Ctx = CGM.getContext();
+
+  if (Path.size() ==  1) {
+    const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
+    return Layout.getBaseClassOffset(Base).getQuantity();
+  }
+
+  int32_t MemberDisplacement = 0;
+  for (CXXBasePathElement *I = Path.begin(), *E = Path.end(); I != E; ++I) {
+    const ASTRecordLayout &MostDerivedLayout = Ctx.getASTRecordLayout(I->Class);
+    const CXXRecordDecl *BaseDecl = I->Base->getType()->getAsCXXRecordDecl();
+
+    MemberDisplacement += 
+      MostDerivedLayout.getBaseClassOffset(BaseDecl).getQuantity();
+  }
+
+  return MemberDisplacement;
+}
+
+VBTableContext::VBTableEntry 
+RTTIBuilder::GetVBaseDisplacement(const CXXRecordDecl *RD,
+                                  CXXRecordDecl *Base) {
+  VBTableContext::VBTableEntry result(0, -1);
+
+  if (RD->isVirtuallyDerivedFrom(Base)) {
+    const VBTableContext::VBTableEntry &RDEntry = 
+      CGM.getVBTableContext().getEntryFromVBTable(RD, RD, RD);
+
+    result.offset = -RDEntry.offset;
+
+    const VBTableContext::VBTableEntry &BaseEntry = 
+      CGM.getVBTableContext().getEntryFromVBTable(RD, RD, Base);
+
+    // Maybe not 4 but Int size.
+    result.index = BaseEntry.index * 4;
+    
+    return result;
+  }
+
+  CXXBasePaths Paths;
+  Paths.setOrigin(const_cast<CXXRecordDecl *>(RD));
+  RD->lookupInBases(&CXXRecordDecl::FindBaseClass,
+                    Base->getCanonicalDecl(), Paths);
+
+  if (!Paths.getDetectedVirtual())
+    return result;
+
+  const CXXRecordDecl *VirtBase = 
+    Paths.getDetectedVirtual()->getAsCXXRecordDecl();
+
+  if (!VirtBase)
+    return result;
+
+  const VBTableContext::VBTableEntry &RDEntry = 
+    CGM.getVBTableContext().getEntryFromVBTable(RD, RD, RD);
+
+  result.offset = -RDEntry.offset;
+
+  const VBTableContext::VBTableEntry &BaseEntry = 
+    CGM.getVBTableContext().getEntryFromVBTable(RD, RD, VirtBase);
+
+  // Maybe not 4 but Int size.
+  result.index = BaseEntry.index * 4;
+
+  return result;
+}
+
+llvm::Constant* 
+RTTIBuilder::BuildRTTIBaseClassDescriptor(const CXXRecordDecl* RD, 
+                                          CXXRecordDecl *Base) {
+  llvm::SmallVector<llvm::Constant*, 6> BaseClassDescrVals;
+
+  // Get ptr to RTTI Type descriptor.
+  llvm::SmallString<256> TypeDescrBuff;
+  llvm::raw_svector_ostream OutType(TypeDescrBuff);
+  CGM.getCXXABI().getMangleContext().
+    getMsExtensions()->mangleCXXRTTITypeDescriptor(Base, OutType);
+  OutType.flush();
+  llvm::StringRef TypeDescriptorName = TypeDescrBuff.str();
+
+  llvm::GlobalVariable *TypeDescr = 
+    CGM.getModule().getGlobalVariable(TypeDescriptorName);
+
+  if (!TypeDescr) {
+    BuildRTTITypeDescriptor(CGM.getContext().getTagDeclType(Base));
+    TypeDescr = 
+      CGM.getModule().getGlobalVariable(TypeDescriptorName);
+    
+    assert(TypeDescr && "Can`t find type descriptor!");
+  }
+
+  BaseClassDescrVals.push_back(llvm::ConstantExpr::getBitCast(TypeDescr,
+                                                              Int8PtrTy));
+  // Number contained bases.
+  BaseClassDescrVals.push_back(llvm::ConstantInt::get(Int32Ty, 
+                                                      GetBasesCount(Base)));
+
+  int32_t MemberDisplacement = 0;
+  if (Base != RD && 
+      !RD->isVirtuallyDerivedFrom(Base))
+    MemberDisplacement = GetMemberDisplacement(RD, Base);
+
+  // Member displacement.
+  BaseClassDescrVals.push_back(llvm::ConstantInt::get(Int32Ty,
+                                                      MemberDisplacement));
+
+  /*int64_t Displacement = -1;
+  int32_t VBTableIndex = 0;
+  
+  if (RD->isVirtuallyDerivedFrom(Base)) {
+    const VBTableContext::VBTableEntry &RDEntry = 
+      CGM.getVBTableContext().getEntryFromVBTable(RD, RD);
+
+    Displacement = -RDEntry.offset;
+
+    const VBTableContext::VBTableEntry &BaseEntry = 
+      CGM.getVBTableContext().getEntryFromVBTable(RD, Base);
+
+    // Maybe not 4 but Int size.
+    VBTableIndex = BaseEntry.index * 4;
+  }*/
+
+  VBTableContext::VBTableEntry VBTableDisps = GetVBaseDisplacement(RD, Base);
+
+  // Vbtable displacement.
+  BaseClassDescrVals.push_back(llvm::ConstantInt::get(Int32Ty, VBTableDisps.offset));
+
+  // Displacement inside vbtable.
+  BaseClassDescrVals.push_back(llvm::ConstantInt::get(Int32Ty, VBTableDisps.index));
+
+  // Attributes.
+  uint32_t Attributes = GetAttributesField(RD, Base);
+
+  BaseClassDescrVals.push_back(llvm::ConstantInt::get(Int32Ty, Attributes));
+
+  llvm::StructType* BaseClassDescrTy = GetBaseClassDescriptorType(CGM);
+
+  llvm::Constant* Init = 
+    llvm::ConstantStruct::get(BaseClassDescrTy, BaseClassDescrVals);
+  
+  llvm::SmallString<256> Name;
+  llvm::raw_svector_ostream Out(Name);
+
+  CGM.getCXXABI().getMangleContext().
+    getMsExtensions()->
+      mangleCXXRTTIBaseClassDescriptor(Base, MemberDisplacement, 
+                                       VBTableDisps.offset, VBTableDisps.index,
+                                       Attributes, Out);
+  Out.flush();
+
+  llvm::StringRef DescrName = Name.str();
+
+  llvm::GlobalVariable *BaseClassDescr = 
+    CGM.getModule().getGlobalVariable(DescrName);
+
+  if (!BaseClassDescr)
+    BaseClassDescr = 
+      new llvm::GlobalVariable(CGM.getModule(), Init->getType(), true,
+                               CurLinkage, Init, DescrName);
+
+  return BaseClassDescr;
+}
+
+// r4start
+llvm::Constant* RTTIBuilder::BuildRTTIBaseClassArray(const CXXRecordDecl* RD) {
+  llvm::SmallVector<llvm::Constant*, 64> BaseClassDescriptors;
+
+  std::deque<CXXRecordDecl *> Bases;
+  
+  Bases.push_front(const_cast<CXXRecordDecl *>(RD));
+
+  while (!Bases.empty()) {
+    CXXRecordDecl *Derived = Bases.front();
+    Bases.pop_front();
+
+    BaseClassDescriptors.push_back(
+       BuildRTTIBaseClassDescriptor(RD, Derived));
+
+    bool Generate = true;
+
+    for (CXXRecordDecl::base_class_const_iterator I = Derived->bases_begin(),
+         E = Derived->bases_end(); I != E; ++I) {
+      CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
+
+      if (Base->getNumBases() ||
+          Base->getNumVBases()) {
+        Generate = false;
+      }
+
+      if (Generate) {
+        BaseClassDescriptors.push_back(
+          BuildRTTIBaseClassDescriptor(RD, Base));
+        continue;
+      }
+
+      Bases.push_back(Base);
+    }
+  }
+
+  llvm::ArrayType* BaseClassArrayType = 
+    llvm::ArrayType::get(BaseClassDescriptors[0]->getType(),
+                         BaseClassDescriptors.size());
+
+  llvm::Constant* BaseClassArrayInit = 
+    llvm::ConstantArray::get(BaseClassArrayType, BaseClassDescriptors);
+
+  llvm::SmallString<256> Name;
+  llvm::raw_svector_ostream Out(Name);
+
+  CGM.getCXXABI().getMangleContext().
+    getMsExtensions()->mangleCXXRTTIBaseClassArray(RD, Out);
+  Out.flush();
+
+  llvm::StringRef ArrayName(Name.str());
+
+  llvm::GlobalVariable* BaseClassArray = CGM.getModule().getGlobalVariable(ArrayName);
+
+  if (!BaseClassArray)
+    BaseClassArray = 
+      new llvm::GlobalVariable(CGM.getModule(), BaseClassArrayInit->getType(),
+                              true, CurLinkage, BaseClassArrayInit, ArrayName);
+
+  return BaseClassArray;
+}
+
+// r4start
+// TODO: rewrite this.
+void RTTIBuilder::GetAmbiguousSubobjects(const CXXRecordDecl *RD) {
+  std::list<const CXXRecordDecl *> Bases;
+  std::set<const CXXRecordDecl *> VisitedBases;
+  std::set<const CXXRecordDecl *> VisitedVirtualBases;
+
+  Bases.push_back(RD);
+
+  while (!Bases.empty()) {
+    const CXXRecordDecl *Derived = Bases.back();
+    Bases.pop_back();
+
+    for (CXXRecordDecl::base_class_const_iterator I = Derived->bases_begin(),
+      E = Derived->bases_end(); I != E; ++I) {
+      const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
+
+      if (I->isVirtual()) {
+        VisitedVirtualBases.insert(Base);
+      }
+
+      if (VisitedBases.find(Base) != VisitedBases.end()) {
+        AmbiguousBases.insert(Base);
+      } else if (VisitedVirtualBases.find(Base) != 
+                      VisitedVirtualBases.end()) {
+        AmbiguousBases.insert(Base);
+        VisitedBases.insert(Base);
+      } else {
+        VisitedBases.insert(Base);
+      }
+
+      Bases.push_back(Base);
+    }
+  }
+}
+
+// r4start
+llvm::Constant * 
+RTTIBuilder::BuildRTTIClassHierarchyDescriptor(const CXXRecordDecl* RD)
+{
+  llvm::SmallString<256> DescriptorName;
+  llvm::raw_svector_ostream Out(DescriptorName);
+
+  MangleContext& Ctx = CGM.getCXXABI().getMangleContext();
+
+  Ctx.getMsExtensions()->
+    mangleCXXRTTIClassHierarhyDescriptor(RD, Out);
+  Out.flush();
+
+  llvm::StringRef ClassHierarchyDescrName = DescriptorName.str();
+
+  llvm::SmallVector<llvm::Type*, 4> CHDFieldTypes;
+  llvm::SmallVector<llvm::Constant*, 4> CHDFieldVals;
+
+  // Signature and attribute fields are integers.
+  for (int i = 0; i < 3; ++i)
+  {
+    CHDFieldTypes.push_back(Int32Ty);
+  }
+
+  // Signature always 0?
+  CHDFieldVals.push_back(llvm::ConstantInt::get(Int32Ty, 0));
+  
+  GetAmbiguousSubobjects(RD);
+
+  uint32_t AttributeVal = 0;
+  if (RD->getNumBases() > 1) {
+    AttributeVal |= 0x01;
+
+    if (RD->getNumVBases())
+      AttributeVal |= 0x02;
+
+    if (!AmbiguousBases.empty()) {
+      AttributeVal |= 0x04;
+    }
+  }
+
+  CHDFieldVals.push_back(llvm::ConstantInt::get(Int32Ty, AttributeVal));
+
+  CHDFieldVals.push_back(llvm::ConstantInt::get(Int32Ty, GetBasesCount(RD) + 1));
+
+  llvm::Constant* BaseClassArray = BuildRTTIBaseClassArray(RD);
+  CHDFieldTypes.push_back(Int8PtrTy);
+  CHDFieldVals.push_back(llvm::ConstantExpr::getBitCast(BaseClassArray, Int8PtrTy));
+
+  llvm::StructType* CHDType = 
+    llvm::StructType::get(CGM.getLLVMContext(), CHDFieldTypes);
+
+  llvm::Constant* ClassHierarchyDescr = 
+    llvm::ConstantStruct::get(CHDType, CHDFieldVals);
+
+  llvm::GlobalVariable* CHDVal = 
+    CGM.getModule().getGlobalVariable(ClassHierarchyDescrName);
+
+  if (!CHDVal)
+  CHDVal = 
+    new llvm::GlobalVariable(CGM.getModule(),
+                              ClassHierarchyDescr->getType(),
+                              true,
+                              CurLinkage,
+                              ClassHierarchyDescr,
+                              ClassHierarchyDescrName);
+
+  return CHDVal;
+}
+
+// r4start
+llvm::Constant *RTTIBuilder::BuildRTTITypeDescriptor(QualType Ty)
+{
+  SmallString<256> Name;
+  llvm::raw_svector_ostream Out(Name);
+  const CXXRecordDecl* RD = Ty->getAsCXXRecordDecl();
+
+  MangleContext& Ctx = CGM.getCXXABI().getMangleContext();
+
+  Ctx.getMsExtensions()->mangleCXXRTTITypeDescriptor(RD, Out);
+  Out.flush();
+
+  StringRef DescrName = Name.str();
+
+  llvm::GlobalVariable* TypeDescriptor = 
+    CGM.getModule().getGlobalVariable(DescrName);
+
+  if (TypeDescriptor)
+    return TypeDescriptor;
+
+  // Last field of type descriptor contains mangled name of class
+  std::string NameField = ".?AV" + RD->getNameAsString() + "@@";
+
+  llvm::Constant* Array = 
+    llvm::ConstantDataArray::getString(CGM.getLLVMContext(), 
+                                       StringRef(NameField));
+
+  BuildVTablePointer(cast<Type>(Ty));
+
+  llvm::Constant* TypeInfo = Fields.pop_back_val();
+
+  llvm::StructType* DescrTy = 
+    GetTypeDescriptorType(CGM, TypeInfo->getType(), NameField.length() + 1);
+
+  llvm::SmallVector<llvm::Constant*, 3> TypeDescrVals;
+
+  TypeDescrVals.push_back(TypeInfo);
+  TypeDescrVals.push_back(llvm::ConstantInt::get(DescrTy->getElementType(1), 0));
+  TypeDescrVals.push_back(Array);
+
+  llvm::Constant* Init = llvm::ConstantStruct::get(DescrTy, TypeDescrVals);
+
+  return new llvm::GlobalVariable(CGM.getModule(), Init->getType(),
+                                  true, CurLinkage, Init, DescrName);
+}
+
+static CharUnits GetClassOffset(const ASTContext &Ctx,
+                                const CXXRecordDecl *RD,
+                                const CXXRecordDecl *Base) {
+  assert(RD != Base && 
+         "GetClassOffset can`t work if RD equal Base");
+
+  CharUnits BaseOffset;
+
+  if (RD->isVirtuallyDerivedFrom(const_cast<CXXRecordDecl *>(Base))) {
+    const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
+    return Layout.getVBaseClassOffset(Base);
+  }
+
+  CXXBasePaths InhPaths;
+  InhPaths.setOrigin(const_cast<CXXRecordDecl *>(RD));
+  RD->lookupInBases(&CXXRecordDecl::FindBaseClass, 
+                 const_cast<CXXRecordDecl *>(Base), InhPaths);
+
+  assert(InhPaths.begin() != InhPaths.end() &&
+         "Can`t find inheritance path from RD to Base!");
+  
+  CXXBasePath& Path = InhPaths.front();
+
+  for (CXXBasePath::const_iterator I = Path.begin(),
+       E = Path.end(); I != E; ++I) {
+    const CXXRecordDecl *BaseElem = I->Base->getType()->getAsCXXRecordDecl();
+    const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(I->Class);
+
+    if (I->Base->isVirtual())
+      BaseOffset += Layout.getVBaseClassOffset(BaseElem);
+    else
+      BaseOffset += Layout.getBaseClassOffset(BaseElem);
+  }
+
+  return BaseOffset;
+}
+
+// r4start
+llvm::Constant *RTTIBuilder::BuildMSTypeInfo(QualType Ty,
+                                             QualType BaseTy,
+                                             bool Force) {
+  // We want to operate on the canonical type.
+  Ty = CGM.getContext().getCanonicalType(Ty);
+
+  llvm::SmallString<256> OutName;
+  llvm::raw_svector_ostream Out(OutName);
+  
+  MangleContext& Ctx = CGM.getCXXABI().getMangleContext();
+  MSMangleContextExtensions* CtxExt = Ctx.getMsExtensions();
+
+  CXXRecordDecl *Base = 0;
+  CXXRecordDecl *LayoutClass = Ty->getAsCXXRecordDecl();
+
+  if (LayoutClass != BaseTy->getAsCXXRecordDecl())
+    Base = BaseTy->getAsCXXRecordDecl();
+
+  const ASTRecordLayout &Layout =
+    CGM.getContext().getASTRecordLayout(LayoutClass);
+
+  CtxExt->mangleCXXRTTICompleteObjectLocator(LayoutClass, Base, Out);
+  
+  Out.flush();
+
+  // Complete Object Locator name
+  llvm::StringRef COLName = OutName.str();
+  
+  CurLinkage = getTypeInfoLinkage(CGM, Ty);
+
+  llvm::Type* Int32Ty = 
+    llvm::IntegerType::getInt32Ty(CGM.getLLVMContext());
+
+  llvm::Constant* SignatureField = llvm::ConstantInt::get(Int32Ty, 0);
+  
+  uint64_t VFTableOffset = 0;
+  if (Base != Layout.getPrimaryBase() && Base) {
+    VFTableOffset = 
+      GetClassOffset(CGM.getContext(), LayoutClass, Base).getQuantity();
+  }
+
+  llvm::Constant* VTableOffset = llvm::ConstantInt::get(Int32Ty, VFTableOffset);
+  
+  llvm::Constant* ConstructorDisplacement = llvm::ConstantInt::get(Int32Ty, 0);
+
+  Fields.push_back(SignatureField);
+  Fields.push_back(VTableOffset);
+  Fields.push_back(ConstructorDisplacement);
+
+  llvm::Constant *TypeDescr = BuildRTTITypeDescriptor(Ty);
+  Fields.push_back(llvm::ConstantExpr::getBitCast(TypeDescr, Int8PtrTy));
+
+  llvm::Constant *CHD = 
+    BuildRTTIClassHierarchyDescriptor(Ty->getAsCXXRecordDecl());
+  Fields.push_back(llvm::ConstantExpr::getBitCast(CHD, Int8PtrTy));
+
+  // Build virtual bases table.
+  /*if (LayoutClass->getNumVBases())
+    BuildVBTable(LayoutClass);*/
+
+  llvm::Constant* Init = llvm::ConstantStruct::getAnon(Fields);
+  
+  llvm::GlobalVariable* GV = CGM.getModule().getGlobalVariable(COLName);
+  if (!GV)
+    GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(),
+                                 /*Constant=*/true, CurLinkage, Init, COLName);
+
+  GV->setUnnamedAddr(true);
+  
+  return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
+}
+
+/*
+// r4start
+static void ParseDeepBases(MangleContext& Context,
+                           const CXXRecordDecl* RD,
+                           llvm::raw_ostream& Out)
+{
+  CXXRecordDecl::reverse_base_class_const_iterator  
+                              baseClass = RD->vbases_rbegin();
+  if (RD->getNumVBases())
+  {
+    // Build vftable for virtual bases.
+
+    for(baseClass;
+        baseClass != RD->vbases_rend();
+        ++baseClass)
+    {
+      Context.mangleCXXVTable(RD,
+        baseClass->getType()->getAsCXXRecordDecl(),
+        Out);
+    }
+  }
+
+  // Built vftables for bases virtual bases. 
+  for(baseClass = RD->bases_rbegin();
+      baseClass != RD->bases_rend();
+      ++baseClass)
+  {
+    if (baseClass->getType()->getAsCXXRecordDecl()->getNumVBases())
+    {
+      ParseDeepBases(Context, baseClass->getType()->getAsCXXRecordDecl(), Out);
+    }
+  }
+}
+
+// r4start
+static bool CXXClassHasNewVirtualFunction(const CXXRecordDecl *RD)
+{
+  for (CXXRecordDecl::method_iterator method = RD->method_begin();
+       method != RD->method_end();
+       ++method)
+  {
+    if (method->isVirtual() &&
+        !method->size_overridden_methods())
+    {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+// r4start
+static bool HasBasesVirtualFunctions(const CXXRecordDecl* RD)
+{
+  for (CXXRecordDecl::base_class_const_iterator base = RD->bases_begin();
+       base != RD->bases_end();
+       ++base)
+  {
+    if (base->getType()->getAsCXXRecordDecl()->isPolymorphic())
+    {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+// r4start
+static bool IsAllBasesVirtual(const CXXRecordDecl *RD)
+{
+  for (CXXRecordDecl::base_class_const_iterator base = RD->bases_begin();
+       base != RD->bases_end();
+       ++base)
+  {
+    if (!base->isVirtual())
+    {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+// r4start
+static bool IsClassDeclareVFunctions(const CXXRecordDecl *RD)
+{
+  for (CXXRecordDecl::method_iterator method = RD->method_begin();
+       method != RD->method_end();
+       ++method)
+  {
+    if (method->isVirtual())
+    {
+      return true;
+    }
+  }
+  return false;
+}
+
+// r4start
+static void BuildVFTableForNonVirtualBases(MangleContext& Context,
+                                           const CXXRecordDecl* RD,
+                                           llvm::raw_ostream& Out)
+{
+  CXXRecordDecl::reverse_base_class_const_iterator baseClass;
+
+  // Build vftable for nonvirtual bases.
+  for (baseClass = RD->bases_rbegin();
+    baseClass != RD->bases_rend();
+    ++baseClass)
+  {
+    // If no virtual functions then no vftable ^_^
+    if (!baseClass->isVirtual() &&
+      baseClass->getType()->getAsCXXRecordDecl()->isPolymorphic())
+    {
+      Context.mangleCXXVTable(RD,
+        baseClass->getType()->getAsCXXRecordDecl(),
+        Out);
+    }
+  }
+}
+
+// r4start
+static void GenerateVFTables(MangleContext& Context,
+                             const CXXRecordDecl* RD,
+                             llvm::raw_ostream& Out)
+{
+  if (RD->getNumVBases())
+  {
+  
+    if (!HasBasesVirtualFunctions(RD))
+    {
+      // Bases don`t have any virtual functions,
+      // so we don`t need to build vftable for them.
+      if (RD->isPolymorphic())
+      {
+        // This class have virtual function.
+        // Build vftable.
+        Context.mangleCXXVTable(RD, 0, Out);
+      }
+      return ;
+    }
+    
+    // We have one virtual base class with vfunctions and
+    // no new vfunctions in child class,
+    // so build one vftable.
+    if (RD->getNumVBases() == 1 &&
+        RD->getNumBases() == RD->getNumVBases() &&
+        HasBasesVirtualFunctions(RD) &&
+        !IsClassDeclareVFunctions(RD))
+    {
+      Context.mangleCXXVTable(RD, 0, Out);
+      return ;
+    }
+
+    // MS compiler do this optimization.
+    // For example:
+    // if we have 2 virtual bases and 1 of them have a virtual base,
+    // then class shares vftable with base without base.
+    if (IsAllBasesVirtual(RD) &&
+        RD->getNumVBases() > RD->getNumBases() &&
+        !IsClassDeclareVFunctions(RD))
+    {
+      bool optimized = false;
+
+      for (CXXRecordDecl::reverse_base_class_const_iterator base = RD->bases_rbegin();
+           base != RD->bases_rend();
+           ++base)
+      {
+        CXXRecordDecl* baseClass = base->getType()->getAsCXXRecordDecl();
+        
+        if (!baseClass->getNumBases() &&
+            !optimized)
+        {
+          Context.mangleCXXVTable(RD, 0, Out);
+          optimized = true;
+          continue ;
+        }
+
+        Context.mangleCXXVTable(RD, baseClass, Out);
+        ParseDeepBases(Context, baseClass, Out);
+      }
+
+      return ;
+    }
+
+    // Build vftable for virtual bases.
+    for (CXXRecordDecl::reverse_base_class_const_iterator virt = RD->vbases_rbegin();
+         virt != RD->vbases_rend();
+         ++virt)
+    {
+      // If class not contains virtual function,
+      // We don`t need to construct it`s vftable.
+      if (virt->getType()->getAsCXXRecordDecl()->isPolymorphic())
+      {
+        Context.mangleCXXVTable(RD,
+          virt->getType()->getAsCXXRecordDecl(),
+          Out);
+      }
+    }
+
+    // If all bases are virtual then we must add
+    // vftable record ??_7class_name@@6B0@@.
+    // Maybe this is marker for vftable sharing???
+    if (IsAllBasesVirtual(RD) && 
+        CXXClassHasNewVirtualFunction(RD))
+    {
+      Context.getMsExtensions()->
+        mangleCXXVFTableByClassName(RD->getNameAsString(), "0", Out);
+      return ;
+    }
+
+    BuildVFTableForNonVirtualBases(Context, RD, Out);
+
+  }
+  else if (HasBasesVirtualFunctions(RD))
+  {
+    BuildVFTableForNonVirtualBases(Context, RD, Out);
+  }
+  else if (RD->isPolymorphic())
+  {
+    // If in class contains virtual function.
+    Context.mangleCXXVTable(RD, 0, Out);
+  }
+}
+
+// r4start
+static void GenerateVBTables(MangleContext& Context,
+                             const CXXRecordDecl* RD,
+                             llvm::raw_ostream& Out)
+{
+  bool haveVitualBasesBases = false;
+
+  for (CXXRecordDecl::reverse_base_class_const_iterator base = RD->bases_rbegin();
+       base != RD->bases_rend();
+       ++base)
+  {
+    if (base->getType()->getAsCXXRecordDecl()->getNumVBases())
+    {
+      Context.getMsExtensions()->
+        mangleCXXVBTable(RD, base->getType()->getAsCXXRecordDecl(), Out);
+      haveVitualBasesBases = true;
+    }
+  }
+
+  if (!haveVitualBasesBases)
+  {
+    Context.getMsExtensions()->mangleCXXVBTable(RD, 0, Out);
+  }
+  else
+  {
+    Context.getMsExtensions()->mangleCXXVBTable(RD, "0", Out);
+  }
+}
+
+// r4start
+static void GenerateCompleteObjectLocatorData(MangleContext& Context,
+                                              const CXXRecordDecl* RD,
+                                              llvm::raw_ostream& Out)
+{
+  if (IsAllBasesVirtual(RD))
+  {
+    if (CXXClassHasNewVirtualFunction(RD))
+    {
+      Context.getMsExtensions()->
+        mangleCXXRTTICompleteObjectLocator(
+          RD,
+          "0",
+          Out
+        );
+    }
+    else
+    {
+      Context.getMsExtensions()->
+        mangleCXXRTTICompleteObjectLocator(
+          RD,
+          RD->vbases_begin()->getType()->getAsCXXRecordDecl(),
+          Out
+        );
+    }
+  }
+  else
+  {
+    if (RD->getNumBases() == 1)
+    {
+      Context.getMsExtensions()->
+        mangleCXXRTTICompleteObjectLocator(
+          RD,
+          0,
+          Out
+        );
+
+      return;
+    }
+
+    for (CXXRecordDecl::base_class_const_iterator baseClass = RD->bases_begin();
+      baseClass != RD->bases_end();
+      ++baseClass)
+    {
+      if (!baseClass->isVirtual())
+      {
+        // Mangle Complete Object Locator for first nonvirtual base
+         Context.getMsExtensions()->
+          mangleCXXRTTICompleteObjectLocator(
+            RD,
+            // first nonvirtual base class
+            baseClass->getType()->getAsCXXRecordDecl(), 
+            Out
+          );
+        break;
+      }
+    }
+  }
+}
+
+// r4start
+static void GenerateBaseClassDescriptorsArray(MangleContext& Context,
+                                              const CXXRecordDecl* RD,
+                                              llvm::raw_ostream& Out)
+{
+  CXXRecordDecl::base_class_const_iterator baseClass = RD->bases_begin();
+
+  int64_t bParameter = 
+    (RD->getNumBases() - RD->getNumVBases()) * 4; // 4 is some magic
+
+  bool isFirstNonVirtualBase = false;
+
+  for (int nonVirtCounter = 0, virtCounter = 4;
+       baseClass != RD->bases_end();
+       ++baseClass)
+  {
+    llvm::StringRef dParameter;
+
+    if (baseClass->isVirtual())
+    {
+      if (baseClass->getAccessSpecifier() == AS_public)
+      {
+        dParameter = "FA";
+      }
+      else
+      {
+        dParameter = "FN";
+      }
+
+      Context.getMsExtensions()->
+        mangleCXXRTTIBaseClassDescriptor(
+          baseClass->getType()->getAsCXXRecordDecl(),
+          0,
+          bParameter,
+          virtCounter,
+          dParameter,
+          Out
+        );
+      virtCounter += 4;
+    }
+    else
+    {
+
+      if (baseClass->getAccessSpecifier() == AS_public)
+      {
+        dParameter = "EA";
+      }
+      else
+      {
+        dParameter = "EN";
+      }
+
+      Context.getMsExtensions()->
+        mangleCXXRTTIBaseClassDescriptor(
+          baseClass->getType()->getAsCXXRecordDecl(),
+          nonVirtCounter,
+          0, // "?0" we need this here
+          0,
+          dParameter,
+          Out
+        );
+
+      nonVirtCounter += 4;
+    }
+
+    Context.mangleCXXRTTI(baseClass->getType(), Out);
+
+    Context.getMsExtensions()->
+      mangleCXXRTTIClassHierarhyDescriptor(
+        baseClass->getType()->getAsCXXRecordDecl(),
+        Out
+      );
+
+    Context.getMsExtensions()->
+      mangleCXXRTTIBaseClassArray(
+        baseClass->getType()->getAsCXXRecordDecl(),
+        Out
+      );
+
+    // End of base class RTTI info.
+    // All virtual classes have this tail and
+    // all base, exclude first nonvirtual base.
+    if (baseClass->isVirtual() || 
+        isFirstNonVirtualBase)
+    {
+      Context.getMsExtensions()->
+        mangleCXXRTTIBaseClassDescriptor(
+          baseClass->getType()->getAsCXXRecordDecl(),
+          0,
+          0, // "?0"
+          0,
+          "EA",
+          Out
+        );
+    }
+    else if (!isFirstNonVirtualBase)
+    {
+      isFirstNonVirtualBase = true;
+    }
+
+  }
+}
+
+// r4start
+static void GenerateCOLTail(MangleContext& Context,
+                            const CXXRecordDecl *RD,
+                            llvm::raw_ostream& Out)
+{
+  // In this case we have more than 1 nonvirtual base class.
+  // Nonvirtual _R4 comes first of all.
+  if (RD->getNumBases() - RD->getNumVBases() > 1)
+  {
+    CXXRecordDecl::base_class_const_iterator 
+                        firstNonVirtualBase = RD->bases_begin();
+    for(; firstNonVirtualBase != RD->bases_end(); ++firstNonVirtualBase)
+    {
+      if (!firstNonVirtualBase->isVirtual())
+      {
+        break;
+      }
+    }
+
+    CXXRecordDecl::base_class_const_iterator 
+                        baseClass = firstNonVirtualBase + 1;
+    for (; baseClass != RD->bases_end(); ++baseClass)
+    {
+      if (!baseClass->isVirtual())
+      {
+        Context.getMsExtensions()->
+          mangleCXXRTTICompleteObjectLocator(
+            RD,
+            baseClass->getType()->getAsCXXRecordDecl(),
+            Out
+          );
+      }
+    }
+
+    baseClass = RD->bases_begin();
+    for (; baseClass != RD->bases_end(); ++baseClass)
+    {
+      if (baseClass->isVirtual())
+      {
+        Context.getMsExtensions()->
+          mangleCXXRTTICompleteObjectLocator(
+            RD,
+            baseClass->getType()->getAsCXXRecordDecl(),
+            Out
+          );
+      }
+    }
+  }
+  else if (RD->getNumBases() - RD->getNumVBases() == 1)
+  {
+    for (CXXRecordDecl::base_class_const_iterator baseClass = RD->bases_begin();
+         baseClass != RD->bases_end();
+         ++baseClass)
+    {
+      if (baseClass->isVirtual())
+      {
+        Context.getMsExtensions()->
+          mangleCXXRTTICompleteObjectLocator(
+            RD,
+            baseClass->getType()->getAsCXXRecordDecl(),
+            Out
+          );
+      }
+    }
+  }
+  else
+  {
+    for(CXXRecordDecl::base_class_const_iterator baseClass = RD->bases_begin();
+        baseClass != RD->bases_end();
+        ++baseClass)
+    {
+      Context.getMsExtensions()->
+        mangleCXXRTTICompleteObjectLocator(
+          RD,
+          baseClass->getType()->getAsCXXRecordDecl(),
+          Out
+        );
+    }
+  }
+}
+
+// r4start
+static void GenerateRTTI(MangleContext& Context,
+                         const CXXRecordDecl *RD,
+                         llvm::raw_ostream& Out)
+{
+  // If we have base classes
+  // we build vftables, start form last.
+  if (RD->getNumBases() != 0) 
+  {
+    GenerateVFTables(Context, RD, Out);
+
+    if (RD->getNumVBases())
+    {
+      GenerateVBTables(Context, RD, Out);
+    }
+
+    GenerateCompleteObjectLocatorData(Context, RD, Out);
+
+    // Mangle type descriptor
+    Context.mangleCXXRTTI(RD->getASTContext().getRecordType(RD), Out);
+
+    // type_info vftable
+    Context.getMsExtensions()->
+      mangleCXXVFTableByClassName(
+        llvm::StringRef("type_info"),
+        llvm::StringRef(), 
+        Out
+      );
+
+    Context.getMsExtensions()->
+      mangleCXXRTTIClassHierarhyDescriptor(RD, Out);
+
+    Context.getMsExtensions()->
+      mangleCXXRTTIBaseClassArray(RD, Out);
+
+    // For this class
+    Context.getMsExtensions()->
+      mangleCXXRTTIBaseClassDescriptor(RD, 0, 0, 0, "EA", Out);
+
+    GenerateBaseClassDescriptorsArray(Context, RD, Out);
+
+    // If we have more than 1 base class then
+    // their COL just appends to the end
+    if (RD->getNumBases() > 1) 
+    {
+      GenerateCOLTail(Context, RD, Out);
+    }
+  }
+  else
+  {
+   Context.mangleCXXVTable(RD, 0, Out);
+  }
+}
+*/
+
 llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {
+  // r4start
+  if (CGM.getContext().getTargetInfo().getCXXABI() == CXXABI_Microsoft) {
+    assert(false && "Must call BuildMSTypeInfo");
+  }
+
   // We want to operate on the canonical type.
   Ty = CGM.getContext().getCanonicalType(Ty);
 
@@ -991,6 +2367,25 @@
   return RTTIBuilder(*this).BuildTypeInfo(Ty);
 }
 
+llvm::Constant *
+CodeGenModule::GetAddrOfMSRTTIDescriptor(QualType Ty,
+                                         QualType BaseTy,
+                                         bool ForEH) {
+  // Return a bogus pointer if RTTI is disabled, unless it's for EH.
+  // FIXME: should we even be calling this method if RTTI is disabled
+  // and it's not for EH?
+  if (!ForEH && !getContext().getLangOpts().RTTI) {
+    llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
+    return llvm::Constant::getNullValue(Int8PtrTy);
+  }
+  
+  if (ForEH && Ty->isObjCObjectPointerType() && !LangOpts.NeXTRuntime) {
+    return ObjCRuntime->GetEHType(Ty);
+  }
+
+  return RTTIBuilder(*this).BuildMSTypeInfo(Ty, BaseTy);
+}
+
 void CodeGenModule::EmitFundamentalRTTIDescriptor(QualType Type) {
   QualType PointerType = Context.getPointerType(Type);
   QualType PointerTypeConst = Context.getPointerType(Type.withConst());
Index: lib/CodeGen/CGVTables.cpp
===================================================================
--- lib/CodeGen/CGVTables.cpp	(revision 154277)
+++ lib/CodeGen/CGVTables.cpp	(working copy)
@@ -22,8 +22,6 @@
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Transforms/Utils/Cloning.h"
-#include <algorithm>
-#include <cstdio>
 
 using namespace clang;
 using namespace CodeGen;
@@ -98,21 +96,93 @@
     // Do the virtual adjustment.
     llvm::Value *VTablePtrPtr = 
       CGF.Builder.CreateBitCast(V, Int8PtrTy->getPointerTo());
-    
+
     llvm::Value *VTablePtr = CGF.Builder.CreateLoad(VTablePtrPtr);
-  
+
     llvm::Value *OffsetPtr =
       CGF.Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment);
-    
+
     OffsetPtr = CGF.Builder.CreateBitCast(OffsetPtr, PtrDiffTy->getPointerTo());
-    
+
     // Load the adjustment offset from the vtable.
     llvm::Value *Offset = CGF.Builder.CreateLoad(OffsetPtr);
+
+    // Adjust our pointer.
+    V = CGF.Builder.CreateInBoundsGEP(V, Offset);
+  }
+
+  // Cast back to the original type.
+  return CGF.Builder.CreateBitCast(V, Ptr->getType());
+}
+
+static bool IsDirectBase(const CXXRecordDecl *RD, const CXXRecordDecl *Base) {
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    if (I->getType()->getAsCXXRecordDecl() == Base)
+      return true;
+  }
+  return false;
+}
+
+static llvm::Value *PerformTypeAdjustmentMS(CodeGenFunction &CGF,
+                                            llvm::Value *Ptr,
+                                            const CXXMethodDecl *MD,
+                                            const CXXRecordDecl *MostDerived,
+                                            int64_t NonVirtualAdjustment,
+                                            int64_t VirtualAdjustment,
+                                            bool IsVtordispEx) {
+  if (!NonVirtualAdjustment && !VirtualAdjustment && !IsVtordispEx)
+    return Ptr;
+
+  llvm::Type *Int32PtrTy = llvm::Type::getInt32PtrTy(CGF.getLLVMContext());
+  
+  llvm::Value *V = CGF.Builder.CreateBitCast(Ptr, CGF.CGM.Int8PtrTy);
+
+  // If we have vtordisp, use it.
+  if (VirtualAdjustment) {
+    llvm::Value *VtorDispPtr = 
+      CGF.Builder.CreateConstGEP1_32(V, -4, "vtordisp.ptr");
+
+    VtorDispPtr = 
+      CGF.Builder.CreateBitCast(VtorDispPtr, Int32PtrTy, "vtordisp");
     
+    // Load the adjustment offset from the vtable.
+    llvm::Value *Offset = 
+      CGF.Builder.CreateLoad(VtorDispPtr, "vtordisp.offset");
+    
     // Adjust our pointer.
     V = CGF.Builder.CreateInBoundsGEP(V, Offset);
   }
 
+  if (IsVtordispEx) {
+    assert(MostDerived && "Can not build vtordispex thunk!");
+
+    VBTableContext &VBTableCtx = CGF.CGM.getVBTableContext();
+
+    const VBTableContext::VBTableEntry &Entry = 
+      VBTableCtx.getEntryFromVBTable(MostDerived, MostDerived, MD->getParent());
+    const VBTableContext::VBTableEntry &FirstEntry = 
+      VBTableCtx.getEntryFromVBTable(MostDerived, MostDerived, MostDerived);
+      
+    llvm::Value *VBPtr = 
+      CGF.Builder.CreateConstGEP1_32(V, FirstEntry.offset, "vbptr.ptr");
+
+    VBPtr = CGF.Builder.CreateBitCast(VBPtr, Int32PtrTy, "vbptr");
+
+    VBPtr = 
+      CGF.Builder.CreateConstGEP1_32(VBPtr, Entry.index, "vbtable.offset");
+
+    llvm::Value *OffsetFromVBTable = 
+      CGF.Builder.CreateLoad(VBPtr, "vbase.offset");
+
+    V = CGF.Builder.CreateGEP(V, OffsetFromVBTable);
+  }
+
+  if (NonVirtualAdjustment) {
+    // Do the non-virtual adjustment.
+    V = CGF.Builder.CreateConstGEP1_32(V, NonVirtualAdjustment);
+  }
+
   // Cast back to the original type.
   return CGF.Builder.CreateBitCast(V, Ptr->getType());
 }
@@ -302,7 +372,8 @@
 
 void CodeGenFunction::GenerateThunk(llvm::Function *Fn,
                                     const CGFunctionInfo &FnInfo,
-                                    GlobalDecl GD, const ThunkInfo &Thunk) {
+                                    GlobalDecl GD, const ThunkInfo &Thunk,
+                                    const CXXRecordDecl *MostDerived) {
   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
   const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
   QualType ResultType = FPT->getResultType();
@@ -332,10 +403,19 @@
   CXXThisValue = CXXABIThisValue;
 
   // Adjust the 'this' pointer if necessary.
-  llvm::Value *AdjustedThisPtr = 
-    PerformTypeAdjustment(*this, LoadCXXThis(), 
-                          Thunk.This.NonVirtual, 
-                          Thunk.This.VCallOffsetOffset);
+  llvm::Value *AdjustedThisPtr;
+  const CXXRecordDecl *Base = MD->getParent();
+  /// r4start
+  if (getContext().getTargetInfo().getCXXABI() == CXXABI_Microsoft)
+    AdjustedThisPtr = PerformTypeAdjustmentMS(*this, LoadCXXThis(), MD,
+                                              MostDerived, 
+                                              Thunk.This.NonVirtual,
+                                              Thunk.This.VCallOffsetOffset,
+                                              Thunk.IsVtordispEx);
+  else
+    AdjustedThisPtr = PerformTypeAdjustment(*this, LoadCXXThis(), 
+                                            Thunk.This.NonVirtual, 
+                                            Thunk.This.VCallOffsetOffset);
   
   CallArgList CallArgs;
   
@@ -396,7 +476,8 @@
 }
 
 void CodeGenVTables::EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk, 
-                               bool UseAvailableExternallyLinkage)
+                               bool UseAvailableExternallyLinkage,
+                               const CXXRecordDecl *MostDerived)
 {
   const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeGlobalDeclaration(GD);
 
@@ -461,7 +542,7 @@
       CodeGenFunction(CGM).GenerateVarArgsThunk(ThunkFn, FnInfo, GD, Thunk);
   } else {
     // Normal thunk body generation.
-    CodeGenFunction(CGM).GenerateThunk(ThunkFn, FnInfo, GD, Thunk);
+    CodeGenFunction(CGM).GenerateThunk(ThunkFn, FnInfo, GD, Thunk, MostDerived);
   }
 
   if (UseAvailableExternallyLinkage)
@@ -483,8 +564,7 @@
   EmitThunk(GD, Thunk, /*UseAvailableExternallyLinkage=*/true);
 }
 
-void CodeGenVTables::EmitThunks(GlobalDecl GD)
-{
+void CodeGenVTables::EmitThunks(GlobalDecl GD) {
   const CXXMethodDecl *MD = 
     cast<CXXMethodDecl>(GD.getDecl())->getCanonicalDecl();
 
@@ -492,8 +572,12 @@
   if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
     return;
 
-  const VTableContext::ThunkInfoVectorTy *ThunkInfoVector =
-    VTContext.getThunkInfo(MD);
+  const VTableContext::ThunkInfoVectorTy *ThunkInfoVector = 0;
+  if (CGM.getContext().getTargetInfo().getCXXABI() != CXXABI_Microsoft) {
+    ThunkInfoVector = VTContext.getThunkInfo(MD);
+  } else {
+    ThunkInfoVector = VTContext.getThunkInfoMS(MD);
+  }
   if (!ThunkInfoVector)
     return;
 
@@ -584,8 +668,8 @@
             VTableThunks[NextVTableThunkIndex].first == I) {
           const ThunkInfo &Thunk = VTableThunks[NextVTableThunkIndex].second;
         
+          Init = CGM.GetAddrOfThunk(GD, Thunk);
           MaybeEmitThunkAvailableExternally(GD, Thunk);
-          Init = CGM.GetAddrOfThunk(GD, Thunk);
 
           NextVTableThunkIndex++;
         } else {
@@ -611,6 +695,186 @@
   return llvm::ConstantArray::get(ArrayType, Inits);
 }
 
+llvm::Constant *
+CodeGenVTables::CreateVFTableInitializer(const CXXRecordDecl *RD,
+                                         const CXXRecordDecl *Base,
+                                         const VTableComponent *Components, 
+                                         unsigned NumComponents,
+                               const VTableLayout::VTableThunkTy *VTableThunks,
+                                         unsigned NumVTableThunks) {
+  SmallVector<llvm::Constant *, 64> Inits;
+
+  llvm::Type *PtrDiffTy = 
+    CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
+
+  QualType ClassType = CGM.getContext().getTagDeclType(RD);
+  QualType BaseType = CGM.getContext().getTagDeclType(Base);
+
+  llvm::Constant *RTTI = CGM.GetAddrOfMSRTTIDescriptor(ClassType, BaseType);
+  unsigned NextVTableThunkIndex = 0;
+
+  for (unsigned I = 0; I < NumComponents; ++I) {
+    llvm::Constant *Init;
+    VTableComponent Component = Components[I];
+
+    switch (Component.getKind()) {
+    case VTableComponent::CK_RTTI:
+      Init = llvm::ConstantExpr::getBitCast(RTTI, CGM.Int8PtrTy);
+      break;
+    case VTableComponent::CK_CompleteDtorPointer:
+    case VTableComponent::CK_FunctionPointer: {
+        GlobalDecl GD;
+
+        switch (Component.getKind()) {
+        case VTableComponent::CK_FunctionPointer:
+          GD = Component.getFunctionDecl();
+          break;
+        case VTableComponent::CK_CompleteDtorPointer:
+          // In MS ABI this is 'scalar deleting destructor'.
+          GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Complete);
+          break;
+        case VTableComponent::CK_DeletingDtorPointer:
+          // In MS ABI this is 'vector deleting destructor'.
+          GD = GlobalDecl(Component.getDestructorDecl(), Dtor_Deleting);
+          break;
+        default:
+          llvm_unreachable("Vftable containes RTTI info and FunctionPtrs!!!");
+        }
+        
+        if (NextVTableThunkIndex < NumVTableThunks &&
+          VTableThunks[NextVTableThunkIndex].first == I) {
+          const ThunkInfo &Thunk = VTableThunks[NextVTableThunkIndex].second;
+
+          llvm::Type *Ty = CGM.getTypes().GetFunctionTypeForVTable(GD);
+          CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true);
+
+          Init = CGM.GetAddrOfThunk(GD, Thunk);
+          MaybeEmitThunkAvailableExternally(GD, Thunk);
+          // TODO: Do for RD thunks deferred generation.
+          EmitThunk(GD, Thunk, true, RD);
+
+          NextVTableThunkIndex++;
+        } else {
+          llvm::Type *Ty = CGM.getTypes().GetFunctionTypeForVTable(GD);
+          Init = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true);
+        }
+
+        Init = llvm::ConstantExpr::getBitCast(Init, CGM.Int8PtrTy);
+        break;
+      }
+    default:
+      llvm_unreachable("Vftable containes RTTI info and FunctionPtrs!!!");
+    }
+    Inits.push_back(Init);
+  }
+
+  llvm::ArrayType *ArrayType = llvm::ArrayType::get(CGM.Int8PtrTy, NumComponents);
+  return llvm::ConstantArray::get(ArrayType, Inits);
+}
+
+// r4start
+llvm::GlobalVariable *
+CodeGenVTables::GetAddrOfVBTable(const CXXRecordDecl *RD,
+                                 const CXXRecordDecl *Base) {
+  llvm::GlobalVariable *&VBTable = MSVBTables[RD][Base];
+  if (VBTable)
+    return VBTable;
+
+  const CXXRecordDecl *BaseDecl = Base;
+  if (BaseDecl == RD)
+    BaseDecl = 0;
+
+  llvm::SmallString<256> Name;
+  llvm::raw_svector_ostream Out(Name);
+
+  CGM.getCXXABI().getMangleContext().
+    getMsExtensions()->mangleCXXVBTable(RD, BaseDecl, Out);
+  Out.flush();
+
+  llvm::StringRef VBTableName = Name.str();
+
+  VBTableContext& Context = CGM.getVBTableContext();
+  const VBTableContext::BaseVBTableTy &Table = Context.getVBTable(RD, Base);
+
+  llvm::ArrayType *VBTableType = 
+                                llvm::ArrayType::get(CGM.Int32Ty, Table.size());
+
+  VBTable = CGM.CreateOrReplaceCXXRuntimeVariable(Name, VBTableType, 
+                                            llvm::GlobalValue::ExternalLinkage);
+
+  VBTable->setUnnamedAddr(true);
+
+  return VBTable;
+}
+
+// r4start
+llvm::GlobalVariable *
+CodeGenVTables::GetAddrOfVFTable(const CXXRecordDecl *RD,
+                                 const CXXRecordDecl *Base) {
+  const CXXRecordDecl *BaseDecl;
+  const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
+
+  if (!Base)
+    BaseDecl = RD;
+  else
+    BaseDecl = Base;
+
+  llvm::GlobalVariable *&VFTable = MSVFTables[RD][BaseDecl];
+  if (VFTable)
+    return VFTable;
+
+  if (ShouldEmitVTableInThisTU(RD))
+    CGM.DeferredVTables.push_back(RD);
+   
+  SmallString<256> OutName;
+  llvm::raw_svector_ostream Out(OutName);
+
+  CGM.getCXXABI().getMangleContext().mangleCXXVTable(RD, BaseDecl, Out);
+  
+  Out.flush();
+  StringRef Name = OutName.str();
+
+  llvm::ArrayType *ArrayType = 
+    llvm::ArrayType::get(CGM.Int8PtrTy,
+             VTContext.getVFTableLayout(RD, BaseDecl).getNumVTableComponents());
+
+  VFTable =
+    CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType, 
+                                          llvm::GlobalValue::ExternalLinkage);
+  VFTable->setUnnamedAddr(true);
+  return VFTable;
+}
+
+// r4start
+void 
+CodeGenVTables::EmitVFTableDefinition(llvm::GlobalVariable *VFTable,
+                                    llvm::GlobalVariable::LinkageTypes Linkage,
+                                      const CXXRecordDecl *RD, 
+                                      const CXXRecordDecl *Base) {
+  const CXXRecordDecl *BaseDecl = Base;
+  if (!Base)
+    BaseDecl = RD;
+
+  const VTableLayout &VTLayout = VTContext.getVFTableLayout(RD, BaseDecl);
+
+  // Create and set the initializer.
+  llvm::Constant *Init = 
+    CreateVFTableInitializer(RD,
+                             BaseDecl,
+                             VTLayout.vtable_component_begin(),
+                             VTLayout.getNumVTableComponents(),
+                             VTLayout.vtable_thunk_begin(),
+                             VTLayout.getNumVTableThunks());
+  VFTable->setInitializer(Init);
+  
+  // Set the correct linkage.
+  VFTable->setLinkage(Linkage);
+  
+  // Set the right visibility.
+  CGM.setTypeVisibility(VFTable, RD, CodeGenModule::TVK_ForVTable);
+}
+
+// r4start
 llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTable(const CXXRecordDecl *RD) {
   llvm::GlobalVariable *&VTable = VTables[RD];
   if (VTable)
@@ -622,7 +886,7 @@
 
   SmallString<256> OutName;
   llvm::raw_svector_ostream Out(OutName);
-  CGM.getCXXABI().getMangleContext().mangleCXXVTable(RD, Out);
+  CGM.getCXXABI().getMangleContext().mangleCXXVTable(RD, 0, Out);
   Out.flush();
   StringRef Name = OutName.str();
 
@@ -706,8 +970,64 @@
 }
 
 void 
+CodeGenVTables::BuildVFTables(const CXXRecordDecl *MostDerivedClass,
+                                   const CXXRecordDecl *RD,
+                                   const CXXRecordDecl *Base,
+                                   llvm::GlobalVariable::LinkageTypes Linkage) {
+  for (CXXRecordDecl::base_class_const_iterator I = Base->bases_begin(),
+       E = Base->bases_end(); I != E; ++I) {
+    const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
+
+    if (!BaseDecl->isPolymorphic())
+      continue;
+
+    BuildVFTables(MostDerivedClass, Base, BaseDecl, Linkage);
+  }
+
+  const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(Base);
+  if (Layout.getPrimaryBase() ||
+      Layout.getVFPtrOffset() == CharUnits::fromQuantity(-1))
+    return;
+
+  llvm::GlobalVariable *VFTable = GetAddrOfVFTable(MostDerivedClass, Base);
+
+  EmitVFTableDefinition(VFTable, Linkage, MostDerivedClass, Base);
+}
+
+void
+CodeGenVTables::MSGenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
+                                    const CXXRecordDecl *RD) {
+  const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
+
+  if (!RD->getNumBases()) {
+    llvm::GlobalVariable *VFTable = GetAddrOfVFTable(RD, 0);
+    EmitVFTableDefinition(VFTable, Linkage, RD, 0);
+    return;
+  }
+
+  if (Layout.getVFPtrOffset() != CharUnits::fromQuantity(-1)) {
+    llvm::GlobalVariable *VFTable = GetAddrOfVFTable(RD, 0);
+    EmitVFTableDefinition(VFTable, Linkage, RD, 0);
+  }
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+        E = RD->bases_end(); I != E; ++I) {
+    const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
+
+    if (!Base->isPolymorphic())
+      continue;
+
+    BuildVFTables(RD, RD, Base, Linkage);
+  }
+}
+
+void 
 CodeGenVTables::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
                                   const CXXRecordDecl *RD) {
+  // r4start
+  if (CGM.getContext().getTargetInfo().getCXXABI() == CXXABI_Microsoft) {
+    return MSGenerateClassData(Linkage, RD);
+  }
+
   llvm::GlobalVariable *VTable = GetAddrOfVTable(RD);
   if (VTable->hasInitializer())
     return;
Index: lib/CodeGen/CGVTables.h
===================================================================
--- lib/CodeGen/CGVTables.h	(revision 154277)
+++ lib/CodeGen/CGVTables.h	(working copy)
@@ -21,6 +21,7 @@
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/GlobalDecl.h"
 #include "clang/AST/VTableBuilder.h"
+#include "clang/AST/VBTableBuilder.h"
 
 namespace clang {
   class CXXRecordDecl;
@@ -33,8 +34,18 @@
 
   VTableContext VTContext;
 
+  VBTableContext VBTContext;
+
+  typedef llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> 
+  VTablesMapTy;
+
   /// VTables - All the vtables which have been defined.
-  llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
+  VTablesMapTy VTables;
+
+  typedef llvm::DenseMap<const CXXRecordDecl *, VTablesMapTy > MSVTablesTy;
+
+  MSVTablesTy MSVFTables;
+  MSVTablesTy MSVBTables;
   
   /// VTableAddressPointsMapTy - Address points for a single vtable.
   typedef llvm::DenseMap<BaseSubobject, uint64_t> VTableAddressPointsMapTy;
@@ -54,7 +65,8 @@
 
   /// EmitThunk - Emit a single thunk.
   void EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk, 
-                 bool UseAvailableExternallyLinkage);
+                 bool UseAvailableExternallyLinkage,
+                 const CXXRecordDecl *MostDerived = 0);
 
   /// MaybeEmitThunkAvailableExternally - Try to emit the given thunk with
   /// available_externally linkage to allow for inlining of thunks.
@@ -72,11 +84,22 @@
                                 const VTableLayout::VTableThunkTy *VTableThunks,
                                           unsigned NumVTableThunks);
 
+  /// r4start
+  /// CreateVFTableInitializer
+  llvm::Constant *CreateVFTableInitializer(const CXXRecordDecl *RD,
+                                           const CXXRecordDecl *Base,
+                                           const VTableComponent *Components, 
+                                           unsigned NumComponents,
+                               const VTableLayout::VTableThunkTy *VTableThunks,
+                                           unsigned NumVTableThunks);
+
 public:
   CodeGenVTables(CodeGenModule &CGM);
 
   VTableContext &getVTableContext() { return VTContext; }
 
+  VBTableContext &getVBTableContext() { return VBTContext; }
+
   /// \brief True if the VTable of this record must be emitted in the
   /// translation unit.
   bool ShouldEmitVTableInThisTU(const CXXRecordDecl *RD);
@@ -107,6 +130,25 @@
                             llvm::GlobalVariable::LinkageTypes Linkage,
                             const CXXRecordDecl *RD);
   
+  /// r4start
+  llvm::GlobalVariable *GetAddrOfVFTable(const CXXRecordDecl *RD,
+                                         const CXXRecordDecl *Base);
+
+  llvm::GlobalVariable *GetAddrOfVBTable(const CXXRecordDecl *RD,
+                                         const CXXRecordDecl *Base);
+
+  /// r4start
+  void EmitVFTableDefinition(llvm::GlobalVariable *VFTable,
+                             llvm::GlobalVariable::LinkageTypes Linkage,
+                             const CXXRecordDecl *RD,
+                             const CXXRecordDecl *Base);
+
+  /// r4start
+  void BuildVFTables(const CXXRecordDecl *MostDerived,
+                     const CXXRecordDecl *RD,
+                     const CXXRecordDecl *Base,
+                     llvm::GlobalVariable::LinkageTypes Linkage);
+  
   /// GenerateConstructionVTable - Generate a construction vtable for the given 
   /// base subobject.
   llvm::GlobalVariable *
@@ -134,6 +176,14 @@
   /// \param Linkage - The desired linkage of the vtable, the RTTI and the VTT.
   void GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
                          const CXXRecordDecl *RD);
+
+  /// GenerateClassData - Generate all the class data required to be generated
+  /// upon definition of a KeyFunction.  This includes the vtable, the
+  /// rtti data structure and the vbtable. Specific for MS ABI.
+  ///
+  /// \param Linkage - The desired linkage of the vtable, the RTTI and the VTT.
+  void MSGenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
+                           const CXXRecordDecl *RD);
 };
 
 } // end namespace CodeGen
Index: lib/CodeGen/CodeGenAction.cpp
===================================================================
--- lib/CodeGen/CodeGenAction.cpp	(revision 154277)
+++ lib/CodeGen/CodeGenAction.cpp	(working copy)
@@ -87,7 +87,13 @@
       Gen->Initialize(Ctx);
 
       TheModule.reset(Gen->GetModule());
+      // r4start
+      // This is need to emit ms names right in object file.
+      /*llvm::Triple Abi;
+      Abi.setEnvironmentName(TargetOpts.CXXABI);
 
+      TheModule->setEnviromentType(Abi.getEnvironment());*/
+
       if (llvm::TimePassesIsEnabled)
         LLVMIRGeneration.stopTimer();
     }
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h	(revision 154277)
+++ lib/CodeGen/CodeGenFunction.h	(working copy)
@@ -1392,7 +1392,8 @@
 
   /// GenerateThunk - Generate a thunk for the given method.
   void GenerateThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo,
-                     GlobalDecl GD, const ThunkInfo &Thunk);
+                     GlobalDecl GD, const ThunkInfo &Thunk,
+                     const CXXRecordDecl *MostDerived = 0);
 
   void GenerateVarArgsThunk(llvm::Function *Fn, const CGFunctionInfo &FnInfo,
                             GlobalDecl GD, const ThunkInfo &Thunk);
@@ -1423,6 +1424,23 @@
 
   void InitializeVTablePointers(const CXXRecordDecl *ClassDecl);
 
+  /// r4start
+  void MSInitializeVBTablePointer(llvm::Constant *VBTable, CharUnits Offset);
+
+  /// r4start
+  void MSInitializeVBTablePointers(const CXXRecordDecl *Class);
+
+  /// r4start
+  void MSInitializeVFTablePointer(llvm::Constant *VFTable, CharUnits Offset);
+
+  /// r4start
+  void MSInitializeVFTablePointers(const CXXRecordDecl *MostDerived,
+                                   const CXXRecordDecl *RD, 
+                                   const CXXRecordDecl *Base);
+
+  /// r4start
+  void MSInitializeVFTablePointers(const CXXRecordDecl *Class);
+
   /// GetVTablePtr - Return the Value of the vtable pointer member pointed
   /// to by This.
   llvm::Value *GetVTablePtr(llvm::Value *This, llvm::Type *Ty);
@@ -1772,13 +1790,14 @@
   void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type,
                               bool ForVirtualBase, llvm::Value *This,
                               CallExpr::const_arg_iterator ArgBeg,
-                              CallExpr::const_arg_iterator ArgEnd);
+                              CallExpr::const_arg_iterator ArgEnd,
+                              bool CallFromCtor = false);
   
   void EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D,
                               llvm::Value *This, llvm::Value *Src,
                               CallExpr::const_arg_iterator ArgBeg,
                               CallExpr::const_arg_iterator ArgEnd);
-
+  
   void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
                                   const ConstantArrayType *ArrayTy,
                                   llvm::Value *ArrayPtr,
@@ -2221,7 +2240,8 @@
                            llvm::Value *This,
                            llvm::Value *VTT,
                            CallExpr::const_arg_iterator ArgBeg,
-                           CallExpr::const_arg_iterator ArgEnd);
+                           CallExpr::const_arg_iterator ArgEnd,
+                           bool CallFromCtor = false);
   RValue EmitCXXMemberCallExpr(const CXXMemberCallExpr *E,
                                ReturnValueSlot ReturnValue);
   RValue EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
@@ -2358,7 +2378,8 @@
   /// EmitAggExpr - Emit the computation of the specified expression
   /// of aggregate type.  The result is computed into the given slot,
   /// which may be null to indicate that the value is not needed.
-  void EmitAggExpr(const Expr *E, AggValueSlot AS, bool IgnoreResult = false);
+  void EmitAggExpr(const Expr *E, AggValueSlot AS, 
+                   bool IgnoreResult = false, bool CallFromCtor = false);
 
   /// EmitAggExprToLValue - Emit the computation of the specified expression of
   /// aggregate type into a temporary LValue.
@@ -2440,7 +2461,8 @@
                                         llvm::GlobalVariable *Addr,
                                         bool PerformInit);
 
-  void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest);
+  void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest, 
+                            bool CallFromCtor = false);
   
   void EmitSynthesizedCXXCopyCtor(llvm::Value *Dest, llvm::Value *Src,
                                   const Expr *Exp);
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp	(revision 154277)
+++ lib/CodeGen/CodeGenModule.cpp	(working copy)
@@ -959,7 +959,14 @@
       if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(Method))
         EmitCXXConstructor(CD, GD.getCtorType());
       else if (const CXXDestructorDecl *DD =dyn_cast<CXXDestructorDecl>(Method))
+      {
+        // r4start
+        if (Context.getTargetInfo().getCXXABI() == CXXABI_Microsoft) {
+          EmitCXXDestructor(DD, Dtor_Base);
+        } else {
         EmitCXXDestructor(DD, GD.getDtorType());
+        }
+      }
       else
         EmitGlobalFunctionDefinition(GD);
 
Index: lib/CodeGen/CodeGenModule.h
===================================================================
--- lib/CodeGen/CodeGenModule.h	(revision 154277)
+++ lib/CodeGen/CodeGenModule.h	(working copy)
@@ -447,6 +447,7 @@
   CodeGenTypes &getTypes() { return Types; }
   CodeGenVTables &getVTables() { return VTables; }
   VTableContext &getVTableContext() { return VTables.getVTableContext(); }
+  VBTableContext &getVBTableContext() { return VTables.getVBTableContext(); }
   DiagnosticsEngine &getDiags() const { return Diags; }
   const llvm::TargetData &getTargetData() const { return TheTargetData; }
   const TargetInfo &getTarget() const { return Context.getTargetInfo(); }
@@ -535,6 +536,12 @@
   /// for the given type.
   llvm::Constant *GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH = false);
 
+  /// r4start
+  /// GetAddrOfRTTIDescriptor - Get the address of the RTTI descriptor 
+  /// for the given type in MS ABI.
+  llvm::Constant *
+  GetAddrOfMSRTTIDescriptor(QualType Ty, QualType BaseTy, bool ForEH = false);
+
   /// GetAddrOfThunk - Get the address of the thunk for the given global decl.
   llvm::Constant *GetAddrOfThunk(GlobalDecl GD, const ThunkInfo &Thunk);
 
Index: lib/CodeGen/MicrosoftCXXABI.cpp
===================================================================
--- lib/CodeGen/MicrosoftCXXABI.cpp	(revision 154277)
+++ lib/CodeGen/MicrosoftCXXABI.cpp	(working copy)
@@ -22,6 +22,7 @@
 using namespace clang;
 using namespace CodeGen;
 
+// r4start
 namespace {
 
 class MicrosoftCXXABI : public CGCXXABI {
@@ -31,31 +32,69 @@
   void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
                                  CXXCtorType Type,
                                  CanQualType &ResTy,
-                                 SmallVectorImpl<CanQualType> &ArgTys) {
-    // 'this' is already in place
-    // TODO: 'for base' flag
-  }  
+                                 SmallVectorImpl<CanQualType> &ArgTys);
 
   void BuildDestructorSignature(const CXXDestructorDecl *Ctor,
                                 CXXDtorType Type,
                                 CanQualType &ResTy,
-                                SmallVectorImpl<CanQualType> &ArgTys) {
-    // 'this' is already in place
-    // TODO: 'for base' flag
-  }
+                                SmallVectorImpl<CanQualType> &ArgTys);
 
   void BuildInstanceFunctionParams(CodeGenFunction &CGF,
                                    QualType &ResTy,
-                                   FunctionArgList &Params) {
-    BuildThisParam(CGF, Params);
-    // TODO: 'for base' flag
-  }
+                                   FunctionArgList &Params);
 
-  void EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
-    EmitThisParam(CGF);
-    // TODO: 'for base' flag
-  }
+  void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
 
+  // Load a member function from an object and a member function
+  // pointer.  Apply the this-adjustment and set 'This' to the
+  // adjusted value.
+  virtual llvm::Value*
+  EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
+                                  llvm::Value *&This,
+                                  llvm::Value *MemPtr,
+                                  const MemberPointerType *MPT);
+
+  // Calculate an l-value from an object and a data member pointer.
+  virtual llvm::Value* EmitMemberDataPointerAddress(CodeGenFunction &CGF,
+                                                    llvm::Value *Base,
+                                                    llvm::Value *MemPtr,
+                                                  const MemberPointerType *MPT);
+
+  // Perform a derived-to-base or base-to-derived member pointer
+  // conversion.
+  virtual llvm::Value* EmitMemberPointerConversion(CodeGenFunction &CGF,
+                                                   const CastExpr *E,
+                                                   llvm::Value *Src);
+
+  // Perform a derived-to-base or base-to-derived member pointer
+  // conversion on a constant member pointer.
+  virtual llvm::Constant* EmitMemberPointerConversion(llvm::Constant *C,
+                                                      const CastExpr *E);
+
+  // Create a null member pointer of the given type.
+  virtual llvm::Constant* EmitNullMemberPointer(const MemberPointerType *MPT);
+
+  // Create a member pointer for the given method.
+  virtual llvm::Constant* EmitMemberPointer(const CXXMethodDecl *MD);
+
+  // Create a member pointer for the given field.
+  virtual llvm::Constant* EmitMemberDataPointer(const MemberPointerType *MPT,
+                                                CharUnits offset);
+
+  // Emit a comparison between two member pointers.  Returns an i1.
+  virtual llvm::Value*
+  EmitMemberPointerComparison(CodeGenFunction &CGF,
+                              llvm::Value *L,
+                              llvm::Value *R,
+                              const MemberPointerType *MPT,
+                              bool Inequality);
+
+  // Determine if a member pointer is non-null.  Returns an i1.
+  virtual llvm::Value*
+  EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
+                             llvm::Value *MemPtr,
+                             const MemberPointerType *MPT);
+
   // ==== Notes on array cookies =========
   //
   // MSVC seems to only use cookies when the class has a destructor; a
@@ -78,18 +117,339 @@
   //     delete[] p;
   //   }
   // Whereas it prints "104" and "104" if you give A a destructor.
-  void ReadArrayCookie(CodeGenFunction &CGF, llvm::Value *Ptr,
+
+  // Returns the extra size required in order to store the array
+  // cookie for the given type.  May return 0 to indicate that no
+  // array cookie is required.
+  //
+  // Several cases are filtered out before this method is called:
+  //   - non-array allocations never need a cookie
+  //   - calls to ::operator new(size_t, void*) never need a cookie
+  //
+  // \param ElementType - the allocated type of the expression,
+  //   i.e. the pointee type of the expression result type
+  virtual CharUnits GetArrayCookieSize(const CXXNewExpr *expr);
+
+  // Initialize the array cookie for the given allocation.
+  //
+  // \param NewPtr - a char* which is the presumed-non-null
+  //   return value of the allocation function
+  // \param NumElements - the computed number of elements,
+  //   potentially collapsed from the multidimensional array case
+  // \param ElementType - the base element allocated type,
+  //   i.e. the allocated type after stripping all array types
+  virtual llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
+                                             llvm::Value *NewPtr,
+                                             llvm::Value *NumElements,
+                                             const CXXNewExpr *expr,
+                                             QualType ElementType);
+
+  // Reads the array cookie associated with the given pointer,
+  // if it has one.
+  //
+  // \param Ptr - a pointer to the first element in the array
+  // \param ElementType - the base element type of elements of the array
+  // \param NumElements - an out parameter which will be initialized
+  //   with the number of elements allocated, or zero if there is no
+  //   cookie
+  // \param AllocPtr - an out parameter which will be initialized
+  //   with a char* pointing to the address returned by the allocation
+  //   function
+  // \param CookieSize - an out parameter which will be initialized
+  //   with the size of the cookie, or zero if there is no cookie
+  virtual void ReadArrayCookie(CodeGenFunction &CGF,
+                               llvm::Value *Ptr,
                        const CXXDeleteExpr *expr,
-                       QualType ElementType, llvm::Value *&NumElements,
-                       llvm::Value *&AllocPtr, CharUnits &CookieSize) {
-    CGF.CGM.ErrorUnsupported(expr, "don't know how to handle array cookies "
-                                   "in the Microsoft C++ ABI");
-  }
+                               QualType ElementType,
+                               llvm::Value *&NumElements,
+                               llvm::Value *&AllocPtr,
+                               CharUnits &CookieSize);
+
+private:
+
+    bool NeedArrayCookie(const CXXNewExpr* newExpr) const;
+    bool NeedArrayCookie(const CXXDeleteExpr* delExpr,
+                         QualType elementType) const;
+
+    static bool NeedThisReturn(GlobalDecl GD);
 };
 
 }
 
+bool MicrosoftCXXABI::NeedThisReturn(GlobalDecl GD) {
+  const CXXMethodDecl* MD = cast<CXXMethodDecl>(GD.getDecl());
+  return isa<CXXConstructorDecl>(MD);
+}
+
+void MicrosoftCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
+                                                CXXCtorType Type,
+                                                CanQualType &ResTy,
+                                   llvm::SmallVectorImpl<CanQualType> &ArgTys) {
+  // 'this' is already in place
+  // Ctor returns this ptr
+  ResTy = ArgTys[0];
+
+  const CXXRecordDecl *Class = Ctor->getParent();
+  if (!Class->getNumVBases())
+    return;
+  ArgTys.push_back(CGM.getContext().Char32Ty);
+}
+
+void MicrosoftCXXABI::BuildDestructorSignature(const CXXDestructorDecl *Ctor,
+                                               CXXDtorType Type,
+                                               CanQualType &ResTy,
+                                   llvm::SmallVectorImpl<CanQualType> &ArgTys) {
+  // 'this' is already in place
+  // TODO: 'for base' flag
+  // TODO: add RTTI if need
+}
+
+void MicrosoftCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
+                                                  QualType &ResTy,
+                                                  FunctionArgList &Params) {
+  BuildThisParam(CGF, Params);
+  if (NeedThisReturn(CGF.CurGD)) {
+    ResTy = Params[0]->getType();
+  }
+
+  const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
+  if (!MD->getParent()->getNumVBases() || !isa<CXXConstructorDecl>(MD))
+    return;
+  ImplicitParamDecl *FlagDecl
+    = ImplicitParamDecl::Create(CGM.getContext(), 0, MD->getLocation(),
+                                &CGM.getContext().Idents.get("ctor.flag"),
+                                CGM.getContext().Char32Ty);
+  Params.push_back(FlagDecl);
+}
+
+void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
+  EmitThisParam(CGF);
+
+  if (NeedThisReturn(CGF.CurGD)) {
+    CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
+  }
+  // TODO: 'for base' flag
+}
+
+bool MicrosoftCXXABI::NeedArrayCookie(const CXXNewExpr* newExpr) const {
+  if (newExpr->doesUsualArrayDeleteWantSize()) {
+    return true;
+  }
+
+  const CXXRecordDecl* type = 
+          newExpr->getAllocatedType()->
+              getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
+
+  return (type && !type->hasTrivialDestructor());
+}
+
+bool MicrosoftCXXABI::NeedArrayCookie(const CXXDeleteExpr* delExpr,
+                                      QualType elemType) const {
+  if (delExpr->doesUsualArrayDeleteWantSize()) {
+    return true;
+  }
+  
+  const CXXRecordDecl* type = 
+    elemType->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
+
+  return (type && !type->hasTrivialDestructor());
+}
+
+llvm::Value*
+MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
+                                                 llvm::Value *&This,
+                                                 llvm::Value *FuncPtr,
+                                                 const MemberPointerType *MPT) {
+  CGBuilderTy &Builder = CGF.Builder;
+
+  const FunctionProtoType* FPT = 
+    MPT->getPointeeType()->getAs<FunctionProtoType>();
+  const CXXRecordDecl* RD = 
+    cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
+
+  llvm::FunctionType* FTy = 
+    CGM.getTypes().
+      GetFunctionType(CGM.getTypes().arrangeCXXMethodType(RD, FPT));
+
+  llvm::Value* NonVirtualFn =
+    Builder.CreateIntToPtr(FuncPtr, FTy->getPointerTo(), "memfun.nonvirtualfn");
+
+  return NonVirtualFn;
+}
+
+CharUnits MicrosoftCXXABI::GetArrayCookieSize(const CXXNewExpr *expr) {
+  if (!NeedArrayCookie(expr)) {
+    return CharUnits::Zero();
+  }
+
+  ASTContext& C = getContext();
+
+  // r4start
+  // Add check for size of allocation.
+  return CharUnits::fromQuantity(C.getTypeSize(C.Char32Ty));
+}
+
 CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
   return new MicrosoftCXXABI(CGM);
 }
 
+llvm::Value* 
+MicrosoftCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,
+                                              llvm::Value *Base,
+                                              llvm::Value *MemPtr,
+                                              const MemberPointerType *MPT) {
+  CGBuilderTy &Builder = CGF.Builder;
+
+  unsigned AS = cast<llvm::PointerType>(Base->getType())->getAddressSpace();
+
+  // Cast to char*.
+  Base = Builder.CreateBitCast(Base, Builder.getInt8Ty()->getPointerTo(AS));
+
+  // Apply the offset, which we assume is non-null.
+  llvm::Value *Addr = Builder.CreateInBoundsGEP(Base, MemPtr, "memptr.offset");
+
+  // Cast the address to the appropriate pointer type, adopting the
+  // address space of the base pointer.
+  llvm::Type *PType
+    = CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS);
+  return Builder.CreateBitCast(Addr, PType);
+}
+
+llvm::Value* MicrosoftCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
+                                                          const CastExpr *E,
+                                                          llvm::Value *Src) {
+  llvm_unreachable("EmitMemberPointerConversion is not implement yet!!!");
+  return nullptr;
+}
+
+llvm::Constant* MicrosoftCXXABI::EmitMemberPointerConversion(llvm::Constant *C,
+                                                             const CastExpr *E) {
+  llvm_unreachable("EmitMemberPointerConversion is not implement yet!!!");
+  return nullptr;
+}
+
+llvm::Constant* 
+MicrosoftCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
+  llvm_unreachable("EmitMemberPointer is not implement yet!!!");
+  return nullptr;
+}
+
+llvm::Constant* MicrosoftCXXABI::EmitMemberPointer(const CXXMethodDecl *MD) {
+  assert(MD->isInstance() && "Member function must not be static!");
+
+  MD = MD->getCanonicalDecl();
+
+  QualType DiffTy = getContext().getPointerDiffType();
+  llvm::Type* ptrDiffTy = 
+    cast<llvm::IntegerType>(
+                 CGM.getTypes().ConvertType(getContext().getPointerDiffType()));
+
+  if (MD->isVirtual()) {
+    llvm_unreachable("Emit member pointer to virtual func is very hard work!");
+  } else {
+    llvm::Type* Ty = CGM.getTypes().GetFunctionType(MD);
+    llvm::Constant* addr = CGM.GetAddrOfFunction(MD, Ty);
+
+    return llvm::ConstantExpr::getPtrToInt(addr, ptrDiffTy);
+  }
+
+}
+
+llvm::Constant* 
+MicrosoftCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
+                                       CharUnits offset) {
+  QualType DiffTy = getContext().getPointerDiffType();
+  llvm::Type* ptrDiffTy = 
+    cast<llvm::IntegerType>(
+                 CGM.getTypes().ConvertType(getContext().getPointerDiffType()));
+
+  return llvm::ConstantInt::get(ptrDiffTy, offset.getQuantity());
+}
+
+llvm::Value*
+MicrosoftCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
+                                             llvm::Value *L,
+                                             llvm::Value *R,
+                                             const MemberPointerType *MPT,
+                                             bool Inequality) {
+  llvm_unreachable("EmitMemberPointerComparison is not implement yet!!!");
+  return nullptr;
+}
+
+llvm::Value* 
+MicrosoftCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
+                                            llvm::Value *MemPtr,
+                                            const MemberPointerType *MPT) {
+  llvm_unreachable("EmitMemberPointerIsNotNull is not implement yet!!!");
+  return nullptr;
+}
+
+void MicrosoftCXXABI::ReadArrayCookie(CodeGenFunction &CGF,
+                                      llvm::Value *Ptr,
+                                      const CXXDeleteExpr *expr,
+                                      QualType ElementType,
+                                      llvm::Value *&NumElements,
+                                      llvm::Value *&AllocPtr,
+                                      CharUnits &CookieSize) {
+  // Derive a char* in the same address space as the pointer.
+  unsigned AS = cast<llvm::PointerType>(Ptr->getType())->getAddressSpace();
+  llvm::Type *CharPtrTy = CGF.Builder.getInt8Ty()->getPointerTo(AS);
+
+  // If we don't need an array cookie, bail out early.
+  if (!NeedArrayCookie(expr, ElementType)) {
+    AllocPtr = CGF.Builder.CreateBitCast(Ptr, CharPtrTy);
+    NumElements = 0;
+    CookieSize = CharUnits::Zero();
+    return;
+  }
+
+  QualType SizeTy = getContext().Char32Ty;
+  llvm::Type *SizeLTy = CGF.ConvertType(SizeTy);
+
+  CookieSize = CharUnits::fromQuantity(getContext().getTypeSize(SizeTy));
+  CharUnits NumElementsOffset = CookieSize;
+
+  // Compute the allocated pointer.
+  AllocPtr = CGF.Builder.CreateBitCast(Ptr, CharPtrTy);
+  AllocPtr = CGF.Builder.CreateConstInBoundsGEP1_64(AllocPtr,
+    -CookieSize.getQuantity());
+
+  llvm::Value *NumElementsPtr = AllocPtr;
+  if (!NumElementsOffset.isZero())
+    NumElementsPtr =
+    CGF.Builder.CreateConstInBoundsGEP1_64(NumElementsPtr,
+    NumElementsOffset.getQuantity());
+  NumElementsPtr = 
+    CGF.Builder.CreateBitCast(NumElementsPtr, SizeLTy->getPointerTo(AS));
+  NumElements = CGF.Builder.CreateLoad(NumElementsPtr);
+}
+
+llvm::Value* MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
+                                                    llvm::Value *NewPtr,
+                                                    llvm::Value *NumElements,
+                                                    const CXXNewExpr *expr,
+                                                    QualType ElementType) {
+  assert(NeedArrayCookie(expr));
+
+  unsigned AS = cast<llvm::PointerType>(NewPtr->getType())->getAddressSpace();
+
+  ASTContext &Ctx = getContext();
+  QualType SizeTy = Ctx.Char32Ty;
+
+  // The size of the cookie.
+  CharUnits CookieSize = GetArrayCookieSize(expr);
+
+  // Compute an offset to the cookie.
+  llvm::Value *CookiePtr = NewPtr;
+
+  // Write the number of elements into the appropriate slot.
+  llvm::Value *NumElementsPtr
+    = CGF.Builder.CreateBitCast(CookiePtr,
+                                CGF.ConvertType(SizeTy)->getPointerTo(AS));
+  CGF.Builder.CreateStore(NumElements, NumElementsPtr);
+
+  // Finally, compute a pointer to the actual data buffer by skipping
+  // over the cookie completely.
+  return CGF.Builder.CreateConstInBoundsGEP1_64(NewPtr,
+                                                CookieSize.getQuantity());
+}
Index: test/CodeGenCXX/ms-rtti.cpp
===================================================================
--- test/CodeGenCXX/ms-rtti.cpp	(revision 0)
+++ test/CodeGenCXX/ms-rtti.cpp	(working copy)
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -fms-extensions -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+// r4start
+#pragma pack(push, 8)
+class first {
+public:
+  virtual void b() {}
+  double b_field;
+protected:
+private:
+};
+
+class second : first {
+public:
+  virtual void C_f(){}
+  int y;
+};
+
+class third : protected second
+{
+public:
+  int a_field;
+  virtual void a(){}
+protected:
+private:
+};
+#pragma pack(pop)
+
+int main() {
+  third k;
+  k.a();
+  return 0;
+}
+//CHECK: %class.third = type { %class.second, i32 }
+//CHECK: %class.second = type { %class.first, i32 }
+//CHECK: %class.first = type { i32 (...)**, double }
+
+//CHECK: @"\01??_7third@@6B@" = linkonce_odr unnamed_addr constant [4 x i8*] [i8* bitcast ({ i32, i32, i32, i8*, i8* }* @"\01??_R4third@@6B@" to i8*), i8* bitcast (void (%class.first*)* @"\01?b@first@@UAEXXZ" to i8*), i8* bitcast (void (%class.second*)* @"\01?C_f@second@@UAEXXZ" to i8*), i8* bitcast (void (%class.third*)* @"\01?a@third@@UAEXXZ" to i8*)]
+//CHECK: @"\01??_7type_info@@6B@" = external global i8*
+//CHECK: @"\01??_R0?AVthird@@@8" = linkonce_odr constant { i8**, i32, [12 x i8] } { i8** @"\01??_7type_info@@6B@", i32 0, [12 x i8] c".?AVthird@@\00" }
+//CHECK: @"\01??_R1A@?0A@EA@third@@8" = linkonce_odr constant { i8*, i32, i32, i32, i32, i32 } { i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVthird@@@8" to i8*), i32 2, i32 0, i32 -1, i32 0, i32 64 }
+//CHECK: @"\01??_R0?AVsecond@@@8" = linkonce_odr constant { i8**, i32, [13 x i8] } { i8** @"\01??_7type_info@@6B@", i32 0, [13 x i8] c".?AVsecond@@\00" }
+//CHECK: @"\01??_R1A@?0A@EN@second@@8" = linkonce_odr constant { i8*, i32, i32, i32, i32, i32 } { i8* bitcast ({ i8**, i32, [13 x i8] }* @"\01??_R0?AVsecond@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 77 }
+//CHECK: @"\01??_R0?AVfirst@@@8" = linkonce_odr constant { i8**, i32, [12 x i8] } { i8** @"\01??_7type_info@@6B@", i32 0, [12 x i8] c".?AVfirst@@\00" }
+//CHECK: @"\01??_R1A@?0A@EN@first@@8" = linkonce_odr constant { i8*, i32, i32, i32, i32, i32 } { i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVfirst@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 77 }
+//CHECK: @"\01??_R2third@@8" = linkonce_odr constant [3 x { i8*, i32, i32, i32, i32, i32 }*] [{ i8*, i32, i32, i32, i32, i32 }* @"\01??_R1A@?0A@EA@third@@8", { i8*, i32, i32, i32, i32, i32 }* @"\01??_R1A@?0A@EN@second@@8", { i8*, i32, i32, i32, i32, i32 }* @"\01??_R1A@?0A@EN@first@@8"]
+//CHECK: @"\01??_R3third@@8" = linkonce_odr constant { i32, i32, i32, i8* } { i32 0, i32 0, i32 3, i8* bitcast ([3 x { i8*, i32, i32, i32, i32, i32 }*]* @"\01??_R2third@@8" to i8*) }
+//CHECK: @"\01??_R4third@@6B@" = linkonce_odr unnamed_addr constant { i32, i32, i32, i8*, i8* } { i32 0, i32 0, i32 0, i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVthird@@@8" to i8*), i8* bitcast ({ i32, i32, i32, i8* }* @"\01??_R3third@@8" to i8*) }
+//CHECK: @"\01??_7second@@6B@" = linkonce_odr unnamed_addr constant [3 x i8*] [i8* bitcast ({ i32, i32, i32, i8*, i8* }* @"\01??_R4second@@6B@" to i8*), i8* bitcast (void (%class.first*)* @"\01?b@first@@UAEXXZ" to i8*), i8* bitcast (void (%class.second*)* @"\01?C_f@second@@UAEXXZ" to i8*)]
+//CHECK: @"\01??_R1A@?0A@EA@second@@8" = linkonce_odr constant { i8*, i32, i32, i32, i32, i32 } { i8* bitcast ({ i8**, i32, [13 x i8] }* @"\01??_R0?AVsecond@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64 }
+//CHECK: @"\01??_R2second@@8" = linkonce_odr constant [2 x { i8*, i32, i32, i32, i32, i32 }*] [{ i8*, i32, i32, i32, i32, i32 }* @"\01??_R1A@?0A@EA@second@@8", { i8*, i32, i32, i32, i32, i32 }* @"\01??_R1A@?0A@EN@first@@8"]
+//CHECK: @"\01??_R3second@@8" = linkonce_odr constant { i32, i32, i32, i8* } { i32 0, i32 0, i32 2, i8* bitcast ([2 x { i8*, i32, i32, i32, i32, i32 }*]* @"\01??_R2second@@8" to i8*) }
+//CHECK: @"\01??_R4second@@6B@" = linkonce_odr unnamed_addr constant { i32, i32, i32, i8*, i8* } { i32 0, i32 0, i32 0, i8* bitcast ({ i8**, i32, [13 x i8] }* @"\01??_R0?AVsecond@@@8" to i8*), i8* bitcast ({ i32, i32, i32, i8* }* @"\01??_R3second@@8" to i8*) }
+//CHECK: @"\01??_7first@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*] [i8* bitcast ({ i32, i32, i32, i8*, i8* }* @"\01??_R4first@@6B@" to i8*), i8* bitcast (void (%class.first*)* @"\01?b@first@@UAEXXZ" to i8*)]
+//CHECK: @"\01??_R1A@?0A@EA@first@@8" = linkonce_odr constant { i8*, i32, i32, i32, i32, i32 } { i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVfirst@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64 }
+//CHECK: @"\01??_R2first@@8" = linkonce_odr constant [1 x { i8*, i32, i32, i32, i32, i32 }*] [{ i8*, i32, i32, i32, i32, i32 }* @"\01??_R1A@?0A@EA@first@@8"]
+//CHECK: @"\01??_R3first@@8" = linkonce_odr constant { i32, i32, i32, i8* } { i32 0, i32 0, i32 1, i8* bitcast ([1 x { i8*, i32, i32, i32, i32, i32 }*]* @"\01??_R2first@@8" to i8*) }
+//CHECK: @"\01??_R4first@@6B@" = linkonce_odr unnamed_addr constant { i32, i32, i32, i8*, i8* } { i32 0, i32 0, i32 0, i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVfirst@@@8" to i8*), i8* bitcast ({ i32, i32, i32, i8* }* @"\01??_R3first@@8" to i8*) }
\ No newline at end of file
Index: test/CodeGenCXX/ms-rtti2.cpp
===================================================================
--- test/CodeGenCXX/ms-rtti2.cpp	(revision 0)
+++ test/CodeGenCXX/ms-rtti2.cpp	(working copy)
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1  -emit-llvm %s -o - -cxx-abi microsoft -triple=i686-pc-win32 | FileCheck %s
+// r4start
+#pragma pack(push, 8)
+class first {
+public:
+  virtual void b() {}
+protected:
+private:
+};
+
+class third: virtual first {
+public:
+  virtual void a(){}
+};
+#pragma pack(pop)
+
+int main() {
+  third k;
+  k.a();
+  return 0;
+}
+
+//CHECK: %class.third = type { i32 (...)**, i32*, %class.first }
+//CHECK: %class.first = type { i32 (...)** }
+
+//CHECK: @"\01??_8third@@7B@" = unnamed_addr constant [2 x i32] [i32 -4, i32 4]
+//CHECK: @"\01??_7third@@6B0@@" = linkonce_odr unnamed_addr constant [2 x i8*] [i8* bitcast ({ i32, i32, i32, i8*, i8* }* @"\01??_R4third@@6B0@@" to i8*), i8* bitcast (void (%class.third*)* @"\01?a@third@@UAEXXZ" to i8*)]
+//CHECK: @"\01??_7third@@6Bfirst@@@" = linkonce_odr unnamed_addr constant [2 x i8*] [i8* bitcast ({ i32, i32, i32, i8*, i8* }* @"\01??_R4third@@6Bfirst@@@" to i8*), i8* bitcast (void (%class.first*)* @"\01?b@first@@UAEXXZ" to i8*)]
+//CHECK: @"\01??_7type_info@@6B@" = external global i8*
+//CHECK: @"\01??_R0?AVthird@@@8" = linkonce_odr constant { i8**, i32, [12 x i8] } { i8** @"\01??_7type_info@@6B@", i32 0, [12 x i8] c".?AVthird@@\00" }
+//CHECK: @"\01??_R1A@?0A@EA@third@@8" = linkonce_odr constant { i8*, i32, i32, i32, i32, i32 } { i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVthird@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64 }
+//CHECK: @"\01??_R0?AVfirst@@@8" = linkonce_odr constant { i8**, i32, [12 x i8] } { i8** @"\01??_7type_info@@6B@", i32 0, [12 x i8] c".?AVfirst@@\00" }
+//CHECK: @"\01??_R1A@33FN@first@@8" = linkonce_odr constant { i8*, i32, i32, i32, i32, i32 } { i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVfirst@@@8" to i8*), i32 0, i32 0, i32 4, i32 4, i32 93 }
+//CHECK: @"\01??_R2third@@8" = linkonce_odr constant [2 x { i8*, i32, i32, i32, i32, i32 }*] [{ i8*, i32, i32, i32, i32, i32 }* @"\01??_R1A@?0A@EA@third@@8", { i8*, i32, i32, i32, i32, i32 }* @"\01??_R1A@33FN@first@@8"]
+//CHECK: @"\01??_R3third@@8" = linkonce_odr constant { i32, i32, i32, i8* } { i32 0, i32 0, i32 2, i8* bitcast ([2 x { i8*, i32, i32, i32, i32, i32 }*]* @"\01??_R2third@@8" to i8*) }
+//CHECK: @"\01??_R4third@@6B0@@" = linkonce_odr unnamed_addr constant { i32, i32, i32, i8*, i8* } { i32 0, i32 0, i32 0, i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVthird@@@8" to i8*), i8* bitcast ({ i32, i32, i32, i8* }* @"\01??_R3third@@8" to i8*) }
+//CHECK: @"\01??_R4third@@6Bfirst@@@" = linkonce_odr unnamed_addr constant { i32, i32, i32, i8*, i8* } { i32 0, i32 8, i32 0, i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVthird@@@8" to i8*), i8* bitcast ({ i32, i32, i32, i8* }* @"\01??_R3third@@8" to i8*) }
+//CHECK: @"\01??_7first@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*] [i8* bitcast ({ i32, i32, i32, i8*, i8* }* @"\01??_R4first@@6B@" to i8*), i8* bitcast (void (%class.first*)* @"\01?b@first@@UAEXXZ" to i8*)]
+//CHECK: @"\01??_R1A@?0A@EA@first@@8" = linkonce_odr constant { i8*, i32, i32, i32, i32, i32 } { i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVfirst@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64 }
+//CHECK: @"\01??_R2first@@8" = linkonce_odr constant [1 x { i8*, i32, i32, i32, i32, i32 }*] [{ i8*, i32, i32, i32, i32, i32 }* @"\01??_R1A@?0A@EA@first@@8"]
+//CHECK: @"\01??_R3first@@8" = linkonce_odr constant { i32, i32, i32, i8* } { i32 0, i32 0, i32 1, i8* bitcast ([1 x { i8*, i32, i32, i32, i32, i32 }*]* @"\01??_R2first@@8" to i8*) }
+//CHECK: @"\01??_R4first@@6B@" = linkonce_odr unnamed_addr constant { i32, i32, i32, i8*, i8* } { i32 0, i32 0, i32 0, i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVfirst@@@8" to i8*), i8* bitcast ({ i32, i32, i32, i8* }* @"\01??_R3first@@8" to i8*) }
\ No newline at end of file
Index: test/CodeGenCXX/ms-rtti3.cpp
===================================================================
--- test/CodeGenCXX/ms-rtti3.cpp	(revision 0)
+++ test/CodeGenCXX/ms-rtti3.cpp	(working copy)
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1  -emit-llvm %s -o - -cxx-abi microsoft -triple=i686-pc-win32 | FileCheck %s
+// r4start
+#pragma pack(push, 8)
+class first {
+public:
+  virtual void b(){}
+  int b_field;
+protected:
+private:
+};
+
+class second : first {
+public:
+  virtual void C_f(){}
+  int y;
+};
+
+class fourth
+{
+public:
+  int q;
+protected:
+private:
+};
+
+class third : public  fourth,  first {
+public:
+  int a_field;
+  virtual void a(){}
+protected:
+private:
+};
+#pragma pack(pop)
+
+int main() {
+  third k;
+  k.a();
+  return 0;
+}
+
+//CHECK: %class.third = type { %class.first, %class.fourth, i32 }
+//CHECK: %class.first = type { i32 (...)**, i32 }
+//CHECK: %class.fourth = type { i32 }
+
+//CHECK: @"\01??_7third@@6B@" = linkonce_odr unnamed_addr constant [3 x i8*] [i8* bitcast ({ i32, i32, i32, i8*, i8* }* @"\01??_R4third@@6B@" to i8*), i8* bitcast (void (%class.first*)* @"\01?b@first@@UAEXXZ" to i8*), i8* bitcast (void (%class.third*)* @"\01?a@third@@UAEXXZ" to i8*)]
+//CHECK: @"\01??_7type_info@@6B@" = external global i8*
+//CHECK: @"\01??_R0?AVthird@@@8" = linkonce_odr constant { i8**, i32, [12 x i8] } { i8** @"\01??_7type_info@@6B@", i32 0, [12 x i8] c".?AVthird@@\00" }
+//CHECK: @"\01??_R1A@?0A@EA@third@@8" = linkonce_odr constant { i8*, i32, i32, i32, i32, i32 } { i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVthird@@@8" to i8*), i32 2, i32 0, i32 -1, i32 0, i32 64 }
+//CHECK: @"\01??_R0?AVfourth@@@8" = linkonce_odr constant { i8**, i32, [13 x i8] } { i8** @"\01??_7type_info@@6B@", i32 0, [13 x i8] c".?AVfourth@@\00" }
+//CHECK: @"\01??_R17?0A@EA@fourth@@8" = linkonce_odr constant { i8*, i32, i32, i32, i32, i32 } { i8* bitcast ({ i8**, i32, [13 x i8] }* @"\01??_R0?AVfourth@@@8" to i8*), i32 0, i32 8, i32 -1, i32 0, i32 64 }
+//CHECK: @"\01??_R0?AVfirst@@@8" = linkonce_odr constant { i8**, i32, [12 x i8] } { i8** @"\01??_7type_info@@6B@", i32 0, [12 x i8] c".?AVfirst@@\00" }
+//CHECK: @"\01??_R1A@?0A@EN@first@@8" = linkonce_odr constant { i8*, i32, i32, i32, i32, i32 } { i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVfirst@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 77 }
+//CHECK: @"\01??_R2third@@8" = linkonce_odr constant [3 x { i8*, i32, i32, i32, i32, i32 }*] [{ i8*, i32, i32, i32, i32, i32 }* @"\01??_R1A@?0A@EA@third@@8", { i8*, i32, i32, i32, i32, i32 }* @"\01??_R17?0A@EA@fourth@@8", { i8*, i32, i32, i32, i32, i32 }* @"\01??_R1A@?0A@EN@first@@8"]
+//CHECK: @"\01??_R3third@@8" = linkonce_odr constant { i32, i32, i32, i8* } { i32 0, i32 1, i32 3, i8* bitcast ([3 x { i8*, i32, i32, i32, i32, i32 }*]* @"\01??_R2third@@8" to i8*) }
+//CHECK: @"\01??_R4third@@6B@" = linkonce_odr unnamed_addr constant { i32, i32, i32, i8*, i8* } { i32 0, i32 0, i32 0, i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVthird@@@8" to i8*), i8* bitcast ({ i32, i32, i32, i8* }* @"\01??_R3third@@8" to i8*) }
+//CHECK: @"\01??_7first@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*] [i8* bitcast ({ i32, i32, i32, i8*, i8* }* @"\01??_R4first@@6B@" to i8*), i8* bitcast (void (%class.first*)* @"\01?b@first@@UAEXXZ" to i8*)]
+//CHECK: @"\01??_R1A@?0A@EA@first@@8" = linkonce_odr constant { i8*, i32, i32, i32, i32, i32 } { i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVfirst@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64 }
+//CHECK: @"\01??_R2first@@8" = linkonce_odr constant [1 x { i8*, i32, i32, i32, i32, i32 }*] [{ i8*, i32, i32, i32, i32, i32 }* @"\01??_R1A@?0A@EA@first@@8"]
+//CHECK: @"\01??_R3first@@8" = linkonce_odr constant { i32, i32, i32, i8* } { i32 0, i32 0, i32 1, i8* bitcast ([1 x { i8*, i32, i32, i32, i32, i32 }*]* @"\01??_R2first@@8" to i8*) }
+//CHECK: @"\01??_R4first@@6B@" = linkonce_odr unnamed_addr constant { i32, i32, i32, i8*, i8* } { i32 0, i32 0, i32 0, i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVfirst@@@8" to i8*), i8* bitcast ({ i32, i32, i32, i8* }* @"\01??_R3first@@8" to i8*) }
Index: test/CodeGenCXX/ms-rtti4.cpp
===================================================================
--- test/CodeGenCXX/ms-rtti4.cpp	(revision 0)
+++ test/CodeGenCXX/ms-rtti4.cpp	(working copy)
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1  -emit-llvm %s -o - -cxx-abi microsoft -triple=i686-pc-win32 | FileCheck %s
+// r4start
+#pragma pack(push, 8)
+class first {
+public:
+  virtual void b(){}
+  int b_field;
+protected:
+private:
+};
+
+class second : first {
+public:
+  virtual void C_f(){}
+  int y;
+};
+
+class fourth
+{
+public:
+  int q;
+protected:
+private:
+};
+
+class third : public  fourth,  virtual second {
+public:
+  int a_field;
+  virtual void a(){}
+protected:
+private:
+};
+#pragma pack(pop)
+
+int main() {
+  third k;
+  k.a();
+  return 0;
+}
+
+//CHECK: %class.third = type { i32 (...)**, %class.fourth, i32*, i32, %class.second }
+//CHECK: %class.fourth = type { i32 }
+//CHECK: %class.second = type { %class.first, i32 }
+//CHECK: %class.first = type { i32 (...)**, i32 }
+
+//CHECK: @"\01??_8third@@7B@" = unnamed_addr constant [2 x i32] [i32 -8, i32 8]
+//CHECK: @"\01??_7third@@6B0@@" = linkonce_odr unnamed_addr constant [2 x i8*] [i8* bitcast ({ i32, i32, i32, i8*, i8* }* @"\01??_R4third@@6B0@@" to i8*), i8* bitcast (void (%class.third*)* @"\01?a@third@@UAEXXZ" to i8*)]
+//CHECK: @"\01??_7third@@6Bsecond@@@" = linkonce_odr unnamed_addr constant [3 x i8*] [i8* bitcast ({ i32, i32, i32, i8*, i8* }* @"\01??_R4third@@6Bsecond@@@" to i8*), i8* bitcast (void (%class.first*)* @"\01?b@first@@UAEXXZ" to i8*), i8* bitcast (void (%class.second*)* @"\01?C_f@second@@UAEXXZ" to i8*)]
+//CHECK: @"\01??_7type_info@@6B@" = external global i8*
+//CHECK: @"\01??_R0?AVthird@@@8" = linkonce_odr constant { i8**, i32, [12 x i8] } { i8** @"\01??_7type_info@@6B@", i32 0, [12 x i8] c".?AVthird@@\00" }
+//CHECK: @"\01??_R1A@?0A@EA@third@@8" = linkonce_odr constant { i8*, i32, i32, i32, i32, i32 } { i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVthird@@@8" to i8*), i32 3, i32 0, i32 -1, i32 0, i32 64 }
+//CHECK: @"\01??_R0?AVfourth@@@8" = linkonce_odr constant { i8**, i32, [13 x i8] } { i8** @"\01??_7type_info@@6B@", i32 0, [13 x i8] c".?AVfourth@@\00" }
+//CHECK: @"\01??_R13?0A@EA@fourth@@8" = linkonce_odr constant { i8*, i32, i32, i32, i32, i32 } { i8* bitcast ({ i8**, i32, [13 x i8] }* @"\01??_R0?AVfourth@@@8" to i8*), i32 0, i32 4, i32 -1, i32 0, i32 64 }
+//CHECK: @"\01??_R0?AVsecond@@@8" = linkonce_odr constant { i8**, i32, [13 x i8] } { i8** @"\01??_7type_info@@6B@", i32 0, [13 x i8] c".?AVsecond@@\00" }
+//CHECK: @"\01??_R1A@73FN@second@@8" = linkonce_odr constant { i8*, i32, i32, i32, i32, i32 } { i8* bitcast ({ i8**, i32, [13 x i8] }* @"\01??_R0?AVsecond@@@8" to i8*), i32 1, i32 0, i32 8, i32 4, i32 93 }
+//CHECK: @"\01??_R0?AVfirst@@@8" = linkonce_odr constant { i8**, i32, [12 x i8] } { i8** @"\01??_7type_info@@6B@", i32 0, [12 x i8] c".?AVfirst@@\00" }
+//CHECK: @"\01??_R1A@73EN@first@@8" = linkonce_odr constant { i8*, i32, i32, i32, i32, i32 } { i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVfirst@@@8" to i8*), i32 0, i32 0, i32 8, i32 4, i32 77 }
+//CHECK: @"\01??_R2third@@8" = linkonce_odr constant [4 x { i8*, i32, i32, i32, i32, i32 }*] [{ i8*, i32, i32, i32, i32, i32 }* @"\01??_R1A@?0A@EA@third@@8", { i8*, i32, i32, i32, i32, i32 }* @"\01??_R13?0A@EA@fourth@@8", { i8*, i32, i32, i32, i32, i32 }* @"\01??_R1A@73FN@second@@8", { i8*, i32, i32, i32, i32, i32 }* @"\01??_R1A@73EN@first@@8"]
+//CHECK: @"\01??_R3third@@8" = linkonce_odr constant { i32, i32, i32, i8* } { i32 0, i32 7, i32 4, i8* bitcast ([4 x { i8*, i32, i32, i32, i32, i32 }*]* @"\01??_R2third@@8" to i8*) }
+//CHECK: @"\01??_R4third@@6B0@@" = linkonce_odr unnamed_addr constant { i32, i32, i32, i8*, i8* } { i32 0, i32 0, i32 0, i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVthird@@@8" to i8*), i8* bitcast ({ i32, i32, i32, i8* }* @"\01??_R3third@@8" to i8*) }
+//CHECK: @"\01??_R4third@@6Bsecond@@@" = linkonce_odr unnamed_addr constant { i32, i32, i32, i8*, i8* } { i32 0, i32 16, i32 0, i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVthird@@@8" to i8*), i8* bitcast ({ i32, i32, i32, i8* }* @"\01??_R3third@@8" to i8*) }
+//CHECK: @"\01??_7second@@6B@" = linkonce_odr unnamed_addr constant [3 x i8*] [i8* bitcast ({ i32, i32, i32, i8*, i8* }* @"\01??_R4second@@6B@" to i8*), i8* bitcast (void (%class.first*)* @"\01?b@first@@UAEXXZ" to i8*), i8* bitcast (void (%class.second*)* @"\01?C_f@second@@UAEXXZ" to i8*)]
+//CHECK: @"\01??_R1A@?0A@EA@second@@8" = linkonce_odr constant { i8*, i32, i32, i32, i32, i32 } { i8* bitcast ({ i8**, i32, [13 x i8] }* @"\01??_R0?AVsecond@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64 }
+//CHECK: @"\01??_R1A@?0A@EN@first@@8" = linkonce_odr constant { i8*, i32, i32, i32, i32, i32 } { i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVfirst@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 77 }
+//CHECK: @"\01??_R2second@@8" = linkonce_odr constant [2 x { i8*, i32, i32, i32, i32, i32 }*] [{ i8*, i32, i32, i32, i32, i32 }* @"\01??_R1A@?0A@EA@second@@8", { i8*, i32, i32, i32, i32, i32 }* @"\01??_R1A@?0A@EN@first@@8"]
+//CHECK: @"\01??_R3second@@8" = linkonce_odr constant { i32, i32, i32, i8* } { i32 0, i32 0, i32 2, i8* bitcast ([2 x { i8*, i32, i32, i32, i32, i32 }*]* @"\01??_R2second@@8" to i8*) }
+//CHECK: @"\01??_R4second@@6B@" = linkonce_odr unnamed_addr constant { i32, i32, i32, i8*, i8* } { i32 0, i32 0, i32 0, i8* bitcast ({ i8**, i32, [13 x i8] }* @"\01??_R0?AVsecond@@@8" to i8*), i8* bitcast ({ i32, i32, i32, i8* }* @"\01??_R3second@@8" to i8*) }
+//CHECK: @"\01??_7first@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*] [i8* bitcast ({ i32, i32, i32, i8*, i8* }* @"\01??_R4first@@6B@" to i8*), i8* bitcast (void (%class.first*)* @"\01?b@first@@UAEXXZ" to i8*)]
+//CHECK: @"\01??_R1A@?0A@EA@first@@8" = linkonce_odr constant { i8*, i32, i32, i32, i32, i32 } { i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVfirst@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64 }
+//CHECK: @"\01??_R2first@@8" = linkonce_odr constant [1 x { i8*, i32, i32, i32, i32, i32 }*] [{ i8*, i32, i32, i32, i32, i32 }* @"\01??_R1A@?0A@EA@first@@8"]
+//CHECK: @"\01??_R3first@@8" = linkonce_odr constant { i32, i32, i32, i8* } { i32 0, i32 0, i32 1, i8* bitcast ([1 x { i8*, i32, i32, i32, i32, i32 }*]* @"\01??_R2first@@8" to i8*) }
+//CHECK: @"\01??_R4first@@6B@" = linkonce_odr unnamed_addr constant { i32, i32, i32, i8*, i8* } { i32 0, i32 0, i32 0, i8* bitcast ({ i8**, i32, [12 x i8] }* @"\01??_R0?AVfirst@@@8" to i8*), i8* bitcast ({ i32, i32, i32, i8* }* @"\01??_R3first@@8" to i8*) }
Index: test/Sema/ms_class_layout.cpp
===================================================================
--- test/Sema/ms_class_layout.cpp	(revision 154277)
+++ test/Sema/ms_class_layout.cpp	(working copy)
@@ -97,6 +97,49 @@
 
 struct R {};
 
+class IA {
+public:
+  virtual ~IA(){}
+  virtual void ia() = 0;
+};
+
+class ICh : public virtual IA {
+public:
+  virtual ~ICh(){}
+  virtual void ia(){}
+  virtual void iCh(){}
+};
+
+struct f {
+  virtual int asd() {return -90;}
+};
+
+struct s : public virtual f {
+  virtual ~s(){}
+  int r;
+  virtual int asd() {return -9;}
+};
+
+struct sd : virtual s, virtual ICh {
+  virtual ~sd(){}
+  int q;
+  char y;
+  virtual int asd() {return -1;}
+};
+struct AV { 
+  virtual void foo(); 
+};
+struct BV : AV { 
+};
+struct CV : virtual BV { 
+  CV(); 
+  virtual void foo(); 
+};
+struct DV : BV {
+};
+struct EV : CV, DV {
+};
+
 #pragma pack(pop)
 
 // This needs only for building layouts. 
@@ -113,6 +156,8 @@
   O* o;
   P* p;
   R* r;
+  sd *h;
+  EV *j;
   return 0;
 }
 
@@ -333,3 +378,111 @@
 // CHECK-NEXT:  nvsize=0, nvalign=1
 
 //CHECK: %struct.R = type { i8 }
+
+// CHECK:       0 | struct f
+// CHECK-NEXT:  0 |   (f vftable pointer)
+// CHECK-NEXT: sizeof=4, dsize=4, align=4
+// CHECK-NEXT: nvsize=4, nvalign=4
+
+// CHECK:       0 | struct s
+// CHECK-NEXT:  0 |   (s vftable pointer)
+// CHECK-NEXT:  4 |   (s vbtable pointer)
+// CHECK-NEXT:  8 |   int r
+// CHECK-NEXT: 12 |   (vtordisp for vbase f)
+// CHECK-NEXT: 16 |   struct f (virtual base)
+// CHECK-NEXT: 16 |     (f vftable pointer)
+// CHECK-NEXT: sizeof=20, dsize=20, align=4
+// CHECK-NEXT: nvsize=12, nvalign=4
+
+// CHECK:       0 | class IA
+// CHECK-NEXT:  0 |   (IA vftable pointer)
+// CHECK-NEXT:  sizeof=4, dsize=4, align=4
+// CHECK-NEXT:  nvsize=4, nvalign=4
+	
+// CHECK:       0 | class ICh
+// CHECK-NEXT:  0 |   (ICh vftable pointer)
+// CHECK-NEXT:  4 |   (ICh vbtable pointer)
+// CHECK-NEXT:  8 |   (vtordisp for vbase IA)
+// CHECK-NEXT: 12 |   class IA (virtual base)
+// CHECK-NEXT: 12 |     (IA vftable pointer)
+// CHECK-NEXT: sizeof=16, dsize=16, align=4
+// CHECK-NEXT: nvsize=8, nvalign=4
+
+// CHECK:       0 | struct sd
+// CHECK-NEXT:  0 |   (sd vbtable pointer)
+// CHECK-NEXT:  4 |   int q
+// CHECK-NEXT:  8 |   char y
+// CHECK-NEXT: 12 |   (vtordisp for vbase f)
+// CHECK-NEXT: 16 |   struct f (virtual base)
+// CHECK-NEXT: 16 |     (f vftable pointer)
+// CHECK-NEXT: 20 |   struct s (virtual base)
+// CHECK-NEXT: 20 |     (s vftable pointer)
+// CHECK-NEXT: 24 |     (s vbtable pointer)
+// CHECK-NEXT: 28 |     int r
+// CHECK-NEXT: 32 |   (vtordisp for vbase IA)
+// CHECK-NEXT: 36 |   class IA (virtual base)
+// CHECK-NEXT: 36 |     (IA vftable pointer)
+// CHECK-NEXT: 40 |   class ICh (virtual base)
+// CHECK-NEXT: 40 |     (ICh vftable pointer)
+// CHECK-NEXT: 44 |     (ICh vbtable pointer)
+// CHECK-NEXT: sizeof=48, dsize=48, align=4
+// CHECK-NEXT: nvsize=12, nvalign=4
+
+// CHECK: %struct.f = type { i32 (...)** }
+// CHECK: %struct.s = type { i32 (...)**, i32*, i32, [4 x i8], %struct.f }
+// CHECK: %class.IA = type { i32 (...)** }
+// CHECK: %class.ICh = type { i32 (...)**, i32*, [4 x i8], %class.IA }
+// CHECK: %struct.sd = type { i32*, i32, i8, [7 x i8], %struct.f, %struct.s.base, [4 x i8], %class.IA, %class.ICh.base }
+
+// CHECK:       0 | struct AV
+// CHECK-NEXT:  0 |   (AV vftable pointer)
+// CHECK-NEXT: sizeof=4, dsize=4, align=4
+// CHECK-NEXT: nvsize=4, nvalign=4
+
+
+// CHECK:       0 | struct BV
+// CHECK-NEXT:  0 |   struct AV (primary base)
+// CHECK-NEXT:  0 |     (AV vftable pointer)
+// CHECK-NEXT: sizeof=4, dsize=4, align=4
+// CHECK-NEXT: nvsize=4, nvalign=4
+
+
+// CHECK:       0 | struct CV
+// CHECK-NEXT:  0 |   (CV vbtable pointer)
+// CHECK-NEXT:  4 |   (vtordisp for vbase BV)
+// CHECK-NEXT:  8 |   struct BV (virtual base)
+// CHECK-NEXT:  8 |     struct AV (primary base)
+// CHECK-NEXT:  8 |       (AV vftable pointer)
+// CHECK-NEXT: sizeof=12, dsize=12, align=4
+// CHECK-NEXT: nvsize=4, nvalign=4
+
+// CHECK: %struct.AV = type { i32 (...)** }
+// CHECK: %struct.BV = type { %struct.AV }
+// CHECK: %struct.CV = type { i32*, [4 x i8], %struct.BV }
+// CHECK: %struct.CV.base = type { i32* }
+
+// CHECK:       0 | struct DV
+// CHECK-NEXT:  0 |   struct BV (primary base)
+// CHECK-NEXT:  0 |     struct AV (primary base)
+// CHECK-NEXT:  0 |       (AV vftable pointer)
+// CHECK-NEXT: sizeof=4, dsize=4, align=4
+// CHECK-NEXT: nvsize=4, nvalign=4
+
+// CHECK: %struct.DV = type { %struct.BV }
+
+// CHECK:       0 | struct EV
+// CHECK-NEXT:  4 |   struct CV (base)
+// CHECK-NEXT:  4 |     (CV vbtable pointer)
+// CHECK-NEXT:  0 |   struct DV (primary base)
+// CHECK-NEXT:  0 |     struct BV (primary base)
+// CHECK-NEXT:  0 |       struct AV (primary base)
+// CHECK-NEXT:  0 |         (AV vftable pointer)
+// CHECK-NEXT:  8 |   (vtordisp for vbase BV)
+// CHECK-NEXT: 12 |   struct BV (virtual base)
+// CHECK-NEXT: 12 |     struct AV (primary base)
+// CHECK-NEXT: 12 |       (AV vftable pointer)
+// CHECK-NEXT: sizeof=16, dsize=16, align=4
+// CHECK-NEXT: nvsize=8, nvalign=4
+
+// CHECK: %struct.EV = type { %struct.DV, %struct.CV.base, [4 x i8], %struct.BV }
+// CHECK: %struct.EV.base = type { %struct.DV, %struct.CV.base }
