Index: include/clang/AST/RecordLayout.h
===================================================================
--- include/clang/AST/RecordLayout.h	(revision 149862)
+++ include/clang/AST/RecordLayout.h	(working copy)
@@ -33,6 +33,10 @@
 /// ObjCInterfaceDecl. FIXME - Find appropriate name.
 /// These objects are managed by ASTContext.
 class ASTRecordLayout {
+public:
+  typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> 
+                                                VtorDispOffsetsMapTy;
+private:
   /// Size - Size of record in characters.
   CharUnits Size;
 
@@ -69,6 +73,10 @@
     /// VBPtrOffset - Virtual base table offset (Microsoft-only).
     CharUnits VBPtrOffset;
     
+    /// VtorDispOffsets - Offsets for adjusting 'this' pointer 
+    /// in thunks (Microsoft-only).
+    VtorDispOffsetsMapTy VtorDispOffsets;
+    
     /// PrimaryBase - The primary base info for this record.
     llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> PrimaryBase;
     
@@ -104,7 +112,8 @@
                   const CXXRecordDecl *PrimaryBase,
                   bool IsPrimaryBaseVirtual,
                   const BaseOffsetsMapTy& BaseOffsets,
-                  const BaseOffsetsMapTy& VBaseOffsets);
+                  const BaseOffsetsMapTy& VBaseOffsets,
+                  const VtorDispOffsetsMapTy& VtorDispOffsets);
 
   ~ASTRecordLayout() {}
 
@@ -221,6 +230,14 @@
     assert(CXXInfo && "Record layout does not have C++ specific info!");
     return CXXInfo->VBPtrOffset;
   }
+
+  /// getVBPtrOffset - Get the offsets of vtordisps fields in layout.
+  /// This is only meaningful with the Microsoft ABI.
+  const VtorDispOffsetsMapTy &getVtorDispOffsets() const {
+    assert(CXXInfo && "Record layout does not have C++ specific info!");
+    return CXXInfo->VtorDispOffsets;
+  }
+
 };
 
 }  // end namespace clang
Index: lib/AST/RecordLayout.cpp
===================================================================
--- lib/AST/RecordLayout.cpp	(revision 149862)
+++ lib/AST/RecordLayout.cpp	(working copy)
@@ -53,7 +53,8 @@
                                  const CXXRecordDecl *PrimaryBase,
                                  bool IsPrimaryBaseVirtual,
                                  const BaseOffsetsMapTy& BaseOffsets,
-                                 const BaseOffsetsMapTy& VBaseOffsets)
+                                 const BaseOffsetsMapTy& VBaseOffsets,
+                                 const VtorDispOffsetsMapTy& VtorDispOffsets)
   : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
     FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
 {
@@ -71,6 +72,7 @@
   CXXInfo->VBaseOffsets = VBaseOffsets;
   CXXInfo->VFPtrOffset = vfptroffset;
   CXXInfo->VBPtrOffset = vbptroffset;
+  CXXInfo->VtorDispOffsets = VtorDispOffsets;
 
 #ifndef NDEBUG
     if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
Index: lib/AST/RecordLayoutBuilder.cpp
===================================================================
--- lib/AST/RecordLayoutBuilder.cpp	(revision 149862)
+++ lib/AST/RecordLayoutBuilder.cpp	(working copy)
@@ -606,6 +606,10 @@
   /// VBPtrOffset - Virtual base table offset. Only for MS layout.
   CharUnits VBPtrOffset;
 
+  /// r4start
+  /// VtorDispOffsets - Offsets of hidden fields.
+  ASTRecordLayout::VtorDispOffsetsMapTy VtorDispOffsets;
+
   typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
 
   /// Bases - base classes and their offsets in the record.
@@ -725,9 +729,18 @@
                                     CharUnits Offset);
 
   bool needsVFTable(const CXXRecordDecl *RD) const;
-  bool hasNewVirtualFunction(const CXXRecordDecl *RD) const;
+  bool hasNewVirtualFunction(const CXXRecordDecl *RD,
+                             bool OnlyMethods = false) const;
   bool isPossiblePrimaryBase(const CXXRecordDecl *Base) const;
 
+  bool needsVtorDispDirectBase(const CXXRecordDecl *RD,
+                               const CXXRecordDecl *Base) const;
+  bool needsVtorDispIndirectBase(const CXXRecordDecl *RD,
+                                 const CXXRecordDecl *Base,
+                                 const CXXBasePath &Path) const;
+  bool needsVtorDisp(const CXXRecordDecl *RD,
+                     const CXXRecordDecl *Base) const;
+
   /// LayoutVirtualBases - Lays out all the virtual bases.
   void LayoutVirtualBases(const CXXRecordDecl *RD,
                           const CXXRecordDecl *MostDerivedClass);
@@ -1044,8 +1057,10 @@
     CharUnits PtrAlign = 
       Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerAlign(0));
     EnsureVTablePointerAlignment(PtrAlign);
+
     if (isMicrosoftCXXABI())
       VFPtrOffset = getSize();
+    
     setSize(getSize() + PtrWidth);
     setDataSize(getSize());
   }
@@ -1193,19 +1208,84 @@
   return hasNewVirtualFunction(RD);
 }
 
+bool RecordLayoutBuilder::needsVtorDispDirectBase(const CXXRecordDecl *RD, 
+                                             const CXXRecordDecl *Base) const {
+  if (!RD->hasUserDeclaredConstructor() && 
+      !RD->hasUserProvidedDefaultConstructor() &&
+      !RD->hasUserDeclaredDestructor())
+    return false;
+
+  if (!hasNewVirtualFunction(Base, true))
+      return false;
+  
+  for (CXXRecordDecl::method_iterator M = RD->method_begin(),
+        E = RD->method_end(); M != E; ++M) {
+    if (M->isVirtual() && (M->size_overridden_methods() == 1) &&
+        M->getKind() != Decl::CXXDestructor) {
+      const CXXMethodDecl *MD = *M->begin_overridden_methods();
+      if (MD->getParent() == Base)
+        return true;
+      }
+  }
+
+  return false;
+}
+
+bool RecordLayoutBuilder::needsVtorDispIndirectBase(const CXXRecordDecl *RD,
+                                                    const CXXRecordDecl *Base,
+                                               const CXXBasePath &Path) const {
+  for (CXXBasePath::const_reverse_iterator PathElem = Path.rbegin(),
+       E = Path.rend(); PathElem != E; ++PathElem) {
+    if (needsVtorDispDirectBase(PathElem->Class, Base))
+      return true;
+  }
+  return false;
+}
+
+bool RecordLayoutBuilder::needsVtorDisp(const CXXRecordDecl *RD,
+                                        const CXXRecordDecl *Base) const {
+  if (Base->isAbstract())
+    return true;
+
+  CXXBasePaths InheritancePaths;
+  InheritancePaths.setOrigin(const_cast<CXXRecordDecl *>(RD));
+  RD->lookupInBases(&CXXRecordDecl::FindBaseClass, 
+                    const_cast<CXXRecordDecl *>(Base->getCanonicalDecl()),
+                    InheritancePaths);
+
+  CanQualType BaseType = 
+    Context.getCanonicalType(Context.getTagDeclType(Base));
+
+  if (InheritancePaths.isAmbiguous(BaseType))
+    llvm_unreachable("needsVtorDisp can not work with ambiguous bases!");
+
+  CXXBasePath& Path = InheritancePaths.front();
+
+  // Simple case, direct base.
+  if (Path.size() == 1) {
+    return needsVtorDispDirectBase(RD, Base);
+  } else if (!Path.empty()) {
+    return needsVtorDispIndirectBase(RD, Base, Path);
+  }
+
+  return false;
+}
+
 /// 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 OnlyMethods) 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() &&
+        !(OnlyMethods && (method->getKind() == Decl::CXXConstructor ||
+                          method->getKind() == Decl::CXXDestructor))) {
       return true;
     }
   }
@@ -1232,6 +1312,9 @@
 
   // If it has no virtual bases, then everything is at a static offset.
   if (!Base->getNumVBases()) return true;
+  
+  // If class has primary base, 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()
@@ -1300,6 +1383,16 @@
     const BaseSubobjectInfo *BaseInfo = VirtualBaseInfo.lookup(BaseDecl);
     assert(BaseInfo && "Did not find virtual base info!");
     
+    if (needsVtorDisp(RD, BaseDecl)) {
+      CharUnits IntSize = 
+        CharUnits::fromQuantity(Context.getTargetInfo().getIntWidth() / 8);
+
+      VtorDispOffsets.insert(std::pair<const CXXRecordDecl *, CharUnits>(BaseDecl, getSize()));
+      
+      setSize(getSize() + IntSize);
+      setDataSize(getSize());
+    }
+
     LayoutVirtualBase(BaseInfo);
   }
 }
@@ -1461,8 +1554,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 +1565,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);
@@ -2244,7 +2337,8 @@
                                   EmptySubobjects.SizeOfLargestEmptySubobject,
                                   Builder.PrimaryBase,
                                   Builder.PrimaryBaseIsVirtual,
-                                  Builder.Bases, Builder.VBases);
+                                  Builder.Bases, Builder.VBases,
+                                  Builder.VtorDispOffsets);
   } else {
     RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0);
     Builder.Layout(D);
@@ -2432,12 +2526,23 @@
     return;
 
   // Dump virtual bases.
+  const ASTRecordLayout::VtorDispOffsetsMapTy &vtordisps = Layout.getVtorDispOffsets();
   for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
          E = RD->vbases_end(); I != E; ++I) {
     assert(I->isVirtual() && "Found non-virtual class!");
     const CXXRecordDecl *VBase =
       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
 
+    if (!vtordisps.empty()) {
+      ASTRecordLayout::VtorDispOffsetsMapTy::const_iterator 
+                                VBaseVtor = vtordisps.find(VBase);
+
+      if (VBaseVtor != vtordisps.end()) {
+        PrintOffset(OS, Offset + VBaseVtor->second, IndentLevel);
+        OS << "(vtordisp for vbase " << *VBase << ")\n";
+      }
+    }
+
     CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBase);
     DumpCXXRecordLayout(OS, VBase, C, VBaseOffset, IndentLevel,
                         VBase == PrimaryBase ?
Index: test/Sema/ms_class_layout.cpp
===================================================================
--- test/Sema/ms_class_layout.cpp	(revision 149862)
+++ test/Sema/ms_class_layout.cpp	(working copy)
@@ -97,6 +97,54 @@
 
 struct R {};
 
+class IA
+{
+public:
+  virtual ~IA(){}
+  virtual void ia() = 0;
+};
+
+class Obj : public virtual IA
+{
+public:
+  virtual ~Obj(){}
+  virtual void ia(){}
+  virtual void obj(){}
+};
+
+class ICh : public virtual IA
+{
+public:
+  virtual ~ICh(){}
+  virtual void ia(){}
+  virtual void iCh(){}
+};
+
+class Comp : public Obj, public virtual ICh
+{
+public:
+  virtual ~Comp(){}
+  virtual void ia(){}
+  virtual void comp(){}
+};
+
+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;}
+};
+
 #pragma pack(pop)
 
 // This needs only for building layouts. 
@@ -113,6 +161,7 @@
   O* o;
   P* p;
   R* r;
+	sd *h;
   return 0;
 }
 
@@ -333,3 +382,58 @@
 // 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 }
