Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/CodeGen/CodeGenerator.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// CodeGenerator.cc -- 
+// CodeGenerator.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Mar  2 17:32:16 2016
-// Update Count     : 243
+// Last Modified By : Rob Schluntz
+// Last Modified On : Mon Apr 04 17:08:06 2016
+// Update Count     : 255
 //
 
@@ -99,5 +99,5 @@
 		handleStorageClass( objectDecl );
 		output << genType( objectDecl->get_type(), mangleName( objectDecl ) );
-	
+
 		if ( objectDecl->get_init() ) {
 			output << " = ";
@@ -113,5 +113,5 @@
 		if ( aggDecl->get_name() != "" )
 			output << aggDecl->get_name();
-	
+
 		std::list< Declaration * > &memb = aggDecl->get_members();
 
@@ -119,12 +119,12 @@
 			output << " {" << endl;
 
-			cur_indent += CodeGenerator::tabsize; 
+			cur_indent += CodeGenerator::tabsize;
 			for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
-				output << indent; 
+				output << indent;
 				(*i)->accept( *this );
 				output << ";" << endl;
 			}
 
-			cur_indent -= CodeGenerator::tabsize; 
+			cur_indent -= CodeGenerator::tabsize;
 
 			output << indent << "}";
@@ -141,5 +141,5 @@
 		handleAggregate( aggregateDecl );
 	}
-  
+
 	void CodeGenerator::visit( EnumDecl *aggDecl ) {
 		output << "enum ";
@@ -147,5 +147,5 @@
 		if ( aggDecl->get_name() != "" )
 			output << aggDecl->get_name();
-	
+
 		std::list< Declaration* > &memb = aggDecl->get_members();
 
@@ -153,9 +153,9 @@
 			output << " {" << endl;
 
-			cur_indent += CodeGenerator::tabsize; 
+			cur_indent += CodeGenerator::tabsize;
 			for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
 				ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
 				assert( obj );
-				output << indent << mangleName( obj ); 
+				output << indent << mangleName( obj );
 				if ( obj->get_init() ) {
 					output << " = ";
@@ -165,17 +165,17 @@
 			} // for
 
-			cur_indent -= CodeGenerator::tabsize; 
+			cur_indent -= CodeGenerator::tabsize;
 
 			output << indent << "}";
 		} // if
 	}
-  
+
 	void CodeGenerator::visit( TraitDecl *aggregateDecl ) {}
-  
+
 	void CodeGenerator::visit( TypedefDecl *typeDecl ) {
 		output << "typedef ";
 		output << genType( typeDecl->get_base(), typeDecl->get_name() );
 	}
-  
+
 	void CodeGenerator::visit( TypeDecl *typeDecl ) {
 		// really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes,
@@ -213,9 +213,15 @@
 		printDesignators( init->get_designators() );
 		output << "{ ";
-		genCommaList( init->begin_initializers(), init->end_initializers() );
+		if ( init->begin_initializers() == init->end_initializers() ) {
+			// illegal to leave initializer list empty for scalar initializers,
+			// but always legal to have 0
+			output << "0";
+		} else {
+			genCommaList( init->begin_initializers(), init->end_initializers() );
+		}
 		output << " }";
 	}
 
-	void CodeGenerator::visit( Constant *constant ) { 
+	void CodeGenerator::visit( Constant *constant ) {
 		output << constant->get_value() ;
 	}
@@ -234,5 +240,5 @@
 						assert( arg != applicationExpr->get_args().end() );
 						if ( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
-	        
+
 							*arg = addrExpr->get_arg();
 						} else {
@@ -243,10 +249,10 @@
 						break;
 					}
-	      
+
 				  default:
 					// do nothing
 					;
 				}
-	    
+
 				switch ( opInfo.type ) {
 				  case OT_INDEX:
@@ -257,10 +263,27 @@
 					output << "]";
 					break;
-	      
+
 				  case OT_CALL:
-					// there are no intrinsic definitions of the function call operator
+					// there are no intrinsic definitions of the function call operator or constructors or destructors
 					assert( false );
 					break;
-	      
+
+				  case OT_CTOR:
+				  // it's just an optimization to disallow this, so for now let it through
+				  // since it makes autogenerating constructors a lot easier
+  				varExpr->accept( *this );
+					output << "(";
+					genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
+					output << ")";
+
+				  // intrinsic constructors should never be called directly - they should be transformed back into Initializer nodes
+				  // assert(false);
+				  break;
+
+				  case OT_DTOR:
+				  // intrinsic destructors do nothing - don't generate any code
+				  output << " /* " << dynamic_cast<VariableExpr*>(applicationExpr->get_function())->get_var()->get_name() << " */";
+				  break;
+
 				  case OT_PREFIX:
 				  case OT_PREFIXASSIGN:
@@ -271,5 +294,5 @@
 					output << ")";
 					break;
-	      
+
 				  case OT_POSTFIX:
 				  case OT_POSTFIXASSIGN:
@@ -278,4 +301,5 @@
 					output << opInfo.symbol;
 					break;
+
 
 				  case OT_INFIX:
@@ -288,5 +312,5 @@
 					output << ")";
 					break;
-	      
+
 				  case OT_CONSTANT:
 				  case OT_LABELADDRESS:
@@ -307,5 +331,5 @@
 		} // if
 	}
-  
+
 	void CodeGenerator::visit( UntypedExpr *untypedExpr ) {
 		if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
@@ -321,9 +345,14 @@
 					output << "]";
 					break;
-	      
+
 				  case OT_CALL:
 					assert( false );
-					break;
-	      
+
+					case OT_CTOR:
+					case OT_DTOR:
+					// intrinsic constructors should never be called
+					// intrinsic destructors do nothing
+					break;
+
 				  case OT_PREFIX:
 				  case OT_PREFIXASSIGN:
@@ -335,5 +364,5 @@
 					output << ")";
 					break;
-	      
+
 				  case OT_POSTFIX:
 				  case OT_POSTFIXASSIGN:
@@ -342,5 +371,5 @@
 					output << opInfo.symbol;
 					break;
-  
+
 				  case OT_INFIX:
 				  case OT_INFIXASSIGN:
@@ -352,5 +381,5 @@
 					output << ")";
 					break;
-					
+
 				  case OT_CONSTANT:
 					// there are no intrinsic definitions of 0 or 1 as functions
@@ -370,5 +399,5 @@
 		} // if
 	}
-  
+
 	void CodeGenerator::visit( NameExpr *nameExpr ) {
 		OperatorInfo opInfo;
@@ -380,5 +409,5 @@
 		} // if
 	}
-  
+
 	void CodeGenerator::visit( AddressExpr *addressExpr ) {
 		output << "(&";
@@ -409,14 +438,14 @@
 		output << ")";
 	}
-  
+
 	void CodeGenerator::visit( UntypedMemberExpr *memberExpr ) {
 		assert( false );
 	}
-  
+
 	void CodeGenerator::visit( MemberExpr *memberExpr ) {
 		memberExpr->get_aggregate()->accept( *this );
 		output << "." << mangleName( memberExpr->get_member() );
 	}
-  
+
 	void CodeGenerator::visit( VariableExpr *variableExpr ) {
 		OperatorInfo opInfo;
@@ -427,10 +456,10 @@
 		} // if
 	}
-  
+
 	void CodeGenerator::visit( ConstantExpr *constantExpr ) {
 		assert( constantExpr->get_constant() );
 		constantExpr->get_constant()->accept( *this );
 	}
-  
+
 	void CodeGenerator::visit( SizeofExpr *sizeofExpr ) {
 		output << "sizeof(";
@@ -465,5 +494,5 @@
 		output << ")";
 	}
-  
+
 	void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
 		output << "(";
@@ -477,5 +506,5 @@
 		output << ")";
 	}
-  
+
 	void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) {
 		output << "(";
@@ -487,5 +516,5 @@
 		output << ")";
 	}
-  
+
 	void CodeGenerator::visit( CommaExpr *commaExpr ) {
 		output << "(";
@@ -495,7 +524,7 @@
 		output << ")";
 	}
-  
+
 	void CodeGenerator::visit( TupleExpr *tupleExpr ) {}
-  
+
 	void CodeGenerator::visit( TypeExpr *typeExpr ) {}
 
@@ -528,5 +557,5 @@
 			}
 		}
-		cur_indent -= CodeGenerator::tabsize; 
+		cur_indent -= CodeGenerator::tabsize;
 
 		output << indent << "}";
@@ -534,6 +563,6 @@
 
 	void CodeGenerator::visit( ExprStmt *exprStmt ) {
-		// I don't see why this check is necessary. 
-		// If this starts to cause problems then put it back in, 
+		// I don't see why this check is necessary.
+		// If this starts to cause problems then put it back in,
 		// with an explanation
 		assert( exprStmt );
@@ -585,5 +614,5 @@
 		switchStmt->get_condition()->accept( *this );
 		output << " ) ";
-		
+
 		output << "{" << std::endl;
 		cur_indent += CodeGenerator::tabsize;
@@ -605,5 +634,5 @@
 		} // if
 		output << ":\n";
-		
+
 		std::list<Statement *> sts = caseStmt->get_statements();
 
@@ -622,5 +651,5 @@
 			if ( ! branchStmt->get_target().empty() )
 				output << "goto " << branchStmt->get_target();
-			else { 
+			else {
 				if ( branchStmt->get_computedTarget() != 0 ) {
 					output << "goto *";
@@ -673,6 +702,6 @@
 
 	void CodeGenerator::visit( ForStmt *forStmt ) {
-		// initialization is always hoisted, so don't 
-		// bother doing anything with that 
+		// initialization is always hoisted, so don't
+		// bother doing anything with that
 		output << "for (;";
 
@@ -698,5 +727,5 @@
 	void CodeGenerator::visit( DeclStmt *declStmt ) {
 		declStmt->get_decl()->accept( *this );
-	
+
 		if ( doSemicolon( declStmt->get_decl() ) ) {
 			output << ";";
Index: src/CodeGen/OperatorTable.cc
===================================================================
--- src/CodeGen/OperatorTable.cc	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/CodeGen/OperatorTable.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// OperatorTable.cc -- 
+// OperatorTable.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jun 23 17:41:14 2015
-// Update Count     : 5
+// Last Modified By : Rob Schluntz
+// Last Modified On : Tue Oct 06 15:26:34 2015
+// Update Count     : 9
 //
 
@@ -21,4 +21,6 @@
 		const OperatorInfo tableValues[] = {
 			{	"?[?]",		"",		"_operator_index",				OT_INDEX			},
+			{	"?{}",		"",		"_constructor",					OT_CTOR				},
+			{	"^?{}",		"",		"_destructor",					OT_DTOR				},
 			{	"?()",		"",		"_operator_call",				OT_CALL				},
 			{	"?++",		"++",	"_operator_postincr",			OT_POSTFIXASSIGN	},
Index: src/CodeGen/OperatorTable.h
===================================================================
--- src/CodeGen/OperatorTable.h	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/CodeGen/OperatorTable.h	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jun 23 16:09:27 2015
-// Update Count     : 3
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed Jun 24 16:17:57 2015
+// Update Count     : 5
 //
 
@@ -22,4 +22,6 @@
 	enum OperatorType {
 		OT_INDEX,
+		OT_CTOR,
+		OT_DTOR,
 		OT_CALL,
 		OT_PREFIX,
Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/GenPoly/Box.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Feb  5 16:45:07 2016
-// Update Count     : 286
+// Last Modified By : Rob Schluntz
+// Last Modified On : Tue Feb 09 14:39:52 2016
+// Update Count     : 295
 //
 
@@ -744,4 +744,5 @@
 
 		Expression *Pass1::makeOffsetArray( StructInstType *ty ) {
+			std::list<Expression*> noDesignators;
 			std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members();
 
@@ -762,7 +763,7 @@
 					memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 );
 				}
-				inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) );
-			}
-			arrayTemp->set_init( new ListInit( inits ) );
+				inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ), noDesignators ) );
+			}
+			arrayTemp->set_init( new ListInit( inits, noDesignators ) );
 
 			// return variable pointing to temporary
@@ -1903,5 +1904,5 @@
 
 					std::list<Expression*> designators;
-					objectDecl->set_init( new SingleInit( alloc, designators ) );
+					objectDecl->set_init( new SingleInit( alloc, designators, false ) ); // not constructed
 				}
 			}
@@ -1944,5 +1945,5 @@
 			return derefdVar;
 		}
-		
+
 		Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) {
 			// mutate, exiting early if no longer MemberExpr
Index: src/GenPoly/CopyParams.cc
===================================================================
--- src/GenPoly/CopyParams.cc	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/GenPoly/CopyParams.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,9 +5,9 @@
 // file "LICENCE" distributed with Cforall.
 //
-// CopyParams.cc -- 
+// CopyParams.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
+// Last Modified By : Rob Schluntz
 // Last Modified On : Tue May 19 07:33:31 2015
 // Update Count     : 1
@@ -29,5 +29,5 @@
 	  public:
 		CopyParams();
-  
+
 		virtual void visit( FunctionDecl *funcDecl );
 		virtual void visit( AddressExpr *addrExpr );
@@ -50,5 +50,5 @@
 		if ( funcDecl->get_statements() ) {
 			funcDecl->get_statements()->accept( *this );
-	
+
 			if ( ! modVars.empty() ) {
 				std::map< std::string, DeclarationWithType* > assignOps;
@@ -57,4 +57,5 @@
 					if ( (*tyVar)->get_kind() == TypeDecl::Any ) {
 						assert( !(*tyVar)->get_assertions().empty() );
+						assert( (*tyVar)->get_assertions().front()->get_name() == "?=?" );
 						assignOps[ (*tyVar)->get_name() ] = (*tyVar)->get_assertions().front();
 					} // if
Index: src/GenPoly/Specialize.cc
===================================================================
--- src/GenPoly/Specialize.cc	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/GenPoly/Specialize.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Wed Jan 20 12:40:33 2016
-// Update Count     : 18
+// Last Modified On : Wed Jan 20 13:00:00 2016
+// Update Count     : 24
 //
 
@@ -142,5 +142,5 @@
 
 	Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) {
-		assert( ! actual->get_results().empty() );
+		assert( ! actual->get_results().empty() ); // using front, should have this assert
 		if ( needsSpecialization( formalType, actual->get_results().front(), env ) ) {
 			FunctionType *funType;
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
+++ src/InitTweak/FixInit.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -0,0 +1,201 @@
+//
+// 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 : Thu Mar 31 13:54:58 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;
+		const std::list<Expression*> noDesignators;
+	}
+
+	class FixInit : public GenPoly::PolyMutator {
+	  public:
+		static void fixInitializers( std::list< Declaration * > &translationUnit );
+
+		virtual ObjectDecl * mutate( ObjectDecl *objDecl );
+
+		virtual CompoundStmt * mutate( CompoundStmt * compoundStmt );
+		virtual Statement * mutate( ReturnStmt * returnStmt );
+		virtual Statement * mutate( BranchStmt * branchStmt );
+
+	  private:
+		// stack of list of statements - used to differentiate scopes
+		std::list< std::list< Statement * > > dtorStmts;
+	};
+
+	void fix( std::list< Declaration * > & translationUnit ) {
+		FixInit::fixInitializers( translationUnit );
+	}
+
+	void FixInit::fixInitializers( std::list< Declaration * > & translationUnit ) {
+		FixInit fixer;
+		mutateAll( translationUnit, fixer );
+	}
+
+	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 ( Statement * ctor = ctorInit->get_ctor() ) {
+				if ( objDecl->get_storageClass() == DeclarationNode::Static ) {
+					// generate:
+					// static bool __objName_uninitialized = true;
+					// if (__objName_uninitialized) {
+					//   __ctor(__objName);
+					//   void dtor_atexit() {
+					//     __dtor(__objName);
+					//   }
+					//   on_exit(dtorOnExit, &__objName);
+					//   __objName_uninitialized = false;
+					// }
+
+					// generate first line
+					BasicType * boolType = new BasicType( Type::Qualifiers(), BasicType::Bool );
+					SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant( boolType->clone(), "1" ) ), noDesignators );
+					ObjectDecl * isUninitializedVar = new ObjectDecl( objDecl->get_mangleName() + "_uninitialized", DeclarationNode::Static, LinkageSpec::Cforall, 0, boolType, boolInitExpr );
+					isUninitializedVar->fixUniqueId();
+
+					// void dtor_atexit(...) {...}
+					FunctionDecl * dtorCaller = new FunctionDecl( objDecl->get_mangleName() + "_dtor_atexit", DeclarationNode::NoStorageClass, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false );
+					dtorCaller->fixUniqueId();
+					dtorCaller->get_statements()->get_kids().push_back( ctorInit->get_dtor() );
+
+					// on_exit(dtor_atexit);
+					UntypedExpr * callAtexit = new UntypedExpr( new NameExpr( "atexit" ) );
+					callAtexit->get_args().push_back( new VariableExpr( dtorCaller ) );
+
+					// __objName_uninitialized = false;
+					UntypedExpr * setTrue = new UntypedExpr( new NameExpr( "?=?" ) );
+					setTrue->get_args().push_back( new VariableExpr( isUninitializedVar ) );
+					setTrue->get_args().push_back( new ConstantExpr( Constant( boolType->clone(), "0" ) ) );
+
+					// generate body of if
+					CompoundStmt * initStmts = new CompoundStmt( noLabels );
+					std::list< Statement * > & body = initStmts->get_kids();
+					body.push_back( ctor );
+					body.push_back( new DeclStmt( noLabels, dtorCaller ) );
+					body.push_back( new ExprStmt( noLabels, callAtexit ) );
+					body.push_back( new ExprStmt( noLabels, setTrue ) );
+
+					// put it all together
+					IfStmt * ifStmt = new IfStmt( noLabels, new VariableExpr( isUninitializedVar ), initStmts, 0 );
+					stmtsToAddAfter.push_back( new DeclStmt( noLabels, isUninitializedVar ) );
+					stmtsToAddAfter.push_back( ifStmt );
+				} else {
+					stmtsToAddAfter.push_back( ctor );
+					dtorStmts.back().push_front( ctorInit->get_dtor() );
+				}
+				objDecl->set_init( NULL );
+				ctorInit->set_ctor( NULL );
+				ctorInit->set_dtor( NULL );  // xxx - only destruct when constructing? Probably not?
+			} 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;
+	}
+
+	template<typename Iterator, typename OutputIterator>
+	void insertDtors( Iterator begin, Iterator end, OutputIterator out ) {
+		for ( Iterator it = begin ; it != end ; ++it ) {
+			// remove if instrinsic destructor statement
+			// xxx - test user manually calling intrinsic functions - what happens?
+			if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( *it ) ) {
+				ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( exprStmt->get_expr() );
+				assert( appExpr );
+				VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() );
+				assert( function );
+				// check for Intrinsic only - don't want to remove all overridable dtors because autogenerated dtor
+				// will call all member dtors, and some members may have a user defined dtor.
+				if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
+					// don't need to call intrinsic dtor, because it does nothing
+				} else {
+					// non-intrinsic dtors must be called
+					*out++ = (*it)->clone();
+				}
+			} else {
+				// could also be a compound statement with a loop, in the case of an array
+				*out++ = (*it)->clone();
+			}
+		}
+	}
+
+
+	CompoundStmt * FixInit::mutate( CompoundStmt * compoundStmt ) {
+		// mutate statements - this will also populate dtorStmts list.
+		// don't want to dump all destructors when block is left,
+		// just the destructors associated with variables defined in this block,
+		// so push a new list to the top of the stack so that we can differentiate scopes
+		dtorStmts.push_back( std::list<Statement *>() );
+
+		compoundStmt = PolyMutator::mutate( compoundStmt );
+		std::list< Statement * > & statements = compoundStmt->get_kids();
+
+		insertDtors( dtorStmts.back().begin(), dtorStmts.back().end(), back_inserter( statements ) );
+
+		deleteAll( dtorStmts.back() );
+		dtorStmts.pop_back();
+		return compoundStmt;
+	}
+
+	Statement * FixInit::mutate( ReturnStmt * returnStmt ) {
+		for ( std::list< std::list< Statement * > >::reverse_iterator list = dtorStmts.rbegin(); list != dtorStmts.rend(); ++list ) {
+			insertDtors( list->begin(), list->end(), back_inserter( stmtsToAdd ) );
+		}
+		return returnStmt;
+	}
+
+	Statement * FixInit::mutate( BranchStmt * branchStmt ) {
+		// TODO: adding to the end of a block isn't sufficient, since
+		// return/break/goto should trigger destructor when block is left.
+		switch( branchStmt->get_type() ) {
+			case BranchStmt::Continue:
+			case BranchStmt::Break:
+				insertDtors( dtorStmts.back().begin(), dtorStmts.back().end(), back_inserter( stmtsToAdd ) );
+				break;
+			case BranchStmt::Goto:
+				// xxx
+				// if goto leaves a block, generate dtors for every block it leaves
+				// if goto is in same block but earlier statement, destruct every object that was defined after the statement
+				break;
+			default:
+				assert( false );
+		}
+		return branchStmt;
+	}
+
+
+} // namespace InitTweak
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/InitTweak/FixInit.h
===================================================================
--- src/InitTweak/FixInit.h	(revision a5a71d0e95113b304e03502a14ccab969324804f)
+++ src/InitTweak/FixInit.h	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -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 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/InitTweak/InitModel.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -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 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/InitTweak/RemoveInit.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -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 : Mon Apr 04 17:18:03 2016
+// Update Count     : 166
+//
+
+#include <stack>
+#include <list>
 #include "RemoveInit.h"
 #include "SynTree/Declaration.h"
@@ -21,25 +23,29 @@
 #include "SynTree/Initializer.h"
 #include "SynTree/Mutator.h"
+#include "SymTab/Autogen.h"
+#include "GenPoly/PolyMutator.h"
 
 namespace InitTweak {
 	namespace {
 		const std::list<Label> noLabels;
-	}
-	
-	class RemoveInit : public Mutator {
+		const std::list<Expression *> noDesignators;
+	}
+
+	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 +53,33 @@
 	};
 
-	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( TraitDecl *aggregateDecl );
+		virtual TypeDecl* mutate( TypeDecl *typeDecl );
+		virtual Declaration* mutate( TypedefDecl *typeDecl );
+
+	  protected:
+		bool inFunction;
+	};
+
+	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 +87,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 +93,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() );
@@ -94,11 +109,14 @@
 		// 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));
+			// ensure return value is not destructed by explicitly creating
+			// an empty SingleInit node wherein maybeConstruct is false
+			ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, returnVals.front()->get_type()->clone(), new ListInit( std::list<Initializer*>(), noDesignators, false ) );
+			stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
+
+			// and explicitly create the constructor expression separately
+			UntypedExpr *construct = new UntypedExpr( new NameExpr( "?{}" ) );
+			construct->get_args().push_back( new AddressExpr (new NameExpr( newObj->get_name() ) ) );
+			construct->get_args().push_back( returnStmt->get_expr() );
+			stmtsToAdd.push_back(new ExprStmt(noLabels, construct));
 
 			returnStmt->set_expr( new VariableExpr( newObj ) );
@@ -110,5 +128,5 @@
 		std::list<DeclarationWithType*> oldReturnVals = returnVals;
 		std::string oldFuncName = funcName;
-		
+
 		FunctionType * type = functionDecl->get_functionType();
 		returnVals = type->get_returnVals();
@@ -119,4 +137,122 @@
 		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 ) {
+				if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) {
+					// call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array
+					// TODO: walk initializer and generate appropriate copy ctor if element has initializer
+					std::list< Statement * > ctor;
+					std::list< Statement * > dtor;
+
+					SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "?{}", back_inserter( ctor ) );
+					SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "^?{}", front_inserter( dtor ), false );
+
+					// Currently makeArrayFunction produces a single Statement - a CompoundStmt
+					// which  wraps everything that needs to happen. As such, it's technically
+					// possible to use a Statement ** in the above calls, but this is inherently
+					// unsafe, so instead we take the slightly less efficient route, but will be
+					// immediately informed if somehow the above assumption is broken. In this case,
+					// we could always wrap the list of statements at this point with a CompoundStmt,
+					// but it seems reasonable at the moment for this to be done by makeArrayFunction
+					// itself
+					assert( ctor.size() == 1 );
+					assert( dtor.size() == 1 );
+
+					objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) );
+				} else {
+					// it's sufficient to attempt to call the ctor/dtor for the given object and its initializer
+					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
+					ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor );
+					ExprStmt * dtorStmt = new ExprStmt( noLabels, dtor );
+					objDecl->set_init( new ConstructorInit( ctorStmt, dtorStmt, objDecl->get_init() ) );
+				}
+			} 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
+				// this can be done by mangling main and replacing it with our own main which calls each
+				// module initialization routine in some decided order (order given in link command?)
+				// and finally calls mangled main
+			}
+		}
+		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;
+	}
+
+	// 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( TraitDecl *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 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/InitTweak/RemoveInit.h	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -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 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/InitTweak/module.mk	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -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
Index: src/MakeLibCfa.cc
===================================================================
--- src/MakeLibCfa.cc	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/MakeLibCfa.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,12 +5,12 @@
 // file "LICENCE" distributed with Cforall.
 //
-// MakeLibCfa.cc -- 
+// MakeLibCfa.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Sat May 16 10:33:33 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Jun 26 16:52:59 2015
-// Update Count     : 14
-// 
+// Last Modified By : Rob Schluntz
+// Last Modified On : Tue Jan 19 13:20:26 2016
+// Update Count     : 40
+//
 
 #include "MakeLibCfa.h"
@@ -29,5 +29,5 @@
 		void visit( FunctionDecl* funcDecl );
 		void visit( ObjectDecl* objDecl );
-  
+
 		std::list< Declaration* > &get_newDecls() { return newDecls; }
 	  private:
@@ -43,5 +43,5 @@
 	void MakeLibCfa::visit( FunctionDecl* origFuncDecl ) {
 		if ( origFuncDecl->get_linkage() != LinkageSpec::Intrinsic ) return;
-  
+
 		FunctionDecl *funcDecl = origFuncDecl->clone();
 		CodeGen::OperatorInfo opInfo;
@@ -54,8 +54,14 @@
 		assert( param != funcDecl->get_functionType()->get_parameters().end() );
 
-		if ( (*param)->get_name() == "" ) {
-			(*param)->set_name( paramNamer.newName() );
-			(*param)->set_linkage( LinkageSpec::C );
-		} // if
+		for ( ; param != funcDecl->get_functionType()->get_parameters().end(); ++param ) {
+			if ( (*param)->get_name() == "" ) {
+				(*param)->set_name( paramNamer.newName() );
+				(*param)->set_linkage( LinkageSpec::C );
+			}
+			newExpr->get_args().push_back( new VariableExpr( *param ) );
+		} // for
+
+		funcDecl->set_statements( new CompoundStmt( std::list< Label >() ) );
+		newDecls.push_back( funcDecl );
 
 		switch ( opInfo.type ) {
@@ -65,16 +71,28 @@
 		  case CodeGen::OT_POSTFIX:
 		  case CodeGen::OT_INFIX:
-			newExpr->get_args().push_back( new VariableExpr( *param ) );
-			break;
 		  case CodeGen::OT_PREFIXASSIGN:
 		  case CodeGen::OT_POSTFIXASSIGN:
 		  case CodeGen::OT_INFIXASSIGN:
-			{
-				newExpr->get_args().push_back( new VariableExpr( *param ) );
-				// UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
-				// deref->get_args().push_back( new VariableExpr( *param ) );
-				// newExpr->get_args().push_back( deref );
+				funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( std::list< Label >(), newExpr ) );
 				break;
-			}
+		  case CodeGen::OT_CTOR:
+		  	// ctors don't return a value
+		  	if ( funcDecl->get_functionType()->get_parameters().size() == 1 ) {
+		  		// intrinsic default constructors should do nothing
+		  		// delete newExpr;
+		  		break;
+		  	} else {
+		  		assert( funcDecl->get_functionType()->get_parameters().size() == 2 );
+		  		// anything else is a single parameter constructor that is effectively a C-style assignment
+		  		// delete newExpr->get_function();
+		  		assert(newExpr->get_args().size()==2);
+		  		newExpr->set_function( new NameExpr( "?=?" ) );
+			  	funcDecl->get_statements()->get_kids().push_back( new ExprStmt( std::list< Label >(), newExpr ) );
+		  	}
+		  	break;
+		  case CodeGen::OT_DTOR:
+		  	// intrinsic destructors should do nothing
+		  	// delete newExpr;
+		  	break;
 		  case CodeGen::OT_CONSTANT:
 		  case CodeGen::OT_LABELADDRESS:
@@ -82,31 +100,14 @@
 			assert( false );
 		} // switch
-
-		for ( param++; param != funcDecl->get_functionType()->get_parameters().end(); ++param ) {
-			if ( (*param)->get_name() == "" ) {
-				(*param)->set_name( paramNamer.newName() );
-				(*param)->set_linkage( LinkageSpec::C );
-			}
-			newExpr->get_args().push_back( new VariableExpr( *param ) );
-		} // for
-		funcDecl->set_statements( new CompoundStmt( std::list< Label >() ) );
-		funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( std::list< Label >(), newExpr ) );
-		newDecls.push_back( funcDecl );
 	}
 
 	void MakeLibCfa::visit( ObjectDecl* origObjDecl ) {
 		if ( origObjDecl->get_linkage() != LinkageSpec::Intrinsic ) return;
-  
+
 		ObjectDecl *objDecl = origObjDecl->clone();
 		assert( ! objDecl->get_init() );
 		std::list< Expression* > noDesignators;
-		objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), noDesignators ) );
+		objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), noDesignators, false ) ); // cannot be constructed
 		newDecls.push_back( objDecl );
 	}
 } // namespace LibCfa
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: src/Makefile.in
===================================================================
--- src/Makefile.in	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/Makefile.in	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -124,4 +124,5 @@
 	GenPoly/driver_cfa_cpp-DeclMutator.$(OBJEXT) \
 	InitTweak/driver_cfa_cpp-RemoveInit.$(OBJEXT) \
+	InitTweak/driver_cfa_cpp-FixInit.$(OBJEXT) \
 	Parser/driver_cfa_cpp-parser.$(OBJEXT) \
 	Parser/driver_cfa_cpp-lex.$(OBJEXT) \
@@ -159,4 +160,5 @@
 	SymTab/driver_cfa_cpp-ImplementationType.$(OBJEXT) \
 	SymTab/driver_cfa_cpp-TypeEquality.$(OBJEXT) \
+	SymTab/driver_cfa_cpp-Autogen.$(OBJEXT) \
 	SynTree/driver_cfa_cpp-Type.$(OBJEXT) \
 	SynTree/driver_cfa_cpp-VoidType.$(OBJEXT) \
@@ -346,9 +348,10 @@
 	GenPoly/CopyParams.cc GenPoly/FindFunction.cc \
 	GenPoly/DeclMutator.cc InitTweak/RemoveInit.cc \
-	Parser/parser.yy Parser/lex.ll Parser/TypedefTable.cc \
-	Parser/ParseNode.cc Parser/DeclarationNode.cc \
-	Parser/ExpressionNode.cc Parser/StatementNode.cc \
-	Parser/InitializerNode.cc Parser/TypeData.cc \
-	Parser/LinkageSpec.cc Parser/parseutility.cc Parser/Parser.cc \
+	InitTweak/FixInit.cc Parser/parser.yy Parser/lex.ll \
+	Parser/TypedefTable.cc Parser/ParseNode.cc \
+	Parser/DeclarationNode.cc Parser/ExpressionNode.cc \
+	Parser/StatementNode.cc Parser/InitializerNode.cc \
+	Parser/TypeData.cc Parser/LinkageSpec.cc \
+	Parser/parseutility.cc Parser/Parser.cc \
 	ResolvExpr/AlternativeFinder.cc ResolvExpr/Alternative.cc \
 	ResolvExpr/Unify.cc ResolvExpr/PtrsAssignable.cc \
@@ -362,8 +365,9 @@
 	SymTab/Mangler.cc SymTab/Validate.cc SymTab/FixFunction.cc \
 	SymTab/ImplementationType.cc SymTab/TypeEquality.cc \
-	SynTree/Type.cc SynTree/VoidType.cc SynTree/BasicType.cc \
-	SynTree/PointerType.cc SynTree/ArrayType.cc \
-	SynTree/FunctionType.cc SynTree/ReferenceToType.cc \
-	SynTree/TupleType.cc SynTree/TypeofType.cc SynTree/AttrType.cc \
+	SymTab/Autogen.cc SynTree/Type.cc SynTree/VoidType.cc \
+	SynTree/BasicType.cc SynTree/PointerType.cc \
+	SynTree/ArrayType.cc SynTree/FunctionType.cc \
+	SynTree/ReferenceToType.cc SynTree/TupleType.cc \
+	SynTree/TypeofType.cc SynTree/AttrType.cc \
 	SynTree/VarArgsType.cc SynTree/Constant.cc \
 	SynTree/Expression.cc SynTree/TupleExpr.cc \
@@ -563,4 +567,6 @@
 InitTweak/driver_cfa_cpp-RemoveInit.$(OBJEXT):  \
 	InitTweak/$(am__dirstamp) InitTweak/$(DEPDIR)/$(am__dirstamp)
+InitTweak/driver_cfa_cpp-FixInit.$(OBJEXT): InitTweak/$(am__dirstamp) \
+	InitTweak/$(DEPDIR)/$(am__dirstamp)
 Parser/parser.h: Parser/parser.cc
 	@if test ! -f $@; then rm -f Parser/parser.cc; else :; fi
@@ -670,4 +676,6 @@
 SymTab/driver_cfa_cpp-TypeEquality.$(OBJEXT): SymTab/$(am__dirstamp) \
 	SymTab/$(DEPDIR)/$(am__dirstamp)
+SymTab/driver_cfa_cpp-Autogen.$(OBJEXT): SymTab/$(am__dirstamp) \
+	SymTab/$(DEPDIR)/$(am__dirstamp)
 SynTree/$(am__dirstamp):
 	@$(MKDIR_P) SynTree
@@ -792,4 +800,5 @@
 	-rm -f GenPoly/driver_cfa_cpp-ScrubTyVars.$(OBJEXT)
 	-rm -f GenPoly/driver_cfa_cpp-Specialize.$(OBJEXT)
+	-rm -f InitTweak/driver_cfa_cpp-FixInit.$(OBJEXT)
 	-rm -f InitTweak/driver_cfa_cpp-RemoveInit.$(OBJEXT)
 	-rm -f Parser/driver_cfa_cpp-DeclarationNode.$(OBJEXT)
@@ -822,4 +831,5 @@
 	-rm -f ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT)
 	-rm -f ResolvExpr/driver_cfa_cpp-Unify.$(OBJEXT)
+	-rm -f SymTab/driver_cfa_cpp-Autogen.$(OBJEXT)
 	-rm -f SymTab/driver_cfa_cpp-FixFunction.$(OBJEXT)
 	-rm -f SymTab/driver_cfa_cpp-ImplementationType.$(OBJEXT)
@@ -897,4 +907,5 @@
 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-RemoveInit.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Po@am__quote@
@@ -927,4 +938,5 @@
 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-TypeEnvironment.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Po@am__quote@
@@ -1380,4 +1392,18 @@
 @am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-RemoveInit.obj `if test -f 'InitTweak/RemoveInit.cc'; then $(CYGPATH_W) 'InitTweak/RemoveInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/RemoveInit.cc'; fi`
 
+InitTweak/driver_cfa_cpp-FixInit.o: InitTweak/FixInit.cc
+@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-FixInit.o -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo -c -o InitTweak/driver_cfa_cpp-FixInit.o `test -f 'InitTweak/FixInit.cc' || echo '$(srcdir)/'`InitTweak/FixInit.cc
+@am__fastdepCXX_TRUE@	$(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='InitTweak/FixInit.cc' object='InitTweak/driver_cfa_cpp-FixInit.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-FixInit.o `test -f 'InitTweak/FixInit.cc' || echo '$(srcdir)/'`InitTweak/FixInit.cc
+
+InitTweak/driver_cfa_cpp-FixInit.obj: InitTweak/FixInit.cc
+@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-FixInit.obj -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo -c -o InitTweak/driver_cfa_cpp-FixInit.obj `if test -f 'InitTweak/FixInit.cc'; then $(CYGPATH_W) 'InitTweak/FixInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/FixInit.cc'; fi`
+@am__fastdepCXX_TRUE@	$(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='InitTweak/FixInit.cc' object='InitTweak/driver_cfa_cpp-FixInit.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-FixInit.obj `if test -f 'InitTweak/FixInit.cc'; then $(CYGPATH_W) 'InitTweak/FixInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/FixInit.cc'; fi`
+
 Parser/driver_cfa_cpp-parser.o: Parser/parser.cc
 @am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-parser.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-parser.Tpo -c -o Parser/driver_cfa_cpp-parser.o `test -f 'Parser/parser.cc' || echo '$(srcdir)/'`Parser/parser.cc
@@ -1869,4 +1895,18 @@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-TypeEquality.obj `if test -f 'SymTab/TypeEquality.cc'; then $(CYGPATH_W) 'SymTab/TypeEquality.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/TypeEquality.cc'; fi`
+
+SymTab/driver_cfa_cpp-Autogen.o: SymTab/Autogen.cc
+@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Autogen.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo -c -o SymTab/driver_cfa_cpp-Autogen.o `test -f 'SymTab/Autogen.cc' || echo '$(srcdir)/'`SymTab/Autogen.cc
+@am__fastdepCXX_TRUE@	$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='SymTab/Autogen.cc' object='SymTab/driver_cfa_cpp-Autogen.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Autogen.o `test -f 'SymTab/Autogen.cc' || echo '$(srcdir)/'`SymTab/Autogen.cc
+
+SymTab/driver_cfa_cpp-Autogen.obj: SymTab/Autogen.cc
+@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Autogen.obj -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo -c -o SymTab/driver_cfa_cpp-Autogen.obj `if test -f 'SymTab/Autogen.cc'; then $(CYGPATH_W) 'SymTab/Autogen.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Autogen.cc'; fi`
+@am__fastdepCXX_TRUE@	$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='SymTab/Autogen.cc' object='SymTab/driver_cfa_cpp-Autogen.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Autogen.obj `if test -f 'SymTab/Autogen.cc'; then $(CYGPATH_W) 'SymTab/Autogen.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Autogen.cc'; fi`
 
 SynTree/driver_cfa_cpp-Type.o: SynTree/Type.cc
Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/Parser/DeclarationNode.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// DeclarationNode.cc -- 
+// DeclarationNode.cc --
 //
 // Author           : Rodolfo G. Esteves
 // Created On       : Sat May 16 12:34:05 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Mar 21 21:04:23 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Mon Apr 04 17:09:46 2016
 // Update Count     : 142
 //
@@ -97,4 +97,6 @@
 		os << endl << string( indent + 2, ' ' ) << "with initializer ";
 		initializer->printOneLine( os );
+		os << " maybe constructed? " << initializer->get_maybeConstructed();
+
 	} // if
 
@@ -369,5 +371,5 @@
 	} // if
 }
-	  
+
 DeclarationNode *DeclarationNode::addQualifiers( DeclarationNode *q ) {
 	if ( q ) {
@@ -520,5 +522,5 @@
 		assert( false );
 	} // switch
-	
+
 	return this;
 }
@@ -631,5 +633,5 @@
 		assert( a->type->kind == TypeData::Array );
 		TypeData *lastArray = findLast( a->type );
-		if ( type ) {  
+		if ( type ) {
 			switch ( type->kind ) {
 			  case TypeData::Aggregate:
@@ -675,5 +677,5 @@
 	} // if
 }
-	
+
 DeclarationNode *DeclarationNode::addIdList( DeclarationNode *ids ) {
 	type = addIdListToType( type, ids );
@@ -880,5 +882,5 @@
 Type *DeclarationNode::buildType() const {
 	assert( type );
-  
+
 	switch ( type->kind ) {
 	  case TypeData::Enum:
Index: src/Parser/InitializerNode.cc
===================================================================
--- src/Parser/InitializerNode.cc	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/Parser/InitializerNode.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,12 +5,12 @@
 // file "LICENCE" distributed with Cforall.
 //
-// InitializerNode.cc -- 
-// 
+// InitializerNode.cc --
+//
 // Author           : Rodolfo G. Esteves
 // Created On       : Sat May 16 13:20:24 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Oct  8 17:18:55 2015
-// Update Count     : 4
-// 
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Jan 07 13:32:57 2016
+// Update Count     : 13
+//
 
 #include <cassert>
@@ -23,5 +23,5 @@
 
 InitializerNode::InitializerNode( ExpressionNode *_expr, bool aggrp, ExpressionNode *des )
-	: expr( _expr ), aggregate( aggrp ), designator( des ), kids( 0 ) {
+	: expr( _expr ), aggregate( aggrp ), designator( des ), kids( 0 ), maybeConstructed( true ) {
 	if ( aggrp )
 		kids = dynamic_cast< InitializerNode *>( get_link() );
@@ -32,5 +32,5 @@
 
 InitializerNode::InitializerNode( InitializerNode *init, bool aggrp, ExpressionNode *des )
-	: expr( 0 ), aggregate( aggrp ), designator( des ), kids( 0 ) {
+	: expr( 0 ), aggregate( aggrp ), designator( des ), kids( 0 ), maybeConstructed( true ) {
 	if ( init != 0 )
 		set_link(init);
@@ -91,5 +91,5 @@
 		} // if
 
-		return new ListInit( initlist, designlist );
+		return new ListInit( initlist, designlist, maybeConstructed );
 	} else {
 		std::list< Expression *> designators;
@@ -99,5 +99,5 @@
 
 		if ( get_expression() != 0)
-			return new SingleInit( get_expression()->build(), designators );
+			return new SingleInit( get_expression()->build(), designators, maybeConstructed );
 	} // if
 
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/Parser/ParseNode.h	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -10,5 +10,5 @@
 // Created On       : Sat May 16 13:28:16 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Mon Apr 04 17:04:22 2016
+// Last Modified On : Mon Apr 04 17:10:10 2016
 // Update Count     : 190
 //
@@ -185,4 +185,5 @@
 				// monadic
 				UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, LabelAddress,
+				Ctor, Dtor,
 	};
 
@@ -525,4 +526,7 @@
 	ExpressionNode *get_designators() const { return designator; }
 
+	InitializerNode *set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
+	bool get_maybeConstructed() const { return maybeConstructed; }
+
 	InitializerNode *next_init() const { return kids; }
 
@@ -536,4 +540,5 @@
 	ExpressionNode *designator; // may be list
 	InitializerNode *kids;
+	bool maybeConstructed;
 };
 
Index: src/Parser/TypeData.cc
===================================================================
--- src/Parser/TypeData.cc	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/Parser/TypeData.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// TypeData.cc -- 
+// TypeData.cc --
 //
 // Author           : Rodolfo G. Esteves
 // Created On       : Sat May 16 15:12:51 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Mar  2 17:26:45 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed Apr 06 16:57:53 2016
 // Update Count     : 49
 //
@@ -449,4 +449,22 @@
 	for ( std::list< TypeDecl* >::iterator i = outputList.begin(); i != outputList.end(); ++i ) {
 		if ( (*i)->get_kind() == TypeDecl::Any ) {
+			// add assertion parameters to `type' tyvars in reverse order
+			// add dtor:  void ^?{}(T *)
+			FunctionType *dtorType = new FunctionType( Type::Qualifiers(), false );
+			dtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
+			(*i)->get_assertions().push_front( new FunctionDecl( "^?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, dtorType, 0, false, false ) );
+
+			// add copy ctor:  void ?{}(T *, T)
+			FunctionType *copyCtorType = new FunctionType( Type::Qualifiers(), false );
+			copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
+			copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
+			(*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, copyCtorType, 0, false, false ) );
+
+			// add default ctor:  void ?{}(T *)
+			FunctionType *ctorType = new FunctionType( Type::Qualifiers(), false );
+			ctorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
+			(*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, ctorType, 0, false, false ) );
+
+			// add assignment operator:  T * ?=?(T *, T)
 			FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
 			assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
@@ -902,5 +920,5 @@
 		if ( cur->get_enumeratorValue() != NULL ) {
 			ObjectDecl *member = dynamic_cast<ObjectDecl *>(*members);
-			member->set_init( new SingleInit( maybeBuild< Expression >( cur->get_enumeratorValue() ) ) );
+			member->set_init( new SingleInit( maybeBuild< Expression >( cur->get_enumeratorValue() ), std::list< Expression * >() ) );
 		} // if
 	} // for
Index: src/Parser/parser.cc
===================================================================
--- src/Parser/parser.cc	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/Parser/parser.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -7415,5 +7415,5 @@
 /* Line 1806 of yacc.c  */
 #line 1694 "parser.yy"
-    { (yyval.in) = (yyvsp[(2) - (2)].in); }
+    { (yyval.in) = (yyvsp[(2) - (2)].in)->set_maybeConstructed( false ); }
     break;
 
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/Parser/parser.yy	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,6 +5,6 @@
 // file "LICENCE" distributed with Cforall.
 //
-// cfa.y -- 
-// 
+// cfa.y --
+//
 // Author           : Peter A. Buhr
 // Created On       : Sat Sep  1 20:22:55 2001
@@ -12,5 +12,5 @@
 // Last Modified On : Thu Mar 24 16:16:16 2016
 // Update Count     : 1498
-// 
+//
 
 // This grammar is based on the ANSI99/11 C grammar, specifically parts of EXPRESSION and STATEMENTS, and on the C
@@ -1692,5 +1692,5 @@
 		{ $$ = $2; }
 	| ATassign initializer
-		{ $$ = $2; }
+		{ $$ = $2->set_maybeConstructed( false ); }
 	;
 
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/ResolvExpr/Resolver.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Resolver.cc -- 
+// Resolver.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 12:17:01 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Mar 24 16:43:11 2016
-// Update Count     : 181
+// Last Modified By : Rob Schluntz
+// Last Modified On : Mon Apr 04 17:11:54 2016
+// Update Count     : 203
 //
 
@@ -33,5 +33,5 @@
 	  public:
 		Resolver() : SymTab::Indexer( false ), switchType( 0 ) {}
-  
+
 		virtual void visit( FunctionDecl *functionDecl );
 		virtual void visit( ObjectDecl *functionDecl );
@@ -54,4 +54,5 @@
 		virtual void visit( SingleInit *singleInit );
 		virtual void visit( ListInit *listInit );
+		virtual void visit( ConstructorInit *ctorInit );
 	  private:
   	typedef std::list< Initializer * >::iterator InitIterator;
@@ -59,4 +60,5 @@
 	  void resolveAggrInit( AggregateDecl *, InitIterator &, InitIterator & );
 	  void resolveSingleAggrInit( Declaration *, InitIterator &, InitIterator & );
+	  void fallbackInit( ConstructorInit * ctorInit );
 
 		std::list< Type * > functionReturn;
@@ -95,5 +97,5 @@
 			return newExpr;
 		}
-  
+
 		Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
 			TypeEnvironment env;
@@ -126,5 +128,5 @@
 			} // if
 		}
-  
+
 		Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
 			TypeEnvironment env;
@@ -159,7 +161,7 @@
 			return newExpr;
 		}
-  
-	}
-  
+
+	}
+
 	void Resolver::visit( ObjectDecl *objectDecl ) {
 		Type *new_type = resolveTypeof( objectDecl->get_type(), *this );
@@ -258,5 +260,5 @@
 			forStmt->set_condition( newExpr );
 		} // if
-		
+
 		if ( forStmt->get_increment() ) {
 			Expression * newExpr = findVoidExpression( forStmt->get_increment(), *this );
@@ -272,5 +274,5 @@
 		delete switchStmt->get_condition();
 		switchStmt->set_condition( newExpr );
-  
+
 		visitor.Visitor::visit( switchStmt );
 	}
@@ -314,5 +316,5 @@
 	bool isCharType( T t ) {
 		if ( BasicType * bt = dynamic_cast< BasicType * >( t ) ) {
-			return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar || 
+			return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar ||
 				bt->get_kind() == BasicType::UnsignedChar;
 		}
@@ -326,5 +328,5 @@
 				string n = ne->get_name();
 				if (n == "0") {
-					initContext = new BasicType(Type::Qualifiers(), 
+					initContext = new BasicType(Type::Qualifiers(),
 												BasicType::SignedInt);
 				} else {
@@ -332,5 +334,5 @@
 					initContext = decl->get_type();
 				}
-			} else if (ConstantExpr * e = 
+			} else if (ConstantExpr * e =
 					   dynamic_cast<ConstantExpr*>(singleInit->get_value())) {
 				Constant *c = e->get_constant();
@@ -355,5 +357,5 @@
 							singleInit->set_value( ce->get_arg() );
 							ce->set_arg( NULL );
-							delete ce;									
+							delete ce;
 						}
 					}
@@ -471,4 +473,42 @@
 #endif
 	}
+
+	// ConstructorInit - fall back on C-style initializer
+	void Resolver::fallbackInit( ConstructorInit * ctorInit ) {
+		// could not find valid constructor, or found an intrinsic constructor
+		// fall back on C-style initializer
+		delete ctorInit->get_ctor();
+		ctorInit->set_ctor( NULL );
+		maybeAccept( ctorInit->get_init(), *this );
+	}
+
+	void Resolver::visit( ConstructorInit *ctorInit ) {
+		TypeEnvironment env;
+		try {
+			maybeAccept( ctorInit->get_ctor(), *this );
+			maybeAccept( ctorInit->get_dtor(), *this );
+		} catch ( SemanticError ) {
+			// no alternatives for the constructor initializer - fallback on C-style initializer
+			// xxx- not sure if this makes a ton of sense - should maybe never be able to have this situation?
+			fallbackInit( ctorInit );
+			return;
+		}
+
+		if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * > ( ctorInit->get_ctor() ) ) {
+			ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( exprStmt->get_expr() );
+			assert( appExpr );
+			VariableExpr * function = dynamic_cast< VariableExpr * > ( appExpr->get_function() );
+			assert( function );
+			if ( LinkageSpec::isOverridable( function->get_var()->get_linkage() ) ) {
+				// if the constructor that was found is intrinsic or autogenerated, reset to C-style
+				// initializer so that code generation is easy to handle
+				fallbackInit( ctorInit );
+				return;
+			}
+		}
+		// found a constructor - can get rid of C-style initializer
+		delete ctorInit->get_init();
+		ctorInit->set_init( NULL );
+	}
 } // namespace ResolvExpr
 
Index: src/SymTab/AddVisit.h
===================================================================
--- src/SymTab/AddVisit.h	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/SymTab/AddVisit.h	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// AddVisit.h -- 
+// AddVisit.h --
 //
 // Author           : Richard C. Bilson
@@ -85,4 +85,18 @@
 		maybeAccept( cathStmt->get_decl(), visitor );
 	}
+
+	template< typename Visitor >
+	void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor, bool addBefore ) {
+		std::list< Declaration * >::iterator i = translationUnit.begin();
+		while ( i != translationUnit.end() ) {
+			(*i)->accept( visitor );
+			std::list< Declaration * >::iterator next = i;
+			next++;
+			if ( ! visitor.get_declsToAdd().empty() ) {
+				translationUnit.splice( addBefore ? i : next, visitor.get_declsToAdd() );
+			} // if
+			i = next;
+		} // while
+	}
 } // namespace SymTab
 
Index: src/SymTab/Autogen.cc
===================================================================
--- src/SymTab/Autogen.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
+++ src/SymTab/Autogen.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -0,0 +1,521 @@
+//
+// 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.
+//
+// Autogen.cc --
+//
+// Author           : Rob Schluntz
+// Created On       : Thu Mar 03 15:45:56 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Mon Apr 04 17:19:28 2016
+// Update Count     : 1
+//
+
+#include <list>
+#include <iterator>
+#include "SynTree/Visitor.h"
+#include "SynTree/Type.h"
+#include "SynTree/Statement.h"
+#include "SynTree/TypeSubstitution.h"
+#include "Common/utility.h"
+#include "AddVisit.h"
+#include "MakeLibCfa.h"
+#include "Autogen.h"
+
+namespace SymTab {
+	class AutogenerateRoutines : public Visitor {
+		public:
+		std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
+
+		virtual void visit( EnumDecl *enumDecl );
+		virtual void visit( StructDecl *structDecl );
+		virtual void visit( UnionDecl *structDecl );
+		virtual void visit( TypeDecl *typeDecl );
+		virtual void visit( TraitDecl *ctxDecl );
+		virtual void visit( FunctionDecl *functionDecl );
+
+		virtual void visit( FunctionType *ftype );
+		virtual void visit( PointerType *ftype );
+
+		virtual void visit( CompoundStmt *compoundStmt );
+		virtual void visit( IfStmt *ifStmt );
+		virtual void visit( WhileStmt *whileStmt );
+		virtual void visit( ForStmt *forStmt );
+		virtual void visit( SwitchStmt *switchStmt );
+		virtual void visit( ChooseStmt *chooseStmt );
+		virtual void visit( CaseStmt *caseStmt );
+		virtual void visit( CatchStmt *catchStmt );
+
+		AutogenerateRoutines() : functionNesting( 0 ) {}
+		private:
+		template< typename StmtClass > void visitStatement( StmtClass *stmt );
+
+		std::list< Declaration * > declsToAdd;
+		std::set< std::string > structsDone;
+		unsigned int functionNesting;     // current level of nested functions
+	};
+
+	void autogenerateRoutines( std::list< Declaration * > &translationUnit ) {
+		AutogenerateRoutines visitor;
+		acceptAndAdd( translationUnit, visitor, false );
+	}
+
+	template< typename OutputIterator >
+	void makeScalarFunction( Expression *src, ObjectDecl *dstParam, DeclarationWithType *member, std::string fname, OutputIterator out ) {
+		ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member );
+		// unnamed bit fields are not copied as they cannot be accessed
+		if ( obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL ) return;
+
+		// want to be able to generate assignment, ctor, and dtor generically,
+		// so fname is either ?=?, ?{}, or ^?{}
+		UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
+
+		UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
+		derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
+
+		// do something special for unnamed members
+		Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );
+		fExpr->get_args().push_back( dstselect );
+
+		if ( src ) {
+			fExpr->get_args().push_back( src );
+		}
+
+		*out++ = new ExprStmt( noLabels, fExpr );
+	}
+
+	template< typename OutputIterator >
+	void makeUnionFieldsAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, UnionInstType *unionType, OutputIterator out ) {
+		UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
+		copy->get_args().push_back( new VariableExpr( dstParam ) );
+		copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
+		copy->get_args().push_back( new SizeofExpr( unionType ) );
+
+		*out++ = new ExprStmt( noLabels, copy );
+	}
+
+	//E ?=?(E volatile*, int),
+	//  ?=?(E _Atomic volatile*, int);
+	void makeEnumFunctions( EnumDecl *enumDecl, EnumInstType *refType, unsigned int functionNesting, std::list< Declaration * > &declsToAdd ) {
+		FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
+
+		ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
+		assignType->get_returnVals().push_back( returnVal );
+
+		// need two assignment operators with different types
+		FunctionType * assignType2 = assignType->clone();
+
+		// E ?=?(E volatile *, E)
+		Type *etype = refType->clone();
+		// etype->get_qualifiers() += Type::Qualifiers(false, true, false, false, false, false);
+
+		ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), etype ), 0 );
+		assignType->get_parameters().push_back( dstParam );
+
+		ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, etype->clone(), 0 );
+		assignType->get_parameters().push_back( srcParam );
+
+		// E ?=?(E volatile *, int)
+		assignType2->get_parameters().push_back( dstParam->clone() );
+		BasicType * paramType = new BasicType(Type::Qualifiers(), BasicType::SignedInt);
+		ObjectDecl *srcParam2 = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, paramType, 0 );
+		assignType2->get_parameters().push_back( srcParam2 );
+
+		// Routines at global scope marked "static" to prevent multiple definitions is separate translation units
+		// because each unit generates copies of the default routines for each aggregate.
+
+		// since there is no definition, these should not be inline
+		// make these intrinsic so that the code generator does not make use of them
+		FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, assignType, 0, false, false );
+		assignDecl->fixUniqueId();
+		FunctionDecl *assignDecl2 = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, assignType2, 0, false, false );
+		assignDecl2->fixUniqueId();
+
+		// these should be built in the same way that the prelude
+		// functions are, so build a list containing the prototypes
+		// and allow MakeLibCfa to autogenerate the bodies.
+		std::list< Declaration * > assigns;
+		assigns.push_back( assignDecl );
+		assigns.push_back( assignDecl2 );
+
+		LibCfa::makeLibCfa( assigns );
+
+		// need to remove the prototypes, since this may be nested in a routine
+		for (int start = 0, end = assigns.size()/2; start < end; start++) {
+			delete assigns.front();
+			assigns.pop_front();
+		} // for
+
+		declsToAdd.insert( declsToAdd.begin(), assigns.begin(), assigns.end() );
+	}
+
+	/// Clones a reference type, replacing any parameters it may have with a clone of the provided list
+	template< typename GenericInstType >
+	GenericInstType *cloneWithParams( GenericInstType *refType, const std::list< Expression* >& params ) {
+		GenericInstType *clone = refType->clone();
+		clone->get_parameters().clear();
+		cloneAll( params, clone->get_parameters() );
+		return clone;
+	}
+
+	/// Creates a new type decl that's the same as src, but renamed and with only the ?=? assertion (for complete types only)
+	TypeDecl *cloneAndRename( TypeDecl *src, const std::string &name ) {
+		TypeDecl *dst = new TypeDecl( name, src->get_storageClass(), 0, src->get_kind() );
+
+		if ( src->get_kind() == TypeDecl::Any ) {
+			// just include assignment operator assertion
+			TypeInstType *assignParamType = new TypeInstType( Type::Qualifiers(), name, dst );
+			FunctionType *assignFunctionType = new FunctionType( Type::Qualifiers(), false );
+			assignFunctionType->get_returnVals().push_back(
+				new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, assignParamType->clone(), 0 ) );
+			assignFunctionType->get_parameters().push_back(
+				new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), assignParamType->clone() ), 0 ) );
+			assignFunctionType->get_parameters().push_back(
+				new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, assignParamType, 0 ) );
+			FunctionDecl *assignAssert = new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignFunctionType, 0, false, false );
+			dst->get_assertions().push_back( assignAssert );
+		}
+
+		return dst;
+	}
+
+	void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, TypeSubstitution & genericSubs, bool isGeneric, bool forward = true ) {
+		if ( isGeneric ) {
+			// rewrite member type in terms of the type variables on this operator
+			field = field->clone();
+			genericSubs.apply( field );
+		}
+
+		ObjectDecl * returnVal = NULL;
+		if ( ! func->get_functionType()->get_returnVals().empty() ) {
+			returnVal = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_returnVals().front() );
+		}
+
+		// assign to destination (and return value if generic)
+		if ( ArrayType *array = dynamic_cast< ArrayType * >( field->get_type() ) ) {
+			UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
+			derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
+			Expression *dstselect = new MemberExpr( field, derefExpr );
+
+			makeArrayFunction( src, dstselect, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ), forward );
+			if ( isGeneric && returnVal ) {
+				UntypedExpr *derefRet = new UntypedExpr( new NameExpr( "*?" ) );
+				derefRet->get_args().push_back( new VariableExpr( returnVal ) );
+				Expression *retselect = new MemberExpr( field, derefRet );
+
+				makeArrayFunction( src, retselect, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ), forward );
+			}
+		} else {
+			makeScalarFunction( src, dstParam, field, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
+			if ( isGeneric && returnVal ) makeScalarFunction( src, returnVal, field, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
+		} // if
+	}
+
+	template<typename Iterator>
+	void makeStructFunctionBody( Iterator member, Iterator end, FunctionDecl * func, TypeSubstitution & genericSubs, bool isGeneric, bool forward = true ) {
+		for ( ; member != end; ++member ) {
+			if ( DeclarationWithType *field = dynamic_cast< DeclarationWithType * >( *member ) ) { // otherwise some form of type declaration, e.g. Aggregate
+				// query the type qualifiers of this field and skip assigning it if it is marked const.
+				// If it is an array type, we need to strip off the array layers to find its qualifiers.
+				Type * type = field->get_type();
+				while ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
+					type = at->get_base();
+				}
+
+				if ( type->get_qualifiers().isConst ) {
+					// don't assign const members
+					continue;
+				}
+
+				assert( ! func->get_functionType()->get_parameters().empty() );
+				ObjectDecl * dstParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().front() );
+				ObjectDecl * srcParam = NULL;
+				if ( func->get_functionType()->get_parameters().size() == 2 ) {
+					srcParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().back() );
+				}
+				// srcParam may be NULL, in which case we have default ctor/dtor
+				assert( dstParam );
+
+				Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL;
+				makeStructMemberOp( dstParam, srcselect, field, func, genericSubs, isGeneric, forward );
+			} // if
+		} // for
+	} // makeStructFunctionBody
+
+	/// generate the body of a constructor which takes parameters that match fields, e.g.
+	/// void ?{}(A *, int) and void?{}(A *, int, int) for a struct A which has two int fields.
+	template<typename Iterator>
+	void makeStructFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func, TypeSubstitution & genericSubs, bool isGeneric ) {
+		FunctionType * ftype = func->get_functionType();
+		std::list<DeclarationWithType*> & params = ftype->get_parameters();
+		assert( params.size() >= 2 );  // should not call this function for default ctor, etc.
+
+		// skip 'this' parameter
+		ObjectDecl * dstParam = dynamic_cast<ObjectDecl*>( params.front() );
+		assert( dstParam );
+		std::list<DeclarationWithType*>::iterator parameter = params.begin()+1;
+		for ( ; member != end; ++member ) {
+			if ( DeclarationWithType * field = dynamic_cast<DeclarationWithType*>( *member ) ) {
+				if ( parameter != params.end() ) {
+					// matching parameter, initialize field with copy ctor
+					Expression *srcselect = new VariableExpr(*parameter);
+					makeStructMemberOp( dstParam, srcselect, field, func, genericSubs, isGeneric );
+					++parameter;
+				} else {
+					// no matching parameter, initialize field with default ctor
+					makeStructMemberOp( dstParam, NULL, field, func, genericSubs, isGeneric );
+				}
+			}
+		}
+	}
+
+	void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd ) {
+		FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
+
+		// Make function polymorphic in same parameters as generic struct, if applicable
+		bool isGeneric = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)
+		std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
+		std::list< Expression* > structParams;  // List of matching parameters to put on types
+		TypeSubstitution genericSubs; // Substitutions to make to member types of struct
+		for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
+			isGeneric = true;
+			TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() );
+			assignType->get_forall().push_back( typeParam );
+			TypeInstType *newParamType = new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam );
+			genericSubs.add( (*param)->get_name(), newParamType );
+			structParams.push_back( new TypeExpr( newParamType ) );
+		}
+
+		ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, structParams ) ), 0 );
+		assignType->get_parameters().push_back( dstParam );
+
+		// void ?{}(T *); void ^?{}(T *);
+		FunctionType *ctorType = assignType->clone();
+		FunctionType *dtorType = assignType->clone();
+
+		ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
+		assignType->get_parameters().push_back( srcParam );
+
+		// void ?{}(T *, T);
+		FunctionType *copyCtorType = assignType->clone();
+
+		// T ?=?(T *, T);
+		ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
+		assignType->get_returnVals().push_back( returnVal );
+
+		// Routines at global scope marked "static" to prevent multiple definitions is separate translation units
+		// because each unit generates copies of the default routines for each aggregate.
+		FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false );
+		FunctionDecl *ctorDecl = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType, new CompoundStmt( noLabels ), true, false );
+		FunctionDecl *copyCtorDecl = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, copyCtorType, new CompoundStmt( noLabels ), true, false );
+		FunctionDecl *dtorDecl = new FunctionDecl( "^?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, dtorType, new CompoundStmt( noLabels ), true, false );
+		assignDecl->fixUniqueId();
+		ctorDecl->fixUniqueId();
+		copyCtorDecl->fixUniqueId();
+		dtorDecl->fixUniqueId();
+
+		// create constructors which take each member type as a parameter.
+		// for example, for struct A { int x, y; }; generate
+		// void ?{}(A *, int) and void ?{}(A *, int, int)
+		std::list<Declaration *> memCtors;
+		FunctionType * memCtorType = ctorType->clone();
+		for ( std::list<Declaration *>::iterator i = aggregateDecl->get_members().begin(); i != aggregateDecl->get_members().end(); ++i ) {
+			DeclarationWithType * member = dynamic_cast<DeclarationWithType *>( *i );
+			assert( member );
+			memCtorType->get_parameters().push_back( new ObjectDecl( member->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, member->get_type()->clone(), 0 ) );
+			FunctionDecl * ctor = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, memCtorType->clone(), new CompoundStmt( noLabels ), true, false );
+			ctor->fixUniqueId();
+			makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor, genericSubs, isGeneric );
+			memCtors.push_back( ctor );
+		}
+		delete memCtorType;
+
+		// generate appropriate calls to member ctor, assignment
+		makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), assignDecl, genericSubs, isGeneric );
+		makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctorDecl, genericSubs, isGeneric );
+		makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), copyCtorDecl, genericSubs, isGeneric );
+		// needs to do everything in reverse, so pass "forward" as false
+		makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dtorDecl, genericSubs, isGeneric, false );
+
+		if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
+
+		declsToAdd.push_back( assignDecl );
+		declsToAdd.push_back( ctorDecl );
+		declsToAdd.push_back( copyCtorDecl );
+		declsToAdd.push_back( dtorDecl );
+		declsToAdd.splice( declsToAdd.end(), memCtors );
+	}
+
+	void makeUnionFunctions( UnionDecl *aggregateDecl, UnionInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd ) {
+		FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
+
+		// Make function polymorphic in same parameters as generic union, if applicable
+		bool isGeneric = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for struct)
+		std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
+		std::list< Expression* > unionParams;  // List of matching parameters to put on types
+		for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
+			isGeneric = true;
+			TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() );
+			assignType->get_forall().push_back( typeParam );
+			unionParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) );
+		}
+
+		ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, unionParams ) ), 0 );
+		assignType->get_parameters().push_back( dstParam );
+
+		// default ctor/dtor need only first parameter
+		FunctionType * ctorType = assignType->clone();
+		FunctionType * dtorType = assignType->clone();
+
+		ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
+		assignType->get_parameters().push_back( srcParam );
+
+		// copy ctor needs both parameters
+		FunctionType * copyCtorType = assignType->clone();
+
+		// assignment needs both and return value
+		ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
+		assignType->get_returnVals().push_back( returnVal );
+
+		// Routines at global scope marked "static" to prevent multiple definitions is separate translation units
+		// because each unit generates copies of the default routines for each aggregate.
+		FunctionDecl *assignDecl = new FunctionDecl( "?=?",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false );
+		FunctionDecl *ctorDecl = new FunctionDecl( "?{}",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType, new CompoundStmt( noLabels ), true, false );
+		FunctionDecl *copyCtorDecl = new FunctionDecl( "?{}",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, copyCtorType, NULL, true, false );
+		FunctionDecl *dtorDecl = new FunctionDecl( "^?{}",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, dtorType, new CompoundStmt( noLabels ), true, false );
+
+		assignDecl->fixUniqueId();
+		ctorDecl->fixUniqueId();
+		copyCtorDecl->fixUniqueId();
+		dtorDecl->fixUniqueId();
+
+		makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
+		if ( isGeneric ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
+
+		if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
+
+		// body of assignment and copy ctor is the same
+		copyCtorDecl->set_statements( assignDecl->get_statements()->clone() );
+
+		declsToAdd.push_back( assignDecl );
+		declsToAdd.push_back( ctorDecl );
+		declsToAdd.push_back( copyCtorDecl );
+		declsToAdd.push_back( dtorDecl );
+	}
+
+	void AutogenerateRoutines::visit( EnumDecl *enumDecl ) {
+		if ( ! enumDecl->get_members().empty() ) {
+			EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() );
+			// enumInst->set_baseEnum( enumDecl );
+			// declsToAdd.push_back(
+			makeEnumFunctions( enumDecl, enumInst, functionNesting, declsToAdd );
+		}
+	}
+
+	void AutogenerateRoutines::visit( StructDecl *structDecl ) {
+		if ( ! structDecl->get_members().empty() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
+			StructInstType structInst( Type::Qualifiers(), structDecl->get_name() );
+			structInst.set_baseStruct( structDecl );
+			makeStructFunctions( structDecl, &structInst, functionNesting, declsToAdd );
+			structsDone.insert( structDecl->get_name() );
+		} // if
+	}
+
+	void AutogenerateRoutines::visit( UnionDecl *unionDecl ) {
+		if ( ! unionDecl->get_members().empty() ) {
+			UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() );
+			unionInst.set_baseUnion( unionDecl );
+			makeUnionFunctions( unionDecl, &unionInst, functionNesting, declsToAdd );
+		} // if
+	}
+
+	void AutogenerateRoutines::visit( TypeDecl *typeDecl ) {
+		CompoundStmt *stmts = 0;
+		TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false );
+		typeInst->set_baseType( typeDecl );
+		ObjectDecl *src = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, typeInst->clone(), 0 );
+		ObjectDecl *dst = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), typeInst->clone() ), 0 );
+		if ( typeDecl->get_base() ) {
+			stmts = new CompoundStmt( std::list< Label >() );
+			UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
+			assign->get_args().push_back( new CastExpr( new VariableExpr( dst ), new PointerType( Type::Qualifiers(), typeDecl->get_base()->clone() ) ) );
+			assign->get_args().push_back( new CastExpr( new VariableExpr( src ), typeDecl->get_base()->clone() ) );
+			stmts->get_kids().push_back( new ReturnStmt( std::list< Label >(), assign ) );
+		} // if
+		FunctionType *type = new FunctionType( Type::Qualifiers(), false );
+		type->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, typeInst, 0 ) );
+		type->get_parameters().push_back( dst );
+		type->get_parameters().push_back( src );
+		FunctionDecl *func = new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::AutoGen, type, stmts, false, false );
+		declsToAdd.push_back( func );
+	}
+
+	void addDecls( std::list< Declaration * > &declsToAdd, std::list< Statement * > &statements, std::list< Statement * >::iterator i ) {
+		for ( std::list< Declaration * >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) {
+			statements.insert( i, new DeclStmt( noLabels, *decl ) );
+		} // for
+		declsToAdd.clear();
+	}
+
+	void AutogenerateRoutines::visit( FunctionType *) {
+		// ensure that we don't add assignment ops for types defined as part of the function
+	}
+
+	void AutogenerateRoutines::visit( PointerType *) {
+		// ensure that we don't add assignment ops for types defined as part of the pointer
+	}
+
+	void AutogenerateRoutines::visit( TraitDecl *) {
+		// ensure that we don't add assignment ops for types defined as part of the trait
+	}
+
+	template< typename StmtClass >
+	inline void AutogenerateRoutines::visitStatement( StmtClass *stmt ) {
+		std::set< std::string > oldStructs = structsDone;
+		addVisit( stmt, *this );
+		structsDone = oldStructs;
+	}
+
+	void AutogenerateRoutines::visit( FunctionDecl *functionDecl ) {
+		maybeAccept( functionDecl->get_functionType(), *this );
+		acceptAll( functionDecl->get_oldDecls(), *this );
+		functionNesting += 1;
+		maybeAccept( functionDecl->get_statements(), *this );
+		functionNesting -= 1;
+	}
+
+	void AutogenerateRoutines::visit( CompoundStmt *compoundStmt ) {
+		visitStatement( compoundStmt );
+	}
+
+	void AutogenerateRoutines::visit( IfStmt *ifStmt ) {
+		visitStatement( ifStmt );
+	}
+
+	void AutogenerateRoutines::visit( WhileStmt *whileStmt ) {
+		visitStatement( whileStmt );
+	}
+
+	void AutogenerateRoutines::visit( ForStmt *forStmt ) {
+		visitStatement( forStmt );
+	}
+
+	void AutogenerateRoutines::visit( SwitchStmt *switchStmt ) {
+		visitStatement( switchStmt );
+	}
+
+	void AutogenerateRoutines::visit( ChooseStmt *switchStmt ) {
+		visitStatement( switchStmt );
+	}
+
+	void AutogenerateRoutines::visit( CaseStmt *caseStmt ) {
+		visitStatement( caseStmt );
+	}
+
+	void AutogenerateRoutines::visit( CatchStmt *cathStmt ) {
+		visitStatement( cathStmt );
+	}
+
+} // SymTab
Index: src/SymTab/Autogen.h
===================================================================
--- src/SymTab/Autogen.h	(revision a5a71d0e95113b304e03502a14ccab969324804f)
+++ src/SymTab/Autogen.h	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -0,0 +1,99 @@
+//
+// 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.
+//
+// Autogen.h --
+//
+// Author           : Rob Schluntz
+// Created On       : Sun May 17 21:53:34 2015
+// Last Modified By : Rob Schluntz
+// Last Modified On : Tue May 19 16:49:43 2015
+// Update Count     : 1
+//
+
+#ifndef AUTOGEN_H
+#define AUTOGEN_H
+
+#include <string>
+#include "SynTree/Statement.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Initializer.h"
+
+namespace SymTab {
+  static const std::list< std::string > noLabels;
+
+  /// Generates assignment operators, constructors, and destructor for aggregate types as required
+  void autogenerateRoutines( std::list< Declaration * > &translationUnit );
+
+  // originally makeArrayAssignment - changed to Function because it is now used for ctors and dtors as well
+  // admittedly not a great name change. This used to live in Validate.cc, but has been moved so it can be reused elsewhere
+
+  /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.
+  /// If forward is true, loop goes from 0 to N-1, else N-1 to 0
+  template< typename OutputIterator >
+  void makeArrayFunction( Expression *srcParam, Expression *dstParam, ArrayType *array, std::string fname, OutputIterator out, bool forward = true ) {
+    static UniqueName indexName( "_index" );
+
+    // for a flexible array member nothing is done -- user must define own assignment
+    if ( ! array->get_dimension() ) return;
+
+    Expression * begin, * end, * update, * cmp;
+    if ( forward ) {
+      // generate: for ( int i = 0; i < 0; ++i )
+      begin = new NameExpr( "0" );
+      end = array->get_dimension()->clone();
+      cmp = new NameExpr( "?<?" );
+      update = new NameExpr( "++?" );
+    } else {
+      // generate: for ( int i = N-1; i >= 0; --i )
+      begin = new UntypedExpr( new NameExpr( "?-?" ) );
+      ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() );
+      ((UntypedExpr*)begin)->get_args().push_back( new NameExpr( "1" ) );
+      end = new NameExpr( "0" );
+      cmp = new NameExpr( "?>=?" );
+      update = new NameExpr( "--?" );
+    }
+
+    ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), NULL );
+
+    UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
+    init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
+    init->get_args().push_back( begin );
+    index->set_init( new SingleInit( init, std::list<Expression*>() ) );
+
+    UntypedExpr *cond = new UntypedExpr( cmp );
+    cond->get_args().push_back( new VariableExpr( index ) );
+    cond->get_args().push_back( end );
+
+    UntypedExpr *inc = new UntypedExpr( update );
+    inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
+
+    // want to be able to generate assignment, ctor, and dtor generically,
+    // so fname is either ?=?, ?{}, or ^?{}
+    UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
+
+    UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) );
+    dstIndex->get_args().push_back( dstParam );
+    dstIndex->get_args().push_back( new VariableExpr( index ) );
+    fExpr->get_args().push_back( dstIndex );
+
+    // srcParam is NULL for default ctor/dtor
+    if ( srcParam ) {
+      UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
+      srcIndex->get_args().push_back( srcParam );
+      srcIndex->get_args().push_back( new VariableExpr( index ) );
+      fExpr->get_args().push_back( srcIndex );
+    }
+
+    std::list<Statement *> initList;
+    CompoundStmt * block = new CompoundStmt( noLabels );
+    block->get_kids().push_back( new DeclStmt( noLabels, index ) );
+    block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, new ExprStmt( noLabels, fExpr ) ) );
+    *out++ = block;
+  }
+} // namespace SymTab
+#endif // AUTOGEN_H
+
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/SymTab/Validate.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 21:50:04 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Mar  2 17:31:39 2016
-// Update Count     : 226
+// Last Modified By : Rob Schluntz
+// Last Modified On : Mon Apr 04 17:13:29 2016
+// Update Count     : 297
 //
 
@@ -54,4 +54,5 @@
 #include "MakeLibCfa.h"
 #include "TypeEquality.h"
+#include "Autogen.h"
 #include "ResolvExpr/typeops.h"
 
@@ -124,39 +125,4 @@
 
 		const Indexer *indexer;
-	};
-
-	class AutogenerateRoutines : public Visitor {
-	  public:
-		/// Generates assignment operators for aggregate types as required
-		static void autogenerateRoutines( std::list< Declaration * > &translationUnit );
-
-		std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
-
-		virtual void visit( EnumDecl *enumDecl );
-		virtual void visit( StructDecl *structDecl );
-		virtual void visit( UnionDecl *structDecl );
-		virtual void visit( TypeDecl *typeDecl );
-		virtual void visit( TraitDecl *ctxDecl );
-		virtual void visit( FunctionDecl *functionDecl );
-
-		virtual void visit( FunctionType *ftype );
-		virtual void visit( PointerType *ftype );
-
-		virtual void visit( CompoundStmt *compoundStmt );
-		virtual void visit( IfStmt *ifStmt );
-		virtual void visit( WhileStmt *whileStmt );
-		virtual void visit( ForStmt *forStmt );
-		virtual void visit( SwitchStmt *switchStmt );
-		virtual void visit( ChooseStmt *chooseStmt );
-		virtual void visit( CaseStmt *caseStmt );
-		virtual void visit( CatchStmt *catchStmt );
-
-		AutogenerateRoutines() : functionNesting( 0 ) {}
-	  private:
-		template< typename StmtClass > void visitStatement( StmtClass *stmt );
-
-		std::list< Declaration * > declsToAdd;
-		std::set< std::string > structsDone;
-		unsigned int functionNesting;			// current level of nested functions
 	};
 
@@ -202,4 +168,17 @@
 	};
 
+	class VerifyCtorDtor : public Visitor {
+	public:
+		/// ensure that constructors and destructors have at least one
+		/// parameter, the first of which must be a pointer, and no
+		/// return values.
+		static void verify( std::list< Declaration * > &translationUnit );
+
+		// VerifyCtorDtor() {}
+
+		virtual void visit( FunctionDecl *funcDecl );
+	private:
+	};
+
 	void validate( std::list< Declaration * > &translationUnit, bool doDebug ) {
 		Pass1 pass1;
@@ -211,6 +190,7 @@
 		acceptAll( translationUnit, pass2 );
 		ReturnChecker::checkFunctionReturns( translationUnit );
-		AutogenerateRoutines::autogenerateRoutines( translationUnit );
+		autogenerateRoutines( translationUnit );
 		acceptAll( translationUnit, pass3 );
+		VerifyCtorDtor::verify( translationUnit );
 	}
 
@@ -222,18 +202,4 @@
 		type->accept( pass2 );
 		type->accept( pass3 );
-	}
-
-	template< typename Visitor >
-	void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor, bool addBefore ) {
-		std::list< Declaration * >::iterator i = translationUnit.begin();
-		while ( i != translationUnit.end() ) {
-			(*i)->accept( visitor );
-			std::list< Declaration * >::iterator next = i;
-			next++;
-			if ( ! visitor.get_declsToAdd().empty() ) {
-				translationUnit.splice( addBefore ? i : next, visitor.get_declsToAdd() );
-			} // if
-			i = next;
-		} // while
 	}
 
@@ -513,393 +479,4 @@
 	}
 
-	static const std::list< std::string > noLabels;
-
-	void AutogenerateRoutines::autogenerateRoutines( std::list< Declaration * > &translationUnit ) {
-		AutogenerateRoutines visitor;
-		acceptAndAdd( translationUnit, visitor, false );
-	}
-
-	template< typename OutputIterator >
-	void makeScalarAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, OutputIterator out ) {
-		ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member );
-		// unnamed bit fields are not copied as they cannot be accessed
-		if ( obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL ) return;
-
-		UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
-
-		UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
-		derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
-
-		// do something special for unnamed members
-		Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );
-		assignExpr->get_args().push_back( dstselect );
-
-		Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
-		assignExpr->get_args().push_back( srcselect );
-
-		*out++ = new ExprStmt( noLabels, assignExpr );
-	}
-
-	template< typename OutputIterator >
-	void makeArrayAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, OutputIterator out ) {
-		static UniqueName indexName( "_index" );
-
-		// for a flexible array member nothing is done -- user must define own assignment
-		if ( ! array->get_dimension() ) return;
-
-		ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 );
-		*out++ = new DeclStmt( noLabels, index );
-
-		UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
-		init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
-		init->get_args().push_back( new NameExpr( "0" ) );
-		Statement *initStmt = new ExprStmt( noLabels, init );
-		std::list<Statement *> initList;
-		initList.push_back( initStmt );
-
-		UntypedExpr *cond = new UntypedExpr( new NameExpr( "?<?" ) );
-		cond->get_args().push_back( new VariableExpr( index ) );
-		cond->get_args().push_back( array->get_dimension()->clone() );
-
-		UntypedExpr *inc = new UntypedExpr( new NameExpr( "++?" ) );
-		inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
-
-		UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
-
-		UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
-		derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
-
-		Expression *dstselect = new MemberExpr( member, derefExpr );
-		UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) );
-		dstIndex->get_args().push_back( dstselect );
-		dstIndex->get_args().push_back( new VariableExpr( index ) );
-		assignExpr->get_args().push_back( dstIndex );
-
-		Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
-		UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
-		srcIndex->get_args().push_back( srcselect );
-		srcIndex->get_args().push_back( new VariableExpr( index ) );
-		assignExpr->get_args().push_back( srcIndex );
-
-		*out++ = new ForStmt( noLabels, initList, cond, inc, new ExprStmt( noLabels, assignExpr ) );
-	}
-
-	template< typename OutputIterator >
-	void makeUnionFieldsAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, UnionInstType *unionType, OutputIterator out ) {
-		UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
-		copy->get_args().push_back( new VariableExpr( dstParam ) );
-		copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
-		copy->get_args().push_back( new SizeofExpr( unionType ) );
-
-		*out++ = new ExprStmt( noLabels, copy );
-	}
-
-	//E ?=?(E volatile*, int),
-	//  ?=?(E _Atomic volatile*, int);
-	void makeEnumAssignment( EnumDecl *enumDecl, EnumInstType *refType, unsigned int functionNesting, std::list< Declaration * > &declsToAdd ) {
-		FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
-
-		ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
-		assignType->get_returnVals().push_back( returnVal );
-
-		// need two assignment operators with different types
-		FunctionType * assignType2 = assignType->clone();
-
-		// E ?=?(E volatile *, E)
-		Type *etype = refType->clone();
-		// etype->get_qualifiers() += Type::Qualifiers(false, true, false, false, false, false);
-
-		ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), etype ), 0 );
-		assignType->get_parameters().push_back( dstParam );
-
-		ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, etype->clone(), 0 );
-		assignType->get_parameters().push_back( srcParam );
-
-		// E ?=?(E volatile *, int)
-		assignType2->get_parameters().push_back( dstParam->clone() );
-		BasicType * paramType = new BasicType(Type::Qualifiers(), BasicType::SignedInt);
-		ObjectDecl *srcParam2 = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, paramType, 0 );
-		assignType2->get_parameters().push_back( srcParam2 );
-
-		// Routines at global scope marked "static" to prevent multiple definitions is separate translation units
-		// because each unit generates copies of the default routines for each aggregate.
-
-		// since there is no definition, these should not be inline
-		// make these intrinsic so that the code generator does not make use of them
-		FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, assignType, 0, false, false );
-		assignDecl->fixUniqueId();
-		FunctionDecl *assignDecl2 = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, assignType2, 0, false, false );
-		assignDecl2->fixUniqueId();
-
-		// these should be built in the same way that the prelude
-		// functions are, so build a list containing the prototypes
-		// and allow MakeLibCfa to autogenerate the bodies.
-		std::list< Declaration * > assigns;
-		assigns.push_back( assignDecl );
-		assigns.push_back( assignDecl2 );
-
-		LibCfa::makeLibCfa( assigns );
-
-		// need to remove the prototypes, since this may be nested in a routine
-		for (int start = 0, end = assigns.size()/2; start < end; start++) {
-			delete assigns.front();
-			assigns.pop_front();
-		} // for
-
-		declsToAdd.insert( declsToAdd.begin(), assigns.begin(), assigns.end() );
-	}
-
-	/// Clones a reference type, replacing any parameters it may have with a clone of the provided list
-	template< typename GenericInstType >
-	GenericInstType *cloneWithParams( GenericInstType *refType, const std::list< Expression* >& params ) {
-		GenericInstType *clone = refType->clone();
-		clone->get_parameters().clear();
-		cloneAll( params, clone->get_parameters() );
-		return clone;
-	}
-
-	/// Creates a new type decl that's the same as src, but renamed and with only the ?=? assertion (for complete types only)
-	TypeDecl *cloneAndRename( TypeDecl *src, const std::string &name ) {
-		TypeDecl *dst = new TypeDecl( name, src->get_storageClass(), 0, src->get_kind() );
-
-		if ( src->get_kind() == TypeDecl::Any ) {
-			// just include assignment operator assertion
-			TypeInstType *assignParamType = new TypeInstType( Type::Qualifiers(), name, dst );
-			FunctionType *assignFunctionType = new FunctionType( Type::Qualifiers(), false );
-			assignFunctionType->get_returnVals().push_back(
-				new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, assignParamType->clone(), 0 ) );
-			assignFunctionType->get_parameters().push_back(
-				new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), assignParamType->clone() ), 0 ) );
-			assignFunctionType->get_parameters().push_back(
-				new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, assignParamType, 0 ) );
-			FunctionDecl *assignAssert = new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignFunctionType, 0, false, false );
-			dst->get_assertions().push_back( assignAssert );
-		}
-
-		return dst;
-	}
-
-	Declaration *makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting ) {
-		FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
-
-		// Make function polymorphic in same parameters as generic struct, if applicable
-		bool isGeneric = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)
-		std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
-		std::list< Expression* > structParams;  // List of matching parameters to put on types
-		TypeSubstitution genericSubs; // Substitutions to make to member types of struct
-		for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
-			isGeneric = true;
-			TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() );
-			assignType->get_forall().push_back( typeParam );
-			TypeInstType *newParamType = new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam );
-			genericSubs.add( (*param)->get_name(), newParamType );
-			structParams.push_back( new TypeExpr( newParamType ) );
-		}
-
-		ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
-		assignType->get_returnVals().push_back( returnVal );
-
-		ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, structParams ) ), 0 );
-		assignType->get_parameters().push_back( dstParam );
-
-		ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
-		assignType->get_parameters().push_back( srcParam );
-
-		// Routines at global scope marked "static" to prevent multiple definitions is separate translation units
-		// because each unit generates copies of the default routines for each aggregate.
-		FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false );
-		assignDecl->fixUniqueId();
-
-		for ( std::list< Declaration * >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) {
-			if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ) ) {
-				// query the type qualifiers of this field and skip assigning it if it is marked const.
-				// If it is an array type, we need to strip off the array layers to find its qualifiers.
-				Type * type = dwt->get_type();
-				while ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
-					type = at->get_base();
-				}
-
-				if ( type->get_qualifiers().isConst ) {
-					// don't assign const members
-					continue;
-				}
-
-				if ( isGeneric ) {
-					// rewrite member type in terms of the type variables on this operator
-					DeclarationWithType *fixedMember = dwt->clone();
-					genericSubs.apply( fixedMember );
-
-					// assign to both destination and return value
-					if ( ArrayType *array = dynamic_cast< ArrayType * >( fixedMember->get_type() ) ) {
-						makeArrayAssignment( srcParam, dstParam, fixedMember, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
-						makeArrayAssignment( srcParam, returnVal, fixedMember, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
-					} else {
-						makeScalarAssignment( srcParam, dstParam, fixedMember, back_inserter( assignDecl->get_statements()->get_kids() ) );
-						makeScalarAssignment( srcParam, returnVal, fixedMember, back_inserter( assignDecl->get_statements()->get_kids() ) );
-					} // if
-				} else {
-					// assign to destination
-					if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
-						makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
-					} else {
-						makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
-					} // if
-				} // if
-			} // if
-		} // for
-		if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
-
-		return assignDecl;
-	}
-
-	Declaration *makeUnionAssignment( UnionDecl *aggregateDecl, UnionInstType *refType, unsigned int functionNesting ) {
-		FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
-
-		// Make function polymorphic in same parameters as generic union, if applicable
-		bool isGeneric = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for struct)
-		std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
-		std::list< Expression* > unionParams;  // List of matching parameters to put on types
-		for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
-			isGeneric = true;
-			TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() );
-			assignType->get_forall().push_back( typeParam );
-			unionParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) );
-		}
-
-		ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
-		assignType->get_returnVals().push_back( returnVal );
-
-		ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, unionParams ) ), 0 );
-		assignType->get_parameters().push_back( dstParam );
-
-		ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
-		assignType->get_parameters().push_back( srcParam );
-
-		// Routines at global scope marked "static" to prevent multiple definitions is separate translation units
-		// because each unit generates copies of the default routines for each aggregate.
-		FunctionDecl *assignDecl = new FunctionDecl( "?=?",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false );
-		assignDecl->fixUniqueId();
-
-		makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
-		if ( isGeneric ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
-		
-		if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
-
-		return assignDecl;
-	}
-
-	void AutogenerateRoutines::visit( EnumDecl *enumDecl ) {
-		if ( ! enumDecl->get_members().empty() ) {
-			EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() );
-			// enumInst->set_baseEnum( enumDecl );
-			// declsToAdd.push_back(
-			makeEnumAssignment( enumDecl, enumInst, functionNesting, declsToAdd );
-		}
-	}
-
-	void AutogenerateRoutines::visit( StructDecl *structDecl ) {
-		if ( ! structDecl->get_members().empty() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
-			StructInstType structInst( Type::Qualifiers(), structDecl->get_name() );
-			structInst.set_baseStruct( structDecl );
-			declsToAdd.push_back( makeStructAssignment( structDecl, &structInst, functionNesting ) );
-			structsDone.insert( structDecl->get_name() );
-		} // if
-	}
-
-	void AutogenerateRoutines::visit( UnionDecl *unionDecl ) {
-		if ( ! unionDecl->get_members().empty() ) {
-			UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() );
-			unionInst.set_baseUnion( unionDecl );
-			declsToAdd.push_back( makeUnionAssignment( unionDecl, &unionInst, functionNesting ) );
-		} // if
-	}
-
-	void AutogenerateRoutines::visit( TypeDecl *typeDecl ) {
-		CompoundStmt *stmts = 0;
-		TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false );
-		typeInst->set_baseType( typeDecl );
-		ObjectDecl *src = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, typeInst->clone(), 0 );
-		ObjectDecl *dst = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), typeInst->clone() ), 0 );
-		if ( typeDecl->get_base() ) {
-			stmts = new CompoundStmt( std::list< Label >() );
-			UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
-			assign->get_args().push_back( new CastExpr( new VariableExpr( dst ), new PointerType( Type::Qualifiers(), typeDecl->get_base()->clone() ) ) );
-			assign->get_args().push_back( new CastExpr( new VariableExpr( src ), typeDecl->get_base()->clone() ) );
-			stmts->get_kids().push_back( new ReturnStmt( std::list< Label >(), assign ) );
-		} // if
-		FunctionType *type = new FunctionType( Type::Qualifiers(), false );
-		type->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, typeInst, 0 ) );
-		type->get_parameters().push_back( dst );
-		type->get_parameters().push_back( src );
-		FunctionDecl *func = new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::AutoGen, type, stmts, false, false );
-		declsToAdd.push_back( func );
-	}
-
-	void addDecls( std::list< Declaration * > &declsToAdd, std::list< Statement * > &statements, std::list< Statement * >::iterator i ) {
-		for ( std::list< Declaration * >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) {
-			statements.insert( i, new DeclStmt( noLabels, *decl ) );
-		} // for
-		declsToAdd.clear();
-	}
-
-	void AutogenerateRoutines::visit( FunctionType *) {
-		// ensure that we don't add assignment ops for types defined as part of the function
-	}
-
-	void AutogenerateRoutines::visit( PointerType *) {
-		// ensure that we don't add assignment ops for types defined as part of the pointer
-	}
-
-	void AutogenerateRoutines::visit( TraitDecl *) {
-		// ensure that we don't add assignment ops for types defined as part of the context
-	}
-
-	template< typename StmtClass >
-	inline void AutogenerateRoutines::visitStatement( StmtClass *stmt ) {
-		std::set< std::string > oldStructs = structsDone;
-		addVisit( stmt, *this );
-		structsDone = oldStructs;
-	}
-
-	void AutogenerateRoutines::visit( FunctionDecl *functionDecl ) {
-		maybeAccept( functionDecl->get_functionType(), *this );
-		acceptAll( functionDecl->get_oldDecls(), *this );
-		functionNesting += 1;
-		maybeAccept( functionDecl->get_statements(), *this );
-		functionNesting -= 1;
-	}
-
-	void AutogenerateRoutines::visit( CompoundStmt *compoundStmt ) {
-		visitStatement( compoundStmt );
-	}
-
-	void AutogenerateRoutines::visit( IfStmt *ifStmt ) {
-		visitStatement( ifStmt );
-	}
-
-	void AutogenerateRoutines::visit( WhileStmt *whileStmt ) {
-		visitStatement( whileStmt );
-	}
-
-	void AutogenerateRoutines::visit( ForStmt *forStmt ) {
-		visitStatement( forStmt );
-	}
-
-	void AutogenerateRoutines::visit( SwitchStmt *switchStmt ) {
-		visitStatement( switchStmt );
-	}
-
-	void AutogenerateRoutines::visit( ChooseStmt *switchStmt ) {
-		visitStatement( switchStmt );
-	}
-
-	void AutogenerateRoutines::visit( CaseStmt *caseStmt ) {
-		visitStatement( caseStmt );
-	}
-
-	void AutogenerateRoutines::visit( CatchStmt *cathStmt ) {
-		visitStatement( cathStmt );
-	}
-
 	void ReturnChecker::checkFunctionReturns( std::list< Declaration * > & translationUnit ) {
 		ReturnChecker checker;
@@ -1080,4 +657,36 @@
 	}
 
+	void VerifyCtorDtor::verify( std::list< Declaration * > & translationUnit ) {
+		VerifyCtorDtor verifier;
+		acceptAll( translationUnit, verifier );
+	}
+
+	void VerifyCtorDtor::visit( FunctionDecl * funcDecl ) {
+		FunctionType * funcType = funcDecl->get_functionType();
+		std::list< DeclarationWithType * > &returnVals = funcType->get_returnVals();
+		std::list< DeclarationWithType * > &params = funcType->get_parameters();
+
+		if ( funcDecl->get_name() == "?{}" || funcDecl->get_name() == "^?{}" ) {
+			if ( params.size() == 0 ) {
+				throw SemanticError( "Constructors and destructors require at least one parameter ", funcDecl );
+			}
+			if ( ! dynamic_cast< PointerType * >( params.front()->get_type() ) ) {
+				throw SemanticError( "First parameter of a constructor or destructor must be a pointer ", funcDecl );
+			}
+			if ( returnVals.size() != 0 ) {
+				throw SemanticError( "Constructors and destructors cannot have explicit return values ", funcDecl );
+			}
+		}
+
+		Visitor::visit( funcDecl );
+		// original idea: modify signature of ctor/dtors and insert appropriate return statements
+		// to cause desired behaviour
+		// new idea: add comma exprs to every ctor call to produce first parameter.
+		// this requires some memoization of the first parameter, because it can be a
+		// complicated expression with side effects (see: malloc). idea: add temporary variable
+		// that is assigned address of constructed object in ctor argument position and
+		// return the temporary. It should also be done after all implicit ctors are
+		// added, so not in this pass!
+	}
 } // namespace SymTab
 
Index: src/SymTab/module.mk
===================================================================
--- src/SymTab/module.mk	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/SymTab/module.mk	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -6,5 +6,5 @@
 ## file "LICENCE" distributed with Cforall.
 ##
-## module.mk -- 
+## module.mk --
 ##
 ## Author           : Richard C. Bilson
@@ -20,3 +20,4 @@
        SymTab/FixFunction.cc \
        SymTab/ImplementationType.cc \
-       SymTab/TypeEquality.cc
+       SymTab/TypeEquality.cc \
+       SymTab/Autogen.cc
Index: src/SynTree/CommaExpr.cc
===================================================================
--- src/SynTree/CommaExpr.cc	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/SynTree/CommaExpr.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// CommaExpr.cc -- 
+// CommaExpr.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Mon May 18 08:09:58 2015
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed Apr 06 17:07:54 2016
 // Update Count     : 1
 //
@@ -20,4 +20,6 @@
 CommaExpr::CommaExpr( Expression *arg1, Expression *arg2, Expression *_aname )
 		: Expression( _aname ), arg1( arg1 ), arg2( arg2 ) {
+	// xxx - result of a comma expression is never an lvalue, so should set lvalue
+	// to false on all result types
 	cloneAll( arg2->get_results(), get_results() );
 }
Index: src/SynTree/CompoundStmt.cc
===================================================================
--- src/SynTree/CompoundStmt.cc	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/SynTree/CompoundStmt.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// XXX.cc -- 
+// XXX.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jun 23 11:37:49 2015
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed Apr 06 14:35:37 2016
 // Update Count     : 3
 //
@@ -18,7 +18,26 @@
 #include <algorithm>
 #include <functional>
+#include "Expression.h"
+#include "Declaration.h"
 
 using std::string;
 using std::endl;
+
+class VarExprReplacer : public Visitor {
+public:
+  typedef std::map< DeclarationWithType *, DeclarationWithType * > DeclMap;
+private:
+  const DeclMap & declMap;
+public:
+  VarExprReplacer( const DeclMap & declMap ) : declMap( declMap ) {}
+
+  // replace variable with new node from decl map
+  virtual void visit( VariableExpr * varExpr ) {
+    if ( declMap.count( varExpr->get_var() ) ) {
+      varExpr->set_var( declMap.at( varExpr->get_var() ) );
+    }
+  }
+};
+
 
 CompoundStmt::CompoundStmt( std::list<Label> labels ) : Statement( labels ) {
@@ -27,4 +46,35 @@
 CompoundStmt::CompoundStmt( const CompoundStmt &other ) : Statement( other ) {
 	cloneAll( other.kids, kids );
+
+  // when cloning a compound statement, we may end up cloning declarations which
+  // are referred to by VariableExprs throughout the block. Cloning a VariableExpr
+  // does a shallow copy, so the VariableExpr will end up pointing to the original
+  // declaration. If the original declaration is deleted, e.g. because the original
+  // CompoundStmt is deleted, then we have a dangling pointer. To avoid this case,
+  // find all DeclarationWithType nodes (since a VariableExpr must point to a
+  // DeclarationWithType) in the original CompoundStmt and map them to the cloned
+  // node in the new CompoundStmt ('this'), then replace the Declarations referred to
+  // by each VariableExpr according to the constructed map. Note that only the declarations
+  // in the current level are collected into the map, because child CompoundStmts will
+  // recursively execute this routine. There may be more efficient ways of doing
+  // this.
+  VarExprReplacer::DeclMap declMap;
+  std::list< Statement * >::const_iterator origit = other.kids.begin();
+  for ( Statement * s : kids ) {
+    assert( origit != other.kids.end() );
+    if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( s ) ) {
+      DeclStmt * origDeclStmt = dynamic_cast< DeclStmt * >( *origit );
+      assert( origDeclStmt );
+      if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * > ( declStmt->get_decl() ) ) {
+        DeclarationWithType * origdwt = dynamic_cast< DeclarationWithType * > ( origDeclStmt->get_decl() );
+        assert( origdwt );
+        declMap[ origdwt ] = dwt;
+      }
+    }
+  }
+  if ( ! declMap.empty() ) {
+    VarExprReplacer replacer( declMap );
+    accept( replacer );
+  }
 }
 
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/SynTree/Declaration.h	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Declaration.h -- 
+// Declaration.h --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Mar  2 17:28:11 2016
-// Update Count     : 33
+// Last Modified By : Rob Schluntz
+// Last Modified On : Mon Apr 04 17:14:00 2016
+// Update Count     : 36
 //
 
Index: src/SynTree/Initializer.cc
===================================================================
--- src/SynTree/Initializer.cc	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/SynTree/Initializer.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,18 +5,19 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Initializer.cc -- 
+// Initializer.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Wed Aug 12 14:05:25 2015
-// Update Count     : 14
+// Last Modified On : Wed Apr 06 16:15:32 2016
+// Update Count     : 28
 //
 
 #include "Initializer.h"
 #include "Expression.h"
+#include "Statement.h"
 #include "Common/utility.h"
 
-Initializer::Initializer() {}
+Initializer::Initializer( bool maybeConstructed ) : maybeConstructed( maybeConstructed ) {}
 
 Initializer::~Initializer() {}
@@ -31,8 +32,8 @@
 void Initializer::print( std::ostream &os, int indent ) {}
 
-SingleInit::SingleInit( Expression *v, std::list< Expression *> &_designators ) : value ( v ), designators( _designators ) { 
+SingleInit::SingleInit( Expression *v, const std::list< Expression *> &_designators, bool maybeConstructed ) : Initializer( maybeConstructed ), value ( v ), designators( _designators ) {
 }
 
-SingleInit::SingleInit( const SingleInit &other ) : value ( other.value ) {
+SingleInit::SingleInit( const SingleInit &other ) : Initializer(other), value ( maybeClone( other.value ) ) {
 	cloneAll(other.designators, designators );
 }
@@ -54,6 +55,6 @@
 }
 
-ListInit::ListInit( std::list<Initializer*> &_initializers, std::list<Expression *> &_designators )
-	: initializers( _initializers ), designators( _designators ) {
+ListInit::ListInit( const std::list<Initializer*> &_initializers, const std::list<Expression *> &_designators, bool maybeConstructed )
+	: Initializer( maybeConstructed), initializers( _initializers ), designators( _designators ) {
 }
 
@@ -65,18 +66,49 @@
 
 void ListInit::print( std::ostream &os, int indent ) {
-	os << std::endl << std::string(indent, ' ') << "Compound initializer:  "; 
+	os << std::endl << std::string(indent, ' ') << "Compound initializer:  ";
 	if ( ! designators.empty() ) {
 		os << std::string(indent + 2, ' ' ) << "designated by: [";
 		for ( std::list < Expression * >::iterator i = designators.begin();
 			  i != designators.end(); i++ ) {
-			( *i )->print(os, indent + 4 ); 
+			( *i )->print(os, indent + 4 );
 		} // for
-	
+
 		os << std::string(indent + 2, ' ' ) << "]";
 	} // if
 
-	for ( std::list<Initializer *>::iterator i = initializers.begin(); i != initializers.end(); i++ ) 
+	for ( std::list<Initializer *>::iterator i = initializers.begin(); i != initializers.end(); i++ )
 		(*i)->print( os, indent + 2 );
 }
+
+
+ConstructorInit::ConstructorInit( Statement * ctor, Statement * dtor, Initializer * init ) : Initializer( true ), ctor( ctor ), dtor( dtor ), init( init ) {}
+ConstructorInit::~ConstructorInit() {
+	delete ctor;
+	delete init;
+}
+
+ConstructorInit *ConstructorInit::clone() const {
+	return new ConstructorInit( *this );
+}
+
+void ConstructorInit::print( std::ostream &os, int indent ) {
+	os << std::endl << std::string(indent, ' ') << "Constructor initializer: ";
+	if ( ctor ) {
+		os << " initially constructed with ";
+		ctor->print( os, indent+2 );
+	} // if
+
+	if ( dtor ) {
+		os << " destructed with ";
+		dtor->print( os, indent+2 );
+	}
+
+	if ( init ) {
+		os << " with fallback C-style initializer: ";
+		init->print( os, indent+2 );
+	}
+}
+
+
 // Local Variables: //
 // tab-width: 4 //
Index: src/SynTree/Initializer.h
===================================================================
--- src/SynTree/Initializer.h	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/SynTree/Initializer.h	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Initializer.h -- 
+// Initializer.h --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Mon May 18 09:03:48 2015
-// Update Count     : 1
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed Mar 30 13:22:08 2016
+// Update Count     : 19
 //
 
@@ -27,5 +27,5 @@
   public:
 	//	Initializer( std::string _name = std::string(""), int _pos = 0 );
-	Initializer( );
+	Initializer( bool maybeConstructed );
 	virtual ~Initializer();
 
@@ -43,4 +43,6 @@
 	}
 
+	bool get_maybeConstructed() { return maybeConstructed; }
+
 	virtual Initializer *clone() const = 0;
 	virtual void accept( Visitor &v ) = 0;
@@ -50,4 +52,5 @@
 	//	std::string name;
 	//	int pos;
+	bool maybeConstructed;
 };
 
@@ -55,8 +58,8 @@
 class SingleInit : public Initializer {
   public:
-	SingleInit( Expression *value, std::list< Expression *> &designators = *(new std::list<Expression *>()) );
+	SingleInit( Expression *value, const std::list< Expression *> &designators, bool maybeConstructed = false );
 	SingleInit( const SingleInit &other );
 	virtual ~SingleInit();
-	
+
 	Expression *get_value() { return value; }
 	void set_value( Expression *newValue ) { value = newValue; }
@@ -79,6 +82,6 @@
 class ListInit : public Initializer {
   public:
-	ListInit( std::list<Initializer*> &, 
-			  std::list<Expression *> &designators = *(new std::list<Expression *>()) );
+	ListInit( const std::list<Initializer*> &initializers,
+			  const std::list<Expression *> &designators, bool maybeConstructed = false );
 	virtual ~ListInit();
 
@@ -100,4 +103,31 @@
 };
 
+// ConstructorInit represents an initializer that is either a constructor expression or
+// a C-style initializer.
+class ConstructorInit : public Initializer {
+  public:
+	ConstructorInit( Statement * ctor, Statement * dtor, Initializer * init );
+	virtual ~ConstructorInit();
+
+	void set_ctor( Statement * newValue ) { ctor = newValue; }
+	Statement * get_ctor() const { return ctor; }
+	void set_dtor( Statement * newValue ) { dtor = newValue; }
+	Statement * get_dtor() const { return dtor; }
+	void set_init( Initializer * newValue ) { init = newValue; }
+	Initializer * get_init() const { return init; }
+
+	virtual ConstructorInit *clone() const;
+	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 );
+
+  private:
+	Statement * ctor;
+	Statement * dtor;
+	// C-style initializer made up of SingleInit and ListInit nodes to use as a fallback
+	// if an appropriate constructor definition is not found by the resolver
+	Initializer * init;
+};
+
 #endif // INITIALIZER_H
 
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/SynTree/Mutator.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Mutator.cc -- 
+// Mutator.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Mar  2 17:28:20 2016
-// Update Count     : 12
+// Last Modified By : Rob Schluntz
+// Last Modified On : Mon Apr 04 17:14:20 2016
+// Update Count     : 15
 //
 
@@ -437,4 +437,10 @@
 }
 
+Initializer *Mutator::mutate( ConstructorInit *ctorInit ) {
+	ctorInit->set_ctor( maybeMutate( ctorInit->get_ctor(), *this ) );
+	ctorInit->set_init( maybeMutate( ctorInit->get_init(), *this ) );
+	return ctorInit;
+}
+
 Subrange *Mutator::mutate( Subrange *subrange ) {
 	return subrange;
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/SynTree/Mutator.h	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Mutator.h -- 
+// Mutator.h --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Mar  2 17:33:11 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Mon Apr 04 17:14:44 2016
 // Update Count     : 9
 //
@@ -62,5 +62,5 @@
 	virtual Expression* mutate( MemberExpr *memberExpr );
 	virtual Expression* mutate( VariableExpr *variableExpr );
-	virtual Expression* mutate( ConstantExpr *constantExpr ); 
+	virtual Expression* mutate( ConstantExpr *constantExpr );
 	virtual Expression* mutate( SizeofExpr *sizeofExpr );
 	virtual Expression* mutate( AlignofExpr *alignofExpr );
@@ -94,4 +94,5 @@
 	virtual Initializer* mutate( SingleInit *singleInit );
 	virtual Initializer* mutate( ListInit *listInit );
+	virtual Initializer* mutate( ConstructorInit *ctorInit );
 
 	virtual Subrange *mutate( Subrange *subrange );
Index: src/SynTree/ObjectDecl.cc
===================================================================
--- src/SynTree/ObjectDecl.cc	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/SynTree/ObjectDecl.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// ObjectDecl.cc -- 
+// ObjectDecl.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Tue Sep 29 14:13:01 2015
-// Update Count     : 18
+// Last Modified On : Tue Feb 09 13:21:03 2016
+// Update Count     : 30
 //
 
@@ -19,4 +19,5 @@
 #include "Expression.h"
 #include "Common/utility.h"
+#include "Statement.h"
 
 ObjectDecl::ObjectDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, Expression *bitfieldWidth, Type *type, Initializer *init, bool isInline, bool isNoreturn )
@@ -58,4 +59,5 @@
 		os << " with initializer ";
 		init->print( os, indent );
+		os << std::string(indent, ' ') << "maybeConstructed? " << init->get_maybeConstructed();
 	} // if
 
@@ -69,6 +71,6 @@
 #if 0
 	if ( get_mangleName() != "") {
-		os << get_mangleName() << ": "; 
-	} else 
+		os << get_mangleName() << ": ";
+	} else
 #endif
 	if ( get_name() != "" ) {
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/SynTree/SynTree.h	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// SynTree.h -- 
+// SynTree.h --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Mar  2 17:29:00 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Mon Apr 04 17:16:09 2016
 // Update Count     : 4
 //
@@ -102,4 +102,5 @@
 class SingleInit;
 class ListInit;
+class ConstructorInit;
 
 class Subrange;
Index: src/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/SynTree/Visitor.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Visitor.cc -- 
+// Visitor.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Mar  2 17:29:23 2016
-// Update Count     : 16
+// Last Modified By : Rob Schluntz
+// Last Modified On : Mon Apr 04 17:16:25 2016
+// Update Count     : 18
 //
 
@@ -368,4 +368,9 @@
 }
 
+void Visitor::visit( ConstructorInit *ctorInit ) {
+	maybeAccept( ctorInit->get_ctor(), *this );
+	maybeAccept( ctorInit->get_init(), *this );
+}
+
 void Visitor::visit( Subrange *subrange ) {}
 
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/SynTree/Visitor.h	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Visitor.h -- 
+// Visitor.h --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Mar  2 17:33:35 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Mon Apr 04 17:16:36 2016
 // Update Count     : 6
 //
@@ -62,5 +62,5 @@
 	virtual void visit( MemberExpr *memberExpr );
 	virtual void visit( VariableExpr *variableExpr );
-	virtual void visit( ConstantExpr *constantExpr ); 
+	virtual void visit( ConstantExpr *constantExpr );
 	virtual void visit( SizeofExpr *sizeofExpr );
 	virtual void visit( AlignofExpr *alignofExpr );
@@ -94,4 +94,5 @@
 	virtual void visit( SingleInit *singleInit );
 	virtual void visit( ListInit *listInit );
+	virtual void visit( ConstructorInit *ctorInit );
 
 	virtual void visit( Subrange *subrange );
Index: src/initialization.txt
===================================================================
--- src/initialization.txt	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/initialization.txt	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -34,2 +34,38 @@
 sure that resolved initializers for all declarations are being
 generated.
+
+
+------
+
+More recent email: (I am quoted; Richard is the responder)
+> As far as I'm aware, the only way that I could currently get the correct
+> results from the unification engine is by feeding it an expression that
+> looks like "?=?( ((struct Y)x.y).a, 10 )", then picking out the pieces that
+> I need (namely the correct choice for a). Does this seem like a reasonable
+> approach to solve this problem?
+
+No, unfortunately. Initialization isn't being rewritten as assignment,
+so you shouldn't allow the particular selection of assignment
+operators that happen to be in scope (and which may include
+user-defined operators) to guide the type resolution.
+
+I don't think there is any way to rewrite an initializer as a single
+expression and have the resolver just do the right thing. I see the
+algorithm as:
+
+For each alternative interpretation of the designator:
+  Construct an expression that casts the initializer to the type of
+    the designator
+  Construct an AlternativeFinder and use it to find the lowest cost
+    interpretation of the expression
+  Add this interpretation to a list of possibilities
+Go through the list of possibilities and pick the lowest cost
+
+As with many things in the resolver, it's conceptually simple but the
+implementation may be a bit of a pain. It fits in with functions like
+findSingleExpression, findIntegralExpression in Resolver.cc, although
+it will be significantly more complicated than any of the existing
+ones.
+
+
+
Index: src/libcfa/Makefile.am
===================================================================
--- src/libcfa/Makefile.am	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/libcfa/Makefile.am	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -6,5 +6,5 @@
 ## file "LICENCE" distributed with Cforall.
 ##
-## Makefile.am -- 
+## Makefile.am --
 ##
 ## Author           : Peter A. Buhr
@@ -51,5 +51,5 @@
 
 CFLAGS = -g -Wall -Wno-unused-function -B${abs_top_srcdir}/src/driver -XCFA -t  # TEMPORARY: does not build with -O2
-CC = ${abs_top_srcdir}/src/driver/cfa 
+CC = ${abs_top_srcdir}/src/driver/cfa
 
 # extension-less header files are overridden by default make rules => explicitly override rule
Index: src/libcfa/Makefile.in
===================================================================
--- src/libcfa/Makefile.in	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/libcfa/Makefile.in	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -110,5 +110,5 @@
 AWK = @AWK@
 BACKEND_CC = @BACKEND_CC@
-CC = ${abs_top_srcdir}/src/driver/cfa 
+CC = ${abs_top_srcdir}/src/driver/cfa
 CCDEPMODE = @CCDEPMODE@
 CFA_BINDIR = @CFA_BINDIR@
Index: src/libcfa/iostream.c
===================================================================
--- src/libcfa/iostream.c	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/libcfa/iostream.c	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// iostream.c -- 
+// iostream.c --
 //
 // Author           : Peter A. Buhr
 // Created On       : Wed May 27 17:56:53 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Mar  7 13:51:23 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed Apr 06 14:42:52 2016
 // Update Count     : 227
 //
@@ -171,10 +171,10 @@
 
 
-forall( dtype ostype | ostream( ostype ) ) 
+forall( dtype ostype | ostream( ostype ) )
 ostype * ?|?( ostype *os, ostype * (* manip)( ostype * ) ) {
 	return manip( os );
 } // ?|?
 
-forall( dtype ostype | ostream( ostype ) ) 
+forall( dtype ostype | ostream( ostype ) )
 ostype * endl( ostype * os ) {
 	os | '\n';
@@ -184,5 +184,5 @@
 } // endl
 
-forall( dtype ostype | ostream( ostype ) ) 
+forall( dtype ostype | ostream( ostype ) )
 ostype * sepOn( ostype * os ) {
 	sepOn( os );
@@ -190,5 +190,5 @@
 } // sepOn
 
-forall( dtype ostype | ostream( ostype ) ) 
+forall( dtype ostype | ostream( ostype ) )
 ostype * sepOff( ostype * os ) {
 	sepOff( os );
@@ -310,5 +310,5 @@
 } // ?|?
 
-_Istream_str1 str( char * s ) { _Istream_str1 s = { s }; return s; }
+_Istream_str1 str( char * str ) { _Istream_str1 s = { str }; return s; }
 forall( dtype istype | istream( istype ) )
 istype * ?|?( istype * is, _Istream_str1 str ) {
@@ -317,5 +317,5 @@
 } // str
 
-_Istream_str2 str( char * s, int size ) { _Istream_str2 s = { s, size }; return s; }
+_Istream_str2 str( char * str, int size ) { _Istream_str2 s = { str, size }; return s; }
 forall( dtype istype | istream( istype ) )
 istype * ?|?( istype * is, _Istream_str2 str ) {
Index: src/libcfa/prelude.cf
===================================================================
--- src/libcfa/prelude.cf	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/libcfa/prelude.cf	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -1,9 +1,9 @@
 # 2 "prelude.cf"  // needed for error messages from this file
-//                               -*- Mode: C -*- 
-// 
+//                               -*- Mode: C -*-
+//
 // Copyright (C) Glen Ditchfield 1994, 1999
-// 
+//
 // prelude.cf -- Standard Cforall Preample for C99
-// 
+//
 // Author           : Glen Ditchfield
 // Created On       : Sat Nov 29 07:23:41 2014
@@ -117,11 +117,11 @@
 forall( ftype FT ) lvalue FT		 *?( FT * );
 
-_Bool			+?( _Bool ),			-?( _Bool ),			~?( _Bool );	     
-signed int		+?( signed int ),		-?( signed int ),		~?( signed int );	     
-unsigned int		+?( unsigned int ),		-?( unsigned int ),		~?( unsigned int );	     
-signed long int		+?( signed long int ),		-?( signed long int ),		~?( signed long int );	     
-unsigned long int	+?( unsigned long int ),	-?( unsigned long int ),	~?( unsigned long int );	     
-signed long long int	+?( signed long long int ),	-?( signed long long int ),	~?( signed long long int );    
-unsigned long long int	+?( unsigned long long int ),	-?( unsigned long long int ),	~?( unsigned long long int );  
+_Bool			+?( _Bool ),			-?( _Bool ),			~?( _Bool );
+signed int		+?( signed int ),		-?( signed int ),		~?( signed int );
+unsigned int		+?( unsigned int ),		-?( unsigned int ),		~?( unsigned int );
+signed long int		+?( signed long int ),		-?( signed long int ),		~?( signed long int );
+unsigned long int	+?( unsigned long int ),	-?( unsigned long int ),	~?( unsigned long int );
+signed long long int	+?( signed long long int ),	-?( signed long long int ),	~?( signed long long int );
+unsigned long long int	+?( unsigned long long int ),	-?( unsigned long long int ),	~?( unsigned long long int );
 float			+?( float ),			-?( float );
 double			+?( double ),			-?( double );
@@ -627,2 +627,229 @@
 			?+=?( long double _Complex *, long double _Complex ), ?+=?( volatile long double _Complex *, long double _Complex ),
 			?-=?( long double _Complex *, long double _Complex ), ?-=?( volatile long double _Complex *, long double _Complex );
+
+
+
+
+
+// ------------------------------------------------------------
+//
+// Section ??? Constructors and Destructors
+//
+// ------------------------------------------------------------
+
+// default ctor
+void	?{}( _Bool * ),				?{}( volatile _Bool * );
+void	?{}( char * ),	?{}( volatile char * );
+void	?{}( unsigned char * ),	?{}( volatile unsigned char * );
+void	?{}( char signed * ),			?{}( volatile char signed * );
+void	?{}( int short * ),				?{}( volatile int short * );
+void	?{}( int short unsigned * ),	?{}( volatile int short unsigned * );
+void	?{}( signed int * ),			?{}( volatile signed int * );
+void	?{}( unsigned int * ),			?{}( volatile unsigned int * );
+void	?{}( signed long int * ),		?{}( volatile signed long int * );
+void	?{}( unsigned long int * ),		?{}( volatile unsigned long int * );
+void	?{}( signed long long int * ),		?{}( volatile signed long long int * );
+void	?{}( unsigned long long int * ),	?{}( volatile unsigned long long int * );
+void	?{}( float * ),				?{}( volatile float * );
+void	?{}( double * ),			?{}( volatile double * );
+void	?{}( long double * ),			?{}( volatile long double * );
+void	?{}( float _Complex * ),		?{}( volatile float _Complex * );
+void	?{}( double _Complex * ),		?{}( volatile double _Complex * );
+void	?{}( long double _Complex * ),		?{}( volatile long double _Complex * );
+
+// copy ctor
+void	?{}( _Bool *, _Bool ),					?{}( volatile _Bool *, _Bool );
+void	?{}( char *, char ),	?{}( volatile char *, char );
+void	?{}( unsigned char *, unsigned char ),			?{}( volatile unsigned char *, unsigned char );
+void	?{}( char signed *, char signed ),			?{}( volatile char signed *, char signed );
+void	?{}( int short *, int short ),				?{}( volatile int short *, int short );
+void	?{}( int short unsigned *, int short unsigned ),	?{}( volatile int short unsigned *, int short unsigned );
+void	?{}( signed int *, signed int),				?{}( volatile signed int *, signed int );
+void	?{}( unsigned int *, unsigned int),			?{}( volatile unsigned int *, unsigned int );
+void	?{}( signed long int *, signed long int),		?{}( volatile signed long int *, signed long int );
+void	?{}( unsigned long int *, unsigned long int),		?{}( volatile unsigned long int *, unsigned long int );
+void	?{}( signed long long int *, signed long long int),	?{}( volatile signed long long int *, signed long long int );
+void	?{}( unsigned long long int *, unsigned long long int),	?{}( volatile unsigned long long int *, unsigned long long int );
+void	?{}( float *, float),					?{}( volatile float *, float );
+void	?{}( double *, double),					?{}( volatile double *, double );
+void	?{}( long double *, long double),			?{}( volatile long double *, long double );
+void	?{}( float _Complex *, float _Complex),			?{}( volatile float _Complex *, float _Complex );
+void	?{}( double _Complex *, double _Complex),		?{}( volatile double _Complex *, double _Complex );
+void	?{}( long double _Complex *, long double _Complex),	?{}( volatile long double _Complex *, long double _Complex );
+
+// dtor
+void	^?{}( _Bool * ),			^?{}( volatile _Bool * );
+void	^?{}( char * ),	^?{}( volatile char * );
+void	^?{}( char unsigned * ),			^?{}( volatile char unsigned * );
+void	^?{}( char signed * ),			^?{}( volatile char signed * );
+void	^?{}( int short * ),				^?{}( volatile int short * );
+void	^?{}( int short unsigned * ),	^?{}( volatile int short unsigned * );
+void	^?{}( signed int * ),			^?{}( volatile signed int * );
+void	^?{}( unsigned int * ),			^?{}( volatile unsigned int * );
+void	^?{}( signed long int * ),		^?{}( volatile signed long int * );
+void	^?{}( unsigned long int * ),		^?{}( volatile unsigned long int * );
+void	^?{}( signed long long int * ),		^?{}( volatile signed long long int * );
+void	^?{}( unsigned long long int * ),	^?{}( volatile unsigned long long int * );
+void	^?{}( float * ),			^?{}( volatile float * );
+void	^?{}( double * ),			^?{}( volatile double * );
+void	^?{}( long double * ),			^?{}( volatile long double * );
+void	^?{}( float _Complex * ),		^?{}( volatile float _Complex * );
+void	^?{}( double _Complex * ),		^?{}( volatile double _Complex * );
+void	^?{}( long double _Complex * ),		^?{}( volatile long double _Complex * );
+
+// // default ctor
+// forall( dtype DT ) void	 ?{}(		     DT ** );
+// forall( dtype DT ) void	 ?{}( const	     DT ** );
+// forall( dtype DT ) void	 ?{}(	    volatile DT ** );
+// forall( dtype DT ) void	 ?{}( const volatile DT ** );
+
+// // copy ctor
+// forall( dtype DT ) void	 ?{}(		     DT **, DT* );
+// forall( dtype DT ) void	 ?{}( const	     DT **, DT* );
+// forall( dtype DT ) void	 ?{}(	    volatile DT **, DT* );
+// forall( dtype DT ) void	 ?{}( const volatile DT **, DT* );
+
+// // dtor
+// forall( dtype DT ) void	^?{}(		     DT ** );
+// forall( dtype DT ) void	^?{}( const	     DT ** );
+// forall( dtype DT ) void	^?{}(	    volatile DT ** );
+// forall( dtype DT ) void	^?{}( const volatile DT ** );
+
+// copied from assignment section
+// copy constructors
+forall( ftype FT ) void ?{}( FT **, FT * );
+forall( ftype FT ) void ?{}( FT * volatile *, FT * );
+
+forall( dtype DT ) void ?{}(		     DT *	   *,			DT * );
+forall( dtype DT ) void ?{}(		     DT * volatile *,			DT * );
+forall( dtype DT ) void ?{}( const	     DT *	   *,			DT * );
+forall( dtype DT ) void ?{}( const	     DT * volatile *,			DT * );
+forall( dtype DT ) void ?{}( const	     DT *	   *, const		DT * );
+forall( dtype DT ) void ?{}( const	     DT * volatile *, const		DT * );
+forall( dtype DT ) void ?{}(	   volatile  DT *	   *,			DT * );
+forall( dtype DT ) void ?{}(	   volatile  DT * volatile *,			DT * );
+forall( dtype DT ) void ?{}(	   volatile  DT *	   *,	    volatile	DT * );
+forall( dtype DT ) void ?{}(	   volatile  DT * volatile *,	    volatile	DT * );
+
+forall( dtype DT ) void ?{}( const volatile  DT *	   *,			DT * );
+forall( dtype DT ) void ?{}( const volatile  DT * volatile *,			DT * );
+forall( dtype DT ) void ?{}( const volatile  DT *	   *, const		DT * );
+forall( dtype DT ) void ?{}( const volatile  DT * volatile *, const		DT * );
+forall( dtype DT ) void ?{}( const volatile  DT *	   *,	    volatile	DT * );
+forall( dtype DT ) void ?{}( const volatile  DT * volatile *,	    volatile	DT * );
+forall( dtype DT ) void ?{}( const volatile  DT *	   *, const volatile	DT * );
+forall( dtype DT ) void ?{}( const volatile  DT * volatile *, const volatile	DT * );
+
+forall( dtype DT ) void ?{}(		     DT *	   *,			void * );
+forall( dtype DT ) void ?{}(		     DT * volatile *,			void * );
+forall( dtype DT ) void ?{}( const	     DT *	   *,			void * );
+forall( dtype DT ) void ?{}( const	     DT * volatile *,			void * );
+forall( dtype DT ) void ?{}( const	     DT *	   *, const		void * );
+forall( dtype DT ) void ?{}( const	     DT * volatile *, const		void * );
+forall( dtype DT ) void ?{}(	   volatile  DT *	   *,			void * );
+forall( dtype DT ) void ?{}(	   volatile  DT * volatile *,			void * );
+forall( dtype DT ) void ?{}(	   volatile  DT *	   *,	    volatile	void * );
+forall( dtype DT ) void ?{}(	   volatile  DT * volatile *,	    volatile	void * );
+
+forall( dtype DT ) void ?{}( const volatile  DT *	   *,			void * );
+forall( dtype DT ) void ?{}( const volatile  DT * volatile *,			void * );
+forall( dtype DT ) void ?{}( const volatile  DT *	   *, const		void * );
+forall( dtype DT ) void ?{}( const volatile  DT * volatile *, const		void * );
+forall( dtype DT ) void ?{}( const volatile  DT *	   *,	    volatile	void * );
+forall( dtype DT ) void ?{}( const volatile  DT * volatile *,	    volatile	void * );
+forall( dtype DT ) void ?{}( const volatile  DT *	   *, const volatile	void * );
+forall( dtype DT ) void ?{}( const volatile  DT * volatile *, const volatile	void * );
+
+forall( dtype DT ) void ?{}(		     void *	     *,			DT * );
+forall( dtype DT ) void ?{}(		     void * volatile *,			DT * );
+forall( dtype DT ) void ?{}( const	     void *	     *,			DT * );
+forall( dtype DT ) void ?{}( const	     void * volatile *,			DT * );
+forall( dtype DT ) void ?{}( const	     void *	     *, const		DT * );
+forall( dtype DT ) void ?{}( const	     void * volatile *, const		DT * );
+forall( dtype DT ) void ?{}(	    volatile void *	     *,			DT * );
+forall( dtype DT ) void ?{}(	    volatile void * volatile *,			DT * );
+forall( dtype DT ) void ?{}(	    volatile void *	     *,	      volatile	DT * );
+forall( dtype DT ) void ?{}(	    volatile void * volatile *,	      volatile	DT * );
+forall( dtype DT ) void ?{}( const volatile void *	     *,			DT * );
+forall( dtype DT ) void ?{}( const volatile void * volatile *,			DT * );
+forall( dtype DT ) void ?{}( const volatile void *	     *, const		DT * );
+forall( dtype DT ) void ?{}( const volatile void * volatile *, const		DT * );
+forall( dtype DT ) void ?{}( const volatile void *	     *,	      volatile	DT * );
+forall( dtype DT ) void ?{}( const volatile void * volatile *,	      volatile	DT * );
+forall( dtype DT ) void ?{}( const volatile void *	     *, const volatile	DT * );
+forall( dtype DT ) void ?{}( const volatile void * volatile *, const volatile	DT * );
+
+void 	?{}(		    void *	    *,		      void * );
+void 	?{}(		    void * volatile *,		      void * );
+void 	?{}( const	    void *	    *,		      void * );
+void 	?{}( const	    void * volatile *,		      void * );
+void 	?{}( const	    void *	    *, const	      void * );
+void 	?{}( const	    void * volatile *, const	      void * );
+void 	?{}(	   volatile void *	    *,		      void * );
+void 	?{}(	   volatile void * volatile *,		      void * );
+void 	?{}(	   volatile void *	    *,	     volatile void * );
+void 	?{}(	   volatile void * volatile *,	     volatile void * );
+void 	?{}( const volatile void *	    *,		      void * );
+void 	?{}( const volatile void * volatile *,		      void * );
+void 	?{}( const volatile void *	    *, const	      void * );
+void 	?{}( const volatile void * volatile *, const	      void * );
+void 	?{}( const volatile void *	    *,	     volatile void * );
+void 	?{}( const volatile void * volatile *,	     volatile void * );
+void 	?{}( const volatile void *	    *, const volatile void * );
+void 	?{}( const volatile void * volatile *, const volatile void * );
+
+//forall( dtype DT ) void ?{}(		    DT *	  *, forall( dtype DT2 ) const DT2 * );
+//forall( dtype DT ) void ?{}(		    DT * volatile *, forall( dtype DT2 ) const DT2 * );
+forall( dtype DT ) void ?{}( const	    DT *	  *, forall( dtype DT2 ) const DT2 * );
+forall( dtype DT ) void ?{}( const	    DT * volatile *, forall( dtype DT2 ) const DT2 * );
+//forall( dtype DT ) void ?{}( volatile	    DT *	  *, forall( dtype DT2 ) const DT2 * );
+//forall( dtype DT ) void ?{}( volatile	    DT * volatile *, forall( dtype DT2 ) const DT2 * );
+forall( dtype DT ) void ?{}( const volatile DT *	  *, forall( dtype DT2 ) const DT2 * );
+forall( dtype DT ) void ?{}( const volatile DT * volatile *, forall( dtype DT2 ) const DT2 * );
+
+forall( ftype FT ) void	?{}( FT *	   *, forall( ftype FT2 ) FT2 * );
+forall( ftype FT ) void	?{}( FT * volatile *, forall( ftype FT2 ) FT2 * );
+
+// default ctors
+forall( ftype FT ) void	?{}( FT *	   * );
+forall( ftype FT ) void	?{}( FT * volatile * );
+
+forall( dtype DT ) void	?{}(		     DT *	   *);
+forall( dtype DT ) void	?{}(		     DT * volatile *);
+forall( dtype DT ) void	?{}( const	     DT *	   *);
+forall( dtype DT ) void	?{}( const	     DT * volatile *);
+forall( dtype DT ) void	?{}(	   volatile  DT *	   *);
+forall( dtype DT ) void	?{}(	   volatile  DT * volatile *);
+forall( dtype DT ) void ?{}( const volatile  DT *	   *);
+forall( dtype DT ) void ?{}( const volatile  DT * volatile *);
+
+void 	?{}(		    void *	    *);
+void 	?{}(		    void * volatile *);
+void 	?{}( const	    void *	    *);
+void 	?{}( const	    void * volatile *);
+void 	?{}(	   volatile void *	    *);
+void 	?{}(	   volatile void * volatile *);
+void 	?{}( const volatile void *	    *);
+void 	?{}( const volatile void * volatile *);
+
+// dtors
+forall( ftype FT ) void	^?{}( FT *	   * );
+forall( ftype FT ) void	^?{}( FT * volatile * );
+
+forall( dtype DT ) void	^?{}(		     DT *	   *);
+forall( dtype DT ) void	^?{}(		     DT * volatile *);
+forall( dtype DT ) void	^?{}( const	     DT *	   *);
+forall( dtype DT ) void	^?{}( const	     DT * volatile *);
+forall( dtype DT ) void	^?{}(	   volatile  DT *	   *);
+forall( dtype DT ) void	^?{}(	   volatile  DT * volatile *);
+forall( dtype DT ) void ^?{}( const volatile  DT *	   *);
+forall( dtype DT ) void ^?{}( const volatile  DT * volatile *);
+
+void 	^?{}(		    void *	    *);
+void 	^?{}(		    void * volatile *);
+void 	^?{}( const	    void *	    *);
+void 	^?{}( const	    void * volatile *);
+void 	^?{}(	   volatile void *	    *);
+void 	^?{}(	   volatile void * volatile *);
+void 	^?{}( const volatile void *	    *);
+void 	^?{}( const volatile void * volatile *);
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 3aba31104a0151fe62a14a3d7b03185117894c84)
+++ src/main.cc	(revision a5a71d0e95113b304e03502a14ccab969324804f)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// main.cc -- 
+// main.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Fri May 15 23:12:02 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Jan 27 22:20:20 2016
-// Update Count     : 199
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Mar 31 14:00:12 2016
+// Update Count     : 200
 //
 
@@ -41,4 +41,5 @@
 #include "InitTweak/Mutate.h"
 #include "InitTweak/RemoveInit.h"
+#include "InitTweak/FixInit.h"
 //#include "Explain/GenProlog.h"
 //#include "Try/Visit.h"
@@ -60,4 +61,5 @@
 	astp = false,
 	bresolvep = false,
+	ctorinitp = false,
 	exprp = false,
 	expraltp = false,
@@ -74,9 +76,10 @@
 	codegenp = false;
 
-enum { Ast, Bresolver, Expr, ExprAlt, Grammar, LibCFA, Nopreamble, Parse, Prototypes, Resolver, Symbol, Tree, Validate, };
+enum { Ast, Bresolver, CtorInitFix, Expr, ExprAlt, Grammar, LibCFA, Nopreamble, Parse, Prototypes, Resolver, Symbol, Tree, Validate, };
 
 static struct option long_opts[] = {
 	{ "ast", no_argument, 0, Ast },
 	{ "before-resolver", no_argument, 0, Bresolver },
+	{ "ctorinitfix", no_argument, 0, CtorInitFix },
 	{ "expr", no_argument, 0, Expr },
 	{ "expralt", no_argument, 0, ExprAlt },
@@ -100,7 +103,7 @@
 
 	opterr = 0;											// prevent getopt from printing error messages
-	
+
 	int c;
-	while ( (c = getopt_long( argc, argv, "abefglnpqrstvyzD:", long_opts, &long_index )) != -1 ) {
+	while ( (c = getopt_long( argc, argv, "abcefFglnpqrstvyzD:", long_opts, &long_index )) != -1 ) {
 		switch ( c ) {
 		  case Ast:
@@ -111,4 +114,8 @@
 		  case 'b':										// print before resolver steps
 			bresolvep = true;
+			break;
+			case CtorInitFix:
+			case 'c':
+			ctorinitp = true;
 			break;
 		  case Expr:
@@ -187,5 +194,5 @@
 			output = new ofstream( argv[ optind ] );
 		} // if
-	
+
 		Parser::get_parser().set_debug( grammarp );
 
@@ -208,11 +215,11 @@
 					exit( 1 );
 				} // if
-		    
+
 				parse( prelude, LinkageSpec::Intrinsic );
 			} // if
 		} // if
 
-		parse( input, libcfap ? LinkageSpec::Intrinsic : LinkageSpec::Cforall, grammarp );	
-  
+		parse( input, libcfap ? LinkageSpec::Intrinsic : LinkageSpec::Cforall, grammarp );
+
 		if ( parsep ) {
 			Parser::get_parser().get_parseTree()->printList( std::cout );
@@ -249,7 +256,7 @@
 		OPTPRINT( "mutate" )
 		ControlStruct::mutate( translationUnit );
-		OPTPRINT( "fixNames" ) 
+		OPTPRINT( "fixNames" )
 		CodeGen::fixNames( translationUnit );
-		OPTPRINT( "tweak" )
+		OPTPRINT( "tweakInit" )
 		InitTweak::tweak( translationUnit );
 
@@ -268,4 +275,13 @@
 		if ( exprp ) {
 			dump( translationUnit );
+			return 0;
+		}
+
+		OPTPRINT( "fixInit" )
+		// fix ObjectDecl - replaces ConstructorInit nodes
+		InitTweak::fix( translationUnit );
+		if ( ctorinitp ) {
+			dump ( translationUnit );
+			return 0;
 		}
 
@@ -278,5 +294,5 @@
 		OPTPRINT( "box" )
 		GenPoly::box( translationUnit );
-		
+
 		// print tree right before code generation
 		if ( codegenp ) {
@@ -314,4 +330,5 @@
 	} // try
 
+	deleteAll( translationUnit );
 	return 0;
 } // main
@@ -334,5 +351,5 @@
 	std::list< Declaration * > decls;
 	if ( noprotop ) {
-		filter( translationUnit.begin(), translationUnit.end(), 
+		filter( translationUnit.begin(), translationUnit.end(),
 				std::back_inserter( decls ), notPrelude );
 	} else {
