From: Fariborz Jahanian Date: Mon, 30 Nov 2009 22:07:18 +0000 (+0000) Subject: More support for virtual destructor calls. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ba2253f234d27d3ecc5b2b88e9cd9198658eb312;p=clang More support for virtual destructor calls. Fixes pr5619 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90158 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 437fed7478..34d1c8d984 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -603,16 +603,7 @@ CodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D, Counter = Builder.CreateLoad(IndexPtr); Counter = Builder.CreateSub(Counter, One); llvm::Value *Address = Builder.CreateInBoundsGEP(This, Counter, "arrayidx"); - if (D->isVirtual()) { - const llvm::Type *Ty = - CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(D), - /*isVariadic=*/false); - - llvm::Value *Callee = BuildVirtualCall(D, Dtor_Deleting, Address, Ty); - EmitCXXMemberCall(D, Callee, Address, 0, 0); - } - else - EmitCXXDestructorCall(D, Dtor_Complete, Address); + EmitCXXDestructorCall(D, Dtor_Complete, Address); EmitBlock(ContinueBlock); @@ -703,6 +694,15 @@ CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, llvm::Value *This) { + if (D->isVirtual()) { + const llvm::Type *Ty = + CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(D), + /*isVariadic=*/false); + + llvm::Value *Callee = BuildVirtualCall(D, Dtor_Deleting, This, Ty); + EmitCXXMemberCall(D, Callee, This, 0, 0); + return; + } llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(D, Type); EmitCXXMemberCall(D, Callee, This, 0, 0); @@ -1777,12 +1777,12 @@ void CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD, // Ignore trivial destructors. if (BaseClassDecl->hasTrivialDestructor()) continue; - + const CXXDestructorDecl *D = BaseClassDecl->getDestructor(getContext()); + llvm::Value *V = GetAddressOfBaseClass(LoadCXXThis(), ClassDecl, BaseClassDecl, /*NullCheckValue=*/false); - EmitCXXDestructorCall(BaseClassDecl->getDestructor(getContext()), - Dtor_Base, V); + EmitCXXDestructorCall(D, Dtor_Base, V); } // If we're emitting a base destructor, we don't want to emit calls to the @@ -1790,10 +1790,21 @@ void CodeGenFunction::EmitDtorEpilogue(const CXXDestructorDecl *DD, if (DtorType == Dtor_Base) return; - // FIXME: Handle virtual bases. + // Handle virtual bases. for (CXXRecordDecl::reverse_base_class_const_iterator I = ClassDecl->vbases_rbegin(), E = ClassDecl->vbases_rend(); I != E; ++I) { - assert(false && "FIXME: Handle virtual bases."); + const CXXBaseSpecifier &Base = *I; + CXXRecordDecl *BaseClassDecl + = cast(Base.getType()->getAs()->getDecl()); + + // Ignore trivial destructors. + if (BaseClassDecl->hasTrivialDestructor()) + continue; + const CXXDestructorDecl *D = BaseClassDecl->getDestructor(getContext()); + llvm::Value *V = GetAddressOfBaseClass(LoadCXXThis(), + ClassDecl, BaseClassDecl, + /*NullCheckValue=*/false); + EmitCXXDestructorCall(D, Dtor_Base, V); } // If we have a deleting destructor, emit a call to the delete operator.