Abstract out the emission of vtables, add basic support for vtable emission when using -cxx-abi microsoft

Reviewed at http://llvm-reviews.chandlerc.com/D1532

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@191523 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp
index 2d3afc9..f4d6861 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -53,9 +53,6 @@
     NextFieldOffsetInChars(CharUnits::Zero()),
     LLVMStructAlignment(CharUnits::One()) { }
 
-  void AppendVTablePointer(BaseSubobject Base, llvm::Constant *VTable,
-                           const CXXRecordDecl *VTableClass);
-
   void AppendField(const FieldDecl *Field, uint64_t FieldOffset,
                    llvm::Constant *InitExpr);
 
@@ -72,8 +69,7 @@
 
   bool Build(InitListExpr *ILE);
   void Build(const APValue &Val, const RecordDecl *RD, bool IsPrimaryBase,
-             llvm::Constant *VTable, const CXXRecordDecl *VTableClass,
-             CharUnits BaseOffset);
+             const CXXRecordDecl *VTableClass, CharUnits BaseOffset);
   llvm::Constant *Finalize(QualType Ty);
 
   CharUnits getAlignment(const llvm::Constant *C) const {
@@ -88,23 +84,6 @@
   }
 };
 
-void ConstStructBuilder::AppendVTablePointer(BaseSubobject Base,
-                                             llvm::Constant *VTable,
-                                             const CXXRecordDecl *VTableClass) {
-  // Find the appropriate vtable within the vtable group.
-  uint64_t AddressPoint =
-    CGM.getVTableContext().getVTableLayout(VTableClass).getAddressPoint(Base);
-  llvm::Value *Indices[] = {
-    llvm::ConstantInt::get(CGM.Int64Ty, 0),
-    llvm::ConstantInt::get(CGM.Int64Ty, AddressPoint)
-  };
-  llvm::Constant *VTableAddressPoint =
-    llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Indices);
-
-  // Add the vtable at the start of the object.
-  AppendBytes(Base.getBaseOffset(), VTableAddressPoint);
-}
-
 void ConstStructBuilder::
 AppendField(const FieldDecl *Field, uint64_t FieldOffset,
             llvm::Constant *InitCst) {
@@ -424,15 +403,19 @@
 }
 
 void ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,
-                               bool IsPrimaryBase, llvm::Constant *VTable,
+                               bool IsPrimaryBase,
                                const CXXRecordDecl *VTableClass,
                                CharUnits Offset) {
   const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
 
   if (const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
     // Add a vtable pointer, if we need one and it hasn't already been added.
-    if (CD->isDynamicClass() && !IsPrimaryBase)
-      AppendVTablePointer(BaseSubobject(CD, Offset), VTable, VTableClass);
+    if (CD->isDynamicClass() && !IsPrimaryBase) {
+      llvm::Constant *VTableAddressPoint =
+          CGM.getCXXABI().getVTableAddressPointForConstExpr(
+              BaseSubobject(CD, Offset), VTableClass);
+      AppendBytes(Offset, VTableAddressPoint);
+    }
 
     // Accumulate and sort bases, in order to visit them in address order, which
     // may not be the same as declaration order.
@@ -453,7 +436,7 @@
 
       bool IsPrimaryBase = Layout.getPrimaryBase() == Base.Decl;
       Build(Val.getStructBase(Base.Index), Base.Decl, IsPrimaryBase,
-            VTable, VTableClass, Offset + Base.Offset);
+            VTableClass, Offset + Base.Offset);
     }
   }
 
@@ -560,11 +543,7 @@
 
   const RecordDecl *RD = ValTy->castAs<RecordType>()->getDecl();
   const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD);
-  llvm::Constant *VTable = 0;
-  if (CD && CD->isDynamicClass())
-    VTable = CGM.getVTables().GetAddrOfVTable(CD);
-
-  Builder.Build(Val, RD, false, VTable, CD, CharUnits::Zero());
+  Builder.Build(Val, RD, false, CD, CharUnits::Zero());
 
   return Builder.Finalize(ValTy);
 }