diff --git lib/AST/VTableBuilder.cpp lib/AST/VTableBuilder.cpp
index 33dad40..906ce94 100644
--- lib/AST/VTableBuilder.cpp
+++ lib/AST/VTableBuilder.cpp
@@ -1295,9 +1295,18 @@ VTableBuilder::AddMethod(const CXXMethodDecl *MD,
     assert(ReturnAdjustment.isEmpty() && 
            "Destructor can't have return adjustment!");
 
-    // Add both the complete destructor and the deleting destructor.
-    Components.push_back(VTableComponent::MakeCompleteDtor(DD));
-    Components.push_back(VTableComponent::MakeDeletingDtor(DD));
+    // FIXME: Should probably add a layer of abstraction for vtable generation.
+    if (Context.getTargetInfo().getCXXABI() != CXXABI_Microsoft) {
+      // Add both the complete destructor and the deleting destructor.
+      Components.push_back(VTableComponent::MakeCompleteDtor(DD));
+      Components.push_back(VTableComponent::MakeDeletingDtor(DD));
+    } else {
+      // Add only one destructor in MS mode.
+      // FIXME: The virtual destructors are handled differently in MS ABI,
+      // we should add such a support later. For now, put the deleting
+      // destructor into the vftable just to make its layout right.
+      Components.push_back(VTableComponent::MakeDeletingDtor(DD));
+    }
   } else {
     // Add the return adjustment if necessary.
     if (!ReturnAdjustment.isEmpty())
@@ -1612,11 +1621,13 @@ VTableBuilder::LayoutPrimaryAndSecondaryVTables(BaseSubobject Base,
   if (Base.getBase() == MostDerivedClass)
     VBaseOffsetOffsets = Builder.getVBaseOffsetOffsets();
 
-  // Add the offset to top.
-  CharUnits OffsetToTop = MostDerivedClassOffset - OffsetInLayoutClass;
-  Components.push_back(
-    VTableComponent::MakeOffsetToTop(OffsetToTop));
-  
+  // FIXME: Should probably add a layer of abstraction for vtable generation.
+  if (Context.getTargetInfo().getCXXABI() != CXXABI_Microsoft) {
+    // Add the offset to top.
+    CharUnits OffsetToTop = MostDerivedClassOffset - OffsetInLayoutClass;
+    Components.push_back(VTableComponent::MakeOffsetToTop(OffsetToTop));
+  }
+
   // Next, add the RTTI.
   Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass));
   
@@ -2120,10 +2131,16 @@ void VTableBuilder::dumpLayout(raw_ostream& Out) {
                                   MD);
 
     if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
-      IndicesMap[VTables.getMethodVTableIndex(GlobalDecl(DD, Dtor_Complete))] =
-        MethodName + " [complete]";
-      IndicesMap[VTables.getMethodVTableIndex(GlobalDecl(DD, Dtor_Deleting))] =
-        MethodName + " [deleting]";
+      // FIXME: Should add a layer of abstraction for vtable generation.
+      if (Context.getTargetInfo().getCXXABI() != CXXABI_Microsoft) {
+        IndicesMap[VTables.getMethodVTableIndex(GlobalDecl(DD, Dtor_Complete))]
+          = MethodName + " [complete]";
+        IndicesMap[VTables.getMethodVTableIndex(GlobalDecl(DD, Dtor_Deleting))]
+          = MethodName + " [deleting]";
+      } else {
+        IndicesMap[VTables.getMethodVTableIndex(GlobalDecl(DD, Dtor_Deleting))]
+          = MethodName;
+      }
     } else {
       IndicesMap[VTables.getMethodVTableIndex(MD)] = MethodName;
     }
@@ -2199,6 +2216,9 @@ void VTableContext::ComputeMethodVTableIndices(const CXXRecordDecl *RD) {
   //   between their return types does not require an adjustment. 
 
   int64_t CurrentIndex = 0;
+
+  // FIXME: Should probably add a layer of abstraction for vtable generation.
+  bool isMicrosoft = (Context.getTargetInfo().getCXXABI() == CXXABI_Microsoft);
   
   const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
   const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
@@ -2239,12 +2259,17 @@ void VTableContext::ComputeMethodVTableIndices(const CXXRecordDecl *RD) {
         if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
           const CXXDestructorDecl *OverriddenDD = 
             cast<CXXDestructorDecl>(OverriddenMD);
-          
-          // Add both the complete and deleting entries.
-          MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] = 
-            getMethodVTableIndex(GlobalDecl(OverriddenDD, Dtor_Complete));
-          MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] = 
-            getMethodVTableIndex(GlobalDecl(OverriddenDD, Dtor_Deleting));
+
+          if (!isMicrosoft) {
+            // Add both the complete and deleting entries.
+            MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] =
+              getMethodVTableIndex(GlobalDecl(OverriddenDD, Dtor_Complete));
+            MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] =
+              getMethodVTableIndex(GlobalDecl(OverriddenDD, Dtor_Deleting));
+          } else {
+            MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] =
+              getMethodVTableIndex(GlobalDecl(OverriddenDD, Dtor_Deleting));
+          }
         } else {
           MethodVTableIndices[MD] = getMethodVTableIndex(OverriddenMD);
         }
@@ -2262,11 +2287,19 @@ void VTableContext::ComputeMethodVTableIndices(const CXXRecordDecl *RD) {
         continue;
       } 
 
-      // Add the complete dtor.
-      MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] = CurrentIndex++;
-      
-      // Add the deleting dtor.
-      MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] = CurrentIndex++;
+      if (!isMicrosoft) {
+        // Add the complete dtor.
+        MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] = CurrentIndex++;
+
+        // Add the deleting dtor.
+        MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] = CurrentIndex++;
+      } else {
+        // Add only the deleting dtor.
+        // FIXME: The virtual destructors are handled differently in MS ABI,
+        // we should add such a support later. For now, put the deleting
+        // destructor into the vftable indices.
+        MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] = CurrentIndex++;
+      }
     } else {
       // Add the entry.
       MethodVTableIndices[MD] = CurrentIndex++;
@@ -2278,6 +2311,9 @@ void VTableContext::ComputeMethodVTableIndices(const CXXRecordDecl *RD) {
     //   If a class has an implicitly-defined virtual destructor, 
     //   its entries come after the declared virtual function pointers.
 
+    assert(!isMicrosoft &&
+           "Implicit virtual dtors are not yet supported in MS ABI");
+
     // Add the complete dtor.
     MethodVTableIndices[GlobalDecl(ImplicitVirtualDtor, Dtor_Complete)] = 
       CurrentIndex++;
diff --git lib/CodeGen/MicrosoftCXXABI.cpp lib/CodeGen/MicrosoftCXXABI.cpp
index 8d205c3..8e49292 100644
--- lib/CodeGen/MicrosoftCXXABI.cpp
+++ lib/CodeGen/MicrosoftCXXABI.cpp
@@ -207,7 +207,7 @@ void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
 }
 
 void MicrosoftCXXABI::EmitVTables(const CXXRecordDecl *Class) {
-  // FIXME: implement
+  CGM.getVTables().GenerateClassData(CGM.getVTableLinkage(Class), Class);
 }
 
 CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
diff --git test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
new file mode 100644
index 0000000..ae4d242
--- /dev/null
+++ test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
@@ -0,0 +1,132 @@
+// RUN: %clang_cc1 %s -fno-rtti -cxx-abi microsoft -triple=i386-pc-win32 -emit-llvm -fdump-vtable-layouts -o - > %t 2>&1
+// RUN: FileCheck --check-prefix=EMITS-VTABLE %s < %t
+// RUN: FileCheck --check-prefix=CHECK-A %s < %t
+// RUN: FileCheck --check-prefix=CHECK-B %s < %t
+// RUN: FileCheck --check-prefix=CHECK-C %s < %t
+// RUN: FileCheck --check-prefix=CHECK-D %s < %t
+// RUN: FileCheck --check-prefix=CHECK-E %s < %t
+// RUN: FileCheck --check-prefix=CHECK-F %s < %t
+// RUN: FileCheck --check-prefix=CHECK-G %s < %t
+
+struct A {
+  // CHECK-A: Vtable for 'A' (4 entries)
+  // CHECK-A-NEXT: 0 | A RTTI
+  // CHECK-A-NEXT: -- (A, 0) vtable address --
+  // CHECK-A-NEXT: 1 | void A::f()
+  // CHECK-A-NEXT: 2 | void A::g()
+  // CHECK-A-NEXT: 3 | void A::h()
+  // EMITS-VTABLE: @"\01??_7A@@6B@" = unnamed_addr constant [4 x i8*]
+  virtual void f();
+  virtual void g();
+  virtual void h();
+  int ia;
+};
+void A::f() {}
+
+struct B : A {
+  // CHECK-B: Vtable for 'B' (6 entries)
+  // CHECK-B-NEXT: 0 | B RTTI
+  // CHECK-B-NEXT: -- (A, 0) vtable address --
+  // CHECK-B-NEXT: -- (B, 0) vtable address --
+  // CHECK-B-NEXT: 1 | void B::f()
+  // CHECK-B-NEXT: 2 | void A::g()
+  // CHECK-B-NEXT: 3 | void A::h()
+  // CHECK-B-NEXT: 4 | void B::i()
+  // CHECK-B-NEXT: 5 | void B::j()
+  // EMITS-VTABLE: @"\01??_7B@@6B@" = unnamed_addr constant [6 x i8*]
+  virtual void f();  // overrides A::f()
+  virtual void i();
+  virtual void j();
+};
+void B::f() {}
+
+struct C {
+  // CHECK-C: Vtable for 'C' (3 entries)
+  // CHECK-C-NEXT: 0 | C RTTI
+  // CHECK-C-NEXT: -- (C, 0) vtable address --
+  // CHECK-C-NEXT: 1 | C::~C()
+  // CHECK-C-NEXT: 2 | void C::f()
+  // CHECK-C: VTable indices for 'C' (2 entries).
+  // CHECK-C-NEXT: 0 | C::~C()
+  // CHECK-C-NEXT: 1 | void C::f()
+  // Never used, so doesn't emit a vtable.
+  virtual ~C();
+
+  virtual void f();
+};
+void C::f() {}
+
+struct D {
+  // CHECK-D: Vtable for 'D' (3 entries)
+  // CHECK-D-NEXT: 0 | D RTTI
+  // CHECK-D-NEXT: -- (D, 0) vtable address --
+  // CHECK-D-NEXT: 1 | void D::f()
+  // CHECK-D-NEXT: 2 | D::~D()
+  // EMITS-VTABLE: @"\01??_7D@@6B@" = unnamed_addr constant [3 x i8*]
+  virtual void f();
+
+  virtual ~D();
+};
+void D::f() {}
+
+struct E : A {
+  // CHECK-E: Vtable for 'E' (6 entries)
+  // CHECK-E-NEXT: 0 | E RTTI
+  // CHECK-E-NEXT: -- (A, 0) vtable address --
+  // CHECK-E-NEXT: -- (E, 0) vtable address --
+  // CHECK-E-NEXT: 1 | void A::f()
+  // CHECK-E-NEXT: 2 | void A::g()
+  // CHECK-E-NEXT: 3 | void A::h()
+  // CHECK-E-NEXT: 4 | E::~E()
+  // CHECK-E-NEXT: 5 | void E::i()
+  // CHECK-E: VTable indices for 'E' (2 entries).
+  // CHECK-E-NEXT: 3 | E::~E()
+  // CHECK-E-NEXT: 4 | void E::i()
+
+  // Never used, so doesn't emit a vtable.
+  virtual ~E();
+  virtual void i();
+};
+void E::i() {}
+
+struct F : A {
+  // CHECK-F: Vtable for 'F' (6 entries)
+  // CHECK-F-NEXT: 0 | F RTTI
+  // CHECK-F-NEXT: -- (A, 0) vtable address --
+  // CHECK-F-NEXT: -- (F, 0) vtable address --
+  // CHECK-F-NEXT: 1 | void A::f()
+  // CHECK-F-NEXT: 2 | void A::g()
+  // CHECK-F-NEXT: 3 | void A::h()
+  // CHECK-F-NEXT: 4 | void F::i()
+  // CHECK-F-NEXT: 5 | F::~F()
+  // CHECK-F: VTable indices for 'F' (2 entries).
+  // CHECK-F-NEXT: 3 | void F::i()
+  // CHECK-F-NEXT: 4 | F::~F()
+  // EMITS-VTABLE: @"\01??_7F@@6B@" = unnamed_addr constant [6 x i8*]
+  virtual void i();
+  virtual ~F();
+};
+void F::i() {}
+
+struct G : E {
+  // CHECK-G: Vtable for 'G' (7 entries)
+  // CHECK-G-NEXT: 0 | G RTTI
+  // CHECK-G-NEXT: -- (A, 0) vtable address --
+  // CHECK-G-NEXT: -- (E, 0) vtable address --
+  // CHECK-G-NEXT: -- (G, 0) vtable address --
+  // CHECK-G-NEXT: 1 | void G::f()
+  // CHECK-G-NEXT: 2 | void A::g()
+  // CHECK-G-NEXT: 3 | void A::h()
+  // CHECK-G-NEXT: 4 | G::~G()
+  // CHECK-G-NEXT: 5 | void E::i()
+  // CHECK-G-NEXT: 6 | void G::j()
+  // CHECK-G: VTable indices for 'G' (3 entries).
+  // CHECK-G-NEXT: 0 | void G::f()
+  // CHECK-G-NEXT: 3 | G::~G()
+  // CHECK-G-NEXT: 5 | void G::j()
+  // Never used, so doesn't emit a vtable.
+  virtual void f();  // overrides A::f()
+  virtual ~G();
+  virtual void j();
+};
+void G::j() {}
