Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision e4d63351e8c4b4dafb1f42983befdfc6c0e697d1)
+++ src/CodeGen/CodeGenerator.cc	(revision 22bc27633b10d98030a7959b4671f00d9985c61a)
@@ -443,11 +443,11 @@
 	void CodeGenerator::postvisit( UntypedExpr * untypedExpr ) {
 		extension( untypedExpr );
-		if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
+		if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->function ) ) {
 			OperatorInfo opInfo;
-			if ( operatorLookup( nameExpr->get_name(), opInfo ) ) {
-				std::list< Expression* >::iterator arg = untypedExpr->get_args().begin();
+			if ( operatorLookup( nameExpr->name, opInfo ) ) {
+				std::list< Expression* >::iterator arg = untypedExpr->args.begin();
 				switch ( opInfo.type ) {
 				  case OT_INDEX:
-					assert( untypedExpr->get_args().size() == 2 );
+					assert( untypedExpr->args.size() == 2 );
 					(*arg++)->accept( *visitor );
 					output << "[";
@@ -461,5 +461,5 @@
 				  case OT_CTOR:
 				  case OT_DTOR:
-					if ( untypedExpr->get_args().size() == 1 ) {
+					if ( untypedExpr->args.size() == 1 ) {
 						// the expression fed into a single parameter constructor or destructor may contain side
 						// effects, so must still output this expression
@@ -480,5 +480,5 @@
 						(*arg++)->accept( *visitor );
 						output << opInfo.symbol << "{ ";
-						genCommaList( arg, untypedExpr->get_args().end() );
+						genCommaList( arg, untypedExpr->args.end() );
 						output << "}) /* " << opInfo.inputName << " */";
 					} // if
@@ -488,5 +488,5 @@
 				  case OT_PREFIXASSIGN:
 				  case OT_LABELADDRESS:
-					assert( untypedExpr->get_args().size() == 1 );
+					assert( untypedExpr->args.size() == 1 );
 					output << "(";
 					output << opInfo.symbol;
@@ -497,5 +497,5 @@
 				  case OT_POSTFIX:
 				  case OT_POSTFIXASSIGN:
-					assert( untypedExpr->get_args().size() == 1 );
+					assert( untypedExpr->args.size() == 1 );
 					(*arg)->accept( *visitor );
 					output << opInfo.symbol;
@@ -504,5 +504,5 @@
 				  case OT_INFIX:
 				  case OT_INFIXASSIGN:
-					assert( untypedExpr->get_args().size() == 2 );
+					assert( untypedExpr->args.size() == 2 );
 					output << "(";
 					(*arg++)->accept( *visitor );
@@ -517,20 +517,14 @@
 				} // switch
 			} else {
-				if ( nameExpr->get_name() == "..." ) { // case V1 ... V2 or case V1~V2
-					assert( untypedExpr->get_args().size() == 2 );
-					(*untypedExpr->get_args().begin())->accept( *visitor );
-					output << " ... ";
-					(*--untypedExpr->get_args().end())->accept( *visitor );
-				} else {								// builtin routines
-					nameExpr->accept( *visitor );
-					output << "(";
-					genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
-					output << ")";
-				} // if
+				// builtin routines
+				nameExpr->accept( *visitor );
+				output << "(";
+				genCommaList( untypedExpr->args.begin(), untypedExpr->args.end() );
+				output << ")";
 			} // if
 		} else {
-			untypedExpr->get_function()->accept( *visitor );
+			untypedExpr->function->accept( *visitor );
 			output << "(";
-			genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
+			genCommaList( untypedExpr->args.begin(), untypedExpr->args.end() );
 			output << ")";
 		} // if
@@ -538,7 +532,7 @@
 
 	void CodeGenerator::postvisit( RangeExpr * rangeExpr ) {
-		rangeExpr->get_low()->accept( *visitor );
+		rangeExpr->low->accept( *visitor );
 		output << " ... ";
-		rangeExpr->get_high()->accept( *visitor );
+		rangeExpr->high->accept( *visitor );
 	}
 
Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision e4d63351e8c4b4dafb1f42983befdfc6c0e697d1)
+++ src/InitTweak/GenInit.cc	(revision 22bc27633b10d98030a7959b4671f00d9985c61a)
@@ -62,5 +62,5 @@
 	};
 
-	struct CtorDtor : public WithGuards, public WithShortCircuiting  {
+	struct CtorDtor : public WithGuards, public WithShortCircuiting, public WithVisitorRef<CtorDtor>  {
 		/// create constructor and destructor statements for object declarations.
 		/// the actual call statements will be added in after the resolver has run
@@ -75,10 +75,7 @@
 		// that need to be constructed or destructed
 		void previsit( StructDecl *aggregateDecl );
-		void previsit( __attribute__((unused)) UnionDecl    * aggregateDecl ) { visit_children = false; }
-		void previsit( __attribute__((unused)) EnumDecl     * aggregateDecl ) { visit_children = false; }
-		void previsit( __attribute__((unused)) TraitDecl    * aggregateDecl ) { visit_children = false; }
-		void previsit( __attribute__((unused)) TypeDecl     * typeDecl )      { visit_children = false; }
-		void previsit( __attribute__((unused)) TypedefDecl  * typeDecl )      { visit_children = false; }
-		void previsit( __attribute__((unused)) FunctionType * funcType )      { visit_children = false; }
+		void premutate( AggregateDecl * ) { visit_children = false; }
+		void premutate( NamedTypeDecl * ) { visit_children = false; }
+		void previsit( FunctionType * ) { visit_children = false; }
 
 		void previsit( CompoundStmt * compoundStmt );
@@ -96,8 +93,5 @@
 	};
 
-	class HoistArrayDimension final : public GenPoly::DeclMutator {
-	  public:
-		typedef GenPoly::DeclMutator Parent;
-
+	struct HoistArrayDimension final : public WithDeclsToAdd, public WithShortCircuiting, public WithGuards {
 		/// hoist dimension from array types in object declaration so that it uses a single
 		/// const variable of type size_t, so that side effecting array dimensions are only
@@ -105,19 +99,12 @@
 		static void hoistArrayDimension( std::list< Declaration * > & translationUnit );
 
-	  private:
-		using Parent::mutate;
-
-		virtual DeclarationWithType * mutate( ObjectDecl * objectDecl ) override;
-		virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ) override;
+		void premutate( ObjectDecl * objectDecl );
+		DeclarationWithType * postmutate( ObjectDecl * objectDecl );
+		void premutate( 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 { return aggregateDecl; }
-		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; }
+		void premutate( AggregateDecl * ) { visit_children = false; }
+		void premutate( NamedTypeDecl * ) { visit_children = false; }
+		void premutate( FunctionType * ) { visit_children = false; }
 
 		void hoist( Type * type );
@@ -143,5 +130,5 @@
 		// hands off if the function returns a reference - we don't want to allocate a temporary if a variable's address
 		// is being returned
-		if ( returnStmt->get_expr() && returnVals.size() == 1 && ! dynamic_cast< ReferenceType * >( returnVals.front()->get_type() ) ) {
+		if ( returnStmt->get_expr() && returnVals.size() == 1 && tryConstruct( returnVals.front() ) ) {
 			// explicitly construct the return value using the return expression and the retVal object
 			assertf( returnVals.front()->get_name() != "", "Function %s has unnamed return value\n", funcName.c_str() );
@@ -158,6 +145,6 @@
 		GuardValue( funcName );
 
-		ftype = functionDecl->get_functionType();
-		funcName = functionDecl->get_name();
+		ftype = functionDecl->type;
+		funcName = functionDecl->name;
 	}
 
@@ -165,13 +152,16 @@
 	// which would be incorrect if it is a side-effecting computation.
 	void HoistArrayDimension::hoistArrayDimension( std::list< Declaration * > & translationUnit ) {
-		HoistArrayDimension hoister;
-		hoister.mutateDeclarationList( translationUnit );
-	}
-
-	DeclarationWithType * HoistArrayDimension::mutate( ObjectDecl * objectDecl ) {
+		PassVisitor<HoistArrayDimension> hoister;
+		mutateAll( translationUnit, hoister );
+	}
+
+	void HoistArrayDimension::premutate( ObjectDecl * objectDecl ) {
+		GuardValue( storageClasses );
 		storageClasses = objectDecl->get_storageClasses();
-		DeclarationWithType * temp = Parent::mutate( objectDecl );
+	}
+
+	DeclarationWithType * HoistArrayDimension::postmutate( ObjectDecl * objectDecl ) {
 		hoist( objectDecl->get_type() );
-		return temp;
+		return objectDecl;
 	}
 
@@ -194,5 +184,5 @@
 
 			arrayType->set_dimension( new VariableExpr( arrayDimension ) );
-			addDeclaration( arrayDimension );
+			declsToAddBefore.push_back( arrayDimension );
 
 			hoist( arrayType->get_base() );
@@ -201,9 +191,6 @@
 	}
 
-	DeclarationWithType * HoistArrayDimension::mutate( FunctionDecl *functionDecl ) {
-		ValueGuard< bool > oldInFunc( inFunction );
-		inFunction = true;
-		DeclarationWithType * decl = Parent::mutate( functionDecl );
-		return decl;
+	void HoistArrayDimension::premutate( FunctionDecl * ) {
+		GuardValue( inFunction );
 	}
 
@@ -214,5 +201,5 @@
 
 	bool CtorDtor::isManaged( Type * type ) const {
-		// at least for now, references are never constructed
+		// references are never constructed
 		if ( dynamic_cast< ReferenceType * >( type ) ) return false;
 		// need to clear and reset qualifiers when determining if a type is managed
@@ -221,5 +208,5 @@
 		if ( TupleType * tupleType = dynamic_cast< TupleType * > ( type ) ) {
 			// tuple is also managed if any of its components are managed
-			if ( std::any_of( tupleType->get_types().begin(), tupleType->get_types().end(), [&](Type * type) { return isManaged( type ); }) ) {
+			if ( std::any_of( tupleType->types.begin(), tupleType->types.end(), [&](Type * type) { return isManaged( type ); }) ) {
 				return true;
 			}
@@ -305,4 +292,5 @@
 
 	void CtorDtor::previsit( FunctionDecl *functionDecl ) {
+		visit_children = false;  // do not try and construct parameters or forall parameters
 		GuardValue( inFunction );
 		inFunction = true;
@@ -318,8 +306,5 @@
 		}
 
-		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
+		maybeAccept( functionDecl->get_statements(), *visitor );
 	}
 
@@ -340,5 +325,5 @@
 	}
 
-	void CtorDtor::previsit( __attribute__((unused)) CompoundStmt * compoundStmt ) {
+	void CtorDtor::previsit( CompoundStmt * ) {
 		GuardScope( managedTypes );
 	}
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision e4d63351e8c4b4dafb1f42983befdfc6c0e697d1)
+++ src/InitTweak/InitTweak.cc	(revision 22bc27633b10d98030a7959b4671f00d9985c61a)
@@ -1,3 +1,2 @@
-#include <stddef.h>                // for NULL
 #include <algorithm>               // for find, all_of
 #include <cassert>                 // for assertf, assert, strict_dynamic_cast
@@ -184,5 +183,5 @@
 			callExpr->get_args().splice( callExpr->get_args().end(), args );
 
-			*out++ = new IfStmt( noLabels, cond, new ExprStmt( noLabels, callExpr ), NULL );
+			*out++ = new IfStmt( noLabels, cond, new ExprStmt( noLabels, callExpr ), nullptr );
 
 			UntypedExpr * increment = new UntypedExpr( new NameExpr( "++?" ) );
@@ -250,18 +249,18 @@
 	// To accomplish this, generate switch statement, consuming all of expander's elements
 	Statement * InitImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) {
-		if ( ! init ) return NULL;
+		if ( ! init ) return nullptr;
 		CompoundStmt * block = new CompoundStmt( noLabels );
 		build( dst, indices.begin(), indices.end(), init, back_inserter( block->get_kids() ) );
 		if ( block->get_kids().empty() ) {
 			delete block;
-			return NULL;
+			return nullptr;
 		} else {
-			init = NULL; // init was consumed in creating the list init
+			init = nullptr; // init was consumed in creating the list init
 			return block;
 		}
 	}
 
-	Statement * ExprImpl::buildListInit( __attribute((unused)) UntypedExpr * dst, __attribute((unused)) std::list< Expression * > & indices ) {
-		return NULL;
+	Statement * ExprImpl::buildListInit( UntypedExpr *, std::list< Expression * > & ) {
+		return nullptr;
 	}
 
@@ -270,9 +269,12 @@
 	}
 
-	bool tryConstruct( ObjectDecl * objDecl ) {
+	bool tryConstruct( DeclarationWithType * dwt ) {
+		ObjectDecl * objDecl = dynamic_cast< ObjectDecl * >( dwt );
+		if ( ! objDecl ) return false;
 		return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) &&
-			(objDecl->get_init() == NULL ||
-				( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() ))
-			&& ! objDecl->get_storageClasses().is_extern;
+			(objDecl->get_init() == nullptr ||
+				( objDecl->get_init() != nullptr && objDecl->get_init()->get_maybeConstructed() ))
+			&& ! objDecl->get_storageClasses().is_extern
+			&& ! dynamic_cast< ReferenceType * >( objDecl->type );
 	}
 
@@ -314,5 +316,5 @@
 		collectCtorDtorCalls( stmt, matches );
 		assert( matches.size() <= 1 );
-		return matches.size() == 1 ? matches.front() : NULL;
+		return matches.size() == 1 ? matches.front() : nullptr;
 	}
 
@@ -359,10 +361,10 @@
 	ApplicationExpr * isIntrinsicCallExpr( Expression * expr ) {
 		ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr );
-		if ( ! appExpr ) return NULL;
+		if ( ! appExpr ) return nullptr;
 		DeclarationWithType * function = getCalledFunction( appExpr->get_function() );
 		assertf( function, "getCalledFunction returned nullptr: %s", toString( appExpr->get_function() ).c_str() );
 		// check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor
 		// will call all member dtors, and some members may have a user defined dtor.
-		return function->get_linkage() == LinkageSpec::Intrinsic ? appExpr : NULL;
+		return function->get_linkage() == LinkageSpec::Intrinsic ? appExpr : nullptr;
 	}
 
@@ -482,5 +484,5 @@
 			return refType->get_base();
 		} else {
-			return NULL;
+			return nullptr;
 		}
 	}
@@ -488,5 +490,5 @@
 	Type * isPointerType( Type * type ) {
 		if ( getPointerBase( type ) ) return type;
-		else return NULL;
+		else return nullptr;
 	}
 
Index: src/InitTweak/InitTweak.h
===================================================================
--- src/InitTweak/InitTweak.h	(revision e4d63351e8c4b4dafb1f42983befdfc6c0e697d1)
+++ src/InitTweak/InitTweak.h	(revision 22bc27633b10d98030a7959b4671f00d9985c61a)
@@ -33,6 +33,6 @@
 	std::list< Expression * > makeInitList( Initializer * init );
 
-	/// True if the resolver should try to construct objDecl
-	bool tryConstruct( ObjectDecl * objDecl );
+	/// True if the resolver should try to construct dwt
+	bool tryConstruct( DeclarationWithType * dwt );
 
 	/// True if the Initializer contains designations
