]> granicus.if.org Git - clang/commitdiff
Refine vtable building for the secondary vtables to exclude yet more
authorMike Stump <mrs@apple.com>
Wed, 12 Aug 2009 17:42:21 +0000 (17:42 +0000)
committerMike Stump <mrs@apple.com>
Wed, 12 Aug 2009 17:42:21 +0000 (17:42 +0000)
cases where a virtual base was already used as a primary base class.
WIP.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78820 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCXX.cpp
lib/CodeGen/CodeGenFunction.h

index e9ebf230d6b47b0fb7065fbcc34c6fe7569fcc0c..7541357a72c903a2ca51d2c80e68ec05920bd82a 100644 (file)
@@ -626,7 +626,8 @@ void CodeGenFunction::GenerateVtableForBase(const CXXRecordDecl *RD,
                                             llvm::Constant *rtti,
                                          std::vector<llvm::Constant *> &methods,
                                             bool isPrimary,
-                                            bool ForVirtualBase) {
+                                            bool ForVirtualBase,
+                   llvm::SmallSet<const CXXRecordDecl *, 32> &IndirectPrimary) {
   typedef CXXRecordDecl::method_iterator meth_iter;
   llvm::Type *Ptr8Ty;
   Ptr8Ty = llvm::PointerType::get(llvm::Type::Int8Ty, 0);
@@ -668,9 +669,11 @@ void CodeGenFunction::GenerateVtableForBase(const CXXRecordDecl *RD,
     const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 
     const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
     if (PrimaryBase) {
+      if (PrimaryBaseWasVirtual)
+        IndirectPrimary.insert(PrimaryBase);
       TopPrimary = false;
       GenerateVtableForBase(0, PrimaryBase, rtti, methods, true,
-                            PrimaryBaseWasVirtual);
+                            PrimaryBaseWasVirtual, IndirectPrimary);
     }
   }
   // then come the vcall offsets for all our virtual bases.
@@ -739,10 +742,11 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
   const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
   const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
   const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
+  llvm::SmallSet<const CXXRecordDecl *, 32> IndirectPrimary;
 
   // The primary base comes first.
   GenerateVtableForBase(PrimaryBase, RD, rtti, methods, true,
-                        PrimaryBaseWasVirtual);
+                        PrimaryBaseWasVirtual, IndirectPrimary);
   for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
          e = RD->bases_end(); i != e; ++i) {
     if (i->isVirtual())
@@ -750,7 +754,8 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
     const CXXRecordDecl *Base = 
       cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
     if (PrimaryBase != Base) {
-      GenerateVtableForBase(Base, RD, rtti, methods);
+      GenerateVtableForBase(Base, RD, rtti, methods, false, false,
+                            IndirectPrimary);
     }
   }
 
@@ -760,8 +765,9 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
          e = RD->vbases_end(); i != e; ++i) {
     const CXXRecordDecl *Base = 
       cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
-    if (Base != PrimaryBase)
-      GenerateVtableForBase(Base, RD, rtti, methods, false, true);
+    if (!IndirectPrimary.count(Base))
+      GenerateVtableForBase(Base, RD, rtti, methods, false, true,
+                            IndirectPrimary);
   }
 
   llvm::Constant *C;
index ebb35ba9485a240a736602810803a6b40dab7c78..ece4f105dc20f59441912ad7857f69f9bc4b7b7b 100644 (file)
@@ -363,8 +363,9 @@ public:
                              const CXXRecordDecl *Class,
                              llvm::Constant *rtti,
                              std::vector<llvm::Constant *> &methods,
-                             bool isPrimary = false,
-                             bool ForVirtualBase = false);
+                             bool isPrimary,
+                             bool ForVirtualBase,
+                    llvm::SmallSet<const CXXRecordDecl *, 32> &IndirectPrimary);
   llvm::Value *GenerateVtable(const CXXRecordDecl *RD);
 
   void EmitCtorPrologue(const CXXConstructorDecl *CD);