aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGVtable.cpp
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-11-12 22:56:32 +0000
committerMike Stump <mrs@apple.com>2009-11-12 22:56:32 +0000
commit28f7ce14ddbc1ba835615df8e4d42648a524b4c1 (patch)
tree9c176de5a19b61c38f99f8be19365d150b3b55d5 /lib/CodeGen/CGVtable.cpp
parentc0213f2691aed7c3f8f252e073b0b3913ee1c33c (diff)
Refine vtable pointers for secondary vtables inside VTTs to point to
the right base vtable. WIP. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@87039 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGVtable.cpp')
-rw-r--r--lib/CodeGen/CGVtable.cpp51
1 files changed, 32 insertions, 19 deletions
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp
index 0844f52f2b..0a413bad18 100644
--- a/lib/CodeGen/CGVtable.cpp
+++ b/lib/CodeGen/CGVtable.cpp
@@ -770,10 +770,26 @@ class VTTBuilder {
llvm::Constant *ClassVtbl;
llvm::LLVMContext &VMContext;
+ /// BuildVtablePtr - Build up a referene to the given secondary vtable
+ llvm::Constant *BuildVtablePtr(llvm::Constant *vtbl, const CXXRecordDecl *RD,
+ uint64_t Offset) {
+ int64_t AddressPoint;
+ AddressPoint = (*CGM.AddressPoints[Class])[std::make_pair(RD, Offset)];
+ D1(printf("XXX address point for %s in %s at offset %d was %d\n",
+ RD->getNameAsCString(), Class->getNameAsCString(),
+ (int)Offset, (int)AddressPoint));
+ uint32_t LLVMPointerWidth = CGM.getContext().Target.getPointerWidth(0);
+ llvm::Constant *init;
+ init = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
+ AddressPoint*LLVMPointerWidth/8);
+ init = llvm::ConstantExpr::getInBoundsGetElementPtr(vtbl, &init, 1);
+ return init;
+ }
+
/// Secondary - Add the secondary vtable pointers to Inits. Offset is the
/// current offset in bits to the object we're working on.
- void Secondary(const CXXRecordDecl *RD, uint64_t Offset=0,
- bool MorallyVirtual=false) {
+ void Secondary(const CXXRecordDecl *RD, llvm::Constant *vtbl,
+ uint64_t Offset=0, bool MorallyVirtual=false) {
if (RD->getNumVBases() == 0 && ! MorallyVirtual)
return;
@@ -796,11 +812,15 @@ class VTTBuilder {
if ((Base->getNumVBases() || BaseMorallyVirtual)
&& !NonVirtualPrimaryBase) {
// FIXME: Slightly too many of these for __ZTT8test8_B2
- llvm::Constant *vtbl;
- vtbl = CGM.getVtableInfo().getCtorVtable(Class, Base, BaseOffset);
- Inits.push_back(vtbl);
+ llvm::Constant *init;
+ if (MorallyVirtual)
+ init = BuildVtablePtr(vtbl, RD, Offset);
+ else
+ init = CGM.getVtableInfo().getCtorVtable(Class, Base, BaseOffset);
+ Inits.push_back(init);
+ // vtbl = dyn_cast<llvm::Constant>(init->getOperand(0));
}
- Secondary(Base, BaseOffset, BaseMorallyVirtual);
+ Secondary(Base, vtbl, BaseOffset, BaseMorallyVirtual);
}
}
@@ -812,25 +832,18 @@ class VTTBuilder {
llvm::Constant *init;
// First comes the primary virtual table pointer...
- if (MorallyVirtual) {
- int64_t AddressPoint;
- AddressPoint = (*CGM.AddressPoints[Class])[std::make_pair(RD, Offset)];
- D1(printf("XXX address point for %s in %s at offset %d was %d\n",
- RD->getNameAsCString(), Class->getNameAsCString(),
- (int)Offset, (int)AddressPoint));
- uint32_t LLVMPointerWidth = CGM.getContext().Target.getPointerWidth(0);
- init = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
- AddressPoint*LLVMPointerWidth/8);
- init = llvm::ConstantExpr::getInBoundsGetElementPtr(ClassVtbl, &init, 1);
- } else
+ if (MorallyVirtual)
+ init = BuildVtablePtr(ClassVtbl, RD, Offset);
+ else
init = CGM.getVtableInfo().getCtorVtable(Class, RD, Offset);
+ llvm::Constant *vtbl = dyn_cast<llvm::Constant>(init->getOperand(0));
Inits.push_back(init);
// then the secondary VTTs....
SecondaryVTTs(RD, Offset, MorallyVirtual);
// and last the secondary vtable pointers.
- Secondary(RD, MorallyVirtual, Offset);
+ Secondary(RD, vtbl, MorallyVirtual, Offset);
}
/// SecondaryVTTs - Add the secondary VTTs to Inits. The secondary VTTs are
@@ -881,7 +894,7 @@ public:
SecondaryVTTs(Class);
// then the secondary vtable pointers...
- Secondary(Class);
+ Secondary(Class, ClassVtbl);
// and last, the virtual VTTs.
VirtualVTTs(Class);