Index: src/ControlStruct/ExceptTranslate.cc
===================================================================
--- src/ControlStruct/ExceptTranslate.cc	(revision 049ead9262ae897ee9082d3d1a085f422407c116)
+++ src/ControlStruct/ExceptTranslate.cc	(revision 7543dec19ee64352219016da00841a81f108814c)
@@ -315,11 +315,11 @@
 			{
 				VarExprReplacer::DeclMap mapping;
-				mapping[ handler_decl ] = local_except;
+				mapping[ handler_decl ] = new VariableExpr( local_except );
 				VarExprReplacer mapper( mapping );
-				handler->get_body()->accept( mapper );
+				handler->body->acceptMutator( mapper );
 			}
 
-			block->push_back( handler->get_body() );
-			handler->set_body( nullptr );
+			block->push_back( handler->body );
+			handler->body = nullptr;
 
 			std::list<Statement *> caseBody
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision 049ead9262ae897ee9082d3d1a085f422407c116)
+++ src/InitTweak/FixInit.cc	(revision 7543dec19ee64352219016da00841a81f108814c)
@@ -676,5 +676,5 @@
 			// the original code contains uses of objDecl - replace them with the newly generated 'this' parameter.
 			ObjectDecl * thisParam = getParamThis( dtorFunc->type );
-			VarExprReplacer::replace( dtor, { std::make_pair( objDecl, thisParam ) } );
+			VarExprReplacer::replace( dtor, { std::make_pair( objDecl, new VariableExpr( thisParam ) ) } );
 			dtorFunc->statements->push_back( dtor );
 
Index: src/SynTree/CompoundStmt.cc
===================================================================
--- src/SynTree/CompoundStmt.cc	(revision 049ead9262ae897ee9082d3d1a085f422407c116)
+++ src/SynTree/CompoundStmt.cc	(revision 7543dec19ee64352219016da00841a81f108814c)
@@ -59,5 +59,5 @@
 				DeclarationWithType * origdwt = strict_dynamic_cast< DeclarationWithType * > ( origDeclStmt->get_decl() );
 				assert( dwt->get_name() == origdwt->get_name() );
-				declMap[ origdwt ] = dwt;
+				declMap[ origdwt ] = new VariableExpr( dwt );
 			} else assert( ! dynamic_cast< DeclarationWithType * > ( origDeclStmt->get_decl() ) );
 		} else assert( ! dynamic_cast< DeclStmt * > ( s ) );
@@ -65,5 +65,5 @@
 	if ( ! declMap.empty() ) {
 		VarExprReplacer replacer( declMap );
-		accept( replacer );
+		acceptMutator( replacer );
 	}
 }
Index: src/SynTree/FunctionDecl.cc
===================================================================
--- src/SynTree/FunctionDecl.cc	(revision 049ead9262ae897ee9082d3d1a085f422407c116)
+++ src/SynTree/FunctionDecl.cc	(revision 7543dec19ee64352219016da00841a81f108814c)
@@ -43,12 +43,12 @@
 	VarExprReplacer::DeclMap declMap;
 	for ( auto p : group_iterate( other.type->parameters, type->parameters ) ) {
-		declMap[ std::get<0>(p) ] = std::get<1>(p);
+		declMap[ std::get<0>(p) ] = new VariableExpr( std::get<1>(p) );
 	}
 	for ( auto p : group_iterate( other.type->returnVals, type->returnVals ) ) {
-		declMap[ std::get<0>(p) ] = std::get<1>(p);
+		declMap[ std::get<0>(p) ] = new VariableExpr( std::get<1>(p) );
 	}
 	if ( ! declMap.empty() ) {
 		VarExprReplacer replacer( declMap );
-		accept( replacer );
+		acceptMutator( replacer );
 	}
 }
Index: src/SynTree/VarExprReplacer.cc
===================================================================
--- src/SynTree/VarExprReplacer.cc	(revision 049ead9262ae897ee9082d3d1a085f422407c116)
+++ src/SynTree/VarExprReplacer.cc	(revision 7543dec19ee64352219016da00841a81f108814c)
@@ -22,12 +22,21 @@
 VarExprReplacer::VarExprReplacer( const DeclMap & declMap, bool debug ) : declMap( declMap ), debug( debug ) {}
 
-// replace variable with new node from decl map
-void VarExprReplacer::visit( VariableExpr * varExpr ) {
-	// xxx - assertions and parameters aren't accounted for in this... (i.e. they aren't inserted into the map when it's made, only DeclStmts are)
-	if ( declMap.count( varExpr->get_var() ) ) {
-		if ( debug ) {
-			std::cerr << "replacing variable reference: " << (void*)varExpr->get_var() << " " << varExpr->get_var() << " with " << (void*)declMap.at( varExpr->get_var() ) << " " << declMap.at( varExpr->get_var() ) << std::endl;
-		}
-		varExpr->set_var( declMap.at( varExpr->get_var() ) );
+VarExprReplacer::~VarExprReplacer() {
+	for ( auto p : declMap ) {
+		delete p.second;
 	}
 }
+
+// replace variable with new node from decl map
+Expression * VarExprReplacer::mutate( VariableExpr * varExpr ) {
+	// xxx - assertions and parameters aren't accounted for in this... (i.e. they aren't inserted into the map when it's made, only DeclStmts are)
+	if ( declMap.count( varExpr->var ) ) {
+		Expression * expr = declMap.at( varExpr->var );
+		if ( debug ) {
+			std::cerr << "replacing variable reference: " << (void*)varExpr->var << " " << varExpr->var << " with " << (void*)expr << " " << expr << std::endl;
+		}
+		delete varExpr;
+		return expr->clone();
+	}
+	return varExpr;
+}
Index: src/SynTree/VarExprReplacer.h
===================================================================
--- src/SynTree/VarExprReplacer.h	(revision 049ead9262ae897ee9082d3d1a085f422407c116)
+++ src/SynTree/VarExprReplacer.h	(revision 7543dec19ee64352219016da00841a81f108814c)
@@ -24,7 +24,7 @@
 
 /// Visitor that replaces the declarations that VariableExprs refer to, according to the supplied mapping
-class VarExprReplacer : public Visitor {
+class VarExprReplacer : public Mutator {
 public:
-	typedef std::map< DeclarationWithType *, DeclarationWithType * > DeclMap;
+	typedef std::map< DeclarationWithType *, Expression * > DeclMap;
 private:
 	const DeclMap & declMap;
@@ -32,11 +32,13 @@
 public:
 	VarExprReplacer( const DeclMap & declMap, bool debug = false );
+	~VarExprReplacer();
 
 	// replace variable with new node from decl map
-	virtual void visit( VariableExpr * varExpr );
+	virtual Expression * mutate( VariableExpr * varExpr );
 
-	static void replace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug = false ) {
+	template<typename Node>
+	static void replace( Node *& node, const DeclMap & declMap, bool debug = false ) {
 		VarExprReplacer replacer( declMap, debug );
-		maybeAccept( node, replacer );
+		node = maybeMutate( node, replacer );
 	}
 };
