aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGCXX.cpp
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-09-05 11:28:33 +0000
committerMike Stump <mrs@apple.com>2009-09-05 11:28:33 +0000
commit98cc71003d385561224e3711cd34c5b03f27ccdc (patch)
tree83f9bba4b59ab107986d7a9b1e33c41b556ef08e /lib/CodeGen/CGCXX.cpp
parent458fb10ef5ba2d7b375c6c64095c1458af0a5be3 (diff)
Refine overrides and thunks for virtual bases. Cleanups. WIP.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81080 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCXX.cpp')
-rw-r--r--lib/CodeGen/CGCXX.cpp66
1 files changed, 41 insertions, 25 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 106f95edc0..22ff22e22e 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -963,27 +963,32 @@ public:
return false;
}
- void InstallThunks(Index_t AddressPoint) {
+ void InstallThunks() {
for (Thunks_t::iterator i = Thunks.begin(), e = Thunks.end();
i != e; ++i) {
const CXXMethodDecl *MD = i->first;
Index_t idx = Index[MD];
Index_t nv_O = i->second.first;
Index_t v_O = i->second.second;
- methods[AddressPoint + idx] = CGM.BuildThunk(MD, Extern, nv_O, v_O);
+ submethods[idx] = CGM.BuildThunk(MD, Extern, nv_O, v_O);
}
Thunks.clear();
}
- void OverrideMethods(const CXXRecordDecl *RD, Index_t AddressPoint,
+ void OverrideMethods(std::vector<const CXXRecordDecl *> *Path,
bool MorallyVirtual, Index_t Offset) {
- for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
- ++mi)
- if (mi->isVirtual()) {
- const CXXMethodDecl *MD = *mi;
- llvm::Constant *m = wrap(CGM.GetAddrOfFunction(GlobalDecl(MD), Ptr8Ty));
- OverrideMethod(MD, m, MorallyVirtual, Offset, methods, AddressPoint);
- }
+ for (std::vector<const CXXRecordDecl *>::reverse_iterator i =Path->rbegin(),
+ e = Path->rend(); i != e; ++i) {
+ const CXXRecordDecl *RD = *i;
+ for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
+ ++mi)
+ if (mi->isVirtual()) {
+ const CXXMethodDecl *MD = *mi;
+ llvm::Constant *m = wrap(CGM.GetAddrOfFunction(GlobalDecl(MD),
+ Ptr8Ty));
+ OverrideMethod(MD, m, MorallyVirtual, Offset, submethods, 0);
+ }
+ }
}
void AddMethod(const CXXMethodDecl *MD, bool MorallyVirtual, Index_t Offset) {
@@ -1027,10 +1032,9 @@ public:
if (Base != PrimaryBase || PrimaryBaseWasVirtual) {
uint64_t o = Offset + Layout.getBaseClassOffset(Base);
StartNewTable();
- Index_t AP;
- AP = GenerateVtableForBase(Base, MorallyVirtual, o, false, RD);
- OverrideMethods(RD, AP, MorallyVirtual, o);
- InstallThunks(AP);
+ std::vector<const CXXRecordDecl *> S;
+ S.push_back(RD);
+ GenerateVtableForBase(Base, MorallyVirtual, o, false, &S);
}
}
}
@@ -1067,9 +1071,9 @@ public:
methods.push_back(rtti);
Index_t AddressPoint = methods.size();
+ InstallThunks();
methods.insert(methods.end(), submethods.begin(), submethods.end());
submethods.clear();
- InstallThunks(AddressPoint);
// and then the non-virtual bases.
NonVirtualBases(RD, Layout, PrimaryBase, PrimaryBaseWasVirtual,
@@ -1099,7 +1103,7 @@ public:
int64_t GenerateVtableForBase(const CXXRecordDecl *RD,
bool MorallyVirtual = false, int64_t Offset = 0,
bool ForVirtualBase = false,
- const CXXRecordDecl *FinalD = 0) {
+ std::vector<const CXXRecordDecl *> *Path = 0) {
if (!RD->isDynamicClass())
return 0;
@@ -1123,11 +1127,23 @@ public:
// And add the virtuals for the class to the primary vtable.
AddMethods(RD, MorallyVirtual, Offset);
+ if (Path)
+ OverrideMethods(Path, MorallyVirtual, Offset);
+
return end(RD, offsets, Layout, PrimaryBase, PrimaryBaseWasVirtual,
MorallyVirtual, Offset, ForVirtualBase);
}
- void GenerateVtableForVBases(const CXXRecordDecl *RD) {
+ void GenerateVtableForVBases(const CXXRecordDecl *RD,
+ std::vector<const CXXRecordDecl *> *Path = 0) {
+ bool alloc = false;
+ if (Path == 0) {
+ alloc = true;
+ Path = new std::vector<const CXXRecordDecl *>;
+ }
+ // FIXME: We also need to override using all paths to a virtual base,
+ // right now, we just process the first path
+ Path->push_back(RD);
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
e = RD->bases_end(); i != e; ++i) {
const CXXRecordDecl *Base =
@@ -1137,14 +1153,14 @@ public:
IndirectPrimary.insert(Base);
StartNewTable();
int64_t BaseOffset = BLayout.getVBaseClassOffset(Base);
- Index_t AP;
- AP = GenerateVtableForBase(Base, true, BaseOffset, true, RD);
- OverrideMethods(RD, AP, true, BaseOffset);
- InstallThunks(AP);
+ GenerateVtableForBase(Base, true, BaseOffset, true, Path);
}
if (Base->getNumVBases())
- GenerateVtableForVBases(Base);
+ GenerateVtableForVBases(Base, Path);
}
+ Path->pop_back();
+ if (alloc)
+ delete Path;
}
};
@@ -1195,12 +1211,12 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
linktype = llvm::GlobalValue::WeakAnyLinkage;
std::vector<llvm::Constant *> methods;
llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0);
- int64_t Offset;
+ int64_t AddressPoint;
VtableBuilder b(methods, RD, CGM);
// First comes the vtables for all the non-virtual bases...
- Offset = b.GenerateVtableForBase(RD);
+ AddressPoint = b.GenerateVtableForBase(RD);
// then the vtables for all the virtual bases.
b.GenerateVtableForVBases(RD);
@@ -1213,7 +1229,7 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
vtable = Builder.CreateBitCast(vtable, Ptr8Ty);
vtable = Builder.CreateGEP(vtable,
llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
- Offset*LLVMPointerWidth/8));
+ AddressPoint*LLVMPointerWidth/8));
return vtable;
}