diff options
author | John McCall <rjmccall@apple.com> | 2010-07-21 01:23:41 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-07-21 01:23:41 +0000 |
commit | 182ab5112650d3228291c4dadd64a9f77f5aeb51 (patch) | |
tree | 37405551e25cc39b6a467888d0dddcbdd92002f8 /lib/CodeGen/CGClass.cpp | |
parent | 59174c0633fb5cde41735cfbff5744bdf837e8d9 (diff) |
Convert the EH cleanups for base and member destructors in a constructor into
lazy cleanups.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108978 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGClass.cpp')
-rw-r--r-- | lib/CodeGen/CGClass.cpp | 60 |
1 files changed, 42 insertions, 18 deletions
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 799dd644a2..bc42ecb3f5 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -310,6 +310,22 @@ static llvm::Value *GetVTTParameter(CodeGenFunction &CGF, GlobalDecl GD, return VTT; } +namespace { + struct CallBaseDtor : EHScopeStack::LazyCleanup { + CXXDestructorDecl *Dtor; + bool isBaseVirtual; + llvm::Value *Addr; + + CallBaseDtor(CXXDestructorDecl *DD, bool isVirtual, llvm::Value *Addr) + : Dtor(DD), isBaseVirtual(isVirtual), Addr(Addr) {} + + void Emit(CodeGenFunction &CGF, bool IsForEH) { + // FIXME: Is this OK for C++0x delegating constructors? + CGF.EmitCXXDestructorCall(Dtor, Dtor_Base, isBaseVirtual, Addr); + } + }; +} + static void EmitBaseInitializer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, CXXBaseOrMemberInitializer *BaseInit, @@ -338,13 +354,10 @@ static void EmitBaseInitializer(CodeGenFunction &CGF, CGF.EmitAggExpr(BaseInit->getInit(), V, false, false, true); - if (CGF.Exceptions && !BaseClassDecl->hasTrivialDestructor()) { - // FIXME: Is this OK for C++0x delegating constructors? - CodeGenFunction::CleanupBlock Cleanup(CGF, EHCleanup); - - CXXDestructorDecl *DD = BaseClassDecl->getDestructor(); - CGF.EmitCXXDestructorCall(DD, Dtor_Base, isBaseVirtual, V); - } + if (CGF.Exceptions && !BaseClassDecl->hasTrivialDestructor()) + CGF.EHStack.pushLazyCleanup<CallBaseDtor>(EHCleanup, + BaseClassDecl->getDestructor(), + isBaseVirtual, V); } static void EmitAggMemberInitializer(CodeGenFunction &CGF, @@ -432,6 +445,25 @@ static void EmitAggMemberInitializer(CodeGenFunction &CGF, // Emit the fall-through block. CGF.EmitBlock(AfterFor, true); } + +namespace { + struct CallMemberDtor : EHScopeStack::LazyCleanup { + FieldDecl *Field; + CXXDestructorDecl *Dtor; + + CallMemberDtor(FieldDecl *Field, CXXDestructorDecl *Dtor) + : Field(Field), Dtor(Dtor) {} + + void Emit(CodeGenFunction &CGF, bool IsForEH) { + // FIXME: Is this OK for C++0x delegating constructors? + llvm::Value *ThisPtr = CGF.LoadCXXThis(); + LValue LHS = CGF.EmitLValueForField(ThisPtr, Field, 0); + + CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false, + LHS.getAddress()); + } + }; +} static void EmitMemberInitializer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, @@ -532,17 +564,9 @@ static void EmitMemberInitializer(CodeGenFunction &CGF, return; CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); - if (!RD->hasTrivialDestructor()) { - // FIXME: Is this OK for C++0x delegating constructors? - CodeGenFunction::CleanupBlock Cleanup(CGF, EHCleanup); - - llvm::Value *ThisPtr = CGF.LoadCXXThis(); - LValue LHS = CGF.EmitLValueForField(ThisPtr, Field, 0); - - CXXDestructorDecl *DD = RD->getDestructor(); - CGF.EmitCXXDestructorCall(DD, Dtor_Complete, /*ForVirtualBase=*/false, - LHS.getAddress()); - } + if (!RD->hasTrivialDestructor()) + CGF.EHStack.pushLazyCleanup<CallMemberDtor>(EHCleanup, Field, + RD->getDestructor()); } } |