Finish off pure virtual function handling.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85354 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Mike Stump 2009-10-28 00:35:46 +00:00
Родитель 5557b25bdb
Коммит 7809e0d165
2 изменённых файлов: 53 добавлений и 5 удалений

Просмотреть файл

@ -72,8 +72,13 @@ public:
LLVMPointerWidth(cgm.getContext().Target.getPointerWidth(0)),
CurrentVBaseOffset(0) {
Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
// FIXME: ___cxa_pure_virtual
cxa_pure = wrap((Index_t)0);
// Calculate pointer for ___cxa_pure_virtual.
const llvm::FunctionType *FTy;
std::vector<const llvm::Type*> ArgTys;
const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext);
FTy = llvm::FunctionType::get(ResultType, ArgTys, false);
cxa_pure = wrap(CGM.CreateRuntimeFunction(FTy, "__cxa_pure_virtual"));
}
llvm::DenseMap<const CXXMethodDecl *, Index_t> &getIndex() { return Index; }
@ -183,6 +188,7 @@ public:
bool OverrideMethod(const CXXMethodDecl *MD, llvm::Constant *m,
bool MorallyVirtual, Index_t OverrideOffset,
Index_t Offset) {
const bool isPure = MD->isPure();
typedef CXXMethodDecl::method_iterator meth_iter;
// FIXME: Should OverrideOffset's be Offset?
@ -221,7 +227,9 @@ public:
}
Index[MD] = i;
submethods[i] = m;
if (isPure)
Pures[MD] = 1;
Pures.erase(OMD);
Thunks.erase(OMD);
if (MorallyVirtual) {
Index_t &idx = VCall[OMD];
@ -243,7 +251,7 @@ public:
CovariantThunks[MD] = std::make_pair(std::make_pair(ThisOffset,
ReturnOffset),
oret);
else
else if (!isPure)
Thunks[MD] = ThisOffset;
return true;
}
@ -258,7 +266,7 @@ public:
CovariantThunks[MD] = std::make_pair(std::make_pair(ThisOffset,
ReturnOffset),
oret);
else
else if (!isPure)
Thunks[MD] = ThisOffset;
}
return true;
@ -272,6 +280,7 @@ public:
for (Thunks_t::iterator i = Thunks.begin(), e = Thunks.end();
i != e; ++i) {
const CXXMethodDecl *MD = i->first;
assert(!MD->isPure() && "Trying to thunk a pure");
Index_t idx = Index[MD];
Index_t nv_O = i->second.first;
Index_t v_O = i->second.second;
@ -282,6 +291,8 @@ public:
e = CovariantThunks.end();
i != e; ++i) {
const CXXMethodDecl *MD = i->first;
if (MD->isPure())
continue;
Index_t idx = Index[MD];
Index_t nv_t = i->second.first.first.first;
Index_t v_t = i->second.first.first.second;
@ -339,6 +350,8 @@ public:
// else allocate a new slot.
Index[MD] = submethods.size();
submethods.push_back(m);
if (MD->isPure())
Pures[MD] = 1;
if (MorallyVirtual) {
VCallOffset[MD] = Offset/8;
Index_t &idx = VCall[MD];

Просмотреть файл

@ -1049,6 +1049,41 @@ struct test16_D : test16_NV1, virtual test16_B2 {
// CHECK-LP32-NEXT: .long __ZN10test16_NV28foo_NV2bEv
class test17_B1 {
virtual void foo() = 0;
virtual void bar() { }
};
class test17_B2 : public test17_B1 {
void foo() { }
virtual void bar() = 0;
};
class test17_D : public test17_B2 {
void bar() { }
} test17_d;
// CHECK-LP64:__ZTV8test17_D:
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64-NEXT: .quad __ZTI8test17_D
// CHECK-LP64-NEXT: .quad __ZN9test17_B23fooEv
// CHECK-LP64-NEXT: .quad __ZN8test17_D3barEv
// CHECK-LP64:__ZTV9test17_B2:
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64-NEXT: .quad __ZTI9test17_B2
// CHECK-LP64-NEXT: .quad __ZN9test17_B23fooEv
// CHECK-LP64-NEXT: .quad ___cxa_pure_virtual
// CHECK-LP64:__ZTV9test17_B1:
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64-NEXT: .quad __ZTI9test17_B1
// CHECK-LP64-NEXT: .quad ___cxa_pure_virtual
// CHECK-LP64-NEXT: .quad __ZN9test17_B13barEv
// CHECK-LP64: __ZTV1B:
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64-NEXT: .quad __ZTI1B