Index: src/GenPoly/DeclMutator.cc
===================================================================
--- src/GenPoly/DeclMutator.cc	(revision b0b958a2dfe5052fbfc59bc8543a758787df2f9d)
+++ src/GenPoly/DeclMutator.cc	(revision b0b958a2dfe5052fbfc59bc8543a758787df2f9d)
@@ -0,0 +1,164 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// DeclMutator.cc --
+//
+// Author           : Aaron B. Moss
+// Created On       : Fri Nov 27 14:44:00 2015
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Fri Nov 27 14:44:00 2015
+// Update Count     : 1
+//
+
+#include "DeclMutator.h"
+
+#include "SynTree/Expression.h"
+#include "SynTree/Statement.h"
+
+namespace GenPoly {
+	namespace {
+		const std::list<Label> noLabels;
+	}
+
+	DeclMutator::DeclMutator() : Mutator(), declsToAdd(1) {}
+
+	DeclMutator::~DeclMutator() {}
+	
+	void DeclMutator::mutateDeclarationList( std::list< Declaration* > &decls ) {
+		for ( std::list< Declaration* >::iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
+			// run mutator on declaration
+			*decl = maybeMutate( *decl, *this );
+
+			// splice in new declarations before current decl
+			decls.splice( decl, declsToAdd.back() );
+		}
+	}
+
+	void DeclMutator::doBeginScope() {
+		// add new decl list for inside of scope
+		declsToAdd.resize( declsToAdd.size()+1 );
+	}
+
+	void DeclMutator::doEndScope() {
+		// splice any leftover declarations from this scope onto the containing scope
+		std::vector< std::list< Declaration* > >::reverse_iterator back = declsToAdd.rbegin();
+		std::vector< std::list< Declaration* > >::reverse_iterator newBack = back + 1;
+		newBack->splice( newBack->end(), *back );
+		declsToAdd.pop_back();
+	}
+
+	Statement* DeclMutator::mutateStatement( Statement *stmt ) {
+		// shunt over to compound statement handling if applicable
+		CompoundStmt *compoundStmt = dynamic_cast< CompoundStmt* >(stmt);
+		if ( compoundStmt ) return mutate( compoundStmt );
+		
+		doBeginScope();
+		
+		// run mutator on statement
+		stmt = maybeMutate( stmt, *this );
+		// return if no declarations to add
+		if ( declsToAdd.back().empty() ) return stmt;
+
+		// otherwise add declarations to new compound statement
+		CompoundStmt *compound = new CompoundStmt( noLabels );
+		for ( std::list< Declaration* >::iterator decl = declsToAdd.back().begin(); decl != declsToAdd.back().end(); ++decl ) {
+			DeclStmt *declStmt = new DeclStmt( noLabels, *decl );
+			compound->get_kids().push_back( declStmt );
+		}
+		declsToAdd.back().clear();
+
+		doEndScope();
+
+		// add mutated statement and return
+		compound->get_kids().push_back( stmt );
+		return compound;
+	}
+
+	void DeclMutator::mutateStatementList( std::list< Statement* > &stmts ) {
+		doBeginScope();
+		
+		for ( std::list< Statement* >::iterator stmt = stmts.begin(); stmt != stmts.end(); ++stmt ) {
+			// run mutator on statement
+			*stmt = maybeMutate( *stmt, *this );
+
+			// add any new declarations before the statement
+			for ( std::list< Declaration* >::iterator decl = declsToAdd.back().begin(); decl != declsToAdd.back().end(); ++decl ) {
+				DeclStmt *declStmt = new DeclStmt( noLabels, *decl );
+				stmts.insert( stmt, declStmt );
+			}
+			declsToAdd.back().clear();
+		}
+
+		doEndScope();
+	}
+
+	void DeclMutator::addDeclaration( Declaration *decl ) {
+		declsToAdd.back().push_back( decl );
+	}
+
+	CompoundStmt* DeclMutator::mutate(CompoundStmt *compoundStmt) {
+		mutateStatementList( compoundStmt->get_kids() );
+		return compoundStmt;
+	}
+	
+	Statement* DeclMutator::mutate(IfStmt *ifStmt) {
+		ifStmt->set_condition( maybeMutate( ifStmt->get_condition(), *this ) );
+		ifStmt->set_thenPart( mutateStatement( ifStmt->get_thenPart() ) );
+		ifStmt->set_elsePart( mutateStatement( ifStmt->get_elsePart() ) );
+		return ifStmt;
+	}
+	
+	Statement* DeclMutator::mutate(WhileStmt *whileStmt) {
+		whileStmt->set_condition( maybeMutate( whileStmt->get_condition(), *this ) );
+		whileStmt->set_body(  mutateStatement( whileStmt->get_body() ) );
+		return whileStmt;
+	}
+	
+	Statement* DeclMutator::mutate(ForStmt *forStmt) {
+		mutateAll( forStmt->get_initialization(), *this );
+		forStmt->set_condition(  maybeMutate( forStmt->get_condition(), *this ) );
+		forStmt->set_increment(  maybeMutate( forStmt->get_increment(), *this ) );
+		forStmt->set_body(  mutateStatement( forStmt->get_body() ) );
+		return forStmt;
+	}
+	
+	Statement* DeclMutator::mutate(SwitchStmt *switchStmt) {
+		switchStmt->set_condition( maybeMutate( switchStmt->get_condition(), *this ) );
+		mutateAll( switchStmt->get_branches(), *this );
+		return switchStmt;
+	}
+	
+	Statement* DeclMutator::mutate(ChooseStmt *chooseStmt) {
+		chooseStmt->set_condition( maybeMutate( chooseStmt->get_condition(), *this ) );
+		mutateAll( chooseStmt->get_branches(), *this );
+		return chooseStmt;
+	}
+	
+	Statement* DeclMutator::mutate(CaseStmt *caseStmt) {
+		caseStmt->set_condition( maybeMutate( caseStmt->get_condition(), *this ) );
+		mutateAll( caseStmt->get_statements(), *this );
+		return caseStmt;
+	}
+	
+	Statement* DeclMutator::mutate(TryStmt *tryStmt) {
+		tryStmt->set_block( maybeMutate( tryStmt->get_block(), *this ) );
+		mutateAll( tryStmt->get_catchers(), *this );
+		tryStmt->set_finally( maybeMutate( tryStmt->get_finally(), *this ) );
+		return tryStmt;
+	}
+	
+	Statement* DeclMutator::mutate(CatchStmt *catchStmt) {
+		catchStmt->set_decl( maybeMutate( catchStmt->get_decl(), *this ) );
+		catchStmt->set_body( mutateStatement( catchStmt->get_body() ) );
+		return catchStmt;
+	}
+}  // namespace GenPoly
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/GenPoly/DeclMutator.h
===================================================================
--- src/GenPoly/DeclMutator.h	(revision b0b958a2dfe5052fbfc59bc8543a758787df2f9d)
+++ src/GenPoly/DeclMutator.h	(revision b0b958a2dfe5052fbfc59bc8543a758787df2f9d)
@@ -0,0 +1,69 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// DeclMutator.h --
+//
+// Author           : Aaron B. Moss
+// Created On       : Fri Nov 27 14:44:00 2015
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Fri Nov 27 14:44:00 2015
+// Update Count     : 1
+//
+
+#ifndef _DECLMUTATOR_H
+#define _DECLMUTATOR_H
+
+#include <list>
+#include <vector>
+
+#include "SynTree/SynTree.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Mutator.h"
+
+namespace GenPoly {
+	/// Mutates a list of declarations, providing a means of adding new declarations into the list
+	class DeclMutator : public Mutator {
+	public:
+		DeclMutator();
+		virtual ~DeclMutator();
+		
+		virtual CompoundStmt* mutate(CompoundStmt *compoundStmt);
+		virtual Statement* mutate(IfStmt *ifStmt);
+		virtual Statement* mutate(WhileStmt *whileStmt);
+		virtual Statement* mutate(ForStmt *forStmt);
+		virtual Statement* mutate(SwitchStmt *switchStmt);
+		virtual Statement* mutate(ChooseStmt *chooseStmt);
+		virtual Statement* mutate(CaseStmt *caseStmt);
+		virtual Statement* mutate(TryStmt *tryStmt);
+		virtual Statement* mutate(CatchStmt *catchStmt);
+
+		/// Mutates a list of declarations with this visitor
+		void mutateDeclarationList(std::list< Declaration* >& decls);
+		
+		/// Called on entry to a new scope; overriders should call this as a super-class call
+		virtual void doBeginScope();
+		/// Called on exit from a scope; overriders should call this as a super-class call
+		virtual void doEndScope();
+	protected:
+		/// Mutate a statement that forms its own scope
+		Statement* mutateStatement( Statement *stmt );
+		/// Mutate a list of statements that form a scope
+		void mutateStatementList( std::list< Statement* > &stmts );
+		/// Add a declaration to the list to be added before the current position
+		void addDeclaration( Declaration* decl );
+	private:
+		/// A stack of declarations to add before the current declaration or statement
+		std::vector< std::list< Declaration* > > declsToAdd;
+	};
+} // namespace
+
+#endif // _DECLMUTATOR_H
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/GenPoly/InstantiateGeneric.cc
===================================================================
--- src/GenPoly/InstantiateGeneric.cc	(revision ed1065cf203b07392f55283f52fd47be3012ffcb)
+++ src/GenPoly/InstantiateGeneric.cc	(revision b0b958a2dfe5052fbfc59bc8543a758787df2f9d)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// InstantiateGeneric.h --
+// InstantiateGeneric.cc --
 //
 // Author           : Aaron B. Moss
@@ -21,5 +21,5 @@
 
 #include "InstantiateGeneric.h"
-#include "PolyMutator.h"
+#include "DeclMutator.h"
 
 #include "ResolvExpr/typeops.h"
@@ -138,14 +138,11 @@
 
 	/// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
-	class Instantiate : public PolyMutator {
+	class Instantiate : public DeclMutator {
 		InstantiationMap instantiations;
 		UniqueName typeNamer;
 
 	public:
-		Instantiate() : instantiations(), typeNamer("_conc_") {}
-
-		/// Mutates the whole translation unit, inserting new struct declarations as appropriate
-		void mutateAll( std::list< Declaration* >& translationUnit );
-		
+		Instantiate() : DeclMutator(), instantiations(), typeNamer("_conc_") {}
+
 		virtual Type* mutate( StructInstType *inst );
 		virtual Type* mutate( UnionInstType *inst );
@@ -153,43 +150,9 @@
 		virtual void doBeginScope();
 		virtual void doEndScope();
-
-	private:
-		/// Adds a declaration to the current environment and the statements to add
-		void addDeclaration( AggregateDecl *decl ) {
-			std::list< Label > nolabels;
-			DeclStmt *stmt = new DeclStmt( nolabels, decl );
-			PolyMutator::stmtsToAdd.push_back( stmt );
-		}
 	};
 	
 	void instantiateGeneric( std::list< Declaration* >& translationUnit ) {
 		Instantiate instantiator;
-//		mutateAll( translationUnit, instantiator );
-		instantiator.mutateAll( translationUnit );
-	}
-
-	void Instantiate::mutateAll( std::list< Declaration* >& translationUnit ) {
-		// below copied and modified from Mutator.h:mutateAll()
-		SemanticError errors;
-		for ( std::list< Declaration* >::iterator decl = translationUnit.begin(); decl != translationUnit.end(); ++decl ) {
-			try {
-				if ( *decl ) {
-					*decl = dynamic_cast< Declaration* >( (*decl)->acceptMutator( *this ) );
-					assert( *decl );
-					// account for missing top-level declarations
-					for ( std::list< Statement* >::const_iterator stmt = PolyMutator::stmtsToAdd.begin(); stmt != PolyMutator::stmtsToAdd.end(); ++stmt ) {
-						DeclStmt *declStmt = dynamic_cast< DeclStmt* >( *stmt );
-						assert( declStmt );
-						translationUnit.insert( decl, declStmt->get_decl() );
-					}
-					PolyMutator::stmtsToAdd.clear();
-				} // if
-			} catch( SemanticError &e ) {
-				errors.append( e );
-			} // try
-		} // for
-		if ( ! errors.isEmpty() ) {
-			throw errors;
-		} // if
+		instantiator.mutateDeclarationList( translationUnit );
 	}
 
@@ -225,5 +188,5 @@
 								*inst->get_baseParameters(), inst->get_parameters(),
 								concDecl->get_members() );
-			addDeclaration( concDecl );
+			DeclMutator::addDeclaration( concDecl );
 			instantiations.insert( inst, concDecl );
 		}
@@ -252,5 +215,5 @@
 								*inst->get_baseParameters(), inst->get_parameters(),
 								concDecl->get_members() );
-			addDeclaration( concDecl );
+			DeclMutator::addDeclaration( concDecl );
 			instantiations.insert( inst, concDecl );
 		}
@@ -262,4 +225,5 @@
 	
 	void Instantiate::doBeginScope() {
+		DeclMutator::doBeginScope();
 		// push a new concrete type scope
 		instantiations.beginScope();
@@ -267,4 +231,5 @@
 
 	void Instantiate::doEndScope() {
+		DeclMutator::doEndScope();
 		// pop the last concrete type scope
 		instantiations.endScope();
Index: src/GenPoly/module.mk
===================================================================
--- src/GenPoly/module.mk	(revision ed1065cf203b07392f55283f52fd47be3012ffcb)
+++ src/GenPoly/module.mk	(revision b0b958a2dfe5052fbfc59bc8543a758787df2f9d)
@@ -23,3 +23,4 @@
        GenPoly/CopyParams.cc \
        GenPoly/FindFunction.cc \
-       GenPoly/InstantiateGeneric.cc
+       GenPoly/InstantiateGeneric.cc \
+       GenPoly/DeclMutator.cc
Index: src/Makefile.in
===================================================================
--- src/Makefile.in	(revision ed1065cf203b07392f55283f52fd47be3012ffcb)
+++ src/Makefile.in	(revision b0b958a2dfe5052fbfc59bc8543a758787df2f9d)
@@ -122,4 +122,5 @@
 	GenPoly/cfa_cpp-FindFunction.$(OBJEXT) \
 	GenPoly/cfa_cpp-InstantiateGeneric.$(OBJEXT) \
+	GenPoly/cfa_cpp-DeclMutator.$(OBJEXT) \
 	InitTweak/cfa_cpp-InitModel.$(OBJEXT) \
 	InitTweak/cfa_cpp-InitExpander.$(OBJEXT) \
@@ -348,12 +349,13 @@
 	GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc GenPoly/Specialize.cc \
 	GenPoly/CopyParams.cc GenPoly/FindFunction.cc \
-	GenPoly/InstantiateGeneric.cc InitTweak/InitModel.cc \
-	InitTweak/InitExpander.cc InitTweak/Mutate.cc \
-	InitTweak/Association.cc InitTweak/RemoveInit.cc \
-	Parser/parser.yy Parser/lex.ll Parser/TypedefTable.cc \
-	Parser/ParseNode.cc Parser/DeclarationNode.cc \
-	Parser/ExpressionNode.cc Parser/StatementNode.cc \
-	Parser/InitializerNode.cc Parser/TypeData.cc \
-	Parser/LinkageSpec.cc Parser/parseutility.cc Parser/Parser.cc \
+	GenPoly/InstantiateGeneric.cc GenPoly/DeclMutator.cc \
+	InitTweak/InitModel.cc InitTweak/InitExpander.cc \
+	InitTweak/Mutate.cc InitTweak/Association.cc \
+	InitTweak/RemoveInit.cc Parser/parser.yy Parser/lex.ll \
+	Parser/TypedefTable.cc Parser/ParseNode.cc \
+	Parser/DeclarationNode.cc Parser/ExpressionNode.cc \
+	Parser/StatementNode.cc Parser/InitializerNode.cc \
+	Parser/TypeData.cc Parser/LinkageSpec.cc \
+	Parser/parseutility.cc Parser/Parser.cc \
 	ResolvExpr/AlternativeFinder.cc ResolvExpr/Alternative.cc \
 	ResolvExpr/Unify.cc ResolvExpr/PtrsAssignable.cc \
@@ -556,4 +558,6 @@
 	GenPoly/$(DEPDIR)/$(am__dirstamp)
 GenPoly/cfa_cpp-InstantiateGeneric.$(OBJEXT): GenPoly/$(am__dirstamp) \
+	GenPoly/$(DEPDIR)/$(am__dirstamp)
+GenPoly/cfa_cpp-DeclMutator.$(OBJEXT): GenPoly/$(am__dirstamp) \
 	GenPoly/$(DEPDIR)/$(am__dirstamp)
 InitTweak/$(am__dirstamp):
@@ -785,4 +789,5 @@
 	-rm -f GenPoly/cfa_cpp-Box.$(OBJEXT)
 	-rm -f GenPoly/cfa_cpp-CopyParams.$(OBJEXT)
+	-rm -f GenPoly/cfa_cpp-DeclMutator.$(OBJEXT)
 	-rm -f GenPoly/cfa_cpp-FindFunction.$(OBJEXT)
 	-rm -f GenPoly/cfa_cpp-GenPoly.$(OBJEXT)
@@ -895,4 +900,5 @@
 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/cfa_cpp-Box.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/cfa_cpp-CopyParams.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/cfa_cpp-DeclMutator.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/cfa_cpp-FindFunction.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/cfa_cpp-GenPoly.Po@am__quote@
@@ -1376,4 +1382,18 @@
 @am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/cfa_cpp-InstantiateGeneric.obj `if test -f 'GenPoly/InstantiateGeneric.cc'; then $(CYGPATH_W) 'GenPoly/InstantiateGeneric.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/InstantiateGeneric.cc'; fi`
 
+GenPoly/cfa_cpp-DeclMutator.o: GenPoly/DeclMutator.cc
+@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/cfa_cpp-DeclMutator.o -MD -MP -MF GenPoly/$(DEPDIR)/cfa_cpp-DeclMutator.Tpo -c -o GenPoly/cfa_cpp-DeclMutator.o `test -f 'GenPoly/DeclMutator.cc' || echo '$(srcdir)/'`GenPoly/DeclMutator.cc
+@am__fastdepCXX_TRUE@	$(am__mv) GenPoly/$(DEPDIR)/cfa_cpp-DeclMutator.Tpo GenPoly/$(DEPDIR)/cfa_cpp-DeclMutator.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='GenPoly/DeclMutator.cc' object='GenPoly/cfa_cpp-DeclMutator.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/cfa_cpp-DeclMutator.o `test -f 'GenPoly/DeclMutator.cc' || echo '$(srcdir)/'`GenPoly/DeclMutator.cc
+
+GenPoly/cfa_cpp-DeclMutator.obj: GenPoly/DeclMutator.cc
+@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/cfa_cpp-DeclMutator.obj -MD -MP -MF GenPoly/$(DEPDIR)/cfa_cpp-DeclMutator.Tpo -c -o GenPoly/cfa_cpp-DeclMutator.obj `if test -f 'GenPoly/DeclMutator.cc'; then $(CYGPATH_W) 'GenPoly/DeclMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/DeclMutator.cc'; fi`
+@am__fastdepCXX_TRUE@	$(am__mv) GenPoly/$(DEPDIR)/cfa_cpp-DeclMutator.Tpo GenPoly/$(DEPDIR)/cfa_cpp-DeclMutator.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='GenPoly/DeclMutator.cc' object='GenPoly/cfa_cpp-DeclMutator.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/cfa_cpp-DeclMutator.obj `if test -f 'GenPoly/DeclMutator.cc'; then $(CYGPATH_W) 'GenPoly/DeclMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/DeclMutator.cc'; fi`
+
 InitTweak/cfa_cpp-InitModel.o: InitTweak/InitModel.cc
 @am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/cfa_cpp-InitModel.o -MD -MP -MF InitTweak/$(DEPDIR)/cfa_cpp-InitModel.Tpo -c -o InitTweak/cfa_cpp-InitModel.o `test -f 'InitTweak/InitModel.cc' || echo '$(srcdir)/'`InitTweak/InitModel.cc
