Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/CodeGen/CodeGenerator.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 : Thu Apr 14 15:40:00 2016
+// Update Count     : 255
 //
 
@@ -67,5 +67,6 @@
 	string mangleName( DeclarationWithType *decl ) {
 		if ( decl->get_mangleName() != "" ) {
-			return decl->get_mangleName();
+			// need to incorporate scope level in order to differentiate names for destructors
+			return decl->get_scopedMangleName();
 		} else {
 			return decl->get_name();
@@ -99,5 +100,5 @@
 		handleStorageClass( objectDecl );
 		output << genType( objectDecl->get_type(), mangleName( objectDecl ) );
-	
+
 		if ( objectDecl->get_init() ) {
 			output << " = ";
@@ -113,5 +114,5 @@
 		if ( aggDecl->get_name() != "" )
 			output << aggDecl->get_name();
-	
+
 		std::list< Declaration * > &memb = aggDecl->get_members();
 
@@ -119,12 +120,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 +142,5 @@
 		handleAggregate( aggregateDecl );
 	}
-  
+
 	void CodeGenerator::visit( EnumDecl *aggDecl ) {
 		output << "enum ";
@@ -147,5 +148,5 @@
 		if ( aggDecl->get_name() != "" )
 			output << aggDecl->get_name();
-	
+
 		std::list< Declaration* > &memb = aggDecl->get_members();
 
@@ -153,9 +154,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 +166,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 +214,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 +241,5 @@
 						assert( arg != applicationExpr->get_args().end() );
 						if ( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
-	        
+
 							*arg = addrExpr->get_arg();
 						} else {
@@ -243,10 +250,10 @@
 						break;
 					}
-	      
+
 				  default:
 					// do nothing
 					;
 				}
-	    
+
 				switch ( opInfo.type ) {
 				  case OT_INDEX:
@@ -257,10 +264,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 +295,5 @@
 					output << ")";
 					break;
-	      
+
 				  case OT_POSTFIX:
 				  case OT_POSTFIXASSIGN:
@@ -278,4 +302,5 @@
 					output << opInfo.symbol;
 					break;
+
 
 				  case OT_INFIX:
@@ -288,5 +313,5 @@
 					output << ")";
 					break;
-	      
+
 				  case OT_CONSTANT:
 				  case OT_LABELADDRESS:
@@ -307,5 +332,5 @@
 		} // if
 	}
-  
+
 	void CodeGenerator::visit( UntypedExpr *untypedExpr ) {
 		if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
@@ -321,9 +346,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 +365,5 @@
 					output << ")";
 					break;
-	      
+
 				  case OT_POSTFIX:
 				  case OT_POSTFIXASSIGN:
@@ -342,5 +372,5 @@
 					output << opInfo.symbol;
 					break;
-  
+
 				  case OT_INFIX:
 				  case OT_INFIXASSIGN:
@@ -352,5 +382,5 @@
 					output << ")";
 					break;
-					
+
 				  case OT_CONSTANT:
 					// there are no intrinsic definitions of 0 or 1 as functions
@@ -370,5 +400,5 @@
 		} // if
 	}
-  
+
 	void CodeGenerator::visit( NameExpr *nameExpr ) {
 		OperatorInfo opInfo;
@@ -380,5 +410,5 @@
 		} // if
 	}
-  
+
 	void CodeGenerator::visit( AddressExpr *addressExpr ) {
 		output << "(&";
@@ -409,14 +439,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 +457,10 @@
 		} // if
 	}
-  
+
 	void CodeGenerator::visit( ConstantExpr *constantExpr ) {
 		assert( constantExpr->get_constant() );
 		constantExpr->get_constant()->accept( *this );
 	}
-  
+
 	void CodeGenerator::visit( SizeofExpr *sizeofExpr ) {
 		output << "sizeof(";
@@ -469,5 +499,5 @@
 		assert( false && "OffsetPackExpr should not reach code generation" );
 	}
-  
+
 	void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
 		output << "(";
@@ -481,5 +511,5 @@
 		output << ")";
 	}
-  
+
 	void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) {
 		output << "(";
@@ -491,5 +521,5 @@
 		output << ")";
 	}
-  
+
 	void CodeGenerator::visit( CommaExpr *commaExpr ) {
 		output << "(";
@@ -499,7 +529,7 @@
 		output << ")";
 	}
-  
+
 	void CodeGenerator::visit( TupleExpr *tupleExpr ) {}
-  
+
 	void CodeGenerator::visit( TypeExpr *typeExpr ) {}
 
@@ -532,5 +562,5 @@
 			}
 		}
-		cur_indent -= CodeGenerator::tabsize; 
+		cur_indent -= CodeGenerator::tabsize;
 
 		output << indent << "}";
@@ -538,6 +568,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 );
@@ -589,5 +619,5 @@
 		switchStmt->get_condition()->accept( *this );
 		output << " ) ";
-		
+
 		output << "{" << std::endl;
 		cur_indent += CodeGenerator::tabsize;
@@ -609,5 +639,5 @@
 		} // if
 		output << ":\n";
-		
+
 		std::list<Statement *> sts = caseStmt->get_statements();
 
@@ -626,5 +656,5 @@
 			if ( ! branchStmt->get_target().empty() )
 				output << "goto " << branchStmt->get_target();
-			else { 
+			else {
 				if ( branchStmt->get_computedTarget() != 0 ) {
 					output << "goto *";
@@ -677,6 +707,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 (;";
 
@@ -702,5 +732,5 @@
 	void CodeGenerator::visit( DeclStmt *declStmt ) {
 		declStmt->get_decl()->accept( *this );
-	
+
 		if ( doSemicolon( declStmt->get_decl() ) ) {
 			output << ";";
Index: src/CodeGen/FixNames.cc
===================================================================
--- src/CodeGen/FixNames.cc	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/CodeGen/FixNames.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// FixNames.cc -- 
+// FixNames.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 23:36:42 2015
+// Last Modified By : Rob Schluntz
+// Last Modified On : Mon Apr 11 15:38:10 2016
 // Update Count     : 1
 //
@@ -26,4 +26,11 @@
 		virtual void visit( ObjectDecl *objectDecl );
 		virtual void visit( FunctionDecl *functionDecl );
+
+		virtual void visit( CompoundStmt *compoundStmt );
+
+	  private:
+		int scopeLevel = 1;
+
+		void fixDWT( DeclarationWithType *dwt );
 	};
 
@@ -33,8 +40,9 @@
 	}
 
-	void fixDWT( DeclarationWithType *dwt ) {
+	void FixNames::fixDWT( DeclarationWithType *dwt ) {
 		if ( dwt->get_name() != "" ) {
 			if ( LinkageSpec::isDecoratable( dwt->get_linkage() ) ) {
 				dwt->set_mangleName( SymTab::Mangler::mangle( dwt ) );
+				dwt->set_scopeLevel( scopeLevel );
 			} // if
 		} // if
@@ -50,4 +58,10 @@
 		fixDWT( functionDecl );
 	}
+
+	void FixNames::visit( CompoundStmt *compoundStmt ) {
+		scopeLevel++;
+		Visitor::visit( compoundStmt );
+		scopeLevel--;
+	}
 } // namespace CodeGen
 
Index: src/CodeGen/OperatorTable.cc
===================================================================
--- src/CodeGen/OperatorTable.cc	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/CodeGen/OperatorTable.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/CodeGen/OperatorTable.h	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/GenPoly/Box.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 : Thu Apr 14 15:57:46 2016
+// Update Count     : 295
 //
 
@@ -133,5 +133,5 @@
 			Value *lookup( Key *key, const std::list< TypeExpr* >& params ) const {
  				TypeList typeList( params );
- 				
+
 				// scan scopes for matches to the key
 				for ( typename InnerMap::const_iterator insts = instantiations.find( key ); insts != instantiations.end(); insts = instantiations.findNext( insts, key ) ) {
@@ -160,5 +160,5 @@
 			virtual Declaration *mutate( UnionDecl *unionDecl );
 		};
-		
+
 		/// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call
 		class Pass1 : public PolyMutator {
@@ -208,5 +208,5 @@
 			ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps;  ///< Currently known assignment operators
 			ScopedMap< std::string, DeclarationWithType* > adapters;     ///< Set of adapter functions in the current scope
-			
+
 			DeclarationWithType *retval;
 			bool useRetval;
@@ -226,5 +226,5 @@
 			virtual Type *mutate( PointerType *pointerType );
 			virtual Type *mutate( FunctionType *funcType );
-			
+
 		  private:
 			void addAdapters( FunctionType *functionType );
@@ -297,5 +297,5 @@
 			/// Exits the type-variable scope
 			void endTypeScope();
-			
+
 			ScopedSet< std::string > knownLayouts;          ///< Set of generic type layouts known in the current scope, indexed by sizeofName
 			ScopedSet< std::string > knownOffsets;          ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName
@@ -351,5 +351,5 @@
 		PolyGenericCalculator polyCalculator;
 		Pass3 pass3;
-		
+
 		layoutBuilder.mutateDeclarationList( translationUnit );
 		mutateTranslationUnit/*All*/( translationUnit, pass1 );
@@ -370,5 +370,5 @@
 		return functionDecl;
 	}
-	
+
 	/// Get a list of type declarations that will affect a layout function
 	std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) {
@@ -380,5 +380,5 @@
 			}
 		}
-		
+
 		return otypeDecls;
 	}
@@ -387,5 +387,5 @@
 	void addOtypeParams( FunctionType *layoutFnType, std::list< TypeDecl* > &otypeParams ) {
 		BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt );
-		
+
 		for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {
 			TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param );
@@ -444,5 +444,5 @@
 		return makeCond( ifCond, ifExpr );
 	}
-	
+
 	/// adds an expression to a compound statement
 	void addExpr( CompoundStmt *stmts, Expression *expr ) {
@@ -454,5 +454,5 @@
 		stmts->get_kids().push_back( stmt );
 	}
-	
+
 	Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) {
 		// do not generate layout function for "empty" tag structs
@@ -467,5 +467,5 @@
 		BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
 		PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
-		
+
 		ObjectDecl *sizeParam = new ObjectDecl( sizeofName( structDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
 		layoutFnType->get_parameters().push_back( sizeParam );
@@ -497,5 +497,5 @@
 				addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) );
 			}
-			
+
 			// place current size in the current offset index
 			addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from( n_members ) ) ),
@@ -505,5 +505,5 @@
 			// add member size to current size
 			addExpr( layoutDecl->get_statements(), makeOp( "?+=?", derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );
-			
+
 			// take max of member alignment and global alignment
 			addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) );
@@ -515,9 +515,9 @@
 		return structDecl;
 	}
-	
+
 	Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) {
 		// do not generate layout function for "empty" tag unions
 		if ( unionDecl->get_members().empty() ) return unionDecl;
-		
+
 		// get parameters that can change layout, exiting early if none
 		std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() );
@@ -528,5 +528,5 @@
 		BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
 		PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
-		
+
 		ObjectDecl *sizeParam = new ObjectDecl( sizeofName( unionDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
 		layoutFnType->get_parameters().push_back( sizeParam );
@@ -545,8 +545,8 @@
 			assert( dwt );
 			Type *memberType = dwt->get_type();
-			
+
 			// take max member size and global size
 			addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );
-			
+
 			// take max of member alignment and global alignment
 			addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) );
@@ -558,5 +558,5 @@
 		return unionDecl;
 	}
-	
+
 	////////////////////////////////////////// Pass1 ////////////////////////////////////////////////////
 
@@ -619,5 +619,5 @@
 			return 0;
 		}
-		
+
 		/// returns T if the given declaration is: (*?=?)(T *, T) for some type T (return not checked, but maybe should be), NULL otherwise
 		/// Only picks assignments where neither parameter is cv-qualified
@@ -631,5 +631,5 @@
 						Type *paramType2 = funType->get_parameters().back()->get_type();
 						if ( paramType2->get_qualifiers() != defaultQualifiers ) return 0;
-						
+
 						if ( PointerType *pointerType = dynamic_cast< PointerType* >( paramType1 ) ) {
 							Type *baseType1 = pointerType->get_base();
@@ -803,5 +803,5 @@
 				passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes );
 			}
-			
+
 			// add type information args for presently unseen types in parameter list
 			for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) {
@@ -882,5 +882,5 @@
 			assert( env );
 			Type *concrete = replaceWithConcrete( appExpr, polyType );
-			// add out-parameter for return value	
+			// add out-parameter for return value
 			return addRetParam( appExpr, function, concrete, arg );
 		}
@@ -1366,5 +1366,5 @@
 			return new VariableExpr( functionObj );
 		}
-		
+
 		Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
 			if ( retval && returnStmt->get_expr() ) {
@@ -1886,5 +1886,5 @@
 				}
 			}
-			
+
 			Type *ret = Mutator::mutate( funcType );
 
@@ -1905,5 +1905,5 @@
 
 					std::list<Expression*> designators;
-					objectDecl->set_init( new SingleInit( alloc, designators ) );
+					objectDecl->set_init( new SingleInit( alloc, designators, false ) ); // not constructed
 				}
 			}
@@ -1946,5 +1946,5 @@
 			return derefdVar;
 		}
-		
+
 		Expression *PolyGenericCalculator::mutate( MemberExpr *memberExpr ) {
 			// mutate, exiting early if no longer MemberExpr
@@ -2144,5 +2144,5 @@
 			Type *ty = offsetofExpr->get_type();
 			if ( ! findGeneric( ty ) ) return offsetofExpr;
-			
+
 			if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) {
 				// replace offsetof expression by index into offset array
Index: src/GenPoly/CopyParams.cc
===================================================================
--- src/GenPoly/CopyParams.cc	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/GenPoly/CopyParams.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/GenPoly/Specialize.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 70a06f62e367e9c06390ae334378318747bac089)
+++ src/InitTweak/FixInit.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -0,0 +1,384 @@
+//
+// 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 Apr 14 15:19:11 2016
+// Update Count     : 30
+//
+
+#include <stack>
+#include <list>
+#include "RemoveInit.h"
+#include "ResolvExpr/Resolver.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 "SymTab/Indexer.h"
+#include "GenPoly/PolyMutator.h"
+
+namespace InitTweak {
+	namespace {
+		const std::list<Label> noLabels;
+		const std::list<Expression*> noDesignators;
+	}
+
+	class InsertImplicitCalls : public Mutator {
+	public:
+		/// wrap function application expressions as ImplicitCopyCtorExpr nodes
+		/// so that it is easy to identify which function calls need their parameters
+		/// to be copy constructed
+		static void insert( std::list< Declaration * > & translationUnit );
+
+		virtual Expression * mutate( ApplicationExpr * appExpr );
+	};
+
+	class ResolveCopyCtors : public SymTab::Indexer {
+	public:
+		/// generate temporary ObjectDecls for each argument and return value of each
+		/// ImplicitCopyCtorExpr, generate/resolve copy construction expressions for each,
+		/// and generate/resolve destructors for both arguments and return value temporaries
+		static void resolveImplicitCalls( std::list< Declaration * > & translationUnit );
+
+		virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr );
+
+		/// create and resolve ctor/dtor expression: fname(var, [cpArg])
+		ApplicationExpr * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL );
+	};
+
+	class FixInit : public GenPoly::PolyMutator {
+	  public:
+		/// expand each object declaration to use its constructor after it is declared.
+		/// insert destructor calls at the appropriate places
+		static void fixInitializers( std::list< Declaration * > &translationUnit );
+
+		virtual DeclarationWithType * 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;
+	};
+
+	class FixCopyCtors : public GenPoly::PolyMutator {
+	  public:
+		/// expand ImplicitCopyCtorExpr nodes into the temporary declarations, copy constructors,
+		/// call expression, and destructors
+		static void fixCopyCtors( std::list< Declaration * > &translationUnit );
+
+		virtual Expression * mutate( ImplicitCopyCtorExpr * impCpCtorExpr );
+
+	  private:
+		// stack of list of statements - used to differentiate scopes
+		std::list< std::list< Statement * > > dtorStmts;
+	};
+
+	void fix( std::list< Declaration * > & translationUnit ) {
+		InsertImplicitCalls::insert( translationUnit );
+		ResolveCopyCtors::resolveImplicitCalls( translationUnit );
+		FixInit::fixInitializers( translationUnit );
+		// FixCopyCtors must happen after FixInit, so that destructors are placed correctly
+		FixCopyCtors::fixCopyCtors( translationUnit );
+	}
+
+	void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit ) {
+		InsertImplicitCalls inserter;
+		mutateAll( translationUnit, inserter );
+	}
+
+	void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit ) {
+		ResolveCopyCtors resolver;
+		acceptAll( translationUnit, resolver );
+	}
+
+	void FixInit::fixInitializers( std::list< Declaration * > & translationUnit ) {
+		FixInit fixer;
+		mutateAll( translationUnit, fixer );
+	}
+
+	void FixCopyCtors::fixCopyCtors( std::list< Declaration * > & translationUnit ) {
+		FixCopyCtors fixer;
+		mutateAll( translationUnit, fixer );
+	}
+
+	Expression * InsertImplicitCalls::mutate( ApplicationExpr * appExpr ) {
+		if ( VariableExpr * function = dynamic_cast< VariableExpr * > ( appExpr->get_function() ) ) {
+			if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
+				// optimization: don't need to copy construct in order to call intrinsic functions
+				return appExpr;
+			} else if ( FunctionDecl * func = dynamic_cast< FunctionDecl * > ( function->get_var() ) ) {
+				// if (  )
+				// // optimization: don't need to copy construct in order to call a copy constructor
+				// return appExpr;
+			}
+		}
+		// wrap each function call so that it is easy to identify nodes that have to be copy constructed
+		appExpr = dynamic_cast< ApplicationExpr * >( Mutator::mutate( appExpr ) );
+		assert( appExpr );
+		return new ImplicitCopyCtorExpr( appExpr );
+	}
+
+	ApplicationExpr * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {
+		assert( var );
+		UntypedExpr * untyped = new UntypedExpr( new NameExpr( fname ) );
+		untyped->get_args().push_back( new AddressExpr( new VariableExpr( var ) ) );
+		if (cpArg) untyped->get_args().push_back( cpArg );
+
+		// resolve copy constructor
+		// should only be one alternative for copy ctor and dtor expressions, since
+		// all arguments are fixed (VariableExpr and already resolved expression)
+		ApplicationExpr * resolved = dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( untyped, *this ) );
+
+		assert( resolved );
+		delete untyped;
+		return resolved;
+	}
+
+	void ResolveCopyCtors::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
+		static UniqueName tempNamer("_tmp_cp");
+		static UniqueName retNamer("_tmp_cp_ret");
+
+		// resolve function call
+		Expression * newExpr = ResolvExpr::findVoidExpression( impCpCtorExpr->get_callExpr(), *this );
+		delete impCpCtorExpr->get_callExpr();
+		ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( newExpr );
+		assert( appExpr );
+		impCpCtorExpr->set_callExpr( appExpr );
+
+		// take each argument and attempt to copy construct it.
+		for ( Expression * & arg : appExpr->get_args() ) {
+			// xxx - need to handle tuple arguments
+			assert( ! arg->get_results().empty() );
+			ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, arg->get_results().front()->clone(), 0 );
+
+			// create and resolve copy constructor
+			ApplicationExpr * cpCtor = makeCtorDtor( "?{}", tmp, arg );
+
+			// if the chosen constructor is intrinsic, the copy is unnecessary, so
+			// don't create the temporary and don't call the copy constructor
+			VariableExpr * function = dynamic_cast< VariableExpr * >( cpCtor->get_function() );
+			assert( function );
+			if ( function->get_var()->get_linkage() != LinkageSpec::Intrinsic ) {
+				// replace argument to function call with temporary
+				arg = new VariableExpr( tmp );
+				impCpCtorExpr->get_tempDecls().push_back( tmp );
+				impCpCtorExpr->get_copyCtors().push_back( cpCtor );
+				impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", tmp ) );
+			}
+		}
+
+		// each return value from the call needs to be connected with an ObjectDecl
+		// at the call site, which is initialized with the return value and is destructed
+		// later
+		// xxx - handle multiple return values
+		for ( Type * result : appExpr->get_results() ) {
+			ObjectDecl * ret = new ObjectDecl( retNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result->clone(), new SingleInit( impCpCtorExpr->get_callExpr() ) );
+			impCpCtorExpr->get_returnDecls().push_back( ret );
+			impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) );
+		}
+	}
+
+
+	Expression * FixCopyCtors::mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) {
+		impCpCtorExpr = dynamic_cast< ImplicitCopyCtorExpr * >( Mutator::mutate( impCpCtorExpr ) );
+		assert( impCpCtorExpr );
+		std::cerr << "Running FixCopyCtors on implicit copy ctor..." << std::endl;
+
+		std::list< Expression * > & copyCtors = impCpCtorExpr->get_copyCtors();
+		std::list< ObjectDecl * > & tempDecls = impCpCtorExpr->get_tempDecls();
+		std::list< ObjectDecl * > & returnDecls = impCpCtorExpr->get_returnDecls();
+		std::list< Expression * > & dtors = impCpCtorExpr->get_dtors();
+
+		// add all temporary declarations and their constructors
+		for ( ObjectDecl * obj : tempDecls ) {
+			assert( ! copyCtors.empty() );
+			stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) );
+			stmtsToAdd.push_back( new ExprStmt( noLabels, copyCtors.front() ) );
+			copyCtors.pop_front();
+		}
+
+		// add destructors after current statement
+		for ( Expression * dtor : dtors ) {
+			stmtsToAddAfter.push_back( new ExprStmt( noLabels, dtor ) );
+		}
+
+		// xxx - update to work with multiple return values
+		ObjectDecl * returnDecl = returnDecls.empty() ? NULL : returnDecls.front();
+
+		// xxx - some of these aren't necessary, and can be removed once this is stable
+		copyCtors.clear();
+		dtors.clear();
+		tempDecls.clear();
+		returnDecls.clear();
+
+		if ( returnDecl ) {
+			// call is currently attached to first returnDecl
+			stmtsToAdd.push_back( new DeclStmt( noLabels, returnDecl ) );
+			return new VariableExpr( returnDecl );
+		} else {
+			// add call expression - if no return values, can call directly
+			return impCpCtorExpr->get_callExpr();
+		}
+	}
+
+	DeclarationWithType *FixInit::mutate( ObjectDecl *objDecl ) {
+		// first recursively handle pieces of ObjectDecl so that they aren't missed by other visitors
+		// when the init is removed from the ObjectDecl
+		objDecl = dynamic_cast< ObjectDecl * >( Mutator::mutate( 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 Mutator::mutate( 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 Mutator::mutate( 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 70a06f62e367e9c06390ae334378318747bac089)
+++ src/InitTweak/FixInit.h	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/InitTweak/InitModel.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/InitTweak/RemoveInit.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 : Thu Apr 14 15:09:36 2016
+// Update Count     : 166
+//
+
+#include <stack>
+#include <list>
 #include "RemoveInit.h"
 #include "SynTree/Declaration.h"
@@ -21,25 +23,30 @@
 #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 +54,35 @@
 	};
 
-	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 DeclarationWithType * 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 );
+
+		virtual Type * mutate( FunctionType *funcType );
+
+	  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 +90,4 @@
 
 	RemoveInit::RemoveInit() : tempNamer( "_retVal" ) {}
-	
-	void RemoveInit::mutateStatementList( std::list< Statement* > &statements ) {
-		for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
-			if ( ! stmtsToAddAfter.empty() ) {
-				statements.splice( i, stmtsToAddAfter );
-			} // if
-			*i = (*i)->acceptMutator( *this );
-			if ( ! stmtsToAddBefore.empty() ) {
-				statements.splice( i, stmtsToAddBefore );
-			} // if
-		} // for
-		if ( ! stmtsToAddAfter.empty() ) {
-			statements.splice( statements.end(), stmtsToAddAfter );
-		} // if
-	}
-
-	CompoundStmt *RemoveInit::mutate(CompoundStmt *compoundStmt) {
-		mutateStatementList( compoundStmt->get_kids() );
-		return compoundStmt;
-	}
 
 	// in the case where an object has an initializer and a polymorphic type, insert an assignment immediately after the
@@ -79,6 +96,7 @@
 		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( "?=?" ) );
-				assign->get_args().push_back( new AddressExpr (new NameExpr( objDecl->get_name() ) ) );
+				// xxx this can be more complicated - consider ListInit
+				UntypedExpr *assign = new UntypedExpr( new NameExpr( "?{}" ) );
+				assign->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
 				assign->get_args().push_back( single->get_value()->clone() );
 				stmtsToAddAfter.push_back(new ExprStmt(noLabels, assign));
@@ -93,12 +111,15 @@
 		// hands off if the function returns an lvalue - we don't want to allocate a temporary if a variable's address
 		// is being returned
-		if ( returnStmt->get_expr() && returnVals.size() == 1 && funcName != "?=?" && ! returnVals.front()->get_type()->get_isLvalue()  ) {
-			ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, returnVals.front()->get_type()->clone(), 0 );
-			stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
-			
-			UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
-			assign->get_args().push_back( new AddressExpr (new NameExpr( newObj->get_name() ) ) );
-			assign->get_args().push_back( returnStmt->get_expr() );
-			stmtsToAddBefore.push_back(new ExprStmt(noLabels, assign));
+		if ( returnStmt->get_expr() && returnVals.size() == 1 && funcName != "?=?" && ! returnVals.front()->get_type()->get_isLvalue() ) {
+			// 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 VariableExpr( newObj ) ) );
+			construct->get_args().push_back( returnStmt->get_expr() );
+			stmtsToAdd.push_back(new ExprStmt(noLabels, construct));
 
 			returnStmt->set_expr( new VariableExpr( newObj ) );
@@ -110,5 +131,5 @@
 		std::list<DeclarationWithType*> oldReturnVals = returnVals;
 		std::string oldFuncName = funcName;
-		
+
 		FunctionType * type = functionDecl->get_functionType();
 		returnVals = type->get_returnVals();
@@ -119,4 +140,123 @@
 		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;
+		}
+	}
+
+	DeclarationWithType * 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 Mutator::mutate( 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; }
+	Type* CtorDtor::mutate( FunctionType *funcType ) { return funcType; }
+
 } // namespace InitTweak
 
Index: src/InitTweak/RemoveInit.h
===================================================================
--- src/InitTweak/RemoveInit.h	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/InitTweak/RemoveInit.h	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/InitTweak/module.mk	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/MakeLibCfa.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/Makefile.in	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/Parser/DeclarationNode.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 : Wed Apr 13 16:53:17 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Apr 14 15:38:09 2016
 // Update Count     : 161
 //
@@ -97,4 +97,6 @@
 		os << endl << string( indent + 2, ' ' ) << "with initializer ";
 		initializer->printOneLine( os );
+		os << " maybe constructed? " << initializer->get_maybeConstructed();
+
 	} // if
 
@@ -353,5 +355,5 @@
 	} // if
 }
-	  
+
 DeclarationNode *DeclarationNode::addQualifiers( DeclarationNode *q ) {
 	if ( q ) {
@@ -504,5 +506,5 @@
 		assert( false );
 	} // switch
-	
+
 	return this;
 }
@@ -615,5 +617,5 @@
 		assert( a->type->kind == TypeData::Array );
 		TypeData *lastArray = findLast( a->type );
-		if ( type ) {  
+		if ( type ) {
 			switch ( type->kind ) {
 			  case TypeData::Aggregate:
@@ -659,5 +661,5 @@
 	} // if
 }
-	
+
 DeclarationNode *DeclarationNode::addIdList( DeclarationNode *ids ) {
 	type = addIdListToType( type, ids );
@@ -864,5 +866,5 @@
 Type *DeclarationNode::buildType() const {
 	assert( type );
-  
+
 	switch ( type->kind ) {
 	  case TypeData::Enum:
Index: src/Parser/InitializerNode.cc
===================================================================
--- src/Parser/InitializerNode.cc	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/Parser/InitializerNode.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/Parser/ParseNode.h	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -10,5 +10,5 @@
 // Created On       : Sat May 16 13:28:16 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Mon Apr 11 11:50:52 2016
+// Last Modified On : Thu Apr 14 15:37:52 2016
 // Update Count     : 205
 //
@@ -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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/Parser/TypeData.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/Parser/parser.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -7468,5 +7468,5 @@
 /* Line 1806 of yacc.c  */
 #line 1704 "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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/Parser/parser.yy	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 : Wed Apr 13 16:58:43 2016
 // Update Count     : 1519
-// 
+//
 
 // This grammar is based on the ANSI99/11 C grammar, specifically parts of EXPRESSION and STATEMENTS, and on the C
@@ -1702,5 +1702,5 @@
 		{ $$ = $2; }
 	| ATassign initializer
-		{ $$ = $2; }
+		{ $$ = $2->set_maybeConstructed( false ); }
 	;
 
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/ResolvExpr/Resolver.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 : Thu Apr 14 11:18:12 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,5 +60,5 @@
 	  void resolveAggrInit( AggregateDecl *, InitIterator &, InitIterator & );
 	  void resolveSingleAggrInit( Declaration *, InitIterator &, InitIterator & );
-
+	  void fallbackInit( ConstructorInit * ctorInit );
 		std::list< Type * > functionReturn;
 		Type *initContext;
@@ -82,4 +83,5 @@
 	}
 
+
 	namespace {
 		void finishExpr( Expression *expr, const TypeEnvironment &env ) {
@@ -87,13 +89,15 @@
 			env.makeSubstitution( *expr->get_env() );
 		}
-
-		Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
-			global_renamer.reset();
-			TypeEnvironment env;
-			Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
-			finishExpr( newExpr, env );
-			return newExpr;
-		}
-  
+	} // namespace
+
+	Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
+		global_renamer.reset();
+		TypeEnvironment env;
+		Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
+		finishExpr( newExpr, env );
+		return newExpr;
+	}
+
+	namespace {
 		Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
 			TypeEnvironment env;
@@ -126,5 +130,5 @@
 			} // if
 		}
-  
+
 		Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
 			TypeEnvironment env;
@@ -159,7 +163,7 @@
 			return newExpr;
 		}
-  
-	}
-  
+
+	}
+
 	void Resolver::visit( ObjectDecl *objectDecl ) {
 		Type *new_type = resolveTypeof( objectDecl->get_type(), *this );
@@ -258,5 +262,5 @@
 			forStmt->set_condition( newExpr );
 		} // if
-		
+
 		if ( forStmt->get_increment() ) {
 			Expression * newExpr = findVoidExpression( forStmt->get_increment(), *this );
@@ -272,5 +276,5 @@
 		delete switchStmt->get_condition();
 		switchStmt->set_condition( newExpr );
-  
+
 		visitor.Visitor::visit( switchStmt );
 	}
@@ -314,5 +318,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 +330,5 @@
 				string n = ne->get_name();
 				if (n == "0") {
-					initContext = new BasicType(Type::Qualifiers(), 
+					initContext = new BasicType(Type::Qualifiers(),
 												BasicType::SignedInt);
 				} else {
@@ -332,5 +336,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 +359,5 @@
 							singleInit->set_value( ce->get_arg() );
 							ce->set_arg( NULL );
-							delete ce;									
+							delete ce;
 						}
 					}
@@ -471,4 +475,41 @@
 #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 ) {
+		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/ResolvExpr/Resolver.h
===================================================================
--- src/ResolvExpr/Resolver.h	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/ResolvExpr/Resolver.h	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Resolver.h -- 
+// Resolver.h --
 //
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 12:18:34 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sun May 17 12:19:32 2015
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Apr 14 15:06:53 2016
 // Update Count     : 2
 //
@@ -24,4 +24,5 @@
 	void resolve( std::list< Declaration * > translationUnit );
 	Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer );
+	Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer );
 } // namespace ResolvExpr
 
Index: src/SymTab/AddVisit.h
===================================================================
--- src/SymTab/AddVisit.h	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/SymTab/AddVisit.h	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// AddVisit.h -- 
+// AddVisit.h --
 //
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 16:14:32 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Apr  7 14:42:21 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Apr 14 15:52:42 2016
 // Update Count     : 5
 //
@@ -48,4 +48,19 @@
 	// 	maybeAccept( caseStmt->get_condition(), 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 70a06f62e367e9c06390ae334378318747bac089)
+++ src/SymTab/Autogen.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -0,0 +1,500 @@
+//
+// 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 : Thu Apr 14 16:00:16 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( SwitchStmt *switchStmt );
+		virtual void visit( ChooseStmt *chooseStmt );
+		// virtual void visit( CaseStmt *caseStmt );
+
+		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( SwitchStmt *switchStmt ) {
+		visitStatement( switchStmt );
+	}
+
+	void AutogenerateRoutines::visit( ChooseStmt *switchStmt ) {
+		visitStatement( switchStmt );
+	}
+
+	// void AutogenerateRoutines::visit( CaseStmt *caseStmt ) {
+	// 	visitStatement( caseStmt );
+	// }
+} // SymTab
Index: src/SymTab/Autogen.h
===================================================================
--- src/SymTab/Autogen.h	(revision 70a06f62e367e9c06390ae334378318747bac089)
+++ src/SymTab/Autogen.h	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/SymTab/Validate.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 Apr 13 16:39:30 2016
-// Update Count     : 251
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Apr 14 15:37:23 2016
+// Update Count     : 297
 //
 
@@ -56,4 +56,5 @@
 #include "MakeLibCfa.h"
 #include "TypeEquality.h"
+#include "Autogen.h"
 #include "ResolvExpr/typeops.h"
 
@@ -122,35 +123,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( SwitchStmt *switchStmt );
-		virtual void visit( ChooseStmt *chooseStmt );
-		// virtual void visit( CaseStmt *caseStmt );
-
-		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
 	};
 
@@ -192,9 +162,19 @@
 		template<typename AggDecl>
 		void addImplicitTypedef( AggDecl * aggDecl );
-		
+
 		typedef std::map< std::string, std::pair< TypedefDecl *, int > > TypedefMap;
 		TypedefMap typedefNames;
 		int scopeLevel;
 	};
+
+	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 );
+
+		virtual void visit( FunctionDecl *funcDecl );
+};
 
 	class CompoundLiteral : public GenPoly::DeclMutator {
@@ -217,6 +197,7 @@
 		ReturnChecker::checkFunctionReturns( translationUnit );
 		mutateAll( translationUnit, compoundliteral );
-		AutogenerateRoutines::autogenerateRoutines( translationUnit );
+		autogenerateRoutines( translationUnit );
 		acceptAll( translationUnit, pass3 );
+		VerifyCtorDtor::verify( translationUnit );
 	}
 
@@ -228,18 +209,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
 	}
 
@@ -503,377 +470,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( SwitchStmt *switchStmt ) {
-		visitStatement( switchStmt );
-	}
-
-	void AutogenerateRoutines::visit( ChooseStmt *switchStmt ) {
-		visitStatement( switchStmt );
-	}
-
-	// void AutogenerateRoutines::visit( CaseStmt *caseStmt ) {
-	// 	visitStatement( caseStmt );
-	// }
-
 	void ReturnChecker::checkFunctionReturns( std::list< Declaration * > & translationUnit ) {
 		ReturnChecker checker;
@@ -1032,5 +626,5 @@
 		return aggDecl;
 	}
-	
+
 	template<typename AggDecl>
 	void EliminateTypedef::addImplicitTypedef( AggDecl * aggDecl ) {
@@ -1071,4 +665,37 @@
 	}
 
+	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!
+	}
+
 	DeclarationWithType * CompoundLiteral::mutate( ObjectDecl *objectDecl ) {
 		storageclass = objectDecl->get_storageClass();
Index: src/SymTab/module.mk
===================================================================
--- src/SymTab/module.mk	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/SymTab/module.mk	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/SynTree/CommaExpr.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/SynTree/CompoundStmt.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/SynTree/Declaration.h	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 11 16:55:12 2016
+// Update Count     : 36
 //
 
@@ -22,4 +22,5 @@
 #include "Parser/LinkageSpec.h"
 #include "Parser/ParseNode.h"
+#include <string>
 
 class Declaration {
@@ -67,4 +68,9 @@
 	void set_mangleName( std::string newValue ) { mangleName = newValue; }
 
+	std::string get_scopedMangleName() const { return mangleName + "_" + std::to_string(scopeLevel); }
+
+	int get_scopeLevel() const { return scopeLevel; }
+	void set_scopeLevel( int newValue ) { scopeLevel = newValue; }
+
 	virtual DeclarationWithType *clone() const = 0;
 	virtual DeclarationWithType *acceptMutator( Mutator &m ) = 0;
@@ -75,4 +81,7 @@
 	// this represents the type with all types and typedefs expanded it is generated by SymTab::Validate::Pass2
 	std::string mangleName;
+	// need to remember the scope level at which the variable was declared, so that
+	// shadowed identifiers can be accessed
+	int scopeLevel = 0;
 };
 
Index: src/SynTree/DeclarationWithType.cc
===================================================================
--- src/SynTree/DeclarationWithType.cc	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/SynTree/DeclarationWithType.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// DeclarationWithType.cc -- 
+// DeclarationWithType.cc --
 //
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jun 13 08:08:07 2015
+// Last Modified By : Rob Schluntz
+// Last Modified On : Mon Apr 11 15:35:27 2016
 // Update Count     : 3
 //
@@ -23,5 +23,5 @@
 
 DeclarationWithType::DeclarationWithType( const DeclarationWithType &other )
-		: Declaration( other ), mangleName( other.mangleName ) {
+		: Declaration( other ), mangleName( other.mangleName ), scopeLevel( other.scopeLevel ) {
 }
 
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/SynTree/Expression.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -9,6 +9,6 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Apr  8 17:16:23 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Apr 14 15:33:12 2016
 // Update Count     : 40
 //
@@ -79,4 +79,6 @@
 
 VariableExpr::VariableExpr( DeclarationWithType *_var, Expression *_aname ) : Expression( _aname ), var( _var ) {
+	assert( var );
+	assert( var->get_type() );
 	add_result( var->get_type()->clone() );
 	for ( std::list< Type* >::iterator i = get_results().begin(); i != get_results().end(); ++i ) {
@@ -454,4 +456,37 @@
 }
 
+
+ImplicitCopyCtorExpr::ImplicitCopyCtorExpr( ApplicationExpr * callExpr ) : callExpr( callExpr ) {
+	assert( callExpr );
+	cloneAll( callExpr->get_results(), results );
+}
+
+ImplicitCopyCtorExpr::ImplicitCopyCtorExpr( const ImplicitCopyCtorExpr & other ) : Expression( other ), callExpr( maybeClone( other.callExpr ) ) {
+	cloneAll( other.results, results );
+	cloneAll( other.copyCtors, copyCtors );
+	cloneAll( other.tempDecls, tempDecls );
+	cloneAll( other.returnDecls, returnDecls );
+	cloneAll( other.dtors, dtors );
+}
+
+ImplicitCopyCtorExpr::~ImplicitCopyCtorExpr() {
+	delete callExpr;
+	deleteAll( copyCtors );
+	deleteAll( tempDecls );
+	deleteAll( returnDecls );
+	deleteAll( dtors );
+}
+
+void ImplicitCopyCtorExpr::print( std::ostream &os, int indent ) const {
+	os << std::string( indent, ' ' ) <<  "Implicit Copy Constructor Expression: " << std::endl;
+	assert( callExpr );
+	callExpr->print( os, indent + 2 );
+	os << std::endl << std::string( indent, ' ' ) << "with temporaries:" << std::endl;
+	printAll(tempDecls, os, indent+2);
+	os << std::endl << std::string( indent, ' ' ) << "with copyCtors:" << std::endl;
+	printAll(copyCtors, os, indent+2);
+	Expression::print( os, indent );
+}
+
 UntypedValofExpr::UntypedValofExpr( const UntypedValofExpr & other ) : Expression( other ), body ( maybeClone( other.body ) ) {}
 
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/SynTree/Expression.h	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -9,6 +9,6 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Apr  8 17:18:06 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Apr 14 15:40:56 2016
 // Update Count     : 21
 //
@@ -22,4 +22,5 @@
 #include "Mutator.h"
 #include "Constant.h"
+#include "Common/UniqueName.h"
 
 /// Expression is the root type for all expressions
@@ -559,4 +560,39 @@
 };
 
+/// ImplicitCopyCtorExpr represents the application of a function to a set of parameters,
+/// along with a set of copy constructor calls, one for each argument.
+class ImplicitCopyCtorExpr : public Expression {
+public:
+	ImplicitCopyCtorExpr( ApplicationExpr * callExpr );
+	ImplicitCopyCtorExpr( const ImplicitCopyCtorExpr & other );
+	virtual ~ImplicitCopyCtorExpr();
+
+	ApplicationExpr *get_callExpr() const { return callExpr; }
+	void set_callExpr( ApplicationExpr *newValue ) { callExpr = newValue; }
+
+	std::list< Expression * > & get_copyCtors() { return copyCtors; }
+	void set_copyCtors( std::list< Expression * > newValue ) { copyCtors = newValue; }
+
+	std::list< ObjectDecl * > & get_tempDecls() { return tempDecls; }
+	void set_tempDecls( std::list< ObjectDecl * > newValue ) { tempDecls = newValue; }
+
+	std::list< ObjectDecl * > & get_returnDecls() { return returnDecls; }
+	void set_returnDecls( std::list< ObjectDecl * > newValue ) { returnDecls = newValue; }
+
+	std::list< Expression * > & get_dtors() { return dtors; }
+	void set_dtors( std::list< Expression * > newValue ) { dtors = newValue; }
+
+	virtual ImplicitCopyCtorExpr *clone() const { return new ImplicitCopyCtorExpr( *this ); }
+	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const;
+  private:
+	ApplicationExpr * callExpr;
+	std::list< Expression * > copyCtors;
+	std::list< ObjectDecl * > tempDecls;
+	std::list< ObjectDecl * > returnDecls;
+	std::list< Expression * > dtors;
+};
+
 /// ValofExpr represents a GCC 'lambda expression'
 class UntypedValofExpr : public Expression {
Index: src/SynTree/Initializer.cc
===================================================================
--- src/SynTree/Initializer.cc	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/SynTree/Initializer.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 : Mon Apr 11 17:36:10 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,53 @@
 
 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 );
+	}
+}
+
+std::ostream & operator<<( std::ostream & out, Initializer * init ) {
+	init->print( out );
+	return out;
+}
+
 // Local Variables: //
 // tab-width: 4 //
Index: src/SynTree/Initializer.h
===================================================================
--- src/SynTree/Initializer.h	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/SynTree/Initializer.h	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 : Tue Apr 12 13:49:13 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 = std::list< Expression * >(), 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 = std::list< Expression * >(), bool maybeConstructed = false );
 	virtual ~ListInit();
 
@@ -100,4 +103,33 @@
 };
 
+// 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;
+};
+
+std::ostream & operator<<( std::ostream & out, Initializer * init );
+
 #endif // INITIALIZER_H
 
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/SynTree/Mutator.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -5,10 +5,10 @@
 // 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 : Fri Apr  1 18:05:16 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Apr 14 15:32:19 2016
 // Update Count     : 16
 //
@@ -337,4 +337,11 @@
 }
 
+Expression* Mutator::mutate( ImplicitCopyCtorExpr *impCpCtorExpr ) {
+	impCpCtorExpr->set_callExpr( maybeMutate( impCpCtorExpr->get_callExpr(), *this ) );
+	mutateAll( impCpCtorExpr->get_copyCtors(), *this );
+	mutateAll( impCpCtorExpr->get_tempDecls(), *this );
+	return impCpCtorExpr;
+}
+
 Expression *Mutator::mutate( UntypedValofExpr *valofExpr ) {
 	mutateAll( valofExpr->get_results(), *this );
@@ -450,4 +457,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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/SynTree/Mutator.h	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 : Fri Apr  1 17:26:56 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Apr 14 15:32:00 2016
 // Update Count     : 10
 //
@@ -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 );
@@ -76,4 +76,5 @@
 	virtual Expression* mutate( TypeExpr *typeExpr );
 	virtual Expression* mutate( AsmExpr *asmExpr );
+	virtual Expression* mutate( ImplicitCopyCtorExpr *impCpCtorExpr );
 	virtual Expression* mutate( UntypedValofExpr *valofExpr );
 	virtual Expression* mutate( CompoundLiteralExpr *compLitExpr );
@@ -96,4 +97,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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/SynTree/ObjectDecl.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/SynTree/SynTree.h	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 : Fri Apr  1 16:47:44 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Apr 14 15:31:36 2016
 // Update Count     : 5
 //
@@ -81,4 +81,5 @@
 class TypeExpr;
 class AsmExpr;
+class ImplicitCopyCtorExpr;
 class UntypedValofExpr;
 class CompoundLiteralExpr;
@@ -104,4 +105,5 @@
 class SingleInit;
 class ListInit;
+class ConstructorInit;
 
 class Subrange;
Index: src/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/SynTree/Visitor.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -5,10 +5,10 @@
 // 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 : Fri Apr  1 18:05:13 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Apr 14 15:31:18 2016
 // Update Count     : 18
 //
@@ -284,4 +284,10 @@
 }
 
+void Visitor::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
+	maybeAccept( impCpCtorExpr->get_callExpr(), *this );
+	acceptAll( impCpCtorExpr->get_copyCtors(), *this );
+	acceptAll( impCpCtorExpr->get_tempDecls(), *this );
+}
+
 void Visitor::visit( UntypedValofExpr *valofExpr ) {
 	acceptAll( valofExpr->get_results(), *this );
@@ -379,4 +385,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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/SynTree/Visitor.h	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 : Fri Apr  1 17:26:55 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Apr 14 15:30:58 2016
 // Update Count     : 7
 //
@@ -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 );
@@ -76,4 +76,5 @@
 	virtual void visit( TypeExpr *typeExpr );
 	virtual void visit( AsmExpr *asmExpr );
+	virtual void visit( ImplicitCopyCtorExpr *impCpCtorExpr );
 	virtual void visit( UntypedValofExpr *valofExpr );
 	virtual void visit( CompoundLiteralExpr *compLitExpr );
@@ -96,4 +97,5 @@
 	virtual void visit( SingleInit *singleInit );
 	virtual void visit( ListInit *listInit );
+	virtual void visit( ConstructorInit *ctorInit );
 
 	virtual void visit( Subrange *subrange );
Index: src/examples/vector_int.c
===================================================================
--- src/examples/vector_int.c	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/examples/vector_int.c	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// vector_int.c -- 
+// vector_int.c --
 //
 // Author           : Richard C. Bilson
 // Created On       : Wed May 27 17:56:53 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed May 27 18:38:05 2015
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed Apr 06 17:18:31 2016
 // Update Count     : 3
 //
@@ -22,18 +22,16 @@
 #define DEFAULT_CAPACITY 20
 
-vector_int vector_int_allocate() {
-	return vector_int_allocate( DEFAULT_CAPACITY );
+void ?{}( vector_int * vec ) {
+	vec { DEFAULT_CAPACITY };
 }
 
-vector_int vector_int_allocate( int reserve ) {
-	vector_int new_vector;
-	new_vector.last = -1;
-	new_vector.capacity = reserve;
-	new_vector.data = malloc( sizeof( int ) * reserve );
-	return new_vector;
+void ?{}( vector_int * vec, int reserve ) {
+	vec->last = -1;
+	vec->capacity = reserve;
+	vec->data = malloc( sizeof( int ) * reserve );
 }
 
-void vector_int_deallocate( vector_int vec ) {
-	free( vec.data );
+void ^?{}( vector_int * vec ) {
+	free( vec->data );
 }
 
Index: src/examples/vector_int.h
===================================================================
--- src/examples/vector_int.h	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/examples/vector_int.h	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// vector_int.h -- 
+// vector_int.h --
 //
 // Author           : Richard C. Bilson
 // Created On       : Wed May 27 17:56:53 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed May 27 18:39:05 2015
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed Apr 06 17:21:59 2016
 // Update Count     : 2
 //
@@ -25,7 +25,7 @@
 } vector_int;
 
-vector_int vector_int_allocate();						// allocate vector with default capacity
-vector_int vector_int_allocate( int reserve );			// allocate vector with specified capacity
-void vector_int_deallocate( vector_int );				// deallocate vector's storage
+void ?{}( vector_int * );								// allocate vector with default capacity
+void ?{}( vector_int *, int reserve ); 					// allocate vector with specified capacity
+void ^?{}( vector_int * );								// deallocate vector's storage
 
 void reserve( vector_int *vec, int reserve );			// reserve more capacity
Index: src/examples/vector_test.c
===================================================================
--- src/examples/vector_test.c	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/examples/vector_test.c	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -5,10 +5,10 @@
 // file "LICENCE" distributed with Cforall.
 //
-// vector_test.c -- 
+// vector_test.c --
 //
 // Author           : Richard C. Bilson
 // Created On       : Wed May 27 17:56:53 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Feb 17 12:23:55 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed Apr 06 17:19:07 2016
 // Update Count     : 18
 //
@@ -20,5 +20,5 @@
 
 int main( void ) {
-	vector_int vec = vector_int_allocate();
+	vector_int vec;
 
 	// read in numbers until EOF or error
Index: src/initialization.txt
===================================================================
--- src/initialization.txt	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/initialization.txt	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/libcfa/Makefile.am	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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
@@ -67,3 +67,4 @@
 include_HEADERS = ${cheaders:=.h} ${libs} ${cfaheaders}
 
+CLEANFILES = libcfa-prelude.c
 MAINTAINERCLEANFILES += ${includedir}/*
Index: src/libcfa/Makefile.in
===================================================================
--- src/libcfa/Makefile.in	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/libcfa/Makefile.in	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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@
@@ -218,4 +218,5 @@
 cfaheaders = # limits
 include_HEADERS = ${cheaders:=.h} ${libs} ${cfaheaders}
+CLEANFILES = libcfa-prelude.c
 all: all-am
 
@@ -455,4 +456,5 @@
 
 clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
 
 distclean-generic:
Index: src/libcfa/iostream.c
===================================================================
--- src/libcfa/iostream.c	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/libcfa/iostream.c	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 : Wed Apr  6 16:13:29 2016
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Apr 14 16:02:09 2016
 // Update Count     : 278
 //
@@ -193,10 +193,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';
@@ -206,5 +206,5 @@
 } // endl
 
-forall( dtype ostype | ostream( ostype ) ) 
+forall( dtype ostype | ostream( ostype ) )
 ostype * sepOn( ostype * os ) {
 	sepOn( os );
@@ -212,5 +212,5 @@
 } // sepOn
 
-forall( dtype ostype | ostream( ostype ) ) 
+forall( dtype ostype | ostream( ostype ) )
 ostype * sepOff( ostype * os ) {
 	sepOff( os );
@@ -218,5 +218,5 @@
 } // sepOff
 
-forall( dtype ostype | ostream( ostype ) ) 
+forall( dtype ostype | ostream( ostype ) )
 ostype * sepEnable( ostype * os ) {
 	sepEnable( os );
@@ -224,5 +224,5 @@
 } // sepEnable
 
-forall( dtype ostype | ostream( ostype ) ) 
+forall( dtype ostype | ostream( ostype ) )
 ostype * sepDisable( ostype * os ) {
 	sepDisable( os );
@@ -344,5 +344,5 @@
 } // ?|?
 
-_Istream_cstrUC cstr( char * s ) { _Istream_cstrUC s = { s }; return s; }
+_Istream_cstrUC cstr( char * str ) { _Istream_cstrUC s = { str }; return s; }
 forall( dtype istype | istream( istype ) )
 istype * ?|?( istype * is, _Istream_cstrUC cstr ) {
@@ -351,5 +351,5 @@
 } // cstr
 
-_Istream_cstrC cstr( char * s, int size ) { _Istream_cstrC s = { s, size }; return s; }
+_Istream_cstrC cstr( char * str, int size ) { _Istream_cstrC s = { str, size }; return s; }
 forall( dtype istype | istream( istype ) )
 istype * ?|?( istype * is, _Istream_cstrC cstr ) {
Index: src/libcfa/prelude.cf
===================================================================
--- src/libcfa/prelude.cf	(revision 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/libcfa/prelude.cf	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 37f0da89b626150c903d8d8fecc683c0c6c8dee0)
+++ src/main.cc	(revision 70a06f62e367e9c06390ae334378318747bac089)
@@ -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 : Mon Apr 11 17:49:38 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"
@@ -55,9 +56,10 @@
 
 static void parse( FILE * input, LinkageSpec::Type t, bool shouldExit = false );
-static void dump( std::list< Declaration * > & translationUnit );
+static void dump( std::list< Declaration * > & translationUnit, std::ostream & out = std::cout );
 
 bool
 	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 ) {
@@ -292,5 +308,7 @@
 	} catch ( SemanticError &e ) {
 		if ( errorp ) {
-			dump( translationUnit );
+			std::cerr << "---AST at error:---" << std::endl;
+			dump( translationUnit, std::cerr );
+			std::cerr << std::endl << "---End of AST, begin error message:---\n" << std::endl;
 		}
 		e.print( std::cerr );
@@ -314,4 +332,5 @@
 	} // try
 
+	deleteAll( translationUnit );
 	return 0;
 } // main
@@ -331,8 +350,8 @@
 }
 
-static void dump( std::list< Declaration * > & translationUnit ) {
+static void dump( std::list< Declaration * > & translationUnit, std::ostream & out ) {
 	std::list< Declaration * > decls;
 	if ( noprotop ) {
-		filter( translationUnit.begin(), translationUnit.end(), 
+		filter( translationUnit.begin(), translationUnit.end(),
 				std::back_inserter( decls ), notPrelude );
 	} else {
@@ -340,5 +359,5 @@
 	}
 
-	printAll( decls, std::cout );
+	printAll( decls, out );
 	deleteAll( translationUnit );
 }
