Index: src/SynTree/CompoundStmt.cc
===================================================================
--- src/SynTree/CompoundStmt.cc	(revision 136ccd79f8c610f8bde4fbe2e065362de2680188)
+++ src/SynTree/CompoundStmt.cc	(revision 9d061427effff83e0da6217d40987ce0ea673835)
@@ -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 136ccd79f8c610f8bde4fbe2e065362de2680188)
+++ src/SynTree/FunctionDecl.cc	(revision 9d061427effff83e0da6217d40987ce0ea673835)
@@ -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 136ccd79f8c610f8bde4fbe2e065362de2680188)
+++ src/SynTree/VarExprReplacer.cc	(revision 9d061427effff83e0da6217d40987ce0ea673835)
@@ -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 136ccd79f8c610f8bde4fbe2e065362de2680188)
+++ src/SynTree/VarExprReplacer.h	(revision 9d061427effff83e0da6217d40987ce0ea673835)
@@ -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 );
 	}
 };
