Index: src/ControlStruct/ForExprMutator.cc
===================================================================
--- src/ControlStruct/ForExprMutator.cc	(revision f94ca7ea5a1653637b80ac0a0d965178dbd30798)
+++ src/ControlStruct/ForExprMutator.cc	(revision 0db6fc0e30a15a277876f071902c2fced6294c93)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// ForExprMutator.cc -- 
+// ForExprMutator.cc --
 //
 // Author           : Rodolfo G. Esteves
@@ -19,9 +19,7 @@
 
 namespace ControlStruct {
-	Statement *ForExprMutator::mutate( ForStmt *forStmt ) {
-		// recurse down all nest for loops to hoist any initializer declarations to make them C89 (rather than C99)
-		forStmt->set_body( forStmt->get_body()->acceptMutator( *this ) );
-
-		std::list<Statement *> &init = forStmt->get_initialization(); 
+	Statement *ForExprMutator::postmutate( ForStmt *forStmt ) {
+		// hoist any initializer declarations to make them C89 (rather than C99)
+		std::list<Statement *> &init = forStmt->get_initialization();
 		if ( init.size() == 0 ) {
 			return forStmt;
@@ -39,6 +37,4 @@
 		forStmt->set_initialization( std::list<Statement *>() );
 		return block;
-
-		return forStmt;
 	}
 } // namespace ControlStruct
Index: src/ControlStruct/ForExprMutator.h
===================================================================
--- src/ControlStruct/ForExprMutator.h	(revision f94ca7ea5a1653637b80ac0a0d965178dbd30798)
+++ src/ControlStruct/ForExprMutator.h	(revision 0db6fc0e30a15a277876f071902c2fced6294c93)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// ForExprMutator.h -- 
+// ForExprMutator.h --
 //
 // Author           : Rodolfo G. Esteves
@@ -21,7 +21,7 @@
 
 namespace ControlStruct {
-	class ForExprMutator : public Mutator {
+	class ForExprMutator {
 	  public:
-		virtual Statement *mutate( ForStmt * );
+		Statement *postmutate( ForStmt * );
 	};
 } // namespace ControlStruct
Index: src/ControlStruct/Mutate.cc
===================================================================
--- src/ControlStruct/Mutate.cc	(revision f94ca7ea5a1653637b80ac0a0d965178dbd30798)
+++ src/ControlStruct/Mutate.cc	(revision 0db6fc0e30a15a277876f071902c2fced6294c93)
@@ -26,4 +26,5 @@
 
 #include "Common/utility.h"
+#include "Common/PassVisitor.h"
 
 #include "SynTree/Visitor.h"
@@ -34,5 +35,5 @@
 	void mutate( std::list< Declaration * > translationUnit ) {
 		// hoist initialization out of for statements
-		ForExprMutator formut;
+		PassVisitor<ForExprMutator> formut;
 
 		// normalizes label definitions and generates multi-level exit labels
Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision f94ca7ea5a1653637b80ac0a0d965178dbd30798)
+++ src/InitTweak/GenInit.cc	(revision 0db6fc0e30a15a277876f071902c2fced6294c93)
@@ -44,6 +44,4 @@
 		static void makeReturnTemp( std::list< Declaration * > &translationUnit );
 
-		ReturnFixer();
-
 		typedef GenPoly::PolyMutator Parent;
 		using Parent::mutate;
@@ -134,6 +132,4 @@
 		mutateAll( translationUnit, fixer );
 	}
-
-	ReturnFixer::ReturnFixer() {}
 
 	Statement *ReturnFixer::mutate( ReturnStmt *returnStmt ) {
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision f94ca7ea5a1653637b80ac0a0d965178dbd30798)
+++ src/SymTab/Validate.cc	(revision 0db6fc0e30a15a277876f071902c2fced6294c93)
@@ -38,29 +38,38 @@
 //   definition occurs later in the input.
 
+#include <algorithm>
+#include <iterator>
 #include <list>
-#include <iterator>
+
+#include "CodeGen/CodeGenerator.h"
+
+#include "Common/PassVisitor.h"
 #include "Common/ScopedMap.h"
+#include "Common/UniqueName.h"
 #include "Common/utility.h"
-#include "Common/UniqueName.h"
+
 #include "Concurrency/Keywords.h"
-#include "Validate.h"
-#include "SynTree/Visitor.h"
-#include "SynTree/Mutator.h"
-#include "SynTree/Type.h"
-#include "SynTree/Expression.h"
-#include "SynTree/Statement.h"
-#include "SynTree/TypeSubstitution.h"
-#include "Indexer.h"
+
+#include "GenPoly/DeclMutator.h"
+
+#include "InitTweak/InitTweak.h"
+
+#include "AddVisit.h"
+#include "Autogen.h"
 #include "FixFunction.h"
 // #include "ImplementationType.h"
-#include "GenPoly/DeclMutator.h"
-#include "AddVisit.h"
+#include "Indexer.h"
 #include "MakeLibCfa.h"
 #include "TypeEquality.h"
-#include "Autogen.h"
+#include "Validate.h"
+
 #include "ResolvExpr/typeops.h"
-#include <algorithm>
-#include "InitTweak/InitTweak.h"
-#include "CodeGen/CodeGenerator.h"
+
+#include "SynTree/Expression.h"
+#include "SynTree/Mutator.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Type.h"
+#include "SynTree/TypeSubstitution.h"
+#include "SynTree/Visitor.h"
 
 #define debugPrint( x ) if ( doDebug ) { std::cout << x; }
@@ -96,13 +105,10 @@
 
 	/// Fix return types so that every function returns exactly one value
-	class ReturnTypeFixer final : public Visitor {
+	class ReturnTypeFixer {
 	  public:
-		typedef Visitor Parent;
-		using Parent::visit;
-
 		static void fix( std::list< Declaration * > &translationUnit );
 
-		virtual void visit( FunctionDecl * functionDecl );
-		virtual void visit( FunctionType * ftype );
+		void postvisit( FunctionDecl * functionDecl );
+		void postvisit( FunctionType * ftype );
 	};
 
@@ -153,5 +159,5 @@
 	};
 
-	class ReturnChecker : public Visitor {
+	class ReturnChecker {
 	  public:
 		/// Checks that return statements return nothing if their return type is void
@@ -159,8 +165,11 @@
 		static void checkFunctionReturns( std::list< Declaration * > & translationUnit );
 	  private:
-		virtual void visit( FunctionDecl * functionDecl );
-		virtual void visit( ReturnStmt * returnStmt );
-
-		std::list< DeclarationWithType * > returnVals;
+		void previsit( FunctionDecl * functionDecl );
+		void postvisit( FunctionDecl * functionDecl );
+		void previsit( ReturnStmt * returnStmt );
+
+		typedef std::list< DeclarationWithType * > ReturnVals;
+		ReturnVals returnVals;
+		std::stack< ReturnVals > returnValsStack;
 	};
 
@@ -198,5 +207,5 @@
 	};
 
-	class VerifyCtorDtorAssign : public Visitor {
+	class VerifyCtorDtorAssign {
 	public:
 		/// ensure that constructors, destructors, and assignment have at least one
@@ -205,16 +214,15 @@
 		static void verify( std::list< Declaration * > &translationUnit );
 
-		virtual void visit( FunctionDecl *funcDecl );
+		void previsit( FunctionDecl *funcDecl );
 	};
 
 	/// ensure that generic types have the correct number of type arguments
-	class ValidateGenericParameters : public Visitor {
+	class ValidateGenericParameters {
 	public:
-		typedef Visitor Parent;
-		virtual void visit( StructInstType * inst ) final override;
-		virtual void visit( UnionInstType * inst ) final override;
-	};
-
-	class ArrayLength : public Visitor {
+		void previsit( StructInstType * inst );
+		void previsit( UnionInstType * inst );
+	};
+
+	class ArrayLength {
 	public:
 		/// for array types without an explicit length, compute the length and store it so that it
@@ -227,5 +235,5 @@
 		static void computeLength( std::list< Declaration * > & translationUnit );
 
-		virtual void visit( ObjectDecl * objDecl );
+		void previsit( ObjectDecl * objDecl );
 	};
 
@@ -243,5 +251,5 @@
 		Pass3 pass3( 0 );
 		CompoundLiteral compoundliteral;
-		ValidateGenericParameters genericParams;
+		PassVisitor<ValidateGenericParameters> genericParams;
 
 		EliminateTypedef::eliminateTypedef( translationUnit );
@@ -594,16 +602,18 @@
 
 	void ReturnChecker::checkFunctionReturns( std::list< Declaration * > & translationUnit ) {
-		ReturnChecker checker;
+		PassVisitor<ReturnChecker> checker;
 		acceptAll( translationUnit, checker );
 	}
 
-	void ReturnChecker::visit( FunctionDecl * functionDecl ) {
-		std::list< DeclarationWithType * > oldReturnVals = returnVals;
+	void ReturnChecker::previsit( FunctionDecl * functionDecl ) {
+		returnValsStack.push( returnVals );
 		returnVals = functionDecl->get_functionType()->get_returnVals();
-		Visitor::visit( functionDecl );
-		returnVals = oldReturnVals;
-	}
-
-	void ReturnChecker::visit( ReturnStmt * returnStmt ) {
+	}
+	void ReturnChecker::postvisit( FunctionDecl * functionDecl ) {
+		returnVals = returnValsStack.top();
+		returnValsStack.pop();
+	}
+
+	void ReturnChecker::previsit( ReturnStmt * returnStmt ) {
 		// Previously this also checked for the existence of an expr paired with no return values on
 		// the  function return type. This is incorrect, since you can have an expression attached to
@@ -815,9 +825,9 @@
 
 	void VerifyCtorDtorAssign::verify( std::list< Declaration * > & translationUnit ) {
-		VerifyCtorDtorAssign verifier;
+		PassVisitor<VerifyCtorDtorAssign> verifier;
 		acceptAll( translationUnit, verifier );
 	}
 
-	void VerifyCtorDtorAssign::visit( FunctionDecl * funcDecl ) {
+	void VerifyCtorDtorAssign::previsit( FunctionDecl * funcDecl ) {
 		FunctionType * funcType = funcDecl->get_functionType();
 		std::list< DeclarationWithType * > &returnVals = funcType->get_returnVals();
@@ -836,6 +846,4 @@
 			}
 		}
-
-		Visitor::visit( funcDecl );
 	}
 
@@ -875,12 +883,10 @@
 	}
 
-	void ValidateGenericParameters::visit( StructInstType * inst ) {
+	void ValidateGenericParameters::previsit( StructInstType * inst ) {
 		validateGeneric( inst );
-		Parent::visit( inst );
-	}
-
-	void ValidateGenericParameters::visit( UnionInstType * inst ) {
+	}
+
+	void ValidateGenericParameters::previsit( UnionInstType * inst ) {
 		validateGeneric( inst );
-		Parent::visit( inst );
 	}
 
@@ -906,10 +912,9 @@
 
 	void ReturnTypeFixer::fix( std::list< Declaration * > &translationUnit ) {
-		ReturnTypeFixer fixer;
+		PassVisitor<ReturnTypeFixer> fixer;
 		acceptAll( translationUnit, fixer );
 	}
 
-	void ReturnTypeFixer::visit( FunctionDecl * functionDecl ) {
-		Parent::visit( functionDecl );
+	void ReturnTypeFixer::postvisit( FunctionDecl * functionDecl ) {
 		FunctionType * ftype = functionDecl->get_functionType();
 		std::list< DeclarationWithType * > & retVals = ftype->get_returnVals();
@@ -925,5 +930,5 @@
 	}
 
-	void ReturnTypeFixer::visit( FunctionType * ftype ) {
+	void ReturnTypeFixer::postvisit( FunctionType * ftype ) {
 		// xxx - need to handle named return values - this information needs to be saved somehow
 		// so that resolution has access to the names.
@@ -943,9 +948,9 @@
 
 	void ArrayLength::computeLength( std::list< Declaration * > & translationUnit ) {
-		ArrayLength len;
+		PassVisitor<ArrayLength> len;
 		acceptAll( translationUnit, len );
 	}
 
-	void ArrayLength::visit( ObjectDecl * objDecl ) {
+	void ArrayLength::previsit( ObjectDecl * objDecl ) {
 		if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) {
 			if ( at->get_dimension() != nullptr ) return;
