Index: src/GenPoly/DeclMutator.cc
===================================================================
--- src/GenPoly/DeclMutator.cc	(revision e58be8e4dcfd81b1135c4fe620c537a3f4ecfea3)
+++ src/GenPoly/DeclMutator.cc	(revision e58be8e4dcfd81b1135c4fe620c537a3f4ecfea3)
@@ -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 e58be8e4dcfd81b1135c4fe620c537a3f4ecfea3)
+++ src/GenPoly/DeclMutator.h	(revision e58be8e4dcfd81b1135c4fe620c537a3f4ecfea3)
@@ -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 f2b20294e89fe2f8c8c9ab798cfbe889cc23fc68)
+++ src/GenPoly/InstantiateGeneric.cc	(revision e58be8e4dcfd81b1135c4fe620c537a3f4ecfea3)
@@ -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"
@@ -44,10 +44,8 @@
 		ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); }
 
-		/// Extracts types from a list of Expression* (which should be TypeExpr*)
-		ConcreteType(AggregateDecl *_base, const std::list< Expression* >& _params) : base(_base), params() {
-			for ( std::list< Expression* >::const_iterator it = _params.begin(); it != _params.end(); ++it ) {
-				TypeExpr *param = dynamic_cast< TypeExpr* >(*it);
-				assert(param && "Aggregate parameters should be type expressions");
-				params.push_back( param->get_type()->clone() );
+		/// Extracts types from a list of TypeExpr*
+		ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base), params() {
+			for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) {
+				params.push_back( (*param)->get_type()->clone() );
 			}
 		}
@@ -66,7 +64,7 @@
 
 		bool operator== (const ConcreteType& that) const {
+			if ( base != that.base ) return false;
+
 			SymTab::Indexer dummy;
-
-			if ( base != that.base ) return false;
 			if ( params.size() != that.params.size() ) return false;
 			for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) {
@@ -82,6 +80,12 @@
 	/// Maps a concrete type to the instantiated struct type, accounting for scope
 	class InstantiationMap {
-		/// Pair of concrete type and declaration that instantiates it
-		typedef std::pair< ConcreteType, AggregateDecl* > Instantiation;
+		/// Instantiation of a generic type, with key information to find it
+		struct Instantiation {
+			ConcreteType key;     ///< Instantiation parameters for this type
+			AggregateDecl *decl;  ///< Declaration of the instantiated generic type
+
+			Instantiation() : key(), decl(0) {}
+			Instantiation(const ConcreteType &_key, AggregateDecl *_decl) : key(_key), decl(_decl) {}
+		};
 		/// Map of generic types to instantiations of them
 		typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope;
@@ -107,5 +111,5 @@
 		/// Gets the declaration for the concrete instantiation of this type, assuming it has already been instantiated in the current scope.
 		/// Returns NULL on none such.
-		AggregateDecl* lookup( AggregateDecl *generic, std::list< Expression* >& params ) {
+		AggregateDecl* lookup( AggregateDecl *generic, const std::list< TypeExpr* >& params ) {
 			ConcreteType key(generic, params);
 			// scan scopes from innermost out
@@ -116,5 +120,5 @@
 				// look through instantiations for matches to concrete type
 				for ( std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) {
-					if ( inst->first == key ) return inst->second;
+					if ( inst->key == key ) return inst->decl;
 				}
 			}
@@ -123,29 +127,29 @@
 		}
 	public:
-		StructDecl* lookup( StructInstType *inst ) { return (StructDecl*)lookup( inst->get_baseStruct(), inst->get_parameters() ); }
-		UnionDecl* lookup( UnionInstType *inst ) { return (UnionDecl*)lookup( inst->get_baseUnion(), inst->get_parameters() ); }
+		StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)lookup( inst->get_baseStruct(), typeSubs ); }
+		UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)lookup( inst->get_baseUnion(), typeSubs ); }
 
 	private:
 		/// Adds a declaration for a concrete type to the current scope
-		void insert( AggregateDecl *generic, std::list< Expression* >& params, AggregateDecl *decl ) {
+		void insert( AggregateDecl *generic, const std::list< TypeExpr* > &params, AggregateDecl *decl ) {
 			ConcreteType key(generic, params);
-			scopes.back()[generic].push_back( std::make_pair( key, decl ) );
+			scopes.back()[generic].push_back( Instantiation( key, decl ) );
 		}
 	public:
-		void insert( StructInstType *inst, StructDecl *decl ) { insert( inst->get_baseStruct(), inst->get_parameters(), decl ); }
-		void insert( UnionInstType *inst, UnionDecl *decl ) { insert( inst->get_baseUnion(), inst->get_parameters(), decl ); }
+		void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { insert( inst->get_baseStruct(), typeSubs, decl ); }
+		void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { insert( inst->get_baseUnion(), typeSubs, decl ); }
 	};
 
 	/// 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 Declaration* mutate( StructDecl *aggregateDecl );
+//		virtual Declaration* mutate( UnionDecl *aggregateDecl );
+
 		virtual Type* mutate( StructInstType *inst );
 		virtual Type* mutate( UnionInstType *inst );
@@ -153,51 +157,61 @@
 		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
-	}
-
-	/// Substitutes types of members of in according to baseParams => params, appending the result to out
-	void substituteMembers( const std::list< Declaration* >& in,
-							const std::list< TypeDecl * >& baseParams, const std::list< Expression* >& params,
+		instantiator.mutateDeclarationList( translationUnit );
+	}
+
+	/// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type
+	bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) {
+		bool allConcrete = true;  // will finish the substitution list even if they're not all concrete
+
+		// substitute concrete types for given parameters, and incomplete types for placeholders
+		std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin();
+		std::list< Expression* >::const_iterator param = params.begin();
+		for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) {
+			switch ( (*baseParam)->get_kind() ) {
+			case TypeDecl::Any: {   // any type is a valid substitution here; complete types can be used to instantiate generics
+				TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
+				assert(paramType && "Aggregate parameters should be type expressions");
+				out.push_back( paramType->clone() );
+				// check that the substituted type isn't a type variable itself
+				if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) {
+					allConcrete = false;
+				}
+				break;
+			}
+			case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
+				out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
+				break;
+			case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
+				out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
+				break;
+			}
+		}
+
+		// if not enough parameters given, substitute remaining incomplete types for placeholders
+		for ( ; baseParam != baseParams.end(); ++baseParam ) {
+			switch ( (*baseParam)->get_kind() ) {
+			case TypeDecl::Any:    // no more substitutions here, fail early
+				return false;
+			case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
+				out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
+				break;
+			case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
+				out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
+				break;
+			}
+		}
+
+		return allConcrete;
+	}
+	
+	/// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out
+	void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs, 
 						    std::list< Declaration* >& out ) {
 		// substitute types into new members
-		TypeSubstitution subs( baseParams.begin(), baseParams.end(), params.begin() );
+		TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
 		for ( std::list< Declaration* >::const_iterator member = in.begin(); member != in.end(); ++member ) {
 			Declaration *newMember = (*member)->clone();
@@ -215,19 +229,26 @@
 		// exit early if no need for further mutation
 		if ( inst->get_parameters().empty() ) return inst;
+		assert( inst->get_baseParameters() && "Base struct has parameters" );
+
+		// check if type can be concretely instantiated; put substitutions into typeSubs
+		std::list< TypeExpr* > typeSubs;
+		if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
+			deleteAll( typeSubs );
+			return inst;
+		}
 		
 		// make concrete instantiation of generic type
-		StructDecl *concDecl = instantiations.lookup( inst );
+		StructDecl *concDecl = instantiations.lookup( inst, typeSubs );
 		if ( ! concDecl ) {
-			assert( inst->get_baseParameters() && "Base struct has parameters" );
 			// set concDecl to new type, insert type declaration into statements to add
 			concDecl = new StructDecl( typeNamer.newName( inst->get_name() ) );
-			substituteMembers( inst->get_baseStruct()->get_members(),
-								*inst->get_baseParameters(), inst->get_parameters(),
-								concDecl->get_members() );
-			addDeclaration( concDecl );
-			instantiations.insert( inst, concDecl );
+			substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs, 	concDecl->get_members() );
+			DeclMutator::addDeclaration( concDecl );
+			instantiations.insert( inst, typeSubs, concDecl );
 		}
 		StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() );
 		newInst->set_baseStruct( concDecl );
+
+		deleteAll( typeSubs );
 		delete inst;
 		return newInst;
@@ -242,19 +263,26 @@
 		// exit early if no need for further mutation
 		if ( inst->get_parameters().empty() ) return inst;
-
+		assert( inst->get_baseParameters() && "Base union has parameters" );
+
+		// check if type can be concretely instantiated; put substitutions into typeSubs
+		std::list< TypeExpr* > typeSubs;
+		if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
+			deleteAll( typeSubs );
+			return inst;
+		}
+		
 		// make concrete instantiation of generic type
-		UnionDecl *concDecl = instantiations.lookup( inst );
+		UnionDecl *concDecl = instantiations.lookup( inst, typeSubs );
 		if ( ! concDecl ) {
 			// set concDecl to new type, insert type declaration into statements to add
-			assert( inst->get_baseParameters() && "Base union has parameters" );
 			concDecl = new UnionDecl( typeNamer.newName( inst->get_name() ) );
-			substituteMembers( inst->get_baseUnion()->get_members(),
-								*inst->get_baseParameters(), inst->get_parameters(),
-								concDecl->get_members() );
-			addDeclaration( concDecl );
-			instantiations.insert( inst, concDecl );
+			substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
+			DeclMutator::addDeclaration( concDecl );
+			instantiations.insert( inst, typeSubs, concDecl );
 		}
 		UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() );
 		newInst->set_baseUnion( concDecl );
+
+		deleteAll( typeSubs );
 		delete inst;
 		return newInst;
@@ -262,4 +290,5 @@
 	
 	void Instantiate::doBeginScope() {
+		DeclMutator::doBeginScope();
 		// push a new concrete type scope
 		instantiations.beginScope();
@@ -267,4 +296,5 @@
 
 	void Instantiate::doEndScope() {
+		DeclMutator::doEndScope();
 		// pop the last concrete type scope
 		instantiations.endScope();
Index: src/GenPoly/module.mk
===================================================================
--- src/GenPoly/module.mk	(revision f2b20294e89fe2f8c8c9ab798cfbe889cc23fc68)
+++ src/GenPoly/module.mk	(revision e58be8e4dcfd81b1135c4fe620c537a3f4ecfea3)
@@ -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 f2b20294e89fe2f8c8c9ab798cfbe889cc23fc68)
+++ src/Makefile.in	(revision e58be8e4dcfd81b1135c4fe620c537a3f4ecfea3)
@@ -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
