forked from OSchip/llvm-project
Generate more of the vbase virtual offset for covariant thunks. WIP.
llvm-svn: 82253
This commit is contained in:
parent
7e90c6db18
commit
f9c95be2f6
|
@ -768,6 +768,7 @@ private:
|
||||||
llvm::DenseMap<const CXXMethodDecl *, Index_t> Index;
|
llvm::DenseMap<const CXXMethodDecl *, Index_t> Index;
|
||||||
llvm::DenseMap<const CXXMethodDecl *, Index_t> VCall;
|
llvm::DenseMap<const CXXMethodDecl *, Index_t> VCall;
|
||||||
llvm::DenseMap<const CXXMethodDecl *, Index_t> VCallOffset;
|
llvm::DenseMap<const CXXMethodDecl *, Index_t> VCallOffset;
|
||||||
|
llvm::DenseMap<const CXXRecordDecl *, Index_t> VBIndex;
|
||||||
typedef std::pair<Index_t, Index_t> CallOffset;
|
typedef std::pair<Index_t, Index_t> CallOffset;
|
||||||
typedef llvm::DenseMap<const CXXMethodDecl *, CallOffset> Thunks_t;
|
typedef llvm::DenseMap<const CXXMethodDecl *, CallOffset> Thunks_t;
|
||||||
Thunks_t Thunks;
|
Thunks_t Thunks;
|
||||||
|
@ -792,6 +793,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::DenseMap<const CXXMethodDecl *, Index_t> &getIndex() { return Index; }
|
llvm::DenseMap<const CXXMethodDecl *, Index_t> &getIndex() { return Index; }
|
||||||
|
llvm::DenseMap<const CXXRecordDecl *, Index_t> &getVBIndex()
|
||||||
|
{ return VBIndex; }
|
||||||
|
|
||||||
llvm::Constant *wrap(Index_t i) {
|
llvm::Constant *wrap(Index_t i) {
|
||||||
llvm::Constant *m;
|
llvm::Constant *m;
|
||||||
|
@ -805,7 +808,7 @@ public:
|
||||||
|
|
||||||
void GenerateVBaseOffsets(std::vector<llvm::Constant *> &offsets,
|
void GenerateVBaseOffsets(std::vector<llvm::Constant *> &offsets,
|
||||||
const CXXRecordDecl *RD, uint64_t Offset) {
|
const CXXRecordDecl *RD, uint64_t Offset) {
|
||||||
for (CXXRecordDecl::base_class_const_iterator i =RD->bases_begin(),
|
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
|
||||||
e = RD->bases_end(); i != e; ++i) {
|
e = RD->bases_end(); i != e; ++i) {
|
||||||
const CXXRecordDecl *Base =
|
const CXXRecordDecl *Base =
|
||||||
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
|
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
|
||||||
|
@ -814,6 +817,8 @@ public:
|
||||||
int64_t BaseOffset = -(Offset/8) + BLayout.getVBaseClassOffset(Base)/8;
|
int64_t BaseOffset = -(Offset/8) + BLayout.getVBaseClassOffset(Base)/8;
|
||||||
llvm::Constant *m = wrap(BaseOffset);
|
llvm::Constant *m = wrap(BaseOffset);
|
||||||
m = wrap((0?700:0) + BaseOffset);
|
m = wrap((0?700:0) + BaseOffset);
|
||||||
|
VBIndex[Base] = -(offsets.size()*LLVMPointerWidth/8)
|
||||||
|
- 3*LLVMPointerWidth/8;
|
||||||
offsets.push_back(m);
|
offsets.push_back(m);
|
||||||
}
|
}
|
||||||
GenerateVBaseOffsets(offsets, Base, Offset);
|
GenerateVBaseOffsets(offsets, Base, Offset);
|
||||||
|
@ -824,6 +829,27 @@ public:
|
||||||
SeenVBase.clear();
|
SeenVBase.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Index_t VBlookup(CXXRecordDecl *D, CXXRecordDecl *B);
|
||||||
|
|
||||||
|
/// getVbaseOffset - Returns the index into the vtable for the virtual base
|
||||||
|
/// offset for the given (B) virtual base of the derived class D.
|
||||||
|
Index_t getVbaseOffset(QualType qB, QualType qD) {
|
||||||
|
qD = qD->getAs<PointerType>()->getPointeeType();
|
||||||
|
qB = qB->getAs<PointerType>()->getPointeeType();
|
||||||
|
CXXRecordDecl *D = cast<CXXRecordDecl>(qD->getAs<RecordType>()->getDecl());
|
||||||
|
CXXRecordDecl *B = cast<CXXRecordDecl>(qB->getAs<RecordType>()->getDecl());
|
||||||
|
if (D != Class)
|
||||||
|
return VBlookup(D, B);
|
||||||
|
llvm::DenseMap<const CXXRecordDecl *, Index_t>::iterator i;
|
||||||
|
i = VBIndex.find(B);
|
||||||
|
if (i != VBIndex.end())
|
||||||
|
return i->second;
|
||||||
|
// FIXME: temporal botch, is this data here, by the time we need it?
|
||||||
|
|
||||||
|
// FIXME: Locate the containing virtual base first.
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
|
||||||
bool OverrideMethod(const CXXMethodDecl *MD, llvm::Constant *m,
|
bool OverrideMethod(const CXXMethodDecl *MD, llvm::Constant *m,
|
||||||
bool MorallyVirtual, Index_t Offset) {
|
bool MorallyVirtual, Index_t Offset) {
|
||||||
typedef CXXMethodDecl::method_iterator meth_iter;
|
typedef CXXMethodDecl::method_iterator meth_iter;
|
||||||
|
@ -853,7 +879,7 @@ public:
|
||||||
CallOffset ReturnOffset = std::make_pair(0, 0);
|
CallOffset ReturnOffset = std::make_pair(0, 0);
|
||||||
if (oret != ret) {
|
if (oret != ret) {
|
||||||
// FIXME: calculate offsets for covariance
|
// FIXME: calculate offsets for covariance
|
||||||
ReturnOffset = std::make_pair(42,42);
|
ReturnOffset = std::make_pair(42,getVbaseOffset(oret, ret));
|
||||||
}
|
}
|
||||||
Index[MD] = i;
|
Index[MD] = i;
|
||||||
submethods[i] = m;
|
submethods[i] = m;
|
||||||
|
@ -1132,33 +1158,74 @@ private:
|
||||||
typedef llvm::DenseMap<const CXXRecordDecl *, ElTy *> MapTy;
|
typedef llvm::DenseMap<const CXXRecordDecl *, ElTy *> MapTy;
|
||||||
// FIXME: Move to Context.
|
// FIXME: Move to Context.
|
||||||
static MapTy IndexFor;
|
static MapTy IndexFor;
|
||||||
|
|
||||||
|
typedef llvm::DenseMap<const CXXRecordDecl *, Index_t> VBElTy;
|
||||||
|
typedef llvm::DenseMap<const CXXRecordDecl *, VBElTy *> VBMapTy;
|
||||||
|
// FIXME: Move to Context.
|
||||||
|
static VBMapTy VBIndexFor;
|
||||||
public:
|
public:
|
||||||
VtableInfo(CodeGenModule &cgm) : CGM(cgm) { }
|
VtableInfo(CodeGenModule &cgm) : CGM(cgm) { }
|
||||||
void register_index(const CXXRecordDecl *RD, const ElTy &e) {
|
void RegisterIndex(const CXXRecordDecl *RD, const ElTy &e) {
|
||||||
assert(IndexFor.find(RD) == IndexFor.end() && "Don't compute vtbl twice");
|
assert(IndexFor.find(RD) == IndexFor.end() && "Don't compute vtbl twice");
|
||||||
// We own a copy of this, it will go away shortly.
|
// We own a copy of this, it will go away shortly.
|
||||||
new ElTy (e);
|
|
||||||
IndexFor[RD] = new ElTy (e);
|
IndexFor[RD] = new ElTy (e);
|
||||||
}
|
}
|
||||||
|
void RegisterVBIndex(const CXXRecordDecl *RD, const VBElTy &e) {
|
||||||
|
assert(VBIndexFor.find(RD) == VBIndexFor.end() && "Don't compute vtbl twice");
|
||||||
|
// We own a copy of this, it will go away shortly.
|
||||||
|
VBIndexFor[RD] = new VBElTy (e);
|
||||||
|
}
|
||||||
Index_t lookup(const CXXMethodDecl *MD) {
|
Index_t lookup(const CXXMethodDecl *MD) {
|
||||||
const CXXRecordDecl *RD = MD->getParent();
|
const CXXRecordDecl *RD = MD->getParent();
|
||||||
MapTy::iterator I = IndexFor.find(RD);
|
MapTy::iterator I = IndexFor.find(RD);
|
||||||
if (I == IndexFor.end()) {
|
if (I == IndexFor.end()) {
|
||||||
std::vector<llvm::Constant *> methods;
|
std::vector<llvm::Constant *> methods;
|
||||||
|
// FIXME: This seems expensive. Can we do a partial job to get
|
||||||
|
// just this data.
|
||||||
VtableBuilder b(methods, RD, CGM);
|
VtableBuilder b(methods, RD, CGM);
|
||||||
b.GenerateVtableForBase(RD);
|
b.GenerateVtableForBase(RD);
|
||||||
b.GenerateVtableForVBases(RD);
|
b.GenerateVtableForVBases(RD);
|
||||||
register_index(RD, b.getIndex());
|
RegisterIndex(RD, b.getIndex());
|
||||||
I = IndexFor.find(RD);
|
I = IndexFor.find(RD);
|
||||||
}
|
}
|
||||||
assert(I->second->find(MD)!=I->second->end() && "Can't find vtable index");
|
assert(I->second->find(MD)!=I->second->end() && "Can't find vtable index");
|
||||||
return (*I->second)[MD];
|
return (*I->second)[MD];
|
||||||
}
|
}
|
||||||
|
Index_t VBlookup(const CXXRecordDecl *RD, const CXXRecordDecl *BD) {
|
||||||
|
VBMapTy::iterator I = VBIndexFor.find(RD);
|
||||||
|
if (I == VBIndexFor.end()) {
|
||||||
|
std::vector<llvm::Constant *> methods;
|
||||||
|
// FIXME: This seems expensive. Can we do a partial job to get
|
||||||
|
// just this data.
|
||||||
|
VtableBuilder b(methods, RD, CGM);
|
||||||
|
b.GenerateVtableForBase(RD);
|
||||||
|
b.GenerateVtableForVBases(RD);
|
||||||
|
RegisterVBIndex(RD, b.getVBIndex());
|
||||||
|
I = VBIndexFor.find(RD);
|
||||||
|
}
|
||||||
|
assert(I->second->find(BD)!=I->second->end() && "Can't find vtable index");
|
||||||
|
return (*I->second)[BD];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// FIXME: move to Context
|
||||||
|
static VtableInfo *vtableinfo;
|
||||||
|
|
||||||
|
VtableBuilder::Index_t VtableBuilder::VBlookup(CXXRecordDecl *D,
|
||||||
|
CXXRecordDecl *B) {
|
||||||
|
if (vtableinfo == 0)
|
||||||
|
vtableinfo = new VtableInfo(CGM);
|
||||||
|
|
||||||
|
return vtableinfo->VBlookup(D, B);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// FIXME: Move to Context.
|
// FIXME: Move to Context.
|
||||||
VtableInfo::MapTy VtableInfo::IndexFor;
|
VtableInfo::MapTy VtableInfo::IndexFor;
|
||||||
|
|
||||||
|
// FIXME: Move to Context.
|
||||||
|
VtableInfo::VBMapTy VtableInfo::VBIndexFor;
|
||||||
|
|
||||||
llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
|
llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
|
||||||
llvm::SmallString<256> OutName;
|
llvm::SmallString<256> OutName;
|
||||||
llvm::raw_svector_ostream Out(OutName);
|
llvm::raw_svector_ostream Out(OutName);
|
||||||
|
@ -1191,9 +1258,6 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
|
||||||
return vtable;
|
return vtable;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: move to Context
|
|
||||||
static VtableInfo *vtableinfo;
|
|
||||||
|
|
||||||
llvm::Constant *CodeGenFunction::GenerateThunk(llvm::Function *Fn,
|
llvm::Constant *CodeGenFunction::GenerateThunk(llvm::Function *Fn,
|
||||||
const CXXMethodDecl *MD,
|
const CXXMethodDecl *MD,
|
||||||
bool Extern, int64_t nv,
|
bool Extern, int64_t nv,
|
||||||
|
|
Loading…
Reference in New Issue