forked from OSchip/llvm-project
Work in progress for setting the vtable pointers for all bases correctly in
the constructor. This doesn't handle cases requiring the VTT at the moment, and generates unnecessary stores, but I think it's essentially correct. llvm-svn: 91731
This commit is contained in:
parent
726b878574
commit
70724ad2ff
|
@ -1700,21 +1700,65 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
|
|||
void CodeGenFunction::InitializeVtablePtrs(const CXXRecordDecl *ClassDecl) {
|
||||
if (!ClassDecl->isDynamicClass())
|
||||
return;
|
||||
|
||||
// Initialize the vtable pointer.
|
||||
// FIXME: This needs to initialize secondary vtable pointers too.
|
||||
llvm::Value *ThisPtr = LoadCXXThis();
|
||||
|
||||
llvm::Constant *Vtable = CGM.getVtableInfo().getVtable(ClassDecl);
|
||||
uint64_t AddressPoint = CGM.getVtableInfo().getVtableAddressPoint(ClassDecl);
|
||||
CodeGenModule::AddrSubMap_t& AddressPoints =
|
||||
*(*CGM.AddressPoints[ClassDecl])[ClassDecl];
|
||||
llvm::Value *ThisPtr = LoadCXXThis();
|
||||
const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl);
|
||||
|
||||
// Store address points for virtual bases
|
||||
for (CXXRecordDecl::base_class_const_iterator I =
|
||||
ClassDecl->vbases_begin(), E = ClassDecl->vbases_end(); I != E; ++I) {
|
||||
const CXXBaseSpecifier &Base = *I;
|
||||
CXXRecordDecl *BaseClassDecl
|
||||
= cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
|
||||
uint64_t Offset = Layout.getVBaseClassOffset(BaseClassDecl);
|
||||
InitializeVtablePtrsRecursive(BaseClassDecl, Vtable, AddressPoints,
|
||||
ThisPtr, Offset);
|
||||
}
|
||||
|
||||
// Store address points for non-virtual bases and current class
|
||||
InitializeVtablePtrsRecursive(ClassDecl, Vtable, AddressPoints, ThisPtr, 0);
|
||||
}
|
||||
|
||||
void CodeGenFunction::InitializeVtablePtrsRecursive(
|
||||
const CXXRecordDecl *ClassDecl,
|
||||
llvm::Constant *Vtable,
|
||||
CodeGenModule::AddrSubMap_t& AddressPoints,
|
||||
llvm::Value *ThisPtr,
|
||||
uint64_t Offset) {
|
||||
if (!ClassDecl->isDynamicClass())
|
||||
return;
|
||||
|
||||
// Store address points for non-virtual bases
|
||||
const ASTRecordLayout &Layout = getContext().getASTRecordLayout(ClassDecl);
|
||||
for (CXXRecordDecl::base_class_const_iterator I =
|
||||
ClassDecl->bases_begin(), E = ClassDecl->bases_end(); I != E; ++I) {
|
||||
const CXXBaseSpecifier &Base = *I;
|
||||
if (Base.isVirtual())
|
||||
continue;
|
||||
CXXRecordDecl *BaseClassDecl
|
||||
= cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
|
||||
uint64_t NewOffset = Offset + Layout.getBaseClassOffset(BaseClassDecl);
|
||||
InitializeVtablePtrsRecursive(BaseClassDecl, Vtable, AddressPoints,
|
||||
ThisPtr, NewOffset);
|
||||
}
|
||||
|
||||
// Compute the address point
|
||||
uint64_t AddressPoint = AddressPoints[std::make_pair(ClassDecl, Offset)];
|
||||
llvm::Value *VtableAddressPoint =
|
||||
Builder.CreateConstInBoundsGEP2_64(Vtable, 0, AddressPoint);
|
||||
|
||||
llvm::Value *VtableField =
|
||||
Builder.CreateBitCast(ThisPtr,
|
||||
VtableAddressPoint->getType()->getPointerTo());
|
||||
|
||||
Builder.CreateConstInBoundsGEP2_64(Vtable, 0, AddressPoint);
|
||||
|
||||
// Compute the address to store the address point
|
||||
const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
|
||||
llvm::Value *VtableField = Builder.CreateBitCast(ThisPtr, Int8PtrTy);
|
||||
VtableField = Builder.CreateConstInBoundsGEP1_64(VtableField, Offset/8);
|
||||
const llvm::Type *AddressPointPtrTy =
|
||||
VtableAddressPoint->getType()->getPointerTo();
|
||||
VtableField = Builder.CreateBitCast(ThisPtr, AddressPointPtrTy);
|
||||
|
||||
// Store address point
|
||||
Builder.CreateStore(VtableAddressPoint, VtableField);
|
||||
}
|
||||
|
||||
|
|
|
@ -515,6 +515,12 @@ public:
|
|||
|
||||
void InitializeVtablePtrs(const CXXRecordDecl *ClassDecl);
|
||||
|
||||
void InitializeVtablePtrsRecursive(const CXXRecordDecl *ClassDecl,
|
||||
llvm::Constant *Vtable,
|
||||
CodeGenModule::AddrSubMap_t& AddressPoints,
|
||||
llvm::Value *ThisPtr,
|
||||
uint64_t Offset);
|
||||
|
||||
void SynthesizeCXXCopyConstructor(const CXXConstructorDecl *Ctor,
|
||||
CXXCtorType Type,
|
||||
llvm::Function *Fn,
|
||||
|
|
|
@ -233,8 +233,8 @@ public:
|
|||
const CovariantThunkAdjustment &Adjustment);
|
||||
|
||||
typedef std::pair<const CXXRecordDecl *, uint64_t> CtorVtable_t;
|
||||
typedef llvm::DenseMap<const CXXRecordDecl *,
|
||||
llvm::DenseMap<CtorVtable_t, int64_t>*> AddrMap_t;
|
||||
typedef llvm::DenseMap<CtorVtable_t, int64_t> AddrSubMap_t;
|
||||
typedef llvm::DenseMap<const CXXRecordDecl *, AddrSubMap_t *> AddrMap_t;
|
||||
llvm::DenseMap<const CXXRecordDecl *, AddrMap_t*> AddressPoints;
|
||||
|
||||
/// GetCXXBaseClassOffset - Returns the offset from a derived class to its
|
||||
|
|
Loading…
Reference in New Issue