Patch for future ir-gen for destructor calls.

llvm-svn: 77608
This commit is contained in:
Fariborz Jahanian 2009-07-30 17:49:11 +00:00
parent 118cef36b8
commit aa01d2a532
4 changed files with 50 additions and 3 deletions

View File

@ -1096,7 +1096,7 @@ public:
return 0;
}
/// getMemberToDestroy - Get the member for the given object.
FieldDecl *getMemberToDestroy(uintptr_t Member) {
FieldDecl *getMemberToDestroy(uintptr_t Member) const {
if (isMemberToDestroy(Member))
return reinterpret_cast<FieldDecl *>(Member);
return 0;

View File

@ -489,7 +489,7 @@ const char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D,
/// base classes and non-static data members belonging to this constructor.
void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) {
const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
assert(ClassDecl->vbases_begin() == ClassDecl->vbases_end()
assert(!ClassDecl->isPolymorphic()
&& "FIXME. virtual base initialization unsupported");
for (CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
@ -538,3 +538,43 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD) {
}
}
}
/// EmitDtorEpilogue - Emit all code that comes at the end of class's
/// destructor. This is to call destructors on members and base classes
/// in reverse order of their construction.
void CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD) {
const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(DD->getDeclContext());
assert(!ClassDecl->isPolymorphic() &&
"FIXME. polymorphic destruction not supported");
(void)ClassDecl; // prevent warning.
for (CXXDestructorDecl::destr_const_iterator *B = DD->destr_begin(),
*E = DD->destr_end(); B != E; ++B) {
uintptr_t BaseOrMember = (*B);
if (DD->isMemberToDestroy(BaseOrMember)) {
FieldDecl *FD = DD->getMemberToDestroy(BaseOrMember);
QualType FieldType = getContext().getCanonicalType((FD)->getType());
assert(!getContext().getAsArrayType(FieldType)
&& "FIXME. Field arrays destruction unsupported");
const RecordType *RT = FieldType->getAs<RecordType>();
CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
if (FieldClassDecl->hasTrivialDestructor())
continue;
llvm::Value *LoadOfThis = LoadCXXThis();
LValue LHS = EmitLValueForField(LoadOfThis, FD, false, 0);
EmitCXXDestructorCall(FieldClassDecl->getDestructor(getContext()),
Dtor_Complete, LHS.getAddress());
}
else {
const RecordType *RT =
DD->getAnyBaseClassToDestroy(BaseOrMember)->getAs<RecordType>();
CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
if (BaseClassDecl->hasTrivialDestructor())
continue;
llvm::Value *V = AddressCXXOfBaseClass(LoadCXXThis(),
ClassDecl,BaseClassDecl);
EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()),
Dtor_Complete, V);
}
}
}

View File

@ -234,6 +234,8 @@ void CodeGenFunction::GenerateCode(const FunctionDecl *FD,
if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD))
EmitCtorPrologue(CD);
EmitStmt(S);
if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD))
EmitDtorEpilogue(DD);
FinishFunction(S->getRBracLoc());
}

View File

@ -359,7 +359,12 @@ public:
void FinishFunction(SourceLocation EndLoc=SourceLocation());
void EmitCtorPrologue(const CXXConstructorDecl *CD);
/// EmitDtorEpilogue - Emit all code that comes at the end of class's
/// destructor. This is to call destructors on members and base classes
/// in reverse order of their construction.
void EmitDtorEpilogue(const CXXDestructorDecl *DD);
/// EmitFunctionProlog - Emit the target specific LLVM code to load the
/// arguments for the given function. This is also responsible for naming the
/// LLVM function arguments.