]> granicus.if.org Git - clang/commitdiff
Ensure we don't output repeated vbase offsets. I have a testcase for
authorMike Stump <mrs@apple.com>
Thu, 20 Aug 2009 02:11:48 +0000 (02:11 +0000)
committerMike Stump <mrs@apple.com>
Thu, 20 Aug 2009 02:11:48 +0000 (02:11 +0000)
this, but need to fixup the actual offset value before I can check it
in.  WIP.

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

lib/CodeGen/CGCXX.cpp
test/CodeGenCXX/virt.cpp

index d3dad897a85265391f2ac8810a04f5f600a899ac..4a8bba80788ca84306d8d1893e29ba7dc9c958d3 100644 (file)
@@ -788,6 +788,7 @@ class VtableBuilder {
   const CXXRecordDecl *Class;
   const ASTRecordLayout &BLayout;
   llvm::SmallSet<const CXXRecordDecl *, 32> IndirectPrimary;
+  llvm::SmallSet<const CXXRecordDecl *, 32> SeenVBase;
   llvm::Constant *rtti;
   llvm::LLVMContext &VMContext;
   CodeGenModule &CGM;  // Per-module state.
@@ -829,6 +830,25 @@ public:
     }
   }
 
+  void GenerateVBaseOffsets(std::vector<llvm::Constant *> &offsets,
+                            const CXXRecordDecl *RD,
+                            uint64_t Offset, const ASTRecordLayout &Layout) {
+    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);
+        int64_t BaseOffset = Offset/8 + Layout.getVBaseClassOffset(Base) / 8;
+        llvm::Constant *m;
+        m = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), BaseOffset);
+        m = llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty);
+        offsets.push_back(m);
+      }
+      GenerateVBaseOffsets(offsets, Base, Offset, Layout);
+    }
+  }
+
   void GenerateMethods(const CXXRecordDecl *RD) {
     llvm::Constant *m;
 
@@ -864,9 +884,8 @@ public:
     // The virtual base offsets come first...
     // FIXME: Audit, is this right?
     if (PrimaryBase == 0 || forPrimary || !PrimaryBaseWasVirtual) {
-      llvm::SmallSet<const CXXRecordDecl *, 32> SeenVBase;
       std::vector<llvm::Constant *> offsets;
-      GenerateVBaseOffsets(offsets, RD, SeenVBase, Offset, Layout);
+      GenerateVBaseOffsets(offsets, RD, Offset, Layout);
       for (std::vector<llvm::Constant *>::reverse_iterator i = offsets.rbegin(),
              e = offsets.rend(); i != e; ++i)
         methods.push_back(*i);
@@ -907,6 +926,7 @@ public:
         cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
       if (Base != PrimaryBase || PrimaryBaseWasVirtual) {
         uint64_t o = Offset + Layout.getBaseClassOffset(Base);
+        SeenVBase.clear();
         GenerateVtableForBase(Base, true, false, o, false);
       }
     }
@@ -921,32 +941,13 @@ public:
       if (i->isVirtual() && !IndirectPrimary.count(Base)) {
         // Mark it so we don't output it twice.
         IndirectPrimary.insert(Base);
+        SeenVBase.clear();
         GenerateVtableForBase(Base, false, true, 0, true);
       }
       if (Base->getNumVBases())
         GenerateVtableForVBases(Base, Class);
     }
   }
-
-  void GenerateVBaseOffsets(std::vector<llvm::Constant *> &offsets,
-                            const CXXRecordDecl *RD,
-                           llvm::SmallSet<const CXXRecordDecl *, 32> &SeenVBase,
-                            uint64_t Offset, const ASTRecordLayout &Layout) {
-    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);
-        int64_t BaseOffset = Offset/8 + Layout.getVBaseClassOffset(Base) / 8;
-        llvm::Constant *m;
-        m = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), BaseOffset);
-        m = llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty);
-        offsets.push_back(m);
-      }
-      GenerateVBaseOffsets(offsets, Base, SeenVBase, Offset, Layout);
-    }
-  }
 };
 
 llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
index d5857bc9aff0ea2925381f817e5a168b43b60e75..85ebaca6a10e2d7cd1dda6755c37637f010504db 100644 (file)
@@ -341,7 +341,7 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
 // CHECK-LP32-NEXT: .long __ZN8test8_B19ftest8_B1Ev
 // CHECK-LP32-NEXT: .long 20
 // CHECK-LP32-NEXT: .long 12
-// CHECK-LP32: .long 4294967292
+// CHECK-LP32-NEXT: .long 4294967292
 // CHECK-LP32-NEXT: .long __ZTI7test8_D
 // CHECK-LP32-NEXT: .long __ZN9test8_B2a10ftest8_B2aEv
 // CHECK-LP32-NEXT: .long __ZN8test8_B29ftest8_B2Ev
@@ -368,7 +368,7 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
 // CHECK-LP64-NEXT: .quad __ZN8test8_B19ftest8_B1Ev
 // CHECK-LP64-NEXT: .quad 40
 // CHECK-LP64-NEXT: .quad 24
-// CHECK-LP64: .quad 18446744073709551608
+// CHECK-LP64-NEXT: .quad 18446744073709551608
 // CHECK-LP64-NEXT: .quad __ZTI7test8_D
 // CHECK-LP64-NEXT: .quad __ZN9test8_B2a10ftest8_B2aEv
 // CHECK-LP64-NEXT: .quad __ZN8test8_B29ftest8_B2Ev