Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 61f9356c5a7f6b519ed835460f72dc5f34708073)
+++ src/CodeGen/CodeGenerator.cc	(revision a56767c553787fe4920170c20ffd7e869a093d76)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Thu Sep 17 15:24:08 2015
-// Update Count     : 231
+// Last Modified On : Thu Sep 17 15:25:58 2015
+// Update Count     : 233
 //
 
@@ -258,5 +258,7 @@
 	      
 				  case OT_CALL:
-					// there are no intrinsic definitions of the function call operator
+				  case OT_CTOR:
+				  case OT_DTOR:
+					// there are no intrinsic definitions of the function call operator or constructors or destructors
 					assert( false );
 					break;
@@ -322,4 +324,6 @@
 	      
 				  case OT_CALL:
+					case OT_CTOR:
+					case OT_DTOR:
 					assert( false );
 					break;
Index: src/CodeGen/OperatorTable.cc
===================================================================
--- src/CodeGen/OperatorTable.cc	(revision 61f9356c5a7f6b519ed835460f72dc5f34708073)
+++ src/CodeGen/OperatorTable.cc	(revision a56767c553787fe4920170c20ffd7e869a093d76)
@@ -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 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				}, // ~?{}, -?{}, !?{}, $?{}, ??{}, ^?{}, ?destroy, ?delete
 			{	"?()",		"",		"_operator_call",				OT_CALL				},
 			{	"?++",		"++",	"_operator_postincr",			OT_POSTFIXASSIGN	},
Index: src/CodeGen/OperatorTable.h
===================================================================
--- src/CodeGen/OperatorTable.h	(revision 61f9356c5a7f6b519ed835460f72dc5f34708073)
+++ src/CodeGen/OperatorTable.h	(revision a56767c553787fe4920170c20ffd7e869a093d76)
@@ -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 61f9356c5a7f6b519ed835460f72dc5f34708073)
+++ src/GenPoly/Box.cc	(revision a56767c553787fe4920170c20ffd7e869a093d76)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Fri Dec 18 14:53:08 2015
-// Update Count     : 217
+// Last Modified On : Thu Jan 07 13:40:05 2016
+// Update Count     : 219
 //
 
@@ -1139,5 +1139,5 @@
 
 					std::list<Expression*> designators;
-					objectDecl->set_init( new SingleInit( alloc, designators ) );
+					objectDecl->set_init( new SingleInit( alloc, designators, false ) ); // not constructed
 				}
 			}
Index: src/InitTweak/InitModel.cc
===================================================================
--- src/InitTweak/InitModel.cc	(revision 61f9356c5a7f6b519ed835460f72dc5f34708073)
+++ src/InitTweak/InitModel.cc	(revision a56767c553787fe4920170c20ffd7e869a093d76)
@@ -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 61f9356c5a7f6b519ed835460f72dc5f34708073)
+++ src/InitTweak/RemoveInit.cc	(revision a56767c553787fe4920170c20ffd7e869a093d76)
@@ -5,13 +5,15 @@
 // file "LICENCE" distributed with Cforall.
 //
-// RemoveInit.cc -- 
+// RemoveInit.cc --
 //
 // Author           : Rob Schluntz
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Dec 15 15:37:26 2015
-// Update Count     : 15
-//
-
+// Last Modified By : Rob Schluntz
+// Last Modified On : Mon Jan 11 14:41:26 2016
+// Update Count     : 118
+//
+
+#include <stack>
+#include <list>
 #include "RemoveInit.h"
 #include "SynTree/Declaration.h"
@@ -21,4 +23,5 @@
 #include "SynTree/Initializer.h"
 #include "SynTree/Mutator.h"
+#include "GenPoly/PolyMutator.h"
 
 namespace InitTweak {
@@ -26,20 +29,14 @@
 		const std::list<Label> noLabels;
 	}
-	
-	class RemoveInit : public Mutator {
+
+	class RemoveInit : public GenPoly::PolyMutator {
 	  public:
 		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,30 +44,28 @@
 	};
 
+	class CtorDtor : public GenPoly::PolyMutator {
+	  public:
+		// CtorDtor();
+
+		virtual ObjectDecl * mutate( ObjectDecl * );
+
+		virtual CompoundStmt * mutate( CompoundStmt * compoundStmt );
+
+	  protected:
+		typedef std::map< std::string, DeclarationWithType * > MMMMAP;
+		std::stack< MMMMAP > constructedObjects;
+
+		// to be added before block ends - use push_front so order is correct
+		std::list< Statement * > destructorStmts;
+	};
+
 	void tweak( std::list< Declaration * > translationUnit ) {
 		RemoveInit remover;
+		CtorDtor ctordtor;
 		mutateAll( translationUnit, remover );
+		mutateAll( translationUnit, ctordtor );
 	}
 
 	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
@@ -95,10 +90,10 @@
 		if ( returnStmt->get_expr() && returnVals.size() == 1 && funcName != "?=?" && ! returnVals.front()->get_type()->get_isLvalue()  ) {
 			ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, returnVals.front()->get_type()->clone(), 0 );
-			stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
-			
+			stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
+
 			UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
 			assign->get_args().push_back( new AddressExpr (new NameExpr( newObj->get_name() ) ) );
 			assign->get_args().push_back( returnStmt->get_expr() );
-			stmtsToAddBefore.push_back(new ExprStmt(noLabels, assign));
+			stmtsToAdd.push_back(new ExprStmt(noLabels, assign));
 
 			returnStmt->set_expr( new VariableExpr( newObj ) );
@@ -110,5 +105,5 @@
 		std::list<DeclarationWithType*> oldReturnVals = returnVals;
 		std::string oldFuncName = funcName;
-		
+
 		FunctionType * type = functionDecl->get_functionType();
 		returnVals = type->get_returnVals();
@@ -119,4 +114,82 @@
 		return decl;
 	}
+
+	bool tryConstruct( ObjectDecl * objDecl ) {
+		// xxx - handle designations
+		return objDecl->get_init() == NULL ||
+			( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() );
+	}
+
+	ExprStmt * makeCtorDtorStmt( std::string name, ObjectDecl * objDecl, std::list< Expression * > args ) {
+		UntypedExpr * expr = new UntypedExpr( new NameExpr( name ) );
+		expr->get_args().push_back( new VariableExpr( objDecl ) );
+		expr->get_args().splice( expr->get_args().end(), args );
+		return new ExprStmt( noLabels, expr );
+	}
+
+	// InitExpander ctor/dtor being marked as weak symbols
+	// this is causing a bug - Rodolfo's InitExpander is being constructed and destructed
+	// with different fields, which causes a segfault
+
+	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 ) {
+		if ( init ) {
+			InitExpander expander;
+			// init->accept( expander );
+			// std::list< Expression * > l = expander.argList;
+			std::list< Expression * > l;
+			return l;
+		} else {
+			std::list< Expression * > l;
+			return l;
+		}
+	}
+
+	ObjectDecl * CtorDtor::mutate( ObjectDecl * objDecl ) {
+		// hands off if designated or if @=
+		if ( tryConstruct( objDecl ) ) {
+			ExprStmt * ctor = makeCtorDtorStmt( "?{}", objDecl, makeInitList( objDecl->get_init() ) );
+			ExprStmt * dtor = makeCtorDtorStmt( "^?{}", objDecl, std::list< Expression * >() );
+
+			// set_ctor...
+			// need to remember init expression, in case no ctors exist
+			// if ctor does exist, want to use ctor stmt instead of init
+			objDecl->set_ctor( ctor );
+			destructorStmts.push_front( dtor );
+		}
+		return objDecl;
+	}
+
+	CompoundStmt * CtorDtor::mutate( CompoundStmt * compoundStmt ) {
+		CompoundStmt * ret = PolyMutator::mutate( compoundStmt );
+		std::list< Statement * > &statements = ret->get_kids();
+		if ( ! destructorStmts.empty() ) {
+			statements.splice( statements.end(), destructorStmts );
+		} // if
+		return ret;
+	}
+
+
+
 } // namespace InitTweak
 
Index: src/MakeLibCfa.cc
===================================================================
--- src/MakeLibCfa.cc	(revision 61f9356c5a7f6b519ed835460f72dc5f34708073)
+++ src/MakeLibCfa.cc	(revision a56767c553787fe4920170c20ffd7e869a093d76)
@@ -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 : Thu Jan 07 13:34:39 2016
+// Update Count     : 20
+//
 
 #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;
@@ -77,4 +77,6 @@
 				break;
 			}
+		  case CodeGen::OT_CTOR:
+		  case CodeGen::OT_DTOR:
 		  case CodeGen::OT_CONSTANT:
 		  case CodeGen::OT_LABELADDRESS:
@@ -97,9 +99,9 @@
 	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 );
 	}
Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision 61f9356c5a7f6b519ed835460f72dc5f34708073)
+++ src/Parser/DeclarationNode.cc	(revision a56767c553787fe4920170c20ffd7e869a093d76)
@@ -5,11 +5,11 @@
 // 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 : Tue Jul 14 14:46:32 2015
-// Update Count     : 126
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Jan 07 13:18:02 2016
+// Update Count     : 130
 //
 
@@ -96,4 +96,6 @@
 		os << endl << string( indent + 2, ' ' ) << "with initializer ";
 		initializer->printOneLine( os );
+		os << " maybe constructed? " << initializer->get_maybeConstructed();
+
 	} // if
 
@@ -357,5 +359,5 @@
 	} // if
 }
-	  
+
 DeclarationNode *DeclarationNode::addQualifiers( DeclarationNode *q ) {
 	if ( q ) {
@@ -508,5 +510,5 @@
 		assert( false );
 	} // switch
-	
+
 	return this;
 }
@@ -619,5 +621,5 @@
 		assert( a->type->kind == TypeData::Array );
 		TypeData *lastArray = findLast( a->type );
-		if ( type ) {  
+		if ( type ) {
 			switch ( type->kind ) {
 			  case TypeData::Aggregate:
@@ -663,5 +665,5 @@
 	} // if
 }
-	
+
 DeclarationNode *DeclarationNode::addIdList( DeclarationNode *ids ) {
 	type = addIdListToType( type, ids );
@@ -868,5 +870,5 @@
 Type *DeclarationNode::buildType() const {
 	assert( type );
-  
+
 	switch ( type->kind ) {
 	  case TypeData::Enum:
Index: src/Parser/InitializerNode.cc
===================================================================
--- src/Parser/InitializerNode.cc	(revision 61f9356c5a7f6b519ed835460f72dc5f34708073)
+++ src/Parser/InitializerNode.cc	(revision a56767c553787fe4920170c20ffd7e869a093d76)
@@ -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 61f9356c5a7f6b519ed835460f72dc5f34708073)
+++ src/Parser/ParseNode.h	(revision a56767c553787fe4920170c20ffd7e869a093d76)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// ParseNode.h -- 
+// ParseNode.h --
 //
 // Author           : Rodolfo G. Esteves
 // Created On       : Sat May 16 13:28:16 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Wed Aug 12 13:27:11 2015
-// Update Count     : 172
+// Last Modified On : Thu Jan 07 13:17:46 2016
+// Update Count     : 177
 //
 
@@ -175,10 +175,11 @@
   public:
 	enum Type { TupleC, Comma, TupleFieldSel,
-				Cond, NCond, 
-				SizeOf, AlignOf, Attr, CompLit, Plus, Minus, Mul, Div, Mod, Or, And, 
-				BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq, 
-				Assign, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn, 
+				Cond, NCond,
+				SizeOf, AlignOf, Attr, CompLit, Plus, Minus, Mul, Div, Mod, Or, And,
+				BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq,
+				Assign, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn,
 				ERAssn, OrAssn, Index, FieldSel, PFieldSel, Range,
-				UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, LabelAddress
+				UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, LabelAddress,
+				Ctor, Dtor,
 	};
 
@@ -306,5 +307,5 @@
 	ValofExprNode( const ValofExprNode &other );
 	~ValofExprNode();
-  
+
 	virtual ValofExprNode *clone() const { return new ValofExprNode( *this ); }
 
@@ -329,5 +330,5 @@
 	enum TypeClass { Type, Dtype, Ftype };
 
-	static const char *storageName[];  
+	static const char *storageName[];
 	static const char *qualifierName[];
 	static const char *basicTypeName[];
@@ -419,5 +420,5 @@
 class StatementNode : public ParseNode {
   public:
-	enum Type { Exp,   If,        Switch,  Case,    Default,  Choose,   Fallthru, 
+	enum Type { Exp,   If,        Switch,  Case,    Default,  Choose,   Fallthru,
 				While, Do,        For,
 				Goto,  Continue,  Break,   Return,  Throw,
@@ -517,4 +518,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; }
 
@@ -528,4 +532,5 @@
 	ExpressionNode *designator; // may be list
 	InitializerNode *kids;
+	bool maybeConstructed;
 };
 
Index: src/Parser/parser.cc
===================================================================
--- src/Parser/parser.cc	(revision 61f9356c5a7f6b519ed835460f72dc5f34708073)
+++ src/Parser/parser.cc	(revision a56767c553787fe4920170c20ffd7e869a093d76)
@@ -7291,5 +7291,5 @@
 /* Line 1806 of yacc.c  */
 #line 1684 "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 61f9356c5a7f6b519ed835460f72dc5f34708073)
+++ src/Parser/parser.yy	(revision a56767c553787fe4920170c20ffd7e869a093d76)
@@ -5,6 +5,6 @@
 // file "LICENCE" distributed with Cforall.
 //
-// cfa.y -- 
-// 
+// cfa.y --
+//
 // Author           : Peter A. Buhr
 // Created On       : Sat Sep  1 20:22:55 2001
@@ -12,5 +12,5 @@
 // Last Modified On : Thu Oct  8 17:17:54 2015
 // Update Count     : 1473
-// 
+//
 
 // This grammar is based on the ANSI99/11 C grammar, specifically parts of EXPRESSION and STATEMENTS, and on the C
@@ -1682,5 +1682,5 @@
 		{ $$ = $2; }
 	| ATassign initializer
-		{ $$ = $2; }
+		{ $$ = $2->set_maybeConstructed( false ); }
 	;
 
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 61f9356c5a7f6b519ed835460f72dc5f34708073)
+++ src/SymTab/Validate.cc	(revision a56767c553787fe4920170c20ffd7e869a093d76)
@@ -10,6 +10,6 @@
 // Created On       : Sun May 17 21:50:04 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Fri Dec 18 15:34:05 2015
-// Update Count     : 218
+// Last Modified On : Thu Jan 07 11:27:49 2016
+// Update Count     : 269
 //
 
@@ -202,4 +202,17 @@
 	};
 
+	class VerifyCtorDtor : public Visitor {
+	public:
+		/// ensure that constructors and destructors have at least one
+		/// parameter, the first of which must be a pointer, and no
+		/// return values.
+		static void verify( std::list< Declaration * > &translationUnit );
+
+		// VerifyCtorDtor() {}
+
+		virtual void visit( FunctionDecl *funcDecl );
+	private:
+	};
+
 	void validate( std::list< Declaration * > &translationUnit, bool doDebug ) {
 		Pass1 pass1;
@@ -213,4 +226,5 @@
 		AutogenerateRoutines::autogenerateRoutines( translationUnit );
 		acceptAll( translationUnit, pass3 );
+		VerifyCtorDtor::verify( translationUnit );
 	}
 
@@ -1029,4 +1043,36 @@
 	}
 
+	void VerifyCtorDtor::verify( std::list< Declaration * > & translationUnit ) {
+		VerifyCtorDtor verifier;
+		acceptAll( translationUnit, verifier );
+	}
+
+	void VerifyCtorDtor::visit( FunctionDecl * funcDecl ) {
+		FunctionType * funcType = funcDecl->get_functionType();
+		std::list< DeclarationWithType * > &returnVals = funcType->get_returnVals();
+		std::list< DeclarationWithType * > &params = funcType->get_parameters();
+
+		if ( funcDecl->get_name() == "?{}" || funcDecl->get_name() == "^?{}" ) {
+			if ( params.size() == 0 ) {
+				throw SemanticError( "Constructors and destructors require at least one parameter ", funcDecl );
+			}
+			if ( ! dynamic_cast< PointerType * >( params.front()->get_type() ) ) {
+				throw SemanticError( "First parameter of a constructor or destructor must be a pointer ", funcDecl );
+			}
+			if ( returnVals.size() != 0 ) {
+				throw SemanticError( "Constructors and destructors cannot have explicit return values ", funcDecl );
+			}
+		}
+
+		Visitor::visit( funcDecl );
+		// original idea: modify signature of ctor/dtors and insert appropriate return statements
+		// to cause desired behaviour
+		// new idea: add comma exprs to every ctor call to produce first parameter.
+		// this requires some memoization of the first parameter, because it can be a
+		// complicated expression with side effects (see: malloc). idea: add temporary variable
+		// that is assigned address of constructed object in ctor argument position and
+		// return the temporary. It should also be done after all implicit ctors are
+		// added, so not in this pass!
+	}
 } // namespace SymTab
 
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision 61f9356c5a7f6b519ed835460f72dc5f34708073)
+++ src/SynTree/Declaration.h	(revision a56767c553787fe4920170c20ffd7e869a093d76)
@@ -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 : Rob Schluntz
-// Last Modified On : Wed Dec 09 14:08:22 2015
-// Update Count     : 32
+// Last Modified On : Thu Jan 07 14:48:44 2016
+// Update Count     : 34
 //
 
@@ -91,4 +91,6 @@
 	Expression *get_bitfieldWidth() const { return bitfieldWidth; }
 	void set_bitfieldWidth( Expression *newValue ) { bitfieldWidth = newValue; }
+	ExprStmt * get_ctor() const { return ctor; }
+	void set_ctor( ExprStmt * newValue ) { ctor = newValue; }
 
 	virtual ObjectDecl *clone() const { return new ObjectDecl( *this ); }
@@ -101,4 +103,5 @@
 	Initializer *init;
 	Expression *bitfieldWidth;
+	ExprStmt * ctor;
 };
 
Index: src/SynTree/Initializer.cc
===================================================================
--- src/SynTree/Initializer.cc	(revision 61f9356c5a7f6b519ed835460f72dc5f34708073)
+++ src/SynTree/Initializer.cc	(revision a56767c553787fe4920170c20ffd7e869a093d76)
@@ -5,11 +5,11 @@
 // 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 : Thu Jan 07 15:00:18 2016
+// Update Count     : 23
 //
 
@@ -18,5 +18,5 @@
 #include "utility.h"
 
-Initializer::Initializer() {}
+Initializer::Initializer( bool maybeConstructed ) : maybeConstructed( maybeConstructed ) {}
 
 Initializer::~Initializer() {}
@@ -31,8 +31,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, 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 ( other.value ) {
 	cloneAll(other.designators, designators );
 }
@@ -54,6 +54,6 @@
 }
 
-ListInit::ListInit( std::list<Initializer*> &_initializers, std::list<Expression *> &_designators )
-	: initializers( _initializers ), designators( _designators ) {
+ListInit::ListInit( std::list<Initializer*> &_initializers, std::list<Expression *> &_designators, bool maybeConstructed )
+	: Initializer( maybeConstructed), initializers( _initializers ), designators( _designators ) {
 }
 
@@ -65,16 +65,16 @@
 
 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 );
 }
Index: src/SynTree/Initializer.h
===================================================================
--- src/SynTree/Initializer.h	(revision 61f9356c5a7f6b519ed835460f72dc5f34708073)
+++ src/SynTree/Initializer.h	(revision a56767c553787fe4920170c20ffd7e869a093d76)
@@ -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 : Thu Jan 07 13:33:20 2016
+// Update Count     : 5
 //
 
@@ -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 );
+	SingleInit( Expression *value, std::list< Expression *> &designators, bool maybeConstructed );
 	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( std::list<Initializer*> &,
+			  std::list<Expression *> &designators, bool maybeConstructed );
 	virtual ~ListInit();
 
Index: src/SynTree/ObjectDecl.cc
===================================================================
--- src/SynTree/ObjectDecl.cc	(revision 61f9356c5a7f6b519ed835460f72dc5f34708073)
+++ src/SynTree/ObjectDecl.cc	(revision a56767c553787fe4920170c20ffd7e869a093d76)
@@ -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 : Fri Jan 08 15:29:10 2016
+// Update Count     : 27
 //
 
@@ -19,4 +19,5 @@
 #include "Expression.h"
 #include "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 )
@@ -24,8 +25,9 @@
 	set_isInline( isInline );
 	set_isNoreturn( isNoreturn );
+	set_ctor( NULL );
 }
 
 ObjectDecl::ObjectDecl( const ObjectDecl &other )
-	: Parent( other ), type( maybeClone( other.type ) ), init( maybeClone( other.init ) ), bitfieldWidth( maybeClone( other.bitfieldWidth ) ) {
+	: Parent( other ), type( maybeClone( other.type ) ), init( maybeClone( other.init ) ), bitfieldWidth( maybeClone( other.bitfieldWidth ) ), ctor( maybeClone( other.ctor ) ) {
 }
 
@@ -34,4 +36,5 @@
 	delete init;
 	delete bitfieldWidth;
+	delete ctor;
 }
 
@@ -58,4 +61,5 @@
 		os << " with initializer ";
 		init->print( os, indent );
+		os << std::string(indent, ' ') << "maybeConstructed? " << init->get_maybeConstructed();
 	} // if
 
@@ -64,4 +68,9 @@
 		bitfieldWidth->print( os );
 	} // if
+
+	if ( ctor ) {
+		os << " initially constructed with ";
+		ctor->print( os, indent );
+	} // if
 }
 
@@ -69,6 +78,6 @@
 #if 0
 	if ( get_mangleName() != "") {
-		os << get_mangleName() << ": "; 
-	} else 
+		os << get_mangleName() << ": ";
+	} else
 #endif
 	if ( get_name() != "" ) {
Index: c/examples/tests/vector_test.in.txt
===================================================================
--- src/examples/tests/vector_test.in.txt	(revision 61f9356c5a7f6b519ed835460f72dc5f34708073)
+++ 	(revision )
@@ -1,1 +1,0 @@
-1 2 3 4 5
Index: c/examples/tests/vector_test.out.txt
===================================================================
--- src/examples/tests/vector_test.out.txt	(revision 61f9356c5a7f6b519ed835460f72dc5f34708073)
+++ 	(revision )
@@ -1,5 +1,0 @@
-enter N elements and C-d on a separate line:
-Array elements:
-1 2 3 4 5 
-Array elements reversed:
-5 4 3 2 1 
Index: src/initialization.txt
===================================================================
--- src/initialization.txt	(revision 61f9356c5a7f6b519ed835460f72dc5f34708073)
+++ src/initialization.txt	(revision a56767c553787fe4920170c20ffd7e869a093d76)
@@ -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.
+
+
+
