[cfe-commits] r81080 - /cfe/trunk/lib/CodeGen/CGCXX.cpp
Mike Stump
mrs at apple.com
Sat Sep 5 04:28:35 PDT 2009
Author: mrs
Date: Sat Sep 5 06:28:33 2009
New Revision: 81080
URL: http://llvm.org/viewvc/llvm-project?rev=81080&view=rev
Log:
Refine overrides and thunks for virtual bases. Cleanups. 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=81080&r1=81079&r2=81080&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Sat Sep 5 06:28:33 2009
@@ -963,27 +963,32 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
vtable = Builder.CreateBitCast(vtable, Ptr8Ty);
vtable = Builder.CreateGEP(vtable,
llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
- Offset*LLVMPointerWidth/8));
+ AddressPoint*LLVMPointerWidth/8));
return vtable;
}
More information about the cfe-commits
mailing list