]> granicus.if.org Git - clang/commitdiff
Stub out most of the VTT building code. WIP.
authorMike Stump <mrs@apple.com>
Wed, 11 Nov 2009 00:35:07 +0000 (00:35 +0000)
committerMike Stump <mrs@apple.com>
Wed, 11 Nov 2009 00:35:07 +0000 (00:35 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86772 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGVtable.cpp

index 636639d05e9b1e79131c9caba821930f4cf62e0e..d98d40c0ecefd32c71db47cd5738273c5c2b0042 100644 (file)
@@ -723,12 +723,93 @@ class VTTBuilder {
   /// Class - The most derived class that this vtable is being built for.
   const CXXRecordDecl *Class;
   CodeGenModule &CGM;  // Per-module state.
+  llvm::SmallSet<const CXXRecordDecl *, 32> SeenVBase;
+
+  /// Secondary - Add the secondary vtable pointers to Inits.
+  void Secondary(const CXXRecordDecl *RD, bool MorallyVirtual=false) {
+    if (RD->getNumVBases() == 0 && ! MorallyVirtual)
+      return;
+
+    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());
+      const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
+      const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
+      const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
+      bool NonVirtualPrimaryBase;
+      NonVirtualPrimaryBase = !PrimaryBaseWasVirtual && Base == PrimaryBase;
+      bool BaseMorallyVirtual = MorallyVirtual | i->isVirtual();
+      if ((Base->getNumVBases() || BaseMorallyVirtual)
+          && !NonVirtualPrimaryBase) {
+        // FIXME: Slightly too many of these for __ZTT8test8_B2
+        // FIXME: ctor vtbl or normal vtable.
+        llvm::Constant *vtbl = CGM.getVtableInfo().getVtable(Base);
+        Inits.push_back(vtbl);
+      }
+      Secondary(Base, BaseMorallyVirtual);
+    }
+  }
+
+  /// BuiltVTT - Add the VTT to Inits.
+  void BuildVTT(const CXXRecordDecl *RD, bool MorallyVirtual=false) {
+    if (RD->getNumVBases() == 0 && !MorallyVirtual)
+      return;
+
+    // First comes the primary virtual table pointer...
+    // FIXME: ctor vtable instead
+    Inits.push_back(CGM.getVtableInfo().getVtable(RD));
+
+    // then the secondary VTTs....
+    SecondaryVTTs(RD, MorallyVirtual);
+
+    // and last the secondary vtable pointers.
+    Secondary(RD, MorallyVirtual);
+  }
+
+  /// 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, bool MorallyVirtual=false) {
+    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;
+      BuildVTT(Base, MorallyVirtual);
+    }
+  }
 
+  /// VirtualVTTs - Add the VTT for each proper virtual base in inheritance
+  /// graph preorder.
+  void VirtualVTTs(const CXXRecordDecl *RD) {
+    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() && !SeenVBase.count(Base)) {
+        SeenVBase.insert(Base);
+        BuildVTT(Base, true);
+      }
+      VirtualVTTs(Base);
+    }
+  }
 public:
   VTTBuilder(std::vector<llvm::Constant *> &inits, const CXXRecordDecl *c,
              CodeGenModule &cgm) : Inits(inits), Class(c), CGM(cgm) {
     
+    // First comes the primary virtual table pointer for the complete class...
     Inits.push_back(CGM.getVtableInfo().getVtable(Class));
+
+    // then the secondary VTTs...
+    SecondaryVTTs(Class);
+
+    // then the secondary vtable pointers...
+    Secondary(Class);
+
+    // and last, the virtual VTTs.
+    VirtualVTTs(Class);
   }
 };
 
@@ -746,10 +827,10 @@ llvm::Constant *CodeGenModule::GenerateVTT(const CXXRecordDecl *RD) {
   std::vector<llvm::Constant *> inits;
   llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0);
 
-  VTTBuilder b(inits, RD, *this);
-
   D1(printf("vtt %s\n", RD->getNameAsCString()));
 
+  VTTBuilder b(inits, RD, *this);
+
   llvm::Constant *C;
   llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, inits.size());
   C = llvm::ConstantArray::get(type, inits);