More vtable work - it's not possible to use the new vtable code for everything by setting a flag inside CGVtable.cpp. My plan is to run some tests and bootstrap and once that's done flip the bit.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99804 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp
index f44b7cc..2f725df 100644
--- a/lib/CodeGen/CGVtable.cpp
+++ b/lib/CodeGen/CGVtable.cpp
@@ -3610,16 +3610,24 @@
   return I->second;
 }
 
+static bool UseNewVTableCode = false;
+
 uint64_t
 CodeGenVTables::getAddressPoint(BaseSubobject Base, const CXXRecordDecl *RD) {
-  const CodeGenVTables::AddrSubMap_t& AddressPoints = getAddressPoints(RD);
+  // FIXME: Always use the new vtable code once we know it works.
+  if (!UseNewVTableCode) {
+    const CodeGenVTables::AddrSubMap_t& AddressPoints = getAddressPoints(RD);
 
-  uint64_t AddressPoint = 
-    AddressPoints.lookup(std::make_pair(Base.getBase(),
-                                        Base.getBaseOffset()));
+    uint64_t AddressPoint = 
+      AddressPoints.lookup(std::make_pair(Base.getBase(),
+                                          Base.getBaseOffset()));
   
+    assert(AddressPoint && "Address point must not be zero!");
+  }
+  
+  uint64_t AddressPoint = AddressPoints.lookup(std::make_pair(RD, Base));
   assert(AddressPoint && "Address point must not be zero!");
-  
+
   return AddressPoint;
 }
 
@@ -4024,22 +4032,6 @@
   }
 }
 
-void 
-CodeGenVTables::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
-                                  const CXXRecordDecl *RD) {
-  llvm::GlobalVariable *&Vtable = Vtables[RD];
-  if (Vtable) {
-    assert(Vtable->getInitializer() && "Vtable doesn't have a definition!");
-    return;
-  }
-  
-  llvm::DenseMap<BaseSubobject, uint64_t> AddressPoints;
-  Vtable = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0,
-                          /*IsVirtual=*/false,
-                          AddressPoints);
-  GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD);
-}
-
 llvm::Constant *
 CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD,
                                         const uint64_t *Components, 
@@ -4176,6 +4168,8 @@
   return GV;
 }
 
+// FIXME: When the new code is in place, we can change this to return a 
+// GlobalVariable.
 llvm::Constant *CodeGenVTables::GetAddrOfVTable(const CXXRecordDecl *RD) {
   llvm::SmallString<256> OutName;
   CGM.getMangleContext().mangleCXXVtable(RD, OutName);
@@ -4186,7 +4180,12 @@
   const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
   llvm::ArrayType *ArrayType = 
     llvm::ArrayType::get(Int8PtrTy, getNumVTableComponents(RD));
-  
+
+  // FIXME: Always use the new vtable code once we know it works.
+  if (UseNewVTableCode)
+    return GetGlobalVariable(CGM.getModule(), Name, ArrayType, 
+                             llvm::GlobalValue::ExternalLinkage);
+
   llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name);
   if (GV) {
     if (!GV->isDeclaration() || GV->getType()->getElementType() == ArrayType)
@@ -4201,6 +4200,29 @@
   return GV;
 }
 
+void
+CodeGenVTables::EmitVTableDefinition(llvm::GlobalVariable *VTable,
+                                     llvm::GlobalVariable::LinkageTypes Linkage,
+                                     const CXXRecordDecl *RD) {
+  // Dump the vtable layout if necessary.
+  if (CGM.getLangOptions().DumpVtableLayouts) {
+    VtableBuilder Builder(*this, RD, 0, /*MostDerivedClassIsVirtual=*/0, RD);
+
+    Builder.dumpLayout(llvm::errs());
+  }
+
+  assert(VTableThunksMap.count(RD) && 
+         "No thunk status for this record decl!");
+  
+  const VTableThunksTy& Thunks = VTableThunksMap[RD];
+  
+  // Create and set the initializer.
+  llvm::Constant *Init = 
+    CreateVTableInitializer(RD, getVTableComponentsData(RD),
+                            getNumVTableComponents(RD), Thunks);
+  VTable->setInitializer(Init);
+}
+
 llvm::GlobalVariable *
 CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD, 
                                       const BaseSubobject &Base, 
@@ -4250,6 +4272,28 @@
   return VTable;
 }
 
+void 
+CodeGenVTables::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
+                                  const CXXRecordDecl *RD) {
+  llvm::GlobalVariable *&VTable = Vtables[RD];
+  if (VTable) {
+    assert(VTable->getInitializer() && "Vtable doesn't have a definition!");
+    return;
+  }
+
+  // FIXME: Always use the new vtable code once we know it works.
+  if (UseNewVTableCode) {
+    VTable = cast<llvm::GlobalVariable>(GetAddrOfVTable(RD));
+    EmitVTableDefinition(VTable, Linkage, RD);
+  } else {
+    llvm::DenseMap<BaseSubobject, uint64_t> AddressPoints;
+    VTable = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0,
+                            /*IsVirtual=*/false,
+                            AddressPoints);
+  }
+  GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD);
+}
+
 void CodeGenVTables::EmitVTableRelatedData(GlobalDecl GD) {
   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
   const CXXRecordDecl *RD = MD->getParent();
diff --git a/lib/CodeGen/CGVtable.h b/lib/CodeGen/CGVtable.h
index 6dd37a4..6a37eb2 100644
--- a/lib/CodeGen/CGVtable.h
+++ b/lib/CodeGen/CGVtable.h
@@ -292,6 +292,13 @@
     return VTableLayoutMap.lookup(RD)[0];
   }
 
+  const uint64_t *getVTableComponentsData(const CXXRecordDecl *RD) const {
+    assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!");
+
+    uint64_t *Components = VTableLayoutMap.lookup(RD);
+    return &Components[1];
+  }
+
   typedef llvm::DenseMap<ClassPairTy, uint64_t> SubVTTIndiciesMapTy;
   
   /// SubVTTIndicies - Contains indices into the various sub-VTTs.
@@ -380,6 +387,11 @@
   /// GetAddrOfVTable - Get the address of the vtable for the given record decl.
   llvm::Constant *GetAddrOfVTable(const CXXRecordDecl *RD);
 
+  /// EmitVTableDefinition - Emit the definition of the given vtable.
+  void EmitVTableDefinition(llvm::GlobalVariable *VTable,
+                            llvm::GlobalVariable::LinkageTypes Linkage,
+                            const CXXRecordDecl *RD);
+  
   /// GenerateConstructionVTable - Generate a construction vtable for the given 
   /// base subobject.
   llvm::GlobalVariable *