Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision 7528ba10cd66aa6353fc8a1b816f5aca7fdde207)
+++ src/InitTweak/FixInit.cc	(revision 7528ba10cd66aa6353fc8a1b816f5aca7fdde207)
@@ -0,0 +1,101 @@
+//
+// 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.
+//
+// FixInit.h --
+//
+// Author           : Rob Schluntz
+// Created On       : Wed Jan 13 16:29:30 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Tue Jan 19 16:36:59 2016
+// Update Count     : 30
+//
+
+#include <stack>
+#include <list>
+#include "RemoveInit.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Initializer.h"
+#include "SynTree/Mutator.h"
+#include "GenPoly/PolyMutator.h"
+
+namespace InitTweak {
+	namespace {
+		const std::list<Label> noLabels;
+	}
+
+	class FixInit : public GenPoly::PolyMutator {
+	  public:
+		static void fixInitializers( std::list< Declaration * > &translationUnit );
+
+		virtual ObjectDecl * mutate( ObjectDecl *objDecl );
+
+		virtual CompoundStmt * mutate( CompoundStmt * compoundStmt );
+	};
+
+	void fix( std::list< Declaration * > & translationUnit ) {
+		FixInit::fixInitializers( translationUnit );
+	}
+
+	void FixInit::fixInitializers( std::list< Declaration * > & translationUnit ) {
+		FixInit fixer;
+		mutateAll( translationUnit, fixer );
+	}
+
+	// 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 *FixInit::mutate( ObjectDecl *objDecl ) {
+		if ( ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() ) ) {
+			// a decision should have been made by the resolver, so ctor and init are not both non-NULL
+			assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() );
+			if ( Expression * ctor = ctorInit->get_ctor() ) {
+				ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor );
+				stmtsToAddAfter.push_back( ctorStmt );
+				objDecl->set_init( NULL );
+				ctorInit->set_ctor( NULL );
+			} else if ( Initializer * init = ctorInit->get_init() ) {
+				objDecl->set_init( init );
+				ctorInit->set_init( NULL );
+			} else {
+				// no constructor and no initializer, which is okay
+				objDecl->set_init( NULL );
+			}
+			delete ctorInit;
+		}
+		return objDecl;
+	}
+
+	CompoundStmt * FixInit::mutate( CompoundStmt * compoundStmt ) {
+		std::list< Statement * > & statements = compoundStmt->get_kids();
+		for ( std::list< Statement * >::iterator it = statements.begin(); it != statements.end(); ) {
+			// remove if instrinsic destructor statement
+			// xxx - test user manually calling intrinsic functions - what happens?
+			if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( *it ) ) {
+				if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( exprStmt->get_expr() ) ) {
+					if ( VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() ) ) {
+						if ( function->get_var()->get_name() == "^?{}" && function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
+							statements.erase(it++);
+							continue;
+						} else {
+						}
+					}
+				}
+			}
+			++it;
+		}
+		// mutate non-destructor statements
+		return PolyMutator::mutate( compoundStmt );
+	}
+
+} // namespace InitTweak
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/InitTweak/FixInit.h
===================================================================
--- src/InitTweak/FixInit.h	(revision 7528ba10cd66aa6353fc8a1b816f5aca7fdde207)
+++ src/InitTweak/FixInit.h	(revision 7528ba10cd66aa6353fc8a1b816f5aca7fdde207)
@@ -0,0 +1,38 @@
+//
+// 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.
+//
+// FixInit.h --
+//
+// Author           : Rob Schluntz
+// Created On       : Wed Jan 13 16:29:30 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed Jan 13 16:31:13 2016
+// Update Count     : 5
+//
+
+#ifndef FIX_INIT_H
+#define FIX_INIT_H
+
+#include <string>
+#include <list>
+
+#include "SynTree/SynTree.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Mutator.h"
+
+namespace InitTweak {
+  /// replace constructor initializers with expression statements
+  /// and unwrap basic C-style initializers
+	void fix( std::list< Declaration * > & translationUnit );
+} // namespace
+
+#endif // GENPOLY_POLYMUTATOR_H
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/InitTweak/InitModel.cc
===================================================================
--- src/InitTweak/InitModel.cc	(revision 2a4b0884c14643e09650daaeb3a6667b5bff6b48)
+++ src/InitTweak/InitModel.cc	(revision 7528ba10cd66aa6353fc8a1b816f5aca7fdde207)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// InitModel.cc -- 
+// InitModel.cc --
 //
 // Author           : Rodolfo G. Esteves
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 16:37:08 2015
-// Update Count     : 1
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Jan 07 13:38:46 2016
+// Update Count     : 5
 //
 
@@ -198,5 +198,5 @@
 		assert(init == 0 && single != 0);
 		std::list< Expression * > empty;
-		init = new SingleInit( single->get_expr(), empty );
+		init = new SingleInit( single->get_expr(), empty, false ); // cannot be constructed
 		return;
 	}
@@ -214,5 +214,6 @@
 			} // if
 
-		init = new ListInit( contents );
+		std::list< Expression * > desig;
+		init = new ListInit( contents, desig, false ); // cannot be constructed
 		return;
 	}
Index: src/InitTweak/RemoveInit.cc
===================================================================
--- src/InitTweak/RemoveInit.cc	(revision 2a4b0884c14643e09650daaeb3a6667b5bff6b48)
+++ src/InitTweak/RemoveInit.cc	(revision 7528ba10cd66aa6353fc8a1b816f5aca7fdde207)
@@ -5,13 +5,15 @@
 // file "LICENCE" distributed with Cforall.
 //
-// RemoveInit.cc -- 
+// RemoveInit.cc --
 //
 // Author           : Rob Schluntz
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Dec 15 15:37:26 2015
-// Update Count     : 15
-//
-
+// Last Modified By : Rob Schluntz
+// Last Modified On : Tue Feb 09 15:12:29 2016
+// Update Count     : 166
+//
+
+#include <stack>
+#include <list>
 #include "RemoveInit.h"
 #include "SynTree/Declaration.h"
@@ -21,4 +23,5 @@
 #include "SynTree/Initializer.h"
 #include "SynTree/Mutator.h"
+#include "GenPoly/PolyMutator.h"
 
 namespace InitTweak {
@@ -26,20 +29,21 @@
 		const std::list<Label> noLabels;
 	}
-	
-	class RemoveInit : public Mutator {
+
+	class RemoveInit : public GenPoly::PolyMutator {
 	  public:
+		/// removes and replaces initialization for polymorphic value objects
+		/// with assignment (TODO: constructor) statements.
+		/// also consistently allocates a temporary variable for the return value
+		/// of a function so that anything which the resolver decides can be assigned
+		/// into the return type of a function can be returned.
+		static void removeInitializers( std::list< Declaration * > &translationUnit );
+
 		RemoveInit();
-		virtual ObjectDecl * mutate(ObjectDecl *objDecl);
+		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;
@@ -47,5 +51,38 @@
 	};
 
-	void tweak( std::list< Declaration * > translationUnit ) {
+	class CtorDtor : public GenPoly::PolyMutator {
+	  public:
+		/// create constructor and destructor statements for object declarations.
+		/// Destructors are inserted directly into the code, whereas constructors
+		/// will be added in after the resolver has run so that the initializer expression
+		/// is only removed if a constructor is found
+		static void generateCtorDtor( std::list< Declaration * > &translationUnit );
+
+		CtorDtor() : inFunction( false ) {}
+
+		virtual ObjectDecl * mutate( ObjectDecl * );
+		virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
+		virtual Declaration* mutate( StructDecl *aggregateDecl );
+		virtual Declaration* mutate( UnionDecl *aggregateDecl );
+		virtual Declaration* mutate( EnumDecl *aggregateDecl );
+		virtual Declaration* mutate( ContextDecl *aggregateDecl );
+		virtual TypeDecl* mutate( TypeDecl *typeDecl );
+		virtual Declaration* mutate( TypedefDecl *typeDecl );
+
+		virtual CompoundStmt * mutate( CompoundStmt * compoundStmt );
+
+	  protected:
+		bool inFunction;
+
+		// to be added before block ends - use push_front so order is correct
+		std::list< Statement * > destructorStmts;
+	};
+
+	void tweak( std::list< Declaration * > & translationUnit ) {
+		RemoveInit::removeInitializers( translationUnit );
+		CtorDtor::generateCtorDtor( translationUnit );
+	}
+
+	void RemoveInit::removeInitializers( std::list< Declaration * > & translationUnit ) {
 		RemoveInit remover;
 		mutateAll( translationUnit, remover );
@@ -53,24 +90,4 @@
 
 	RemoveInit::RemoveInit() : tempNamer( "_retVal" ) {}
-	
-	void RemoveInit::mutateStatementList( std::list< Statement* > &statements ) {
-		for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
-			if ( ! stmtsToAddAfter.empty() ) {
-				statements.splice( i, stmtsToAddAfter );
-			} // if
-			*i = (*i)->acceptMutator( *this );
-			if ( ! stmtsToAddBefore.empty() ) {
-				statements.splice( i, stmtsToAddBefore );
-			} // if
-		} // for
-		if ( ! stmtsToAddAfter.empty() ) {
-			statements.splice( statements.end(), stmtsToAddAfter );
-		} // if
-	}
-
-	CompoundStmt *RemoveInit::mutate(CompoundStmt *compoundStmt) {
-		mutateStatementList( compoundStmt->get_kids() );
-		return compoundStmt;
-	}
 
 	// in the case where an object has an initializer and a polymorphic type, insert an assignment immediately after the
@@ -79,5 +96,6 @@
 		if (objDecl->get_init() && dynamic_cast<TypeInstType*>(objDecl->get_type())) {
 			if (SingleInit * single = dynamic_cast<SingleInit*>(objDecl->get_init())) {
-				UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
+				// xxx this can be more complicated - consider ListInit
+				UntypedExpr *assign = new UntypedExpr( new NameExpr( "?{}" ) );
 				assign->get_args().push_back( new AddressExpr (new NameExpr( objDecl->get_name() ) ) );
 				assign->get_args().push_back( single->get_value()->clone() );
@@ -93,12 +111,13 @@
 		// hands off if the function returns an lvalue - we don't want to allocate a temporary if a variable's address
 		// is being returned
+		// xxx - this should construct rather than assign
 		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 ) );
-			
+			stmtsToAdd.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));
+			stmtsToAdd.push_back(new ExprStmt(noLabels, assign));
 
 			returnStmt->set_expr( new VariableExpr( newObj ) );
@@ -110,5 +129,5 @@
 		std::list<DeclarationWithType*> oldReturnVals = returnVals;
 		std::string oldFuncName = funcName;
-		
+
 		FunctionType * type = functionDecl->get_functionType();
 		returnVals = type->get_returnVals();
@@ -119,4 +138,105 @@
 		return decl;
 	}
+
+
+	void CtorDtor::generateCtorDtor( std::list< Declaration * > & translationUnit ) {
+		CtorDtor ctordtor;
+		mutateAll( translationUnit, ctordtor );
+	}
+
+	namespace {
+		bool tryConstruct( ObjectDecl * objDecl ) {
+			// xxx - handle designations
+			return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) &&
+	 			(objDecl->get_init() == NULL ||
+				( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() ));
+		}
+
+		Expression * makeCtorDtorExpr( std::string name, ObjectDecl * objDecl, std::list< Expression * > args ) {
+			UntypedExpr * expr = new UntypedExpr( new NameExpr( name ) );
+			expr->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
+			expr->get_args().splice( expr->get_args().end(), args );
+			return expr;
+		}
+
+		class InitExpander : public Visitor {
+		  public:
+		  InitExpander() {}
+		  // ~InitExpander() {}
+			virtual void visit( SingleInit * singleInit );
+			virtual void visit( ListInit * listInit );
+			std::list< Expression * > argList;
+		};
+
+		void InitExpander::visit( SingleInit * singleInit ) {
+			argList.push_back( singleInit->get_value()->clone() );
+		}
+
+		void InitExpander::visit( ListInit * listInit ) {
+			// xxx - for now, assume no nested list inits
+			std::list<Initializer*>::iterator it = listInit->begin_initializers();
+			for ( ; it != listInit->end_initializers(); ++it ) {
+				(*it)->accept( *this );
+			}
+		}
+
+		std::list< Expression * > makeInitList( Initializer * init ) {
+			InitExpander expander;
+			maybeAccept( init, expander );
+			return expander.argList;
+		}
+	}
+
+	ObjectDecl * CtorDtor::mutate( ObjectDecl * objDecl ) {
+		// hands off if designated or if @=
+		if ( tryConstruct( objDecl ) ) {
+			if ( inFunction ) {
+				Expression * ctor = makeCtorDtorExpr( "?{}", objDecl, makeInitList( objDecl->get_init() ) );
+				Expression * dtor = makeCtorDtorExpr( "^?{}", objDecl, std::list< Expression * >() );
+
+				// need to remember init expression, in case no ctors exist
+				// if ctor does exist, want to use ctor expression instead of init
+				// push this decision to the resolver
+				objDecl->set_init( new ConstructorInit( ctor, objDecl->get_init() ) );
+				destructorStmts.push_front( new ExprStmt( noLabels, dtor ) );
+			} else {
+				// xxx - find a way to construct/destruct globals
+				// hack: implicit "static" initialization routine for each struct type? or something similar?
+				// --ties into module system
+			}
+		}
+		return objDecl;
+	}
+
+	DeclarationWithType * CtorDtor::mutate( FunctionDecl *functionDecl ) {
+		// parameters should not be constructed and destructed, so don't mutate FunctionType
+		bool oldInFunc = inFunction;
+		mutateAll( functionDecl->get_oldDecls(), *this );
+		inFunction = true;
+		functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
+		inFunction = oldInFunc;
+		return functionDecl;
+	}
+
+	CompoundStmt * CtorDtor::mutate( CompoundStmt * compoundStmt ) {
+		CompoundStmt * ret = PolyMutator::mutate( compoundStmt );
+		std::list< Statement * > &statements = ret->get_kids();
+		if ( ! destructorStmts.empty() ) {
+			// TODO: adding to the end of a block isn't sufficient, since
+			// return/break/goto should trigger destructor when block is left.
+			statements.splice( statements.end(), destructorStmts );
+		} // if
+		return ret;
+	}
+
+	// should not traverse into any of these declarations to find objects
+	// that need to be constructed or destructed
+	Declaration* CtorDtor::mutate( StructDecl *aggregateDecl ) { return aggregateDecl; }
+	Declaration* CtorDtor::mutate( UnionDecl *aggregateDecl ) { return aggregateDecl; }
+	Declaration* CtorDtor::mutate( EnumDecl *aggregateDecl ) { return aggregateDecl; }
+	Declaration* CtorDtor::mutate( ContextDecl *aggregateDecl ) { return aggregateDecl; }
+	TypeDecl* CtorDtor::mutate( TypeDecl *typeDecl ) { return typeDecl; }
+	Declaration* CtorDtor::mutate( TypedefDecl *typeDecl ) { return typeDecl; }
+
 } // namespace InitTweak
 
Index: src/InitTweak/RemoveInit.h
===================================================================
--- src/InitTweak/RemoveInit.h	(revision 2a4b0884c14643e09650daaeb3a6667b5bff6b48)
+++ src/InitTweak/RemoveInit.h	(revision 7528ba10cd66aa6353fc8a1b816f5aca7fdde207)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// RemoveInit.h -- 
+// RemoveInit.h --
 //
 // Author           : Rodolfo G. Esteves
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Nov 27 17:00:47 2015
-// Update Count     : 2
+// Last Modified By : Rob Schluntz
+// Last Modified On : Mon Jan 11 16:02:44 2016
+// Update Count     : 3
 //
 
@@ -26,6 +26,6 @@
 namespace InitTweak {
 	/// Adds assignment statements for polymorphic type initializers
-	void tweak( std::list< Declaration * > translationUnit );
-} // namespace 
+	void tweak( std::list< Declaration * > & translationUnit );
+} // namespace
 
 #endif // GENPOLY_POLYMUTATOR_H
Index: src/InitTweak/module.mk
===================================================================
--- src/InitTweak/module.mk	(revision 2a4b0884c14643e09650daaeb3a6667b5bff6b48)
+++ src/InitTweak/module.mk	(revision 7528ba10cd66aa6353fc8a1b816f5aca7fdde207)
@@ -11,8 +11,8 @@
 ## Created On       : Mon Jun  1 17:49:17 2015
 ## Last Modified By : Rob Schluntz
-## Last Modified On : Mon Jan 11 14:40:16 2016
-## Update Count     : 2
+## Last Modified On : Wed Jan 13 16:29:03 2016
+## Update Count     : 3
 ###############################################################################
 
-SRC += InitTweak/RemoveInit.cc
-
+SRC += InitTweak/RemoveInit.cc \
+	InitTweak/FixInit.cc
