Index: src/GenPoly/InstantiateGeneric.cc
===================================================================
--- src/GenPoly/InstantiateGeneric.cc	(revision f8b961b2dbd5821dc28db05e5097a385b8179c88)
+++ src/GenPoly/InstantiateGeneric.cc	(revision 63db3d762d0c667527bfc924b6af64374b1399b2)
@@ -77,5 +77,5 @@
 		std::list< Type* > params;  ///< Instantiation parameters
 	};
-
+	
 	/// Maps a concrete type to the instantiated struct type, accounting for scope
 	class InstantiationMap {
@@ -143,5 +143,7 @@
 	/// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
 	class Instantiate : public DeclMutator {
+		/// Map of (generic type, parameter list) pairs to concrete type instantiations
 		InstantiationMap instantiations;
+		/// Namer for concrete types
 		UniqueName typeNamer;
 
@@ -149,9 +151,8 @@
 		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 );
+
+// 		virtual Expression* mutate( MemberExpr *memberExpr );
 		
 		virtual void doBeginScope();
@@ -166,5 +167,5 @@
 	/// 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
+ 		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
@@ -172,6 +173,6 @@
 		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
+// 			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");
@@ -179,34 +180,36 @@
 				// check that the substituted type isn't a type variable itself
 				if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) {
-					allConcrete = false;
+ 					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;
-	}
-	
+// 				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 any parameters left over, not done
+		if ( baseParam != baseParams.end() ) return false;
+// 		// 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, 
@@ -288,8 +291,57 @@
 		return newInst;
 	}
+
+// 	/// Gets the base struct or union declaration for a member expression; NULL if not applicable
+// 	AggregateDecl* getMemberBaseDecl( MemberExpr *memberExpr ) {
+// 		// get variable for member aggregate
+// 		VariableExpr *varExpr = dynamic_cast< VariableExpr* >( memberExpr->get_aggregate() );
+// 		if ( ! varExpr ) return NULL;
+// 
+// 		// get object for variable
+// 		ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
+// 		if ( ! objectDecl ) return NULL;
+// 
+// 		// get base declaration from object type
+// 		Type *objectType = objectDecl->get_type();
+// 		StructInstType *structType = dynamic_cast< StructInstType* >( objectType );
+// 		if ( structType ) return structType->get_baseStruct();
+// 		UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType );
+// 		if ( unionType ) return unionType->get_baseUnion();
+// 
+// 		return NULL;
+// 	}
+// 
+// 	/// Finds the declaration with the given name, returning decls.end() if none such
+// 	std::list< Declaration* >::const_iterator findDeclNamed( const std::list< Declaration* > &decls, const std::string &name ) {
+// 		for( std::list< Declaration* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
+// 			if ( (*decl)->get_name() == name ) return decl;
+// 		}
+// 		return decls.end();
+// 	}
+// 	
+// 	Expression* Instantiate::mutate( MemberExpr *memberExpr ) {
+// 		// mutate, exiting early if no longer MemberExpr
+// 		Expression *expr = Mutator::mutate( memberExpr );
+// 		memberExpr = dynamic_cast< MemberExpr* >( expr );
+// 		if ( ! memberExpr ) return expr;
+// 
+// 		// get declaration of member and base declaration of member, exiting early if not found
+// 		AggregateDecl *memberBase = getMemberBaseDecl( memberExpr );
+// 		if ( ! memberBase ) return memberExpr;
+// 		DeclarationWithType *memberDecl = memberExpr->get_member();
+// 		std::list< Declaration* >::const_iterator baseIt = findDeclNamed( memberBase->get_members(), memberDecl->get_name() );
+// 		if ( baseIt == memberBase->get_members().end() ) return memberExpr;
+// 		DeclarationWithType *baseDecl = dynamic_cast< DeclarationWithType* >( *baseIt );
+// 		if ( ! baseDecl ) return memberExpr;
+// 
+// 		// check if stated type of the member is not the type of the member's declaration; if so, need a cast
+// 		// this *SHOULD* be safe, I don't think anything but the void-replacements I put in for dtypes would make it past the typechecker
+// 		SymTab::Indexer dummy;
+// 		if ( ResolvExpr::typesCompatible( memberDecl->get_type(), baseDecl->get_type(), dummy ) ) return memberExpr;
+// 		else return new CastExpr( memberExpr, memberDecl->get_type() );
+// 	}
 	
 	void Instantiate::doBeginScope() {
 		DeclMutator::doBeginScope();
-		// push a new concrete type scope
 		instantiations.beginScope();
 	}
@@ -297,5 +349,4 @@
 	void Instantiate::doEndScope() {
 		DeclMutator::doEndScope();
-		// pop the last concrete type scope
 		instantiations.endScope();
 	}
