Start cleaning up the VTT builder to make it work more like the VTable builder.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99581 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGVTT.cpp b/lib/CodeGen/CGVTT.cpp
index e820bef..1989d6c 100644
--- a/lib/CodeGen/CGVTT.cpp
+++ b/lib/CodeGen/CGVTT.cpp
@@ -169,56 +169,14 @@
     }
   }
 
-  /// BuiltVTT - Add the VTT to Inits.  Offset is the offset in bits to the
-  /// currnet object we're working on.
-  void BuildVTT(const CXXRecordDecl *RD, uint64_t Offset, bool BaseIsVirtual) {
-    // Itanium C++ ABI 2.6.2:
-    //   An array of virtual table addresses, called the VTT, is declared for 
-    //   each class type that has indirect or direct virtual base classes.
-    if (RD->getNumVBases() == 0)
-      return;
+  /// LayoutVTT - Will lay out the VTT for the given subobject, including any
+  /// secondary VTTs, secondary virtual pointers and virtual VTTs.
+  void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);
 
-    // Remember the sub-VTT index.
-    SubVTTIndicies[RD] = Inits.size();
-
-    llvm::Constant *Vtable;
-    const CXXRecordDecl *VtableClass;
-
-    // First comes the primary virtual table pointer...
-    Vtable = getCtorVtable(BaseSubobject(RD, Offset), 
-                           /*IsVirtual=*/BaseIsVirtual);
-    VtableClass = RD;
-    
-    llvm::Constant *Init = BuildVtablePtr(Vtable, VtableClass, RD, Offset);
-    Inits.push_back(Init);
-
-    // then the secondary VTTs....
-    SecondaryVTTs(RD, Offset);
-
-    // Make sure to clear the set of seen virtual bases.
-    SeenVBasesInSecondary.clear();
-
-    // and last the secondary vtable pointers.
-    Secondary(RD, Vtable, VtableClass, Offset, false);
-  }
-
-  /// SecondaryVTTs - Add the secondary VTTs to Inits.  The secondary VTTs are
-  /// built from each direct non-virtual proper base that requires a VTT in
-  /// declaration order.
-  void SecondaryVTTs(const CXXRecordDecl *RD, uint64_t Offset) {
-    for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
-           e = RD->bases_end(); i != e; ++i) {
-      const CXXRecordDecl *Base =
-        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
-      if (i->isVirtual())
-        continue;
-      const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
-      uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(Base);
-      
-      BuildVTT(Base, BaseOffset, /*BaseIsVirtual=*/false);
-    }
-  }
-
+  /// LayoutSecondaryVTTs - Lay out the secondary VTTs of the given base 
+  /// subobject.
+  void LayoutSecondaryVTTs(BaseSubobject Base);
+  
   /// VirtualVTTs - Add the VTT for each proper virtual base in inheritance
   /// graph preorder.
   void VirtualVTTs(const CXXRecordDecl *RD) {
@@ -229,7 +187,8 @@
       if (i->isVirtual() && !SeenVBase.count(Base)) {
         SeenVBase.insert(Base);
         uint64_t BaseOffset = BLayout.getVBaseClassOffset(Base);
-        BuildVTT(Base, BaseOffset, /*BaseIsVirtual=*/true);
+        
+        LayoutVTT(BaseSubobject(Base, BaseOffset), /*BaseIsVirtual=*/true);
       }
       VirtualVTTs(Base);
     }
@@ -251,7 +210,7 @@
     Inits.push_back(Init);
     
     // then the secondary VTTs...
-    SecondaryVTTs(Class, 0);
+    LayoutSecondaryVTTs(BaseSubobject(Class, 0));
 
     // Make sure to clear the set of seen virtual bases.
     SeenVBasesInSecondary.clear();
@@ -267,6 +226,62 @@
     return SubVTTIndicies;
   }
 };
+  
+void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) {
+  const CXXRecordDecl *RD = Base.getBase();
+
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+       E = RD->bases_end(); I != E; ++I) {
+    
+    // Don't layout virtual bases.
+    if (I->isVirtual())
+        continue;
+
+    const CXXRecordDecl *BaseDecl =
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+    const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
+    uint64_t BaseOffset = Base.getBaseOffset() + 
+      Layout.getBaseClassOffset(BaseDecl);
+   
+    // Layout the VTT for this base.
+    LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/false);
+  }
+}
+
+void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) {
+  const CXXRecordDecl *RD = Base.getBase();
+
+  // Itanium C++ ABI 2.6.2:
+  //   An array of virtual table addresses, called the VTT, is declared for 
+  //   each class type that has indirect or direct virtual base classes.
+  if (RD->getNumVBases() == 0)
+    return;
+  
+  // Remember the sub-VTT index.
+  SubVTTIndicies[RD] = Inits.size();
+
+  llvm::Constant *Vtable;
+  const CXXRecordDecl *VtableClass;
+
+  // First comes the primary virtual table pointer...
+  Vtable = getCtorVtable(Base, /*IsVirtual=*/BaseIsVirtual);
+  VtableClass = RD;
+  
+  llvm::Constant *Init = BuildVtablePtr(Vtable, VtableClass, RD, 
+                                        Base.getBaseOffset());
+  Inits.push_back(Init);
+
+  // then the secondary VTTs....
+  LayoutSecondaryVTTs(Base);
+
+  // Make sure to clear the set of seen virtual bases.
+  SeenVBasesInSecondary.clear();
+
+  // and last the secondary vtable pointers.
+  Secondary(RD, Vtable, VtableClass, Base.getBaseOffset(), false);
+}
+  
 }
 
 llvm::GlobalVariable *