diff options
author | John McCall <rjmccall@apple.com> | 2011-07-12 16:41:08 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-07-12 16:41:08 +0000 |
commit | 9928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3 (patch) | |
tree | b3860a47a6a5f606e5057653deddc0dd84d70635 /lib/CodeGen/CodeGenFunction.h | |
parent | f1588660c109610e6a79c786b83b7c9bbd6ed31e (diff) |
Switch field destruction over to use the new destroyer-based API
and kill a lot of redundant code.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134988 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.h')
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 73 |
1 files changed, 54 insertions, 19 deletions
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 67e63cd346..f1a7187013 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -255,6 +255,30 @@ public: : a0_saved(a0), a1_saved(a1), a2_saved(a2) {} }; + template <class T, class A0, class A1, class A2, class A3> + class ConditionalCleanup4 : public Cleanup { + typedef typename DominatingValue<A0>::saved_type A0_saved; + typedef typename DominatingValue<A1>::saved_type A1_saved; + typedef typename DominatingValue<A2>::saved_type A2_saved; + typedef typename DominatingValue<A3>::saved_type A3_saved; + A0_saved a0_saved; + A1_saved a1_saved; + A2_saved a2_saved; + A3_saved a3_saved; + + void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) { + A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved); + A1 a1 = DominatingValue<A1>::restore(CGF, a1_saved); + A2 a2 = DominatingValue<A2>::restore(CGF, a2_saved); + A3 a3 = DominatingValue<A3>::restore(CGF, a3_saved); + T(a0, a1, a2, a3).Emit(CGF, IsForEHCleanup); + } + + public: + ConditionalCleanup4(A0_saved a0, A1_saved a1, A2_saved a2, A3_saved a3) + : a0_saved(a0), a1_saved(a1), a2_saved(a2), a3_saved(a3) {} + }; + private: // The implementation for this class is in CGException.h and // CGException.cpp; the definition is here because it's used as a @@ -710,6 +734,28 @@ public: initFullExprCleanup(); } + /// pushFullExprCleanup - Push a cleanup to be run at the end of the + /// current full-expression. Safe against the possibility that + /// we're currently inside a conditionally-evaluated expression. + template <class T, class A0, class A1, class A2, class A3> + void pushFullExprCleanup(CleanupKind kind, A0 a0, A1 a1, A2 a2, A3 a3) { + // If we're not in a conditional branch, or if none of the + // arguments requires saving, then use the unconditional cleanup. + if (!isInConditionalBranch()) { + return EHStack.pushCleanup<T>(kind, a0, a1, a2, a3); + } + + typename DominatingValue<A0>::saved_type a0_saved = saveValueInCond(a0); + typename DominatingValue<A1>::saved_type a1_saved = saveValueInCond(a1); + typename DominatingValue<A2>::saved_type a2_saved = saveValueInCond(a2); + typename DominatingValue<A3>::saved_type a3_saved = saveValueInCond(a3); + + typedef EHScopeStack::ConditionalCleanup4<T, A0, A1, A2, A3> CleanupType; + EHStack.pushCleanup<CleanupType>(kind, a0_saved, a1_saved, + a2_saved, a3_saved); + initFullExprCleanup(); + } + /// PushDestructorCleanup - Push a cleanup to call the /// complete-object destructor of an object of the given type at the /// given address. Does nothing if T is not a C++ class type with a @@ -1126,7 +1172,8 @@ public: QualType elementType, Destroyer &destroyer); - Destroyer &getDestroyer(QualType::DestructionKind destructionKind); + void pushDestroy(QualType::DestructionKind dtorKind, + llvm::Value *addr, QualType type); void pushDestroy(CleanupKind kind, llvm::Value *addr, QualType type, Destroyer &destroyer, bool useEHCleanupForArray); void emitDestroy(llvm::Value *addr, QualType type, Destroyer &destroyer, @@ -1135,6 +1182,8 @@ public: QualType type, Destroyer &destroyer, bool useEHCleanup); + Destroyer &getDestroyer(QualType::DestructionKind destructionKind); + /// Determines whether an EH cleanup is required to destroy a type /// with the given destruction kind. bool needsEHCleanup(QualType::DestructionKind kind) { @@ -1151,6 +1200,10 @@ public: llvm_unreachable("bad destruction kind"); } + CleanupKind getCleanupKind(QualType::DestructionKind kind) { + return (needsEHCleanup(kind) ? NormalAndEHCleanup : NormalCleanup); + } + //===--------------------------------------------------------------------===// // Objective-C //===--------------------------------------------------------------------===// @@ -2109,28 +2162,10 @@ public: llvm::Value *EmitARCRetainScalarExpr(const Expr *expr); llvm::Value *EmitARCRetainAutoreleaseScalarExpr(const Expr *expr); - void PushARCReleaseCleanup(CleanupKind kind, QualType type, - llvm::Value *addr, bool precise, - bool forFullExpr = false); - void PushARCArrayReleaseCleanup(CleanupKind kind, QualType elementType, - llvm::Value *addr, - llvm::Value *countOrCountPtr, - bool precise, bool forFullExpr = false); - void PushARCWeakReleaseCleanup(CleanupKind kind, QualType type, - llvm::Value *addr, bool forFullExpr = false); - void PushARCArrayWeakReleaseCleanup(CleanupKind kind, QualType elementType, - llvm::Value *addr, - llvm::Value *countOrCountPtr, - bool forFullExpr = false); static Destroyer destroyARCStrongImprecise; static Destroyer destroyARCStrongPrecise; static Destroyer destroyARCWeak; - void PushARCFieldReleaseCleanup(CleanupKind cleanupKind, - const FieldDecl *Field); - void PushARCFieldWeakReleaseCleanup(CleanupKind cleanupKind, - const FieldDecl *Field); - void EmitObjCAutoreleasePoolPop(llvm::Value *Ptr); llvm::Value *EmitObjCAutoreleasePoolPush(); llvm::Value *EmitObjCMRRAutoreleasePoolPush(); |