summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-08-19 02:06:38 +0000
committerMike Stump <mrs@apple.com>2009-08-19 02:06:38 +0000
commitb46c92dfedf02239e7c73b9a18dcf09071731793 (patch)
tree2dcbdc7bf3c15bb0f7dfc2d3e29ac5baeb1d3be1
parent35d44e5673e772d1cc7eab66818de8d9796b89ca (diff)
Refine vcalls a little.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79400 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGCXX.cpp52
-rw-r--r--test/CodeGenCXX/virt.cpp44
2 files changed, 54 insertions, 42 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index ecde2ad192..f95aa289a3 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -707,6 +707,7 @@ class ABIBuilder {
std::vector<llvm::Constant *> &methods;
llvm::Type *Ptr8Ty;
const CXXRecordDecl *Class;
+ const ASTRecordLayout &BLayout;
llvm::Constant *rtti;
llvm::LLVMContext &VMContext;
CodeGenModule &CGM; // Per-module state.
@@ -716,21 +717,34 @@ public:
ABIBuilder(std::vector<llvm::Constant *> &meth,
const CXXRecordDecl *c,
CodeGenModule &cgm)
- : methods(meth), Class(c), rtti(cgm.GenerateRtti(c)),
- VMContext(cgm.getModule().getContext()), CGM(cgm) {
+ : methods(meth), Class(c), BLayout(cgm.getContext().getASTRecordLayout(c)),
+ rtti(cgm.GenerateRtti(c)), VMContext(cgm.getModule().getContext()),
+ CGM(cgm) {
Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
}
- void GenerateVcalls(const CXXRecordDecl *RD) {
+ llvm::Constant *GenerateVcall(const CXXMethodDecl *MD,
+ const CXXRecordDecl *RD,
+ bool VBoundary,
+ bool SecondaryVirtual) {
+ llvm::Constant *m = 0;
+
+ // FIXME: vcall: offset for virtual base for this function
+ if (SecondaryVirtual || VBoundary)
+ m = llvm::Constant::getNullValue(Ptr8Ty);
+ return m;
+ }
+
+ void GenerateVcalls(const CXXRecordDecl *RD, bool VBoundary,
+ bool SecondaryVirtual) {
llvm::Constant *m;
- // FIXME: audit order
for (method_iter mi = RD->method_begin(),
me = RD->method_end(); mi != me; ++mi) {
if (mi->isVirtual()) {
- // FIXME: vcall: offset for virtual base for this function
- m = llvm::Constant::getNullValue(Ptr8Ty);
- methods.push_back(m);
+ m = GenerateVcall(*mi, RD, VBoundary, SecondaryVirtual);
+ if (m)
+ methods.push_back(m);
}
}
}
@@ -750,8 +764,8 @@ public:
void GenerateVtableForBase(const CXXRecordDecl *RD,
bool forPrimary,
+ bool VBoundary,
int64_t Offset,
- const CXXRecordDecl *Class,
bool ForVirtualBase,
llvm::SmallSet<const CXXRecordDecl *, 32> &IndirectPrimary) {
llvm::Constant *m = llvm::Constant::getNullValue(Ptr8Ty);
@@ -763,6 +777,11 @@ public:
const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
+ if (VBoundary || forPrimary || ForVirtualBase) {
+ // then comes the the vcall offsets for all our functions...
+ GenerateVcalls(RD, VBoundary, !forPrimary && ForVirtualBase);
+ }
+
// The virtual base offsets come first...
// FIXME: Audit, is this right?
if (forPrimary || !PrimaryBaseWasVirtual) {
@@ -774,11 +793,6 @@ public:
methods.push_back(*i);
}
- if (forPrimary || ForVirtualBase) {
- // then comes the the vcall offsets for all our functions...
- GenerateVcalls(RD);
- }
-
bool Top = true;
// vtables are composed from the chain of primaries.
@@ -786,15 +800,13 @@ public:
if (PrimaryBaseWasVirtual)
IndirectPrimary.insert(PrimaryBase);
Top = false;
- GenerateVtableForBase(PrimaryBase, true, Offset, Class,
- PrimaryBaseWasVirtual, IndirectPrimary);
+ GenerateVtableForBase(PrimaryBase, true, PrimaryBaseWasVirtual|VBoundary,
+ Offset, PrimaryBaseWasVirtual, IndirectPrimary);
}
if (Top) {
int64_t BaseOffset;
if (ForVirtualBase) {
- const ASTRecordLayout &BLayout = CGM.getContext()
- .getASTRecordLayout(Class);
BaseOffset = -(BLayout.getVBaseClassOffset(RD) / 8);
} else
BaseOffset = -Offset/8;
@@ -816,7 +828,7 @@ public:
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
if (Base != PrimaryBase || PrimaryBaseWasVirtual) {
uint64_t o = Offset + Layout.getBaseClassOffset(Base);
- GenerateVtableForBase(Base, true, o, Class, false, IndirectPrimary);
+ GenerateVtableForBase(Base, true, false, o, false, IndirectPrimary);
}
}
}
@@ -831,7 +843,7 @@ public:
if (i->isVirtual() && !IndirectPrimary.count(Base)) {
// Mark it so we don't output it twice.
IndirectPrimary.insert(Base);
- GenerateVtableForBase(Base, true, 0, Class, true, IndirectPrimary);
+ GenerateVtableForBase(Base, false, true, 0, true, IndirectPrimary);
}
if (Base->getNumVBases())
GenerateVtableForVBases(Base, Class, IndirectPrimary);
@@ -880,7 +892,7 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
ABIBuilder b(methods, RD, CGM);
// First comes the vtables for all the non-virtual bases...
- b.GenerateVtableForBase(RD, true, 0, RD, false, IndirectPrimary);
+ b.GenerateVtableForBase(RD, true, false, 0, false, IndirectPrimary);
// then the vtables for all the virtual bases.
b.GenerateVtableForVBases(RD, RD, IndirectPrimary);
diff --git a/test/CodeGenCXX/virt.cpp b/test/CodeGenCXX/virt.cpp
index 25d47ccf8e..95e98ac2fb 100644
--- a/test/CodeGenCXX/virt.cpp
+++ b/test/CodeGenCXX/virt.cpp
@@ -228,16 +228,16 @@ struct test5_D : virtual test5_B1, virtual test5_B21, virtual test5_B31 {
// CHECK-LP32-NEXT: .space 4
// CHECK-LP32-NEXT: .space 4
// CHECK-LP32-NEXT: .space 4
-// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT .space 4 FIXME
// CHECK-LP32: .long 4294967292
// CHECK-LP32-NEXT: .long __ZTI7test5_D
// CHECK-LP32-NEXT: .long __ZN9test5_B237funcB23Ev
// CHECK-LP32-NEXT: .long __ZN9test5_B227funcB22Ev
// CHECK-LP32-NEXT: .long __ZN9test5_B217funcB21Ev
// CHECK-LP32 .space 4
-// CHECK-LP32: .long 8
+// CHECK-LP32 .long 8 FIXME
// CHECK-LP32: .space 4
-// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT .space 4 FIXME
// CHECK-LP32: .long 4
// CHECK-LP32-NEXT: .space 4
// CHECK-LP32-NEXT: .space 4
@@ -280,16 +280,16 @@ struct test5_D : virtual test5_B1, virtual test5_B21, virtual test5_B31 {
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64-NEXT: .space 8
-// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT .space 8 FIXME
// CHECK-LP64: .quad 18446744073709551608
// CHECK-LP64-NEXT: .quad __ZTI7test5_D
// CHECK-LP64-NEXT: .quad __ZN9test5_B237funcB23Ev
// CHECK-LP64-NEXT: .quad __ZN9test5_B227funcB22Ev
// CHECK-LP64-NEXT: .quad __ZN9test5_B217funcB21Ev
// CHECK-LP64 .space 8
-// CHECK-LP64: .quad 16
+// CHECK-LP64 .quad 16 FIXME
// CHECK-LP64: .space 8
-// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT .space 8 FIXME
// CHECK-LP64: .quad 8
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64-NEXT: .space 8
@@ -337,7 +337,7 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
// CHECK-LP32-NEXT: .long 24
// CHECK-LP32-NEXT: .long 16
// CHECK-LP32-NEXT: .space 4
-// CHECK-LP32: .long __ZTI7test8_D
+// CHECK-LP32-NEXT: .long __ZTI7test8_D
// CHECK-LP32-NEXT: .long __ZN8test8_B19ftest8_B1Ev
// CHECK-LP32-NEXT: .long 20
// CHECK-LP32-NEXT: .long 12
@@ -345,10 +345,10 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
// CHECK-LP32-NEXT: .long __ZTI7test8_D
// CHECK-LP32-NEXT: .long __ZN9test8_B2a10ftest8_B2aEv
// CHECK-LP32-NEXT: .long __ZN8test8_B29ftest8_B2Ev
-// CHECK-LP32: .long 4294967288
+// CHECK-LP32-NEXT: .long 4294967288
// CHECK-LP32-NEXT: .long __ZTI7test8_D
// CHECK-LP32-NEXT: .long __ZN9test8_B2b10ftest8_B2bEv
-// CHECK-LP32: .long 4294967284
+// CHECK-LP32-NEXT: .long 4294967284
// CHECK-LP32-NEXT: .long __ZTI7test8_D
// CHECK-LP32-NEXT: .long __ZN8test8_B39ftest8_B3Ev
// CHECK-LP32-NEXT: .space 4
@@ -364,7 +364,7 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
// CHECK-LP64-NEXT: .quad 48
// CHECK-LP64-NEXT: .quad 32
// CHECK-LP64-NEXT: .space 8
-// CHECK-LP64: .quad __ZTI7test8_D
+// CHECK-LP64-NEXT: .quad __ZTI7test8_D
// CHECK-LP64-NEXT: .quad __ZN8test8_B19ftest8_B1Ev
// CHECK-LP64-NEXT: .quad 40
// CHECK-LP64-NEXT: .quad 24
@@ -372,10 +372,10 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
// CHECK-LP64-NEXT: .quad __ZTI7test8_D
// CHECK-LP64-NEXT: .quad __ZN9test8_B2a10ftest8_B2aEv
// CHECK-LP64-NEXT: .quad __ZN8test8_B29ftest8_B2Ev
-// CHECK-LP64: .quad 18446744073709551600
+// CHECK-LP64-NEXT: .quad 18446744073709551600
// CHECK-LP64-NEXT: .quad __ZTI7test8_D
// CHECK-LP64-NEXT: .quad __ZN9test8_B2b10ftest8_B2bEv
-// CHECK-LP64: .quad 18446744073709551592
+// CHECK-LP64-NEXT: .quad 18446744073709551592
// CHECK-LP64-NEXT: .quad __ZTI7test8_D
// CHECK-LP64-NEXT: .quad __ZN8test8_B39ftest8_B3Ev
// CHECK-LP64-NEXT: .space 8
@@ -390,37 +390,37 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
// CHECK-LP64: __ZTV1B:
-// CHECK-LP64: .space 8
-// CHECK-LP64: .quad __ZTI1B
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad __ZTI1B
// CHECK-LP64-NEXT: .quad __ZN1B4bar1Ev
// CHECK-LP64-NEXT: .quad __ZN1B4bar2Ev
// CHECK-LP32: __ZTV1B:
-// CHECK-LP32: .space 4
-// CHECK-LP32: .long __ZTI1B
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long __ZTI1B
// CHECK-LP32-NEXT: .long __ZN1B4bar1Ev
// CHECK-LP32-NEXT: .long __ZN1B4bar2Ev
// CHECK-LP64: __ZTV1A:
// CHECK-LP64-NEXT: .space 8
-// CHECK-LP64: .quad __ZTI1A
+// CHECK-LP64-NEXT: .quad __ZTI1A
// CHECK-LP64-NEXT: .quad __ZN1B4bar1Ev
// CHECK-LP64-NEXT: .quad __ZN1B4bar2Ev
// CHECK-LP64-NEXT: .quad __ZN1A4foo1Ev
// CHECK-LP64-NEXT: .quad __ZN1A4foo2Ev
-// CHECK-LP64: .quad 18446744073709551600
+// CHECK-LP64-NEXT: .quad 18446744073709551600
// CHECK-LP64-NEXT: .quad __ZTI1A
// CHECK-LP64-NEXT: .quad __ZN1C4bee1Ev
// CHECK-LP64-NEXT: .quad __ZN1C4bee2Ev
// CHECK-LP32: __ZTV1A:
// CHECK-LP32-NEXT: .space 4
-// CHECK-LP32: .long __ZTI1A
+// CHECK-LP32-NEXT: .long __ZTI1A
// CHECK-LP32-NEXT: .long __ZN1B4bar1Ev
// CHECK-LP32-NEXT: .long __ZN1B4bar2Ev
// CHECK-LP32-NEXT: .long __ZN1A4foo1Ev
// CHECK-LP32-NEXT: .long __ZN1A4foo2Ev
-// CHECK-LP32: .long 4294967284
+// CHECK-LP32-NEXT: .long 4294967284
// CHECK-LP32-NEXT: .long __ZTI1A
// CHECK-LP32-NEXT: .long __ZN1C4bee1Ev
// CHECK-LP32-NEXT: .long __ZN1C4bee2Ev
@@ -430,7 +430,7 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
// CHECK-LP32-NEXT: .long 8
// CHECK-LP32-NEXT: .space 4
// CHECK-LP32-NEXT: .space 4
-// CHECK-LP32: .long __ZTI1F
+// CHECK-LP32-NEXT: .long __ZTI1F
// CHECK-LP32-NEXT: .long __ZN1D3booEv
// CHECK-LP32-NEXT: .long __ZN1F3fooEv
// CHECK-LP32-NEXT: .space 4
@@ -451,7 +451,7 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
// CHECK-LP64-NEXT: .quad 16
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64-NEXT: .space 8
-// CHECK-LP64: .quad __ZTI1F
+// CHECK-LP64-NEXT: .quad __ZTI1F
// CHECK-LP64-NEXT: .quad __ZN1D3booEv
// CHECK-LP64-NEXT: .quad __ZN1F3fooEv
// CHECK-LP64-NEXT: .space 8