Cleanups. WIP.

llvm-svn: 81069
This commit is contained in:
Mike Stump 2009-09-05 07:49:12 +00:00
parent 1b4ebfab2b
commit 001ad31c9a
1 changed files with 53 additions and 50 deletions

View File

@ -986,8 +986,7 @@ public:
} }
} }
void AddMethod(const CXXMethodDecl *MD, Index_t AddressPoint, void AddMethod(const CXXMethodDecl *MD, bool MorallyVirtual, Index_t Offset) {
bool MorallyVirtual, Index_t Offset) {
llvm::Constant *m = wrap(CGM.GetAddrOfFunction(GlobalDecl(MD), Ptr8Ty)); llvm::Constant *m = wrap(CGM.GetAddrOfFunction(GlobalDecl(MD), Ptr8Ty));
// If we can find a previously allocated slot for this, reuse it. // If we can find a previously allocated slot for this, reuse it.
if (OverrideMethod(MD, m, MorallyVirtual, Offset, submethods, 0)) if (OverrideMethod(MD, m, MorallyVirtual, Offset, submethods, 0))
@ -1007,12 +1006,12 @@ public:
submethods.push_back(m); submethods.push_back(m);
} }
void AddMethods(const CXXRecordDecl *RD, Index_t AddressPoint, void AddMethods(const CXXRecordDecl *RD, bool MorallyVirtual,
bool MorallyVirtual, Index_t Offset) { Index_t Offset) {
for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me; for (method_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
++mi) ++mi)
if (mi->isVirtual()) if (mi->isVirtual())
AddMethod(*mi, AddressPoint, MorallyVirtual, Offset); AddMethod(*mi, MorallyVirtual, Offset);
} }
void NonVirtualBases(const CXXRecordDecl *RD, const ASTRecordLayout &Layout, void NonVirtualBases(const CXXRecordDecl *RD, const ASTRecordLayout &Layout,
@ -1036,12 +1035,51 @@ public:
} }
} }
Index_t end(const CXXRecordDecl *RD, std::vector<llvm::Constant *> &offsets,
const ASTRecordLayout &Layout,
const CXXRecordDecl *PrimaryBase,
bool PrimaryBaseWasVirtual, bool MorallyVirtual,
int64_t Offset, bool ForVirtualBase) {
StartNewTable();
extra = 0;
// FIXME: Cleanup.
if (!ForVirtualBase) {
// then virtual base offsets...
for (std::vector<llvm::Constant *>::reverse_iterator i = offsets.rbegin(),
e = offsets.rend(); i != e; ++i)
methods.push_back(*i);
}
// The vcalls come first...
for (std::vector<Index_t>::iterator i=VCalls.begin(), e=VCalls.end();
i < e; ++i)
methods.push_back(wrap((0?600:0) + *i));
VCalls.clear();
if (ForVirtualBase) {
// then virtual base offsets...
for (std::vector<llvm::Constant *>::reverse_iterator i = offsets.rbegin(),
e = offsets.rend(); i != e; ++i)
methods.push_back(*i);
}
methods.push_back(wrap(-(Offset/8)));
methods.push_back(rtti);
Index_t AddressPoint = methods.size();
methods.insert(methods.end(), submethods.begin(), submethods.end());
submethods.clear();
InstallThunks(AddressPoint);
// and then the non-virtual bases.
NonVirtualBases(RD, Layout, PrimaryBase, PrimaryBaseWasVirtual,
MorallyVirtual, Offset);
return AddressPoint;
}
int64_t GenerateVtableForBase(const CXXRecordDecl *RD, bool forPrimary, int64_t GenerateVtableForBase(const CXXRecordDecl *RD, bool forPrimary,
bool Bottom, bool MorallyVirtual, bool Bottom, bool MorallyVirtual,
int64_t Offset, bool ForVirtualBase) { int64_t Offset, bool ForVirtualBase) {
llvm::Constant *m = llvm::Constant::getNullValue(Ptr8Ty);
int64_t AddressPoint=0;
if (RD && !RD->isDynamicClass()) if (RD && !RD->isDynamicClass())
return 0; return 0;
@ -1066,53 +1104,18 @@ public:
if (PrimaryBaseWasVirtual) if (PrimaryBaseWasVirtual)
IndirectPrimary.insert(PrimaryBase); IndirectPrimary.insert(PrimaryBase);
Top = false; Top = false;
AddressPoint = GenerateVtableForBase(PrimaryBase, true, false, GenerateVtableForBase(PrimaryBase, true, false,
PrimaryBaseWasVirtual|MorallyVirtual, PrimaryBaseWasVirtual|MorallyVirtual, Offset,
Offset, PrimaryBaseWasVirtual); PrimaryBaseWasVirtual);
} }
// And add the virtuals for the class to the primary vtable. // And add the virtuals for the class to the primary vtable.
AddMethods(RD, AddressPoint, MorallyVirtual, Offset); AddMethods(RD, MorallyVirtual, Offset);
if (!Bottom) if (!Bottom)
return AddressPoint; return 0;
return end(RD, offsets, Layout, PrimaryBase, PrimaryBaseWasVirtual,
StartNewTable(); MorallyVirtual, Offset, ForVirtualBase);
extra = 0;
// FIXME: Cleanup.
if (!ForVirtualBase) {
// then virtual base offsets...
for (std::vector<llvm::Constant *>::reverse_iterator i = offsets.rbegin(),
e = offsets.rend(); i != e; ++i)
methods.push_back(*i);
}
// The vcalls come first...
for (std::vector<Index_t>::iterator i=VCalls.begin(), e=VCalls.end();
i < e; ++i)
methods.push_back(wrap((0?600:0) + *i));
VCalls.clear();
if (ForVirtualBase) {
// then virtual base offsets...
for (std::vector<llvm::Constant *>::reverse_iterator i = offsets.rbegin(),
e = offsets.rend(); i != e; ++i)
methods.push_back(*i);
}
m = wrap(-(Offset/8));
methods.push_back(m);
methods.push_back(rtti);
AddressPoint = methods.size();
methods.insert(methods.end(), submethods.begin(), submethods.end());
submethods.clear();
InstallThunks(AddressPoint);
// and then the non-virtual bases.
NonVirtualBases(RD, Layout, PrimaryBase, PrimaryBaseWasVirtual, MorallyVirtual,
Offset);
return AddressPoint;
} }
void GenerateVtableForVBases(const CXXRecordDecl *RD, void GenerateVtableForVBases(const CXXRecordDecl *RD,