summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-07-12 00:15:30 +0000
committerJohn McCall <rjmccall@apple.com>2011-07-12 00:15:30 +0000
commit5fcf8da33dfb9a54f047718223ddba16a263f6c1 (patch)
tree75ba783c9f84f57aaa7c8e5e0c1f667c1fe83d89 /clang/lib
parentcdc2297ee1475125b2b55edb61df14b722c2cc10 (diff)
downloadbcm5719-llvm-5fcf8da33dfb9a54f047718223ddba16a263f6c1.tar.gz
bcm5719-llvm-5fcf8da33dfb9a54f047718223ddba16a263f6c1.zip
Do full-expression cleanups in a much more sensible way that still lets
people write useful cleanup classes. llvm-svn: 134942
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGCleanup.cpp4
-rw-r--r--clang/lib/CodeGen/CGException.cpp7
-rw-r--r--clang/lib/CodeGen/CGObjC.cpp33
-rw-r--r--clang/lib/CodeGen/CGTemporaries.cpp9
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h69
5 files changed, 26 insertions, 96 deletions
diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp
index f75253bf788..4147c241c25 100644
--- a/clang/lib/CodeGen/CGCleanup.cpp
+++ b/clang/lib/CodeGen/CGCleanup.cpp
@@ -256,9 +256,7 @@ void CodeGenFunction::initFullExprCleanup() {
if (cleanup.isEHCleanup()) cleanup.setTestFlagInEHCleanup();
}
-EHScopeStack::Cleanup::~Cleanup() {
- llvm_unreachable("Cleanup is indestructable");
-}
+void EHScopeStack::Cleanup::anchor() {}
/// All the branch fixups on the EH stack have propagated out past the
/// outermost normal cleanup; resolve them all by adding cases to the
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index 35429e3b841..c25b9a68831 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -323,9 +323,10 @@ static llvm::Constant *getCleanupValue(CodeGenFunction &CGF) {
namespace {
/// A cleanup to free the exception object if its initialization
/// throws.
- struct FreeException {
- static void Emit(CodeGenFunction &CGF, bool forEH,
- llvm::Value *exn) {
+ struct FreeException : EHScopeStack::Cleanup {
+ llvm::Value *exn;
+ FreeException(llvm::Value *exn) : exn(exn) {}
+ void Emit(CodeGenFunction &CGF, bool forEH) {
CGF.Builder.CreateCall(getFreeExceptionFn(CGF), exn)
->setDoesNotThrow();
}
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index 2f0d827fc3b..8ea481f23a5 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -1902,23 +1902,6 @@ namespace {
CallReleaseForObject(QualType type, llvm::Value *addr,
CodeGenFunction::Destroyer *destroyer)
: ObjCReleasingCleanup(type, addr, destroyer) {}
-
- using ObjCReleasingCleanup::Emit;
- static void Emit(CodeGenFunction &CGF, bool IsForEH,
- QualType type, llvm::Value *addr,
- CodeGenFunction::Destroyer *destroyer) {
- // EHScopeStack::Cleanup objects can never have their destructors called,
- // so use placement new to construct our temporary object.
- union {
- void* align;
- char data[sizeof(CallReleaseForObject)];
- };
-
- CallReleaseForObject *Object
- = new (&align) CallReleaseForObject(type, addr, destroyer);
- Object->Emit(CGF, IsForEH);
- (void)data[0];
- }
};
/// A cleanup that calls @objc_storeStrong(nil) on all the objects to
@@ -1965,22 +1948,6 @@ namespace {
struct CallWeakReleaseForObject : ObjCReleasingCleanup {
CallWeakReleaseForObject(QualType type, llvm::Value *addr)
: ObjCReleasingCleanup(type, addr, CodeGenFunction::destroyARCWeak) {}
-
- using ObjCReleasingCleanup::Emit;
- static void Emit(CodeGenFunction &CGF, bool IsForEH,
- QualType type, llvm::Value *addr) {
- // EHScopeStack::Cleanup objects can never have their destructors called,
- // so use placement new to construct our temporary object.
- union {
- void* align;
- char data[sizeof(CallWeakReleaseForObject)];
- };
-
- CallWeakReleaseForObject *Object
- = new (&align) CallWeakReleaseForObject(type, addr);
- Object->Emit(CGF, IsForEH);
- (void)data[0];
- }
};
diff --git a/clang/lib/CodeGen/CGTemporaries.cpp b/clang/lib/CodeGen/CGTemporaries.cpp
index 3b4c50910bf..7e07b4e5c8c 100644
--- a/clang/lib/CodeGen/CGTemporaries.cpp
+++ b/clang/lib/CodeGen/CGTemporaries.cpp
@@ -16,9 +16,12 @@ using namespace clang;
using namespace CodeGen;
namespace {
- struct DestroyTemporary {
- static void Emit(CodeGenFunction &CGF, bool forEH,
- const CXXDestructorDecl *dtor, llvm::Value *addr) {
+ struct DestroyTemporary : EHScopeStack::Cleanup {
+ const CXXDestructorDecl *dtor;
+ llvm::Value *addr;
+ DestroyTemporary(const CXXDestructorDecl *dtor, llvm::Value *addr)
+ : dtor(dtor), addr(addr) {}
+ void Emit(CodeGenFunction &CGF, bool forEH) {
CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*ForVirtualBase=*/false,
addr);
}
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 968222e334a..74324e4dc0c 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -181,15 +181,13 @@ public:
/// Cleanup implementations should generally be declared in an
/// anonymous namespace.
class Cleanup {
+ // Anchor the construction vtable.
+ virtual void anchor();
public:
- // Anchor the construction vtable. We use the destructor because
- // gcc gives an obnoxious warning if there are virtual methods
- // with an accessible non-virtual destructor. Unfortunately,
- // declaring this destructor makes it non-trivial, but there
- // doesn't seem to be any other way around this warning.
- //
- // This destructor will never be called.
- virtual ~Cleanup();
+ // Provide a virtual destructor to suppress a very common warning
+ // that unfortunately cannot be suppressed without this. Cleanups
+ // should not rely on this destructor ever being called.
+ virtual ~Cleanup() {}
/// Emit the cleanup. For normal cleanups, this is run in the
/// same EH context as when the cleanup was pushed, i.e. the
@@ -201,38 +199,6 @@ public:
virtual void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) = 0;
};
- /// UnconditionalCleanupN stores its N parameters and just passes
- /// them to the real cleanup function.
- template <class T, class A0>
- class UnconditionalCleanup1 : public Cleanup {
- A0 a0;
- public:
- UnconditionalCleanup1(A0 a0) : a0(a0) {}
- void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
- T::Emit(CGF, IsForEHCleanup, a0);
- }
- };
-
- template <class T, class A0, class A1>
- class UnconditionalCleanup2 : public Cleanup {
- A0 a0; A1 a1;
- public:
- UnconditionalCleanup2(A0 a0, A1 a1) : a0(a0), a1(a1) {}
- void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
- T::Emit(CGF, IsForEHCleanup, a0, a1);
- }
- };
-
- template <class T, class A0, class A1, class A2>
- class UnconditionalCleanup3 : public Cleanup {
- A0 a0; A1 a1; A2 a2;
- public:
- UnconditionalCleanup3(A0 a0, A1 a1, A2 a2) : a0(a0), a1(a1), a2(a2) {}
- void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
- T::Emit(CGF, IsForEHCleanup, a0, a1, a2);
- }
- };
-
/// ConditionalCleanupN stores the saved form of its N parameters,
/// then restores them and performs the cleanup.
template <class T, class A0>
@@ -242,7 +208,7 @@ public:
void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved);
- T::Emit(CGF, IsForEHCleanup, a0);
+ T(a0).Emit(CGF, IsForEHCleanup);
}
public:
@@ -260,7 +226,7 @@ public:
void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved);
A1 a1 = DominatingValue<A1>::restore(CGF, a1_saved);
- T::Emit(CGF, IsForEHCleanup, a0, a1);
+ T(a0, a1).Emit(CGF, IsForEHCleanup);
}
public:
@@ -281,12 +247,12 @@ public:
A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved);
A1 a1 = DominatingValue<A1>::restore(CGF, a1_saved);
A2 a2 = DominatingValue<A2>::restore(CGF, a2_saved);
- T::Emit(CGF, IsForEHCleanup, a0, a1, a2);
+ T(a0, a1, a2).Emit(CGF, IsForEHCleanup);
}
public:
ConditionalCleanup3(A0_saved a0, A1_saved a1, A2_saved a2)
- : a0_saved(a0), a1_saved(a1), a2_saved(a2) {}
+ : a0_saved(a0), a1_saved(a1), a2_saved(a2) {}
};
private:
@@ -696,10 +662,8 @@ public:
void pushFullExprCleanup(CleanupKind kind, A0 a0) {
// If we're not in a conditional branch, or if none of the
// arguments requires saving, then use the unconditional cleanup.
- if (!isInConditionalBranch()) {
- typedef EHScopeStack::UnconditionalCleanup1<T, A0> CleanupType;
- return EHStack.pushCleanup<CleanupType>(kind, a0);
- }
+ if (!isInConditionalBranch())
+ return EHStack.pushCleanup<T>(kind, a0);
typename DominatingValue<A0>::saved_type a0_saved = saveValueInCond(a0);
@@ -715,10 +679,8 @@ public:
void pushFullExprCleanup(CleanupKind kind, A0 a0, A1 a1) {
// If we're not in a conditional branch, or if none of the
// arguments requires saving, then use the unconditional cleanup.
- if (!isInConditionalBranch()) {
- typedef EHScopeStack::UnconditionalCleanup2<T, A0, A1> CleanupType;
- return EHStack.pushCleanup<CleanupType>(kind, a0, a1);
- }
+ if (!isInConditionalBranch())
+ return EHStack.pushCleanup<T>(kind, a0, a1);
typename DominatingValue<A0>::saved_type a0_saved = saveValueInCond(a0);
typename DominatingValue<A1>::saved_type a1_saved = saveValueInCond(a1);
@@ -736,8 +698,7 @@ public:
// If we're not in a conditional branch, or if none of the
// arguments requires saving, then use the unconditional cleanup.
if (!isInConditionalBranch()) {
- typedef EHScopeStack::UnconditionalCleanup3<T, A0, A1, A2> CleanupType;
- return EHStack.pushCleanup<CleanupType>(kind, a0, a1, a2);
+ return EHStack.pushCleanup<T>(kind, a0, a1, a2);
}
typename DominatingValue<A0>::saved_type a0_saved = saveValueInCond(a0);
OpenPOWER on IntegriCloud