diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-07-30 17:49:11 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-07-30 17:49:11 +0000 |
commit | 426cc3828ce07a2cff15c9837f5958e6fc4b7739 (patch) | |
tree | 95493da6c4863091df9486ebf008ed255c1b7852 /lib/CodeGen/CGCXX.cpp | |
parent | 4b5acc5454330046cf651c7eef61d1cdfff87d99 (diff) |
Patch for future ir-gen for destructor calls.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77608 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCXX.cpp')
-rw-r--r-- | lib/CodeGen/CGCXX.cpp | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index bce22e5ec3..8c960c7f98 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -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); + } + } +} |