summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-08-20 02:11:48 +0000
committerMike Stump <mrs@apple.com>2009-08-20 02:11:48 +0000
commit7fa0d93a3bbe290244f4f157078d9a0d6e87b44f (patch)
tree8e7be7b6febd0434c02a26bf910ee27436830567
parente29ba20148e9b7835ad463b39cd4ee9223eafbbf (diff)
Ensure we don't output repeated vbase offsets. I have a testcase for
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
-rw-r--r--lib/CodeGen/CGCXX.cpp45
-rw-r--r--test/CodeGenCXX/virt.cpp4
2 files changed, 25 insertions, 24 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index d3dad897a8..4a8bba8078 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -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) {
diff --git a/test/CodeGenCXX/virt.cpp b/test/CodeGenCXX/virt.cpp
index d5857bc9af..85ebaca6a1 100644
--- a/test/CodeGenCXX/virt.cpp
+++ b/test/CodeGenCXX/virt.cpp
@@ -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