Index: src/InitTweak/RemoveInit.cc
===================================================================
--- src/InitTweak/RemoveInit.cc	(revision 7cd23d5dd33292e89939b23cf11970e74bf7538a)
+++ src/InitTweak/RemoveInit.cc	(revision cf16f94d500fdd6115ce4918ac612fd7946e7f19)
@@ -7,9 +7,9 @@
 // RemoveInit.cc -- 
 //
-// Author           : Rodolfo G. Esteves
+// Author           : Rob Schluntz
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 16:39:32 2015
-// Update Count     : 1
+// Last Modified On : Tue Dec 15 15:37:26 2015
+// Update Count     : 15
 //
 
@@ -26,4 +26,24 @@
 		const std::list<Label> noLabels;
 	}
+	
+	class RemoveInit : public Mutator {
+	  public:
+		RemoveInit();
+		virtual ObjectDecl * mutate(ObjectDecl *objDecl);
+		virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
+
+		virtual Statement * mutate( ReturnStmt * returnStmt );
+		
+		virtual CompoundStmt * mutate(CompoundStmt * compoundStmt);
+		
+	  protected:
+		std::list< Statement* > stmtsToAddBefore;
+		std::list< Statement* > stmtsToAddAfter;
+		void mutateStatementList( std::list< Statement* > &statements );
+
+		std::list<DeclarationWithType*> returnVals;
+		UniqueName tempNamer;
+		std::string funcName;
+	};
 
 	void tweak( std::list< Declaration * > translationUnit ) {
@@ -32,4 +52,6 @@
 	}
 
+	RemoveInit::RemoveInit() : tempNamer( "_retVal" ) {}
+	
 	void RemoveInit::mutateStatementList( std::list< Statement* > &statements ) {
 		for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
@@ -38,4 +60,7 @@
 			} // if
 			*i = (*i)->acceptMutator( *this );
+			if ( ! stmtsToAddBefore.empty() ) {
+				statements.splice( i, stmtsToAddBefore );
+			} // if
 		} // for
 		if ( ! stmtsToAddAfter.empty() ) {
@@ -49,7 +74,6 @@
 	}
 
-// in the case where an object has an initializer and a polymorphic type, insert an assignment
-// immediately after the declaration. This will (seemingly) cause the later phases to do the right
-// thing with the assignment
+	// in the case where an object has an initializer and a polymorphic type, insert an assignment immediately after the
+	// declaration. This will (seemingly) cause the later phases to do the right thing with the assignment
 	ObjectDecl *RemoveInit::mutate( ObjectDecl *objDecl ) {
 		if (objDecl->get_init() && dynamic_cast<TypeInstType*>(objDecl->get_type())) {
@@ -63,4 +87,36 @@
 		return objDecl;
 	}
+
+	Statement *RemoveInit::mutate( ReturnStmt *returnStmt ) {
+		// update for multiple return values
+		assert( returnVals.size() == 0 || returnVals.size() == 1 );
+		// hands off if the function returns an lvalue - we don't want to allocate a temporary if a variable's address
+		// is being returned
+		if ( returnStmt->get_expr() && returnVals.size() == 1 && funcName != "?=?" && ! returnVals.front()->get_type()->get_isLvalue()  ) {
+			ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, returnVals.front()->get_type()->clone(), 0 );
+			stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
+			
+			UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
+			assign->get_args().push_back( new AddressExpr (new NameExpr( newObj->get_name() ) ) );
+			assign->get_args().push_back( returnStmt->get_expr() );
+			stmtsToAddBefore.push_back(new ExprStmt(noLabels, assign));
+
+			returnStmt->set_expr( new VariableExpr( newObj ) );
+		} // if
+		return returnStmt;
+	}
+
+	DeclarationWithType* RemoveInit::mutate( FunctionDecl *functionDecl ) {
+		std::list<DeclarationWithType*> oldReturnVals = returnVals;
+		std::string oldFuncName = funcName;
+		
+		FunctionType * type = functionDecl->get_functionType();
+		returnVals = type->get_returnVals();
+		funcName = functionDecl->get_name();
+		DeclarationWithType * decl = Mutator::mutate( functionDecl );
+		returnVals = oldReturnVals;
+		funcName = oldFuncName;
+		return decl;
+	}
 } // namespace InitTweak
 
