Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision d7dc82447d825854b37e78a7aa777b1a58e7e1b2)
+++ src/Common/PassVisitor.h	(revision cdd1695f9fcbfaa783e678c6f8e2f739eb1069b3)
@@ -54,4 +54,5 @@
 	virtual void visit( BranchStmt *branchStmt ) override final;
 	virtual void visit( ReturnStmt *returnStmt ) override final;
+	virtual void visit( ThrowStmt *throwStmt ) override final;
 	virtual void visit( TryStmt *tryStmt ) override final;
 	virtual void visit( CatchStmt *catchStmt ) override final;
@@ -139,4 +140,5 @@
 	virtual Statement* mutate( BranchStmt *branchStmt ) override final;
 	virtual Statement* mutate( ReturnStmt *returnStmt ) override final;
+	virtual Statement* mutate( ThrowStmt *throwStmt ) override final;
 	virtual Statement* mutate( TryStmt *returnStmt ) override final;
 	virtual Statement* mutate( CatchStmt *catchStmt ) override final;
@@ -230,5 +232,24 @@
 	std::list< Statement* > * 	get_afterStmts () { return stmtsToAddAfter_impl ( pass, 0); }
 	bool visit_children() { bool* skip = skip_children_impl(pass, 0); return ! (skip && *skip); }
+	void reset_visit() { bool* skip = skip_children_impl(pass, 0); if(skip) *skip = false; }
+
+	guard_value_impl init_guard() {
+		guard_value_impl guard;
+		auto at_cleanup = at_cleanup_impl(pass, 0);
+		if( at_cleanup ) {
+			*at_cleanup = [&guard]( cleanup_func_t && func, void* val ) {
+				guard.push( std::move( func ), val );
+			};
+		}
+		return guard;
+	}
 };
 
+template<typename pass_type, typename T>
+void GuardValue( pass_type * pass, T& val ) {
+	pass->at_cleanup( [ val ]( void * newVal ) {
+		* static_cast< T * >( newVal ) = val;
+	}, static_cast< void * >( & val ) );
+}
+
 #include "PassVisitor.impl.h"
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision d7dc82447d825854b37e78a7aa777b1a58e7e1b2)
+++ src/Common/PassVisitor.impl.h	(revision cdd1695f9fcbfaa783e678c6f8e2f739eb1069b3)
@@ -1,15 +1,21 @@
 #pragma once
 
-#define VISIT_START( node )  \
-	call_previsit( node ); \
-	if( visit_children() ) { \
-
-#define VISIT_END( node )            \
-	}                              \
-	return call_postvisit( node ); \
-
-#define MUTATE_START( node )  \
-	call_premutate( node ); \
-	if( visit_children() ) { \
+#define VISIT_START( node )                     \
+	__attribute__((unused))                   \
+	const auto & guard = init_guard();        \
+	call_previsit( node );                    \
+	if( visit_children() ) {                  \
+		reset_visit();                      \
+
+#define VISIT_END( node )                       \
+	}                                         \
+	call_postvisit( node );                   \
+
+#define MUTATE_START( node )                    \
+	__attribute__((unused))                   \
+	const auto & guard = init_guard();        \
+	call_premutate( node );                   \
+	if( visit_children() ) {                  \
+		reset_visit();                      \
 
 #define MUTATE_END( type, node )                \
@@ -18,8 +24,8 @@
 
 
-#define VISIT_BODY( node )    \
-	VISIT_START( node );  \
-	Visitor::visit( node ); \
-	VISIT_END( node ); \
+#define VISIT_BODY( node )        \
+	VISIT_START( node );        \
+	Visitor::visit( node );     \
+	VISIT_END( node );          \
 
 
@@ -389,4 +395,17 @@
 
 //--------------------------------------------------------------------------
+// ThrowStmt
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( ThrowStmt * node ) {
+	VISIT_BODY( node );
+}
+
+template< typename pass_type >
+Statement * PassVisitor< pass_type >::mutate( ThrowStmt * node ) {
+	MUTATE_BODY( Statement, node );
+}
+
+//--------------------------------------------------------------------------
 // TryStmt
 template< typename pass_type >
Index: src/Common/PassVisitor.proto.h
===================================================================
--- src/Common/PassVisitor.proto.h	(revision d7dc82447d825854b37e78a7aa777b1a58e7e1b2)
+++ src/Common/PassVisitor.proto.h	(revision cdd1695f9fcbfaa783e678c6f8e2f739eb1069b3)
@@ -1,3 +1,34 @@
 #pragma once
+
+typedef std::function<void( void * )> cleanup_func_t;
+
+class guard_value_impl {
+public:
+	guard_value_impl() = default;
+
+	~guard_value_impl() {
+		while( !cleanups.empty() ) {
+			auto& cleanup = cleanups.top();
+			cleanup.func( cleanup.val );
+			cleanups.pop();
+		}
+	}
+
+	void push( cleanup_func_t && func, void* val ) {
+		cleanups.emplace( std::move(func), val );
+	}
+
+private:
+	struct cleanup_t {
+		cleanup_func_t func;
+		void * val;
+
+		cleanup_t( cleanup_func_t&& func, void * val ) : func(func), val(val) {}
+	};
+
+	std::stack< cleanup_t > cleanups;
+};
+
+typedef std::function< void( cleanup_func_t, void * ) > at_cleanup_t;
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -73,5 +104,5 @@
 #define FIELD_PTR( type, name )                                                                                                        \
 template<typename pass_type>                                                                                                           \
-static inline auto name##_impl( pass_type& pass, __attribute__((unused)) int unused ) -> decltype( &pass.name ) { return &pass.name; }  \
+static inline auto name##_impl( pass_type& pass, __attribute__((unused)) int unused ) -> decltype( &pass.name ) { return &pass.name; } \
                                                                                                                                        \
 template<typename pass_type>                                                                                                           \
@@ -82,2 +113,3 @@
 FIELD_PTR( std::list< Statement* >, stmtsToAddAfter  )
 FIELD_PTR( bool, skip_children )
+FIELD_PTR( at_cleanup_t, at_cleanup )
