[cfe-commits] r82253 - /cfe/trunk/lib/CodeGen/CGCXX.cpp
Mike Stump
mrs at apple.com
Fri Sep 18 12:06:36 PDT 2009
Author: mrs
Date: Fri Sep 18 14:06:35 2009
New Revision: 82253
URL: http://llvm.org/viewvc/llvm-project?rev=82253&view=rev
Log:
Generate more of the vbase virtual offset for covariant thunks. WIP.
Modified:
cfe/trunk/lib/CodeGen/CGCXX.cpp
Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=82253&r1=82252&r2=82253&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Fri Sep 18 14:06:35 2009
@@ -768,6 +768,7 @@
llvm::DenseMap<const CXXMethodDecl *, Index_t> Index;
llvm::DenseMap<const CXXMethodDecl *, Index_t> VCall;
llvm::DenseMap<const CXXMethodDecl *, Index_t> VCallOffset;
+ llvm::DenseMap<const CXXRecordDecl *, Index_t> VBIndex;
typedef std::pair<Index_t, Index_t> CallOffset;
typedef llvm::DenseMap<const CXXMethodDecl *, CallOffset> Thunks_t;
Thunks_t Thunks;
@@ -792,6 +793,8 @@
}
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 *m;
@@ -805,7 +808,7 @@
void GenerateVBaseOffsets(std::vector<llvm::Constant *> &offsets,
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) {
const CXXRecordDecl *Base =
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
@@ -814,6 +817,8 @@
int64_t BaseOffset = -(Offset/8) + BLayout.getVBaseClassOffset(Base)/8;
llvm::Constant *m = wrap(BaseOffset);
m = wrap((0?700:0) + BaseOffset);
+ VBIndex[Base] = -(offsets.size()*LLVMPointerWidth/8)
+ - 3*LLVMPointerWidth/8;
offsets.push_back(m);
}
GenerateVBaseOffsets(offsets, Base, Offset);
@@ -824,6 +829,27 @@
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 MorallyVirtual, Index_t Offset) {
typedef CXXMethodDecl::method_iterator meth_iter;
@@ -853,7 +879,7 @@
CallOffset ReturnOffset = std::make_pair(0, 0);
if (oret != ret) {
// FIXME: calculate offsets for covariance
- ReturnOffset = std::make_pair(42,42);
+ ReturnOffset = std::make_pair(42,getVbaseOffset(oret, ret));
}
Index[MD] = i;
submethods[i] = m;
@@ -1132,33 +1158,74 @@
typedef llvm::DenseMap<const CXXRecordDecl *, ElTy *> MapTy;
// FIXME: Move to Context.
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:
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");
// We own a copy of this, it will go away shortly.
- 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) {
const CXXRecordDecl *RD = MD->getParent();
MapTy::iterator I = IndexFor.find(RD);
if (I == IndexFor.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);
- register_index(RD, b.getIndex());
+ RegisterIndex(RD, b.getIndex());
I = IndexFor.find(RD);
}
assert(I->second->find(MD)!=I->second->end() && "Can't find vtable index");
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.
VtableInfo::MapTy VtableInfo::IndexFor;
+// FIXME: Move to Context.
+VtableInfo::VBMapTy VtableInfo::VBIndexFor;
+
llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
llvm::SmallString<256> OutName;
llvm::raw_svector_ostream Out(OutName);
@@ -1191,9 +1258,6 @@
return vtable;
}
-// FIXME: move to Context
-static VtableInfo *vtableinfo;
-
llvm::Constant *CodeGenFunction::GenerateThunk(llvm::Function *Fn,
const CXXMethodDecl *MD,
bool Extern, int64_t nv,
More information about the cfe-commits
mailing list