Index: src/CodeGen/GenType.cc
===================================================================
--- src/CodeGen/GenType.cc	(revision 27caf8d03f24f559d9889acd368b5bcca03135c4)
+++ src/CodeGen/GenType.cc	(revision 535adabb437e164f07f47ec1bea146841e2e25a3)
@@ -237,5 +237,4 @@
 	void GenType::visit( TupleType * tupleType ) {
 		assertf( ! genC, "Tuple types should not reach code generation." );
-		Visitor::visit( tupleType );
 		unsigned int i = 0;
 		std::ostringstream os;
@@ -245,5 +244,5 @@
 			os << genType( t, "", pretty, genC, lineMarks ) << (i == tupleType->size() ? "" : ", ");
 		}
-		os << "]";
+		os << "] ";
 		typeString = os.str() + typeString;
 	}
Index: src/GenPoly/InstantiateGeneric.cc
===================================================================
--- src/GenPoly/InstantiateGeneric.cc	(revision 27caf8d03f24f559d9889acd368b5bcca03135c4)
+++ src/GenPoly/InstantiateGeneric.cc	(revision 535adabb437e164f07f47ec1bea146841e2e25a3)
@@ -367,7 +367,7 @@
 				concDecl->set_body( inst->get_baseStruct()->has_body() );
 				substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
-				DeclMutator::addDeclaration( concDecl );
-				insert( inst, typeSubs, concDecl );
+				insert( inst, typeSubs, concDecl ); // must insert before recursion
 				concDecl->acceptMutator( *this ); // recursively instantiate members
+				DeclMutator::addDeclaration( concDecl ); // must occur before declaration is added so that member instantiations appear first
 			}
 			StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() );
@@ -422,7 +422,7 @@
 				concDecl->set_body( inst->get_baseUnion()->has_body() );
 				substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
-				DeclMutator::addDeclaration( concDecl );
-				insert( inst, typeSubs, concDecl );
+				insert( inst, typeSubs, concDecl ); // must insert before recursion
 				concDecl->acceptMutator( *this ); // recursively instantiate members
+				DeclMutator::addDeclaration( concDecl ); // must occur before declaration is added so that member instantiations appear first
 			}
 			UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() );
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision 27caf8d03f24f559d9889acd368b5bcca03135c4)
+++ src/InitTweak/FixInit.cc	(revision 535adabb437e164f07f47ec1bea146841e2e25a3)
@@ -619,5 +619,15 @@
 
 		Expression * FixCopyCtors::mutate( StmtExpr * stmtExpr ) {
-			stmtExpr = safe_dynamic_cast< StmtExpr * >( Parent::mutate( stmtExpr ) );
+			// function call temporaries should be placed at statement-level, rather than nested inside of a new statement expression,
+			// since temporaries can be shared across sub-expressions, e.g.
+			//   [A, A] f();
+			//   g([A] x, [A] y);
+			//   f(g());
+			// f is executed once, so the return temporary is shared across the tuple constructors for x and y.
+			std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids();
+			for ( Statement *& stmt : stmts ) {
+				stmt = stmt->acceptMutator( *this );
+			} // for
+			// stmtExpr = safe_dynamic_cast< StmtExpr * >( Parent::mutate( stmtExpr ) );
 			assert( stmtExpr->get_result() );
 			Type * result = stmtExpr->get_result();
Index: src/SynTree/TypeSubstitution.cc
===================================================================
--- src/SynTree/TypeSubstitution.cc	(revision 27caf8d03f24f559d9889acd368b5bcca03135c4)
+++ src/SynTree/TypeSubstitution.cc	(revision 535adabb437e164f07f47ec1bea146841e2e25a3)
@@ -166,11 +166,11 @@
 			boundVars.insert( (*tyvar )->get_name() );
 		} // for
-	} // if
-	// bind type variables from generic type instantiations
-	std::list< TypeDecl* > *baseParameters = type->get_baseParameters();
-	if ( baseParameters && ! type->get_parameters().empty() ) {
-		for ( std::list< TypeDecl* >::const_iterator tyvar = baseParameters->begin(); tyvar != baseParameters->end(); ++tyvar ) {
-			boundVars.insert( (*tyvar)->get_name() );
-		} // for
+		// bind type variables from generic type instantiations
+		std::list< TypeDecl* > *baseParameters = type->get_baseParameters();
+		if ( baseParameters && ! type->get_parameters().empty() ) {
+			for ( std::list< TypeDecl* >::const_iterator tyvar = baseParameters->begin(); tyvar != baseParameters->end(); ++tyvar ) {
+				boundVars.insert( (*tyvar)->get_name() );
+			} // for
+		} // if
 	} // if
 	Type *ret = Mutator::mutate( type );
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 27caf8d03f24f559d9889acd368b5bcca03135c4)
+++ src/main.cc	(revision 535adabb437e164f07f47ec1bea146841e2e25a3)
@@ -64,4 +64,5 @@
 	bresolvep = false,
 	bboxp = false,
+	bcodegenp = false,
 	ctorinitp = false,
 	declstatsp = false,
@@ -306,4 +307,9 @@
 		OPTPRINT( "box" )
 		GenPoly::box( translationUnit );
+
+		if ( bcodegenp ) {
+			dump( translationUnit );
+			return 0;
+		}
 
 		if ( optind < argc ) {							// any commands after the flags and input file ? => output file name
@@ -377,5 +383,5 @@
 
 	int c;
-	while ( (c = getopt_long( argc, argv, "abBcdefglLmnpqrstTvyzZD:F:", long_opts, &long_index )) != -1 ) {
+	while ( (c = getopt_long( argc, argv, "abBcCdefglLmnpqrstTvyzZD:F:", long_opts, &long_index )) != -1 ) {
 		switch ( c ) {
 		  case Ast:
@@ -393,4 +399,7 @@
 		  case 'c':										// print after constructors and destructors are replaced
 			ctorinitp = true;
+			break;
+		  case 'C':										// print before code generation
+			bcodegenp = true;
 			break;
 		  case DeclStats:
