Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision 65dc8635169a69696916835b7ef9060318cc4904)
+++ src/InitTweak/GenInit.cc	(revision 2a7b3ca400fe85559a7ebbd5d3b09859d5dfc4da)
@@ -44,6 +44,5 @@
 	}
 
-	class ReturnFixer : public WithStmtsToAdd, public WithScopes {
-	  public:
+	struct ReturnFixer : public WithStmtsToAdd, public WithGuards {
 		/// consistently allocates a temporary variable for the return value
 		/// of a function so that anything which the resolver decides can be constructed
@@ -59,8 +58,5 @@
 	};
 
-	class CtorDtor final : public GenPoly::PolyMutator {
-	  public:
-		typedef GenPoly::PolyMutator Parent;
-		using Parent::mutate;
+	struct CtorDtor : public WithGuards, public WithShortCircuiting  {
 		/// create constructor and destructor statements for object declarations.
 		/// the actual call statements will be added in after the resolver has run
@@ -69,18 +65,19 @@
 		static void generateCtorDtor( std::list< Declaration * > &translationUnit );
 
-		virtual DeclarationWithType * mutate( ObjectDecl * ) override;
-		virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ) override;
+		void previsit( ObjectDecl * );
+		void previsit( FunctionDecl *functionDecl );
+
 		// should not traverse into any of these declarations to find objects
 		// that need to be constructed or destructed
-		virtual Declaration* mutate( StructDecl *aggregateDecl ) override;
-		virtual Declaration* mutate( UnionDecl *aggregateDecl ) override { return aggregateDecl; }
-		virtual Declaration* mutate( EnumDecl *aggregateDecl ) override { return aggregateDecl; }
-		virtual Declaration* mutate( TraitDecl *aggregateDecl ) override { return aggregateDecl; }
-		virtual TypeDecl* mutate( TypeDecl *typeDecl ) override { return typeDecl; }
-		virtual Declaration* mutate( TypedefDecl *typeDecl ) override { return typeDecl; }
-
-		virtual Type * mutate( FunctionType *funcType ) override { return funcType; }
-
-		virtual CompoundStmt * mutate( CompoundStmt * compoundStmt ) override;
+		void previsit( StructDecl *aggregateDecl );
+		void previsit( UnionDecl *aggregateDecl ) { visit_children = false; }
+		void previsit( EnumDecl *aggregateDecl ) { visit_children = false; }
+		void previsit( TraitDecl *aggregateDecl ) { visit_children = false; }
+		void previsit( TypeDecl *typeDecl ) { visit_children = false; }
+		void previsit( TypedefDecl *typeDecl ) { visit_children = false; }
+
+		void previsit( FunctionType *funcType ) { visit_children = false; }
+
+		void previsit( CompoundStmt * compoundStmt );
 
 	  private:
@@ -211,6 +208,6 @@
 
 	void CtorDtor::generateCtorDtor( std::list< Declaration * > & translationUnit ) {
-		CtorDtor ctordtor;
-		mutateAll( translationUnit, ctordtor );
+		PassVisitor<CtorDtor> ctordtor;
+		acceptAll( translationUnit, ctordtor );
 	}
 
@@ -289,5 +286,5 @@
 	}
 
-	DeclarationWithType * CtorDtor::mutate( ObjectDecl * objDecl ) {
+	void CtorDtor::previsit( ObjectDecl * objDecl ) {
 		handleDWT( objDecl );
 		// hands off if @=, extern, builtin, etc.
@@ -301,14 +298,13 @@
 			objDecl->set_init( genCtorInit( objDecl ) );
 		}
-		return Parent::mutate( objDecl );
-	}
-
-	DeclarationWithType * CtorDtor::mutate( FunctionDecl *functionDecl ) {
-		ValueGuard< bool > oldInFunc = inFunction;
+	}
+
+	void CtorDtor::previsit( FunctionDecl *functionDecl ) {
+		GuardValue( inFunction );
 		inFunction = true;
 
 		handleDWT( functionDecl );
 
-		managedTypes.beginScope();
+		GuardScope( managedTypes );
 		// go through assertions and recursively add seen ctor/dtors
 		for ( auto & tyDecl : functionDecl->get_functionType()->get_forall() ) {
@@ -317,12 +313,14 @@
 			}
 		}
-		// parameters should not be constructed and destructed, so don't mutate FunctionType
-		functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
-
-		managedTypes.endScope();
-		return functionDecl;
-	}
-
-	Declaration* CtorDtor::mutate( StructDecl *aggregateDecl ) {
+
+		PassVisitor<CtorDtor> newCtorDtor;
+		newCtorDtor.pass = *this;
+		maybeAccept( functionDecl->get_statements(), newCtorDtor );
+		visit_children = false;  // do not try and construct parameters or forall parameters - must happen after maybeAccept
+	}
+
+	void CtorDtor::previsit( StructDecl *aggregateDecl ) {
+		visit_children = false; // do not try to construct and destruct aggregate members
+
 		// don't construct members, but need to take note if there is a managed member,
 		// because that means that this type is also managed
@@ -336,14 +334,9 @@
 			}
 		}
-		return aggregateDecl;
-	}
-
-	CompoundStmt * CtorDtor::mutate( CompoundStmt * compoundStmt ) {
-		managedTypes.beginScope();
-		CompoundStmt * stmt = Parent::mutate( compoundStmt );
-		managedTypes.endScope();
-		return stmt;
-	}
-
+	}
+
+	void CtorDtor::previsit( CompoundStmt * compoundStmt ) {
+		GuardScope( managedTypes );
+	}
 } // namespace InitTweak
 
