aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGVtable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGVtable.cpp')
-rw-r--r--lib/CodeGen/CGVtable.cpp58
1 files changed, 30 insertions, 28 deletions
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp
index bca893e5b6..7efa88b8e1 100644
--- a/lib/CodeGen/CGVtable.cpp
+++ b/lib/CodeGen/CGVtable.cpp
@@ -26,6 +26,9 @@ class VtableBuilder {
public:
/// Index_t - Vtable index type.
typedef uint64_t Index_t;
+ typedef std::vector<std::pair<GlobalDecl,
+ std::pair<GlobalDecl, ThunkAdjustment> > >
+ SavedAdjustmentsVectorTy;
private:
// VtableComponents - The components of the vtable being built.
@@ -142,9 +145,7 @@ private:
typedef llvm::DenseMap<uint64_t, ThunkAdjustment> ThisAdjustmentsMapTy;
ThisAdjustmentsMapTy ThisAdjustments;
- typedef std::vector<std::pair<std::pair<GlobalDecl, GlobalDecl>,
- ThunkAdjustment> > SavedThisAdjustmentsVectorTy;
- SavedThisAdjustmentsVectorTy SavedThisAdjustments;
+ SavedAdjustmentsVectorTy SavedAdjustments;
/// BaseReturnTypes - Contains the base return types of methods who have been
/// overridden with methods whose return types require adjustment. Used for
@@ -213,8 +214,8 @@ public:
llvm::DenseMap<const CXXRecordDecl *, Index_t> &getVBIndex()
{ return VBIndex; }
- SavedThisAdjustmentsVectorTy &getSavedThisAdjustments()
- { return SavedThisAdjustments; }
+ SavedAdjustmentsVectorTy &getSavedAdjustments()
+ { return SavedAdjustments; }
llvm::Constant *wrap(Index_t i) {
llvm::Constant *m;
@@ -376,8 +377,9 @@ public:
D1(printf(" vfn for %s at %d\n", MD->getNameAsString().c_str(),
(int)Index[GD]));
+
+ VCallOffset[GD] = Offset/8;
if (MorallyVirtual) {
- VCallOffset[GD] = Offset/8;
Index_t &idx = VCall[GD];
// Allocate the first one, after that, we reuse the previous one.
if (idx == 0) {
@@ -838,22 +840,21 @@ bool VtableBuilder::OverrideMethod(GlobalDecl GD, bool MorallyVirtual,
if (!isPure && !ThisAdjustment.isEmpty()) {
ThisAdjustments[Index] = ThisAdjustment;
- SavedThisAdjustments.push_back(std::make_pair(std::make_pair(GD, OGD),
- ThisAdjustment));
+ SavedAdjustments.push_back(
+ std::make_pair(GD, std::make_pair(OGD, ThisAdjustment)));
}
return true;
}
- // FIXME: finish off
- int64_t NonVirtualAdjustment = VCallOffset[OGD] - OverrideOffset/8;
+ int64_t NonVirtualAdjustment = -VCallOffset[OGD] + OverrideOffset/8;
if (NonVirtualAdjustment) {
ThunkAdjustment ThisAdjustment(NonVirtualAdjustment, 0);
if (!isPure) {
ThisAdjustments[Index] = ThisAdjustment;
- SavedThisAdjustments.push_back(std::make_pair(std::make_pair(GD, OGD),
- ThisAdjustment));
+ SavedAdjustments.push_back(
+ std::make_pair(GD, std::make_pair(OGD, ThisAdjustment)));
}
}
return true;
@@ -1070,30 +1071,31 @@ uint64_t CGVtableInfo::getMethodVtableIndex(GlobalDecl GD) {
return I->second;
}
-ThunkAdjustment CGVtableInfo::getThisAdjustment(GlobalDecl GD,
- GlobalDecl OGD) {
- SavedThisAdjustmentsTy::iterator I =
- SavedThisAdjustments.find(std::make_pair(GD, OGD));
- if (I != SavedThisAdjustments.end())
- return I->second;
+CGVtableInfo::AdjustmentVectorTy*
+CGVtableInfo::getAdjustments(GlobalDecl GD) {
+ SavedAdjustmentsTy::iterator I = SavedAdjustments.find(GD);
+ if (I != SavedAdjustments.end())
+ return &I->second;
const CXXRecordDecl *RD = cast<CXXRecordDecl>(GD.getDecl()->getDeclContext());
- if (!SavedThisAdjustmentRecords.insert(RD).second)
- return ThunkAdjustment();
+ if (!SavedAdjustmentRecords.insert(RD).second)
+ return 0;
VtableBuilder b(RD, RD, 0, CGM, false);
D1(printf("vtable %s\n", RD->getNameAsCString()));
b.GenerateVtableForBase(RD);
b.GenerateVtableForVBases(RD);
-
- SavedThisAdjustments.insert(b.getSavedThisAdjustments().begin(),
- b.getSavedThisAdjustments().end());
- I = SavedThisAdjustments.find(std::make_pair(GD, OGD));
- if (I != SavedThisAdjustments.end())
- return I->second;
+ for (VtableBuilder::SavedAdjustmentsVectorTy::iterator
+ i = b.getSavedAdjustments().begin(),
+ e = b.getSavedAdjustments().end(); i != e; i++)
+ SavedAdjustments[i->first].push_back(i->second);
+
+ I = SavedAdjustments.find(GD);
+ if (I != SavedAdjustments.end())
+ return &I->second;
- return ThunkAdjustment();
+ return 0;
}
int64_t CGVtableInfo::getVirtualBaseOffsetIndex(const CXXRecordDecl *RD,
@@ -1470,7 +1472,7 @@ void CGVtableInfo::MaybeEmitVtable(GlobalDecl GD) {
for (CXXRecordDecl::method_iterator i = RD->method_begin(),
e = RD->method_end(); i != e; ++i) {
- if ((*i)->isVirtual() && (*i)->hasInlineBody()) {
+ if ((*i)->isVirtual() && ((*i)->hasInlineBody() || (*i)->isImplicit())) {
if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(*i)) {
CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Complete));
CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Deleting));