Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision baf7fee060790c21c0bbe680e7fba33fe7b6b433)
+++ src/GenPoly/Box.cc	(revision ae63a185a34928dad284a49a9cd4c4d0d7655bb2)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Box.cc -- 
+// Box.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Wed Dec 02 11:52:37 2015
-// Update Count     : 201
+// Last Modified On : Fri Dec 18 14:53:08 2015
+// Update Count     : 217
 //
 
@@ -28,4 +28,5 @@
 #include "Parser/ParseNode.h"
 
+#include "SynTree/Constant.h"
 #include "SynTree/Type.h"
 #include "SynTree/Expression.h"
@@ -61,8 +62,8 @@
 			virtual Expression *mutate( CommaExpr *commaExpr );
 			virtual Expression *mutate( ConditionalExpr *condExpr );
-			virtual Statement *mutate(ReturnStmt *catchStmt);
+			virtual Statement * mutate( ReturnStmt *returnStmt );
 			virtual Type *mutate( PointerType *pointerType );
-			virtual Type *mutate( FunctionType *pointerType );
-  
+			virtual Type * mutate( FunctionType *functionType );
+
 			virtual void doBeginScope();
 			virtual void doEndScope();
@@ -92,5 +93,4 @@
 		class Pass2 : public PolyMutator {
 		  public:
-			Pass2();
 			template< typename DeclClass >
 			DeclClass *handleDecl( DeclClass *decl, Type *type );
@@ -103,5 +103,5 @@
 		  private:
 			void addAdapters( FunctionType *functionType );
-  
+
 			std::map< UniqueId, std::string > adapterName;
 		};
@@ -151,9 +151,9 @@
 			// the correct thing in some situations. It's not clear to me why this wasn't working.
 
-			// if the return type or a parameter type involved polymorphic types, then the adapter will need 
-			// to take those polymorphic types as pointers. Therefore, there can be two different functions 
+			// if the return type or a parameter type involved polymorphic types, then the adapter will need
+			// to take those polymorphic types as pointers. Therefore, there can be two different functions
 			// with the same mangled name, so we need to further mangle the names.
 			for ( std::list< DeclarationWithType *>::iterator retval = function->get_returnVals().begin(); retval != function->get_returnVals().end(); ++retval ) {
-				if ( isPolyVal( (*retval)->get_type(), tyVars ) ) {
+				if ( isPolyType( (*retval)->get_type(), tyVars ) ) {
 					name << "P";
 				} else {
@@ -164,8 +164,8 @@
 			std::list< DeclarationWithType *> &paramList = function->get_parameters();
 			for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
-				if ( isPolyVal( (*arg)->get_type(), tyVars ) ) {
+				if ( isPolyType( (*arg)->get_type(), tyVars ) ) {
 					name << "P";
 				} else {
-					name << "M";				
+					name << "M";
 				}
 			} // for
@@ -181,6 +181,5 @@
 		}
 
-		Pass1::Pass1()
-			: useRetval( false ), tempNamer( "_temp" ) {
+		Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {
 			adapters.push(AdapterMap());
 		}
@@ -194,6 +193,10 @@
 							if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) {
 								if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) {
-									name = typeInst->get_name();
-									return true;
+									if ( TypeInstType *typeInst2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) {
+										if ( typeInst->get_name() == typeInst2->get_name() ) {
+											name = typeInst->get_name();
+											return true;
+										} // if
+									} // if
 								} // if
 							} // if
@@ -231,5 +234,5 @@
 				if ( isPolyRet( functionDecl->get_functionType(), typeName ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) {
 					retval = functionDecl->get_functionType()->get_returnVals().front();
-  
+
 					// give names to unnamed return values
 					if ( retval->get_name() == "" ) {
@@ -238,5 +241,5 @@
 					} // if
 				} // if
-	
+
 				FunctionType *functionType = functionDecl->get_functionType();
 				makeTyVarMap( functionDecl->get_functionType(), scopeTyVars );
@@ -263,5 +266,5 @@
 
 				functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) );
-  
+
 				scopeTyVars = oldtyVars;
 				assignOps = oldassignOps;
@@ -279,5 +282,4 @@
 
 		TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) {
-///     std::cerr << "add " << typeDecl->get_name() << "\n";
 			scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
 			return Mutator::mutate( typeDecl );
@@ -305,4 +307,5 @@
 
 		void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
+			// pass size/align for type variables
 			for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) {
 				ResolvExpr::EqvClass eqvClass;
@@ -313,4 +316,6 @@
 						arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) );
 						arg++;
+						arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) );
+						arg++;
 					} else {
 						throw SemanticError( "unbound type variable in application ", appExpr );
@@ -318,4 +323,30 @@
 				} // if
 			} // for
+
+			// add size/align for generic types to parameter list
+			//assert( ! appExpr->get_function()->get_results().empty() );
+			if ( appExpr->get_function()->get_results().empty() ) return;
+			FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() );
+			assert( funcType );
+
+			std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin();
+			std::list< Expression* >::const_iterator fnArg = arg;
+			std::set< std::string > seenTypes; //< names for generic types we've seen
+			for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) {
+				Type *parmType = (*fnParm)->get_type();
+				if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, exprTyVars ) ) {
+					std::string sizeName = sizeofName( parmType );
+					if ( seenTypes.count( sizeName ) ) continue;
+
+					assert( ! (*fnArg)->get_results().empty() );
+					Type *argType = (*fnArg)->get_results().front();
+					arg = appExpr->get_args().insert( arg, new SizeofExpr( argType->clone() ) );
+					arg++;
+					arg = appExpr->get_args().insert( arg, new AlignofExpr( argType->clone() ) );
+					arg++;
+
+					seenTypes.insert( sizeName );
+				}
+			}
 		}
 
@@ -326,41 +357,31 @@
 		}
 
-		TypeInstType *isPolyType( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) {
-			if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
-				if ( env ) {
-					if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
-						return isPolyType( newType, env, tyVars );
-					} // if
-				} // if
-				if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
-					return typeInst;
-				} else {
-					return 0;
-				} // if
-			} else {
-				return 0;
-			} // if
-		}
-
 		Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) {
-			if ( useRetval ) {
-				assert( retval );
-				arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );
-				arg++;
-			} else {
-				ObjectDecl *newObj = makeTemporary( retType->clone() );
-				Expression *paramExpr = new VariableExpr( newObj );
-				if ( ! isPolyType( newObj->get_type(), env, scopeTyVars ) ) {
-					paramExpr = new AddressExpr( paramExpr );
-				} // if
-				arg = appExpr->get_args().insert( arg, paramExpr );
-				arg++;
-///     stmtsToAdd.push_back( new ExprStmt( noLabels, appExpr ) );
-				CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) );
-				commaExpr->set_env( appExpr->get_env() );
-				appExpr->set_env( 0 );
-				return commaExpr;
-			} // if
-			return appExpr;
+			// ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous.
+			// if ( useRetval ) {
+			// 	assert( retval );
+			// 	arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );
+			// 	arg++;
+			// } else {
+
+			// Create temporary to hold return value of polymorphic function and produce that temporary as a result
+			// using a comma expression.  Possibly change comma expression into statement expression "{}" for multiple
+			// return values.
+			ObjectDecl *newObj = makeTemporary( retType->clone() );
+			Expression *paramExpr = new VariableExpr( newObj );
+			// If the type of the temporary is not polymorphic, box temporary by taking its address; otherwise the
+			// temporary is already boxed and can be used directly.
+			if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) {
+				paramExpr = new AddressExpr( paramExpr );
+			} // if
+			arg = appExpr->get_args().insert( arg, paramExpr ); // add argument to function call
+			arg++;
+			// Build a comma expression to call the function and emulate a normal return.
+			CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) );
+			commaExpr->set_env( appExpr->get_env() );
+			appExpr->set_env( 0 );
+			return commaExpr;
+			// } // if
+			// return appExpr;
 		}
 
@@ -377,5 +398,5 @@
 		Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {
 			Expression *ret = appExpr;
-			if ( ! function->get_returnVals().empty() && isPolyVal( function->get_returnVals().front()->get_type(), tyVars ) ) {
+			if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) {
 				ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg );
 			} // if
@@ -385,5 +406,5 @@
 			appExpr->get_args().push_front( appExpr->get_function() );
 			appExpr->set_function( new NameExpr( adapterName ) );
-  
+
 			return ret;
 		}
@@ -391,5 +412,5 @@
 		void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) {
 			assert( ! arg->get_results().empty() );
-///   if ( ! dynamic_cast< PointerType *>( arg->get_results().front() ) ) {
+//   if ( ! dynamic_cast< PointerType *>( arg->get_results().front() ) ) {
 			TypeInstType *typeInst = dynamic_cast< TypeInstType *>( param );
 			if ( typeInst && exprTyVars.find( typeInst->get_name() ) != exprTyVars.end() ) {
@@ -411,5 +432,5 @@
 				} // if
 			} // if
-///   }
+//   }
 		}
 
@@ -428,11 +449,5 @@
 
 		void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
-///   std::cout << "function is ";
-///   function->print( std::cout );
 			for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) {
-///     std::cout << "parameter is ";
-///     (*param)->print( std::fcout );
-///     std::cout << std::endl << "argument is ";
-///     (*arg)->print( std::cout );
 				assert( arg != appExpr->get_args().end() );
 				addCast( *arg, (*param)->get_type(), exprTyVars );
@@ -469,5 +484,5 @@
 			// actually make the adapter type
 			FunctionType *adapter = adaptee->clone();
-			if ( ! adapter->get_returnVals().empty() && isPolyVal( adapter->get_returnVals().front()->get_type(), tyVars ) ) {
+			if ( ! adapter->get_returnVals().empty() && isPolyType( adapter->get_returnVals().front()->get_type(), tyVars ) ) {
 				makeRetParm( adapter );
 			} // if
@@ -479,14 +494,8 @@
 			assert( param );
 			assert( arg );
-///   std::cout << "arg type is ";
-///   arg->get_type()->print( std::cout );
-///   std::cout << "param type is ";
-///   param->get_type()->print( std::cout );
-///   std::cout << " tyVars are: ";
-///   printTyVarMap( std::cout, tyVars );
-			if ( isPolyVal( realParam->get_type(), tyVars ) ) {
-///     if ( dynamic_cast< PointerType *>( arg->get_type() ) ) {
-///       return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() );
-///     } else {
+			if ( isPolyType( realParam->get_type(), tyVars ) ) {
+//     if ( dynamic_cast< PointerType *>( arg->get_type() ) ) {
+//       return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() );
+//     } else {
 				if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) {
 					UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
@@ -495,5 +504,5 @@
 					return deref;
 				} // if
-///     }
+//     }
 			} // if
 			return new VariableExpr( param );
@@ -520,5 +529,5 @@
 			ApplicationExpr *adapteeApp = new ApplicationExpr( new CastExpr( new VariableExpr( adapteeDecl ), new PointerType( Type::Qualifiers(), realType ) ) );
 			Statement *bodyStmt;
-  
+
 			std::list< TypeDecl *>::iterator tyArg = realType->get_forall().begin();
 			std::list< TypeDecl *>::iterator tyParam = adapterType->get_forall().begin();
@@ -534,5 +543,5 @@
 				} // for
 			} // for
-  
+
 			std::list< DeclarationWithType *>::iterator arg = realType->get_parameters().begin();
 			std::list< DeclarationWithType *>::iterator param = adapterType->get_parameters().begin();
@@ -542,5 +551,5 @@
 				addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
 				bodyStmt = new ExprStmt( noLabels, adapteeApp );
-			} else if ( isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
+			} else if ( isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
 				if ( (*param)->get_name() == "" ) {
 					(*param)->set_name( "_ret" );
@@ -591,9 +600,9 @@
 				if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
 					adaptersDone.insert( adaptersDone.begin(), mangleName );
-					
+
 					// apply substitution to type variables to figure out what the adapter's type should look like
 					assert( env );
 					env->apply( realFunction );
-					mangleName = SymTab::Mangler::mangle( realFunction ); 
+					mangleName = SymTab::Mangler::mangle( realFunction );
 					mangleName += makePolyMonoSuffix( originalFunction, exprTyVars );
 
@@ -614,31 +623,5 @@
 		} // passAdapters
 
-		TypeInstType *isPolyPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) {
-			if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
-				return isPolyType( ptr->get_base(), env, tyVars );
-			} else if ( env ) {
-				if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
-					if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
-						return isPolyPtr( newType, env, tyVars );
-					} // if
-				} // if
-			} // if
-			return 0;
-		}
-
-		TypeInstType *isPolyPtrPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) {
-			if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
-				return isPolyPtr( ptr->get_base(), env, tyVars );
-			} else if ( env ) {
-				if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
-					if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
-						return isPolyPtrPtr( newType, env, tyVars );
-					} // if
-				} // if
-			} // if
-			return 0;
-		}
-
-		Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, std::string polyName, bool isIncr ) {
+		Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) {
 			NameExpr *opExpr;
 			if ( isIncr ) {
@@ -653,5 +636,5 @@
 				addAssign->get_args().push_back( appExpr->get_args().front() );
 			} // if
-			addAssign->get_args().push_back( new NameExpr( polyName ) );
+			addAssign->get_args().push_back( new NameExpr( sizeofName( polyType ) ) );
 			addAssign->get_results().front() = appExpr->get_results().front()->clone();
 			if ( appExpr->get_env() ) {
@@ -670,25 +653,25 @@
 						assert( ! appExpr->get_results().empty() );
 						assert( appExpr->get_args().size() == 2 );
-						TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars );
-						TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars );
-						assert( ! typeInst1 || ! typeInst2 );  // the arguments cannot both be polymorphic pointers
+						Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env );
+						Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env );
+						assert( ! baseType1 || ! baseType2 ); // the arguments cannot both be polymorphic pointers
 						UntypedExpr *ret = 0;
-						if ( typeInst1 || typeInst2 ) { // one of the arguments is a polymorphic pointer
+						if ( baseType1 || baseType2 ) { // one of the arguments is a polymorphic pointer
 							ret = new UntypedExpr( new NameExpr( "?+?" ) );
 						} // if
-						if ( typeInst1 ) {
+						if ( baseType1 ) {
 							UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
 							multiply->get_args().push_back( appExpr->get_args().back() );
-							multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
+							multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
 							ret->get_args().push_back( appExpr->get_args().front() );
 							ret->get_args().push_back( multiply );
-						} else if ( typeInst2 ) {
+						} else if ( baseType2 ) {
 							UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
 							multiply->get_args().push_back( appExpr->get_args().front() );
-							multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );
+							multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) );
 							ret->get_args().push_back( multiply );
 							ret->get_args().push_back( appExpr->get_args().back() );
 						} // if
-						if ( typeInst1 || typeInst2 ) {
+						if ( baseType1 || baseType2 ) {
 							ret->get_results().push_front( appExpr->get_results().front()->clone() );
 							if ( appExpr->get_env() ) {
@@ -703,5 +686,5 @@
 						assert( ! appExpr->get_results().empty() );
 						assert( ! appExpr->get_args().empty() );
-						if ( isPolyType( appExpr->get_results().front(), env, scopeTyVars ) ) {
+						if ( isPolyType( appExpr->get_results().front(), scopeTyVars, env ) ) {
 							Expression *ret = appExpr->get_args().front();
 							delete ret->get_results().front();
@@ -718,5 +701,5 @@
 						assert( ! appExpr->get_results().empty() );
 						assert( appExpr->get_args().size() == 1 );
-						if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) {
+						if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) {
 							Type *tempType = appExpr->get_results().front()->clone();
 							if ( env ) {
@@ -732,5 +715,5 @@
 								assignExpr->get_args().push_back( appExpr->get_args().front()->clone() );
 							} // if
-							CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "?++" ) );
+							CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, baseType, varExpr->get_var()->get_name() == "?++" ) );
 							return new CommaExpr( firstComma, tempExpr );
 						} // if
@@ -738,16 +721,16 @@
 						assert( ! appExpr->get_results().empty() );
 						assert( appExpr->get_args().size() == 1 );
-						if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) {
-							return makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "++?" );
+						if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) {
+							return makeIncrDecrExpr( appExpr, baseType, varExpr->get_var()->get_name() == "++?" );
 						} // if
 					} else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) {
 						assert( ! appExpr->get_results().empty() );
 						assert( appExpr->get_args().size() == 2 );
-						TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars );
-						TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars );
-						if ( typeInst1 && typeInst2 ) {
+						Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env );
+						Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env );
+						if ( baseType1 && baseType2 ) {
 							UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) );
 							divide->get_args().push_back( appExpr );
-							divide->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
+							divide->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
 							divide->get_results().push_front( appExpr->get_results().front()->clone() );
 							if ( appExpr->get_env() ) {
@@ -756,13 +739,13 @@
 							} // if
 							return divide;
-						} else if ( typeInst1 ) {
+						} else if ( baseType1 ) {
 							UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
 							multiply->get_args().push_back( appExpr->get_args().back() );
-							multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
+							multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
 							appExpr->get_args().back() = multiply;
-						} else if ( typeInst2 ) {
+						} else if ( baseType2 ) {
 							UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
 							multiply->get_args().push_back( appExpr->get_args().front() );
-							multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );
+							multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) );
 							appExpr->get_args().front() = multiply;
 						} // if
@@ -770,9 +753,9 @@
 						assert( ! appExpr->get_results().empty() );
 						assert( appExpr->get_args().size() == 2 );
-						TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars );
-						if ( typeInst ) {
+						Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env );
+						if ( baseType ) {
 							UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
 							multiply->get_args().push_back( appExpr->get_args().back() );
-							multiply->get_args().push_back( new NameExpr( typeInst->get_name() ) );
+							multiply->get_args().push_back( new NameExpr( sizeofName( baseType ) ) );
 							appExpr->get_args().back() = multiply;
 						} // if
@@ -795,5 +778,5 @@
 			mutateAll( appExpr->get_args(), *this );
 			useRetval = oldUseRetval;
-  
+
 			assert( ! appExpr->get_function()->get_results().empty() );
 			PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() );
@@ -801,14 +784,14 @@
 			FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() );
 			assert( function );
-  
+
 			if ( Expression *newExpr = handleIntrinsics( appExpr ) ) {
 				return newExpr;
 			} // if
-  
+
 			Expression *ret = appExpr;
-  
+
 			std::list< Expression *>::iterator arg = appExpr->get_args().begin();
 			std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin();
-  
+
 			std::string typeName;
 			if ( isPolyRet( function, typeName ) ) {
@@ -824,13 +807,13 @@
 			} // if
 			arg = appExpr->get_args().begin();
-  
+
 			TyVarMap exprTyVars;
 			makeTyVarMap( function, exprTyVars );
-  
+
 			passTypeVars( appExpr, arg, exprTyVars );
 			addInferredParams( appExpr, function, arg, exprTyVars );
 
 			arg = paramBegin;
-  
+
 			boxParams( appExpr, function, arg, exprTyVars );
 
@@ -841,5 +824,5 @@
 
 		Expression *Pass1::mutate( UntypedExpr *expr ) {
-			if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), env, scopeTyVars ) ) {
+			if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) {
 				if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
 					if ( name->get_name() == "*?" ) {
@@ -856,6 +839,24 @@
 		Expression *Pass1::mutate( AddressExpr *addrExpr ) {
 			assert( ! addrExpr->get_arg()->get_results().empty() );
+
+			bool needs = false;
+			if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) {
+				if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) {
+					if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
+						if ( name->get_name() == "*?" ) {
+							if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) {
+								assert( ! appExpr->get_function()->get_results().empty() );
+								PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() );
+								assert( pointer );
+								FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() );
+								assert( function );
+								needs = needsAdapter( function, scopeTyVars );
+							} // if
+						} // if
+					} // if
+				} // if
+			} // if
 			addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
-			if ( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars ) ) {
+			if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) || needs ) {
 				Expression *ret = addrExpr->get_arg();
 				delete ret->get_results().front();
@@ -869,39 +870,39 @@
 		}
 
-		Statement * Pass1::mutate(ReturnStmt *retStmt) {
-			// by this point, a cast expr on a polymorphic return value is redundant
-			while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( retStmt->get_expr() ) ) {
-				retStmt->set_expr( castExpr->get_arg() );
-				retStmt->get_expr()->set_env( castExpr->get_env() );
-				castExpr->set_env( 0 );
-				castExpr->set_arg( 0 );
-				delete castExpr;
-			}
-			if ( retval && retStmt->get_expr() ) {
-				assert( ! retStmt->get_expr()->get_results().empty() );
-				if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
-///       retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
-					TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() );
-					assert( typeInst );
-					std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
-					if ( assignIter == assignOps.end() ) {
-						throw SemanticError( "Attempt to return dtype or ftype object in ", retStmt->get_expr() );
-					} // if
-					ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
-					Expression *retParm = new NameExpr( retval->get_name() );
-					retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
-					assignExpr->get_args().push_back( retParm );
-					assignExpr->get_args().push_back( retStmt->get_expr() );
-					stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) );
-				} else {
-					useRetval = true;
-					stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( retStmt->get_expr() ) ) );
-					useRetval = false;
+		Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
+			if ( retval && returnStmt->get_expr() ) {
+				assert( ! returnStmt->get_expr()->get_results().empty() );
+				// ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous.
+				// if ( returnStmt->get_expr()->get_results().front()->get_isLvalue() ) {
+				// by this point, a cast expr on a polymorphic return value is redundant
+				while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( returnStmt->get_expr() ) ) {
+					returnStmt->set_expr( castExpr->get_arg() );
+					returnStmt->get_expr()->set_env( castExpr->get_env() );
+					castExpr->set_env( 0 );
+					castExpr->set_arg( 0 );
+					delete castExpr;
+				} //while
+				TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() );
+				assert( typeInst );
+				std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
+				if ( assignIter == assignOps.end() ) {
+					throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
 				} // if
-				retStmt->set_expr( 0 );
+				ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
+				Expression *retParm = new NameExpr( retval->get_name() );
+				retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
+				assignExpr->get_args().push_back( retParm );
+				assignExpr->get_args().push_back( returnStmt->get_expr() );
+				stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) );
+				// } else {
+				// 	useRetval = true;
+				// 	stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( returnStmt->get_expr() ) ) );
+				// 	useRetval = false;
+				// } // if
+				returnStmt->set_expr( 0 );
 			} else {
-				retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
-			} // if
-			return retStmt;
+				returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) );
+			} // if
+			return returnStmt;
 		}
 
@@ -909,7 +910,7 @@
 			TyVarMap oldtyVars = scopeTyVars;
 			makeTyVarMap( pointerType, scopeTyVars );
-  
+
 			Type *ret = Mutator::mutate( pointerType );
-  
+
 			scopeTyVars = oldtyVars;
 			return ret;
@@ -919,7 +920,7 @@
 			TyVarMap oldtyVars = scopeTyVars;
 			makeTyVarMap( functionType, scopeTyVars );
-  
+
 			Type *ret = Mutator::mutate( functionType );
-  
+
 			scopeTyVars = oldtyVars;
 			return ret;
@@ -936,6 +937,4 @@
 
 ////////////////////////////////////////// Pass2 ////////////////////////////////////////////////////
-
-		Pass2::Pass2() {}
 
 		void Pass2::addAdapters( FunctionType *functionType ) {
@@ -956,5 +955,5 @@
 				}
 			}
-///  deleteAll( functions );
+//  deleteAll( functions );
 		}
 
@@ -990,7 +989,7 @@
 			TyVarMap oldtyVars = scopeTyVars;
 			makeTyVarMap( pointerType, scopeTyVars );
-  
+
 			Type *ret = Mutator::mutate( pointerType );
-  
+
 			scopeTyVars = oldtyVars;
 			return ret;
@@ -1000,5 +999,6 @@
 			TyVarMap oldtyVars = scopeTyVars;
 			makeTyVarMap( funcType, scopeTyVars );
-  
+
+			// move polymorphic return type to parameter list
 			std::string typeName;
 			if ( isPolyRet( funcType, typeName ) ) {
@@ -1008,16 +1008,24 @@
 				funcType->get_returnVals().pop_front();
 			}
-  
+
+			// add size/align and assertions for type parameters to parameter list
 			std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin();
 			std::list< DeclarationWithType *> inferredParams;
-			ObjectDecl *newObj = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
+			ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
 //   ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
 			for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
-				ObjectDecl *thisParm;
-				// add all size parameters to parameter list
+				ObjectDecl *sizeParm, *alignParm;
+				// add all size and alignment parameters to parameter list
 				if ( (*tyParm)->get_kind() == TypeDecl::Any ) {
-					thisParm = newObj->clone();
-					thisParm->set_name( (*tyParm)->get_name() );
-					last = funcType->get_parameters().insert( last, thisParm );
+					TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm );
+
+					sizeParm = newObj.clone();
+					sizeParm->set_name( sizeofName( &parmType ) );
+					last = funcType->get_parameters().insert( last, sizeParm );
+					++last;
+
+					alignParm = newObj.clone();
+					alignParm->set_name( alignofName( &parmType ) );
+					last = funcType->get_parameters().insert( last, alignParm );
 					++last;
 				}
@@ -1029,10 +1037,34 @@
 				(*tyParm)->get_assertions().clear();
 			}
-			delete newObj;
+
+			// add size/align for generic types to parameter list
+			std::set< std::string > seenTypes; //< sizeofName for generic types we've seen
+			for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) {
+				Type *parmType = (*fnParm)->get_type();
+				if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, scopeTyVars ) ) {
+					std::string sizeName = sizeofName( parmType );
+					if ( seenTypes.count( sizeName ) ) continue;
+
+					ObjectDecl *sizeParm, *alignParm;
+					sizeParm = newObj.clone();
+					sizeParm->set_name( sizeName );
+					last = funcType->get_parameters().insert( last, sizeParm );
+					++last;
+
+					alignParm = newObj.clone();
+					alignParm->set_name( alignofName( parmType ) );
+					last = funcType->get_parameters().insert( last, alignParm );
+					++last;
+
+					seenTypes.insert( sizeName );
+				}
+			}
+
+			// splice assertion parameters into parameter list
 			funcType->get_parameters().splice( last, inferredParams );
 			addAdapters( funcType );
 			mutateAll( funcType->get_returnVals(), *this );
 			mutateAll( funcType->get_parameters(), *this );
-  
+
 			scopeTyVars = oldtyVars;
 			return funcType;
@@ -1045,5 +1077,5 @@
 			TyVarMap oldtyVars = scopeTyVars;
 			makeTyVarMap( type, scopeTyVars );
-  
+
 			DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );
 			ScrubTyVars::scrub( decl, scopeTyVars );
@@ -1081,7 +1113,7 @@
 			TyVarMap oldtyVars = scopeTyVars;
 			makeTyVarMap( pointerType, scopeTyVars );
-  
+
 			Type *ret = Mutator::mutate( pointerType );
-  
+
 			scopeTyVars = oldtyVars;
 			return ret;
@@ -1091,7 +1123,7 @@
 			TyVarMap oldtyVars = scopeTyVars;
 			makeTyVarMap( functionType, scopeTyVars );
-  
+
 			Type *ret = Mutator::mutate( functionType );
-  
+
 			scopeTyVars = oldtyVars;
 			return ret;
@@ -1100,11 +1132,10 @@
 		Statement *Pass3::mutate( DeclStmt *declStmt ) {
 			if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
-				if ( isPolyVal( objectDecl->get_type(), scopeTyVars ) ) {
+				if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) {
 					// change initialization of a polymorphic value object
 					// to allocate storage with alloca
-					TypeInstType *typeInst = dynamic_cast< TypeInstType *>( objectDecl->get_type() );
-					assert( typeInst );
+					Type *declType = objectDecl->get_type();
 					UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );
-					alloc->get_args().push_back( new NameExpr( typeInst->get_name() ) );
+					alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) );
 
 					delete objectDecl->get_init();
Index: src/GenPoly/GenPoly.cc
===================================================================
--- src/GenPoly/GenPoly.cc	(revision baf7fee060790c21c0bbe680e7fba33fe7b6b433)
+++ src/GenPoly/GenPoly.cc	(revision ae63a185a34928dad284a49a9cd4c4d0d7655bb2)
@@ -9,10 +9,13 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Rob Schluntz
-// Last Modified On : Tue Nov 24 15:23:08 2015
-// Update Count     : 11
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Tue Dec 15 16:11:18 2015
+// Update Count     : 13
 //
 
 #include "GenPoly.h"
+
+#include "SymTab/Mangler.h"
+#include "SynTree/Expression.h"
 #include "SynTree/Type.h"
 
@@ -21,12 +24,10 @@
 
 namespace GenPoly {
-	/// A function needs an adapter if it returns a polymorphic value or if any of its
-	/// parameters have polymorphic type
 	bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) {
-		if ( ! adaptee->get_returnVals().empty() && isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
+		if ( ! adaptee->get_returnVals().empty() && isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
 			return true;
 		} // if
 		for ( std::list< DeclarationWithType* >::const_iterator innerArg = adaptee->get_parameters().begin(); innerArg != adaptee->get_parameters().end(); ++innerArg ) {
-			if ( isPolyVal( (*innerArg)->get_type(), tyVars ) ) {
+			if ( isPolyType( (*innerArg)->get_type(), tyVars ) ) {
 				return true;
 			} // if
@@ -66,20 +67,92 @@
 	}
 
-	bool isPolyVal( Type *type, const TyVarMap &tyVars ) {
+	namespace {
+		/// Checks a parameter list for polymorphic parameters; will substitute according to env if present
+		bool hasPolyParams( std::list< Expression* >& params, const TypeSubstitution *env ) {
+			for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
+				TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
+				assert(paramType && "Aggregate parameters should be type expressions");
+				if ( isPolyType( paramType->get_type(), env ) ) return true;
+			}
+			return false;
+		}
+
+		/// Checks a parameter list for polymorphic parameters from tyVars; will substitute according to env if present
+		bool hasPolyParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) {
+			for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
+				TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
+				assert(paramType && "Aggregate parameters should be type expressions");
+				if ( isPolyType( paramType->get_type(), tyVars, env ) ) return true;
+			}
+			return false;
+		}
+	}
+
+	Type *isPolyType( Type *type, const TypeSubstitution *env ) {
 		if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
+			if ( env ) {
+				if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
+					return isPolyType( newType, env );
+				} // if
+			} // if
+			return type;
+		} else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
+			if ( hasPolyParams( structType->get_parameters(), env ) ) return type;
+		} else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
+			if ( hasPolyParams( unionType->get_parameters(), env ) ) return type;
+		}
+		return 0;
+	}
+	
+	Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
+		if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
+			if ( env ) {
+				if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
+					return isPolyType( newType, tyVars, env );
+				} // if
+			} // if
 			if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
-				return true;
+				return type;
+			}
+		} else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
+			if ( hasPolyParams( structType->get_parameters(), tyVars, env ) ) return type;
+		} else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
+			if ( hasPolyParams( unionType->get_parameters(), tyVars, env ) ) return type;
+		}
+		return 0;
+	}
+
+	Type *isPolyPtr( Type *type, const TypeSubstitution *env ) {
+		if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
+			return isPolyType( ptr->get_base(), env );
+		} else if ( env ) {
+			if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
+				if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
+					return isPolyPtr( newType, env );
+				} // if
 			} // if
 		} // if
-		return false;
+		return 0;
+	}
+	
+	Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
+		if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
+			return isPolyType( ptr->get_base(), tyVars, env );
+		} else if ( env ) {
+			if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {
+				if ( Type *newType = env->lookup( typeInst->get_name() ) ) {
+					return isPolyPtr( newType, tyVars, env );
+				} // if
+			} // if
+		} // if
+		return 0;
 	}
 
-	bool isPolyObj( Type *type, const TyVarMap &tyVars ) {
-		if ( isPolyVal( type, tyVars ) ) {
-			return true;
-		} else if ( PointerType *pt = dynamic_cast<PointerType*>( type ) ) {
-			return isPolyObj( pt->get_base(), tyVars );
+	FunctionType * getFunctionType( Type *ty ) {
+		PointerType *ptrType;
+		if ( ( ptrType = dynamic_cast< PointerType* >( ty ) ) ) {
+			return dynamic_cast< FunctionType* >( ptrType->get_base() ); // pointer if FunctionType, NULL otherwise
 		} else {
-			return false;
+			return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise
 		}
 	}
@@ -91,4 +164,12 @@
 		os << std::endl;
 	}
+
+	std::string sizeofName( Type *ty ) {
+		return std::string( "_sizeof_" ) + SymTab::Mangler::mangleType( ty );
+	}
+
+	std::string alignofName( Type *ty ) {
+		return std::string( "_alignof_" ) + SymTab::Mangler::mangleType( ty );
+	}
 } // namespace GenPoly
 
Index: src/GenPoly/GenPoly.h
===================================================================
--- src/GenPoly/GenPoly.h	(revision baf7fee060790c21c0bbe680e7fba33fe7b6b433)
+++ src/GenPoly/GenPoly.h	(revision ae63a185a34928dad284a49a9cd4c4d0d7655bb2)
@@ -20,19 +20,43 @@
 #include <string>
 #include <iostream>
+
 #include "SynTree/Declaration.h"
+#include "SynTree/TypeSubstitution.h"
 
 namespace GenPoly {
 	typedef std::map< std::string, TypeDecl::Kind > TyVarMap;
 
+	/// A function needs an adapter if it returns a polymorphic value or if any of its
+	/// parameters have polymorphic type
 	bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVarr );
+
+	/// true iff function has polymorphic return type
 	bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars );
 	bool isPolyRet( FunctionType *function, std::string &name );
 	bool isPolyRet( FunctionType *function, const TyVarMap &otherTyVars );
-//	bool isPolyFun( FunctionType *fun, const TyVarMap &tyVars );
-	bool isPolyVal( Type *type, const TyVarMap &tyVars );
 
-  // true if type variable or any number of pointers to type variable 
-  bool isPolyObj( Type *type, const TyVarMap &tyVars );
+	/// returns polymorphic type if is polymorphic type, NULL otherwise; will look up substitution in env if provided
+	Type *isPolyType( Type *type, const TypeSubstitution *env = 0 );
+	
+	/// returns polymorphic type if is polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided
+	Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
+
+	/// returns polymorphic type if is pointer to polymorphic type, NULL otherwise; will look up substitution in env if provided
+	Type *isPolyPtr( Type *type, const TypeSubstitution *env = 0 );
+	
+	/// returns polymorphic type if is pointer to polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided
+	Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 );
+
+	/// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise
+	FunctionType * getFunctionType( Type *ty );
+
+	/// Prints type variable map
 	void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap );
+
+	/// Gets the name of the sizeof parameter for the type
+	std::string sizeofName( Type *ty );
+
+	/// Gets the name of the alignof parameter for the type
+	std::string alignofName( Type *ty );
 } // namespace GenPoly
 
Index: src/GenPoly/InstantiateGeneric.cc
===================================================================
--- src/GenPoly/InstantiateGeneric.cc	(revision baf7fee060790c21c0bbe680e7fba33fe7b6b433)
+++ src/GenPoly/InstantiateGeneric.cc	(revision ae63a185a34928dad284a49a9cd4c4d0d7655bb2)
@@ -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();
 	}
Index: src/GenPoly/Lvalue.cc
===================================================================
--- src/GenPoly/Lvalue.cc	(revision baf7fee060790c21c0bbe680e7fba33fe7b6b433)
+++ src/GenPoly/Lvalue.cc	(revision ae63a185a34928dad284a49a9cd4c4d0d7655bb2)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 07:41:33 2015
-// Update Count     : 1
+// Last Modified On : Tue Dec 15 15:33:13 2015
+// Update Count     : 3
 //
 
@@ -122,12 +122,15 @@
 			if ( retval && retStmt->get_expr() ) {
 				assert( ! retStmt->get_expr()->get_results().empty() );
-				while ( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) {
-					retStmt->set_expr( castExpr->get_arg() );
-					retStmt->get_expr()->set_env( castExpr->get_env() );
-					castExpr->set_env( 0 );
-					castExpr->set_arg( 0 );
-					delete castExpr;
-				} // while
 				if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
+					// ***** Code Removal ***** because casts may be stripped already
+
+					// strip casts because not allowed to take address of cast
+					// while ( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) {
+					// 	retStmt->set_expr( castExpr->get_arg() );
+					// 	retStmt->get_expr()->set_env( castExpr->get_env() );
+					// 	castExpr->set_env( 0 );
+					// 	castExpr->set_arg( 0 );
+					// 	delete castExpr;
+					// } // while
 					retStmt->set_expr( new AddressExpr( retStmt->get_expr()->acceptMutator( *this ) ) );
 				} else {
Index: src/GenPoly/ScrubTyVars.cc
===================================================================
--- src/GenPoly/ScrubTyVars.cc	(revision baf7fee060790c21c0bbe680e7fba33fe7b6b433)
+++ src/GenPoly/ScrubTyVars.cc	(revision ae63a185a34928dad284a49a9cd4c4d0d7655bb2)
@@ -13,4 +13,7 @@
 // Update Count     : 2
 //
+
+#include <sstream>
+#include <string>
 
 #include "GenPoly.h"
@@ -42,10 +45,20 @@
 
 	Expression * ScrubTyVars::mutate( SizeofExpr *szeof ) {
-		// sizeof( T ) => T parameter, which is the size of T
-		if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( szeof->get_type() ) ) {
-			Expression *expr = new NameExpr( typeInst->get_name() );
+		// sizeof( T ) => _sizeof_T parameter, which is the size of T
+		if ( Type *polyType = isPolyType( szeof->get_type() ) ) {
+			Expression *expr = new NameExpr( sizeofName( polyType ) );
 			return expr;
 		} else {
 			return Mutator::mutate( szeof );
+		} // if
+	}
+
+	Expression * ScrubTyVars::mutate( AlignofExpr *algnof ) {
+		// alignof( T ) => _alignof_T parameter, which is the alignment of T
+		if ( Type *polyType = isPolyType( algnof->get_type() ) ) {
+			Expression *expr = new NameExpr( alignofName( polyType ) );
+			return expr;
+		} else {
+			return Mutator::mutate( algnof );
 		} // if
 	}
Index: src/GenPoly/ScrubTyVars.h
===================================================================
--- src/GenPoly/ScrubTyVars.h	(revision baf7fee060790c21c0bbe680e7fba33fe7b6b433)
+++ src/GenPoly/ScrubTyVars.h	(revision ae63a185a34928dad284a49a9cd4c4d0d7655bb2)
@@ -16,4 +16,6 @@
 #ifndef _SCRUBTYVARS_H
 #define _SCRUBTYVARS_H
+
+#include <string>
 
 #include "GenPoly.h"
@@ -36,4 +38,5 @@
 		virtual Type* mutate( TypeInstType *typeInst );
 		Expression* mutate( SizeofExpr *szeof );
+		Expression* mutate( AlignofExpr *algnof );
 		virtual Type* mutate( PointerType *pointer );
 	  private:
Index: src/GenPoly/Specialize.cc
===================================================================
--- src/GenPoly/Specialize.cc	(revision baf7fee060790c21c0bbe680e7fba33fe7b6b433)
+++ src/GenPoly/Specialize.cc	(revision ae63a185a34928dad284a49a9cd4c4d0d7655bb2)
@@ -17,4 +17,5 @@
 
 #include "Specialize.h"
+#include "GenPoly.h"
 #include "PolyMutator.h"
 
@@ -87,14 +88,4 @@
 	}
 
-	/// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise
-	FunctionType * getFunctionType( Type *ty ) {
-		PointerType *ptrType;
-		if ( ( ptrType = dynamic_cast< PointerType* >( ty ) ) ) {
-			return dynamic_cast< FunctionType* >( ptrType->get_base() ); // pointer if FunctionType, NULL otherwise
-		} else {
-			return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise
-		}
-	}
-
 	/// Generates a thunk that calls `actual` with type `funType` and returns its address
 	Expression * Specialize::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) {
