Index: src/AST/Expr.hpp
===================================================================
--- src/AST/Expr.hpp	(revision 234b1cb4afd88ccf2b1f3e001a2eae5dc12ca39b)
+++ src/AST/Expr.hpp	(revision b8524ca1420ff28d69347f46888a20baa805f797)
@@ -248,4 +248,7 @@
 	AddressExpr( const CodeLocation & loc, const Expr * a );
 
+	/// Generate AddressExpr wrapping given expression at same location
+	AddressExpr( const Expr * a ) : AddressExpr( a->location, a ) {}
+
 	const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
 private:
@@ -281,4 +284,10 @@
 	/// Cast-to-void
 	CastExpr( const CodeLocation & loc, const Expr * a, GeneratedFlag g = GeneratedCast );
+
+	/// Wrap a cast expression around an existing expression (always generated)
+	CastExpr( const Expr * a, const Type * to ) : CastExpr( a->location, a, to, GeneratedCast ) {}
+
+	/// Wrap a cast-to-void expression around an existing expression (always generated)
+	CastExpr( const Expr * a ) : CastExpr( a->location, a, GeneratedCast ) {}
 
 	const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
Index: src/AST/Node.hpp
===================================================================
--- src/AST/Node.hpp	(revision 234b1cb4afd88ccf2b1f3e001a2eae5dc12ca39b)
+++ src/AST/Node.hpp	(revision b8524ca1420ff28d69347f46888a20baa805f797)
@@ -17,4 +17,5 @@
 
 #include <cassert>
+#include <cstddef>     // for nullptr_t
 #include <iosfwd>
 #include <type_traits> // for remove_reference
@@ -181,4 +182,10 @@
 	}
 
+	ptr_base & operator=( std::nullptr_t ) {
+		if ( node ) _dec(node);
+		node = nullptr;
+		return *this;
+	}
+
 	ptr_base & operator=( const ptr_base & o ) {
 		assign(o.node);
Index: src/AST/Stmt.hpp
===================================================================
--- src/AST/Stmt.hpp	(revision 234b1cb4afd88ccf2b1f3e001a2eae5dc12ca39b)
+++ src/AST/Stmt.hpp	(revision b8524ca1420ff28d69347f46888a20baa805f797)
@@ -61,6 +61,6 @@
 	CompoundStmt( CompoundStmt&& o ) = default;
 
-	void push_back( Stmt * s ) { kids.emplace_back( s ); }
-	void push_front( Stmt * s ) { kids.emplace_front( s ); }
+	void push_back( const Stmt * s ) { kids.emplace_back( s ); }
+	void push_front( const Stmt * s ) { kids.emplace_front( s ); }
 
 	const CompoundStmt * accept( Visitor & v ) const override { return v.visit( this ); }
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision 234b1cb4afd88ccf2b1f3e001a2eae5dc12ca39b)
+++ src/InitTweak/FixInit.cc	(revision b8524ca1420ff28d69347f46888a20baa805f797)
@@ -1111,5 +1111,5 @@
 						arg2 = new MemberExpr( field, new VariableExpr( params.back() ) );
 					}
-					InitExpander srcParam( arg2 );
+					InitExpander_old srcParam( arg2 );
 					// cast away reference type and construct field.
 					Expression * thisExpr = new CastExpr( new VariableExpr( thisParam ), thisParam->get_type()->stripReferences()->clone() );
Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision 234b1cb4afd88ccf2b1f3e001a2eae5dc12ca39b)
+++ src/InitTweak/GenInit.cc	(revision b8524ca1420ff28d69347f46888a20baa805f797)
@@ -18,7 +18,12 @@
 #include <algorithm>                   // for any_of
 #include <cassert>                     // for assert, strict_dynamic_cast, assertf
+#include <deque>
 #include <iterator>                    // for back_inserter, inserter, back_inse...
 #include <list>                        // for _List_iterator, list
 
+#include "AST/Decl.hpp"
+#include "AST/Init.hpp"
+#include "AST/Node.hpp"
+#include "AST/Stmt.hpp"
 #include "CodeGen/OperatorTable.h"
 #include "Common/PassVisitor.h"        // for PassVisitor, WithGuards, WithShort...
@@ -274,5 +279,5 @@
 		assertf( objDecl, "genCtorDtor passed null objDecl" );
 		std::list< Statement * > stmts;
-		InitExpander srcParam( maybeClone( arg ) );
+		InitExpander_old srcParam( maybeClone( arg ) );
 		SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), fname, back_inserter( stmts ), objDecl );
 		assert( stmts.size() <= 1 );
@@ -286,6 +291,6 @@
 		std::list< Statement * > dtor;
 
-		InitExpander srcParam( objDecl->get_init() );
-		InitExpander nullParam( (Initializer *)NULL );
+		InitExpander_old srcParam( objDecl->get_init() );
+		InitExpander_old nullParam( (Initializer *)NULL );
 		SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl );
 		SymTab::genImplicitCall( nullParam, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false );
@@ -354,8 +359,27 @@
 	}
 
-ast::ConstructorInit * genCtorInit( const ast::ObjectDecl * objDecl ) {
-	#warning unimplemented
-	(void)objDecl;
-	assert( false );
+ast::ConstructorInit * genCtorInit( const CodeLocation & loc, const ast::ObjectDecl * objDecl ) {
+	// call into genImplicitCall from Autogen.h to generate calls to ctor/dtor for each 
+	// constructable object
+	InitExpander_new srcParam{ objDecl->init }, nullParam{ (const ast::Init *)nullptr };
+	
+	ast::ptr< ast::Stmt > ctor = SymTab::genImplicitCall( 
+		srcParam, new ast::VariableExpr{ loc, objDecl }, loc, "?{}", objDecl );
+	ast::ptr< ast::Stmt > dtor = SymTab::genImplicitCall( 
+		nullParam, new ast::VariableExpr{ loc, objDecl }, loc, "^?{}", objDecl, 
+		SymTab::LoopBackward );
+	
+	// check that either both ctor and dtor are present, or neither
+	assert( (bool)ctor == (bool)dtor );
+
+	if ( ctor ) {
+		// need to remember init expression, in case no ctors exist. If ctor does exist, want to 
+		// use ctor expression instead of init.
+		ctor.strict_as< ast::ImplicitCtorDtorStmt >(); 
+		dtor.strict_as< ast::ImplicitCtorDtorStmt >();
+
+		return new ast::ConstructorInit{ loc, ctor, dtor, objDecl->init };
+	}
+
 	return nullptr;
 }
Index: src/InitTweak/GenInit.h
===================================================================
--- src/InitTweak/GenInit.h	(revision 234b1cb4afd88ccf2b1f3e001a2eae5dc12ca39b)
+++ src/InitTweak/GenInit.h	(revision b8524ca1420ff28d69347f46888a20baa805f797)
@@ -20,4 +20,5 @@
 
 #include "AST/Fwd.hpp"
+#include "Common/CodeLocation.h"
 #include "GenPoly/ScopedSet.h" // for ScopedSet
 #include "SynTree/SynTree.h"   // for Visitor Nodes
@@ -35,5 +36,5 @@
 	/// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer
 	ConstructorInit * genCtorInit( ObjectDecl * objDecl );
-	ast::ConstructorInit * genCtorInit( const ast::ObjectDecl * objDecl );
+	ast::ConstructorInit * genCtorInit( const CodeLocation & loc, const ast::ObjectDecl * objDecl );
 
 	class ManagedTypes {
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 234b1cb4afd88ccf2b1f3e001a2eae5dc12ca39b)
+++ src/InitTweak/InitTweak.cc	(revision b8524ca1420ff28d69347f46888a20baa805f797)
@@ -22,4 +22,5 @@
 
 #include "AST/Expr.hpp"
+#include "AST/Node.hpp"
 #include "AST/Stmt.hpp"
 #include "AST/Type.hpp"
@@ -112,5 +113,12 @@
 	}
 
-	class InitExpander::ExpanderImpl {
+std::vector< ast::ptr< ast::Expr > > makeInitList( const ast::Init * init ) {
+	#warning unimplmented
+	(void)init;
+	assert(false);
+	return {};
+}
+
+	class InitExpander_old::ExpanderImpl {
 	public:
 		virtual ~ExpanderImpl() = default;
@@ -119,8 +127,8 @@
 	};
 
-	class InitImpl : public InitExpander::ExpanderImpl {
+	class InitImpl_old : public InitExpander_old::ExpanderImpl {
 	public:
-		InitImpl( Initializer * init ) : init( init ) {}
-		virtual ~InitImpl() = default;
+		InitImpl_old( Initializer * init ) : init( init ) {}
+		virtual ~InitImpl_old() = default;
 
 		virtual std::list< Expression * > next( __attribute((unused)) std::list< Expression * > & indices ) {
@@ -136,8 +144,8 @@
 	};
 
-	class ExprImpl : public InitExpander::ExpanderImpl {
+	class ExprImpl_old : public InitExpander_old::ExpanderImpl {
 	public:
-		ExprImpl( Expression * expr ) : arg( expr ) {}
-		virtual ~ExprImpl() { delete arg; }
+		ExprImpl_old( Expression * expr ) : arg( expr ) {}
+		virtual ~ExprImpl_old() { delete arg; }
 
 		virtual std::list< Expression * > next( std::list< Expression * > & indices ) {
@@ -163,13 +171,13 @@
 	};
 
-	InitExpander::InitExpander( Initializer * init ) : expander( new InitImpl( init ) ) {}
-
-	InitExpander::InitExpander( Expression * expr ) : expander( new ExprImpl( expr ) ) {}
-
-	std::list< Expression * > InitExpander::operator*() {
+	InitExpander_old::InitExpander_old( Initializer * init ) : expander( new InitImpl_old( init ) ) {}
+
+	InitExpander_old::InitExpander_old( Expression * expr ) : expander( new ExprImpl_old( expr ) ) {}
+
+	std::list< Expression * > InitExpander_old::operator*() {
 		return cur;
 	}
 
-	InitExpander & InitExpander::operator++() {
+	InitExpander_old & InitExpander_old::operator++() {
 		cur = expander->next( indices );
 		return *this;
@@ -177,15 +185,15 @@
 
 	// use array indices list to build switch statement
-	void InitExpander::addArrayIndex( Expression * index, Expression * dimension ) {
+	void InitExpander_old::addArrayIndex( Expression * index, Expression * dimension ) {
 		indices.push_back( index );
 		indices.push_back( dimension );
 	}
 
-	void InitExpander::clearArrayIndices() {
+	void InitExpander_old::clearArrayIndices() {
 		deleteAll( indices );
 		indices.clear();
 	}
 
-	bool InitExpander::addReference() {
+	bool InitExpander_old::addReference() {
 		bool added = false;
 		for ( Expression *& expr : cur ) {
@@ -218,5 +226,5 @@
 
 		template< typename OutIterator >
-		void build( UntypedExpr * callExpr, InitExpander::IndexList::iterator idx, InitExpander::IndexList::iterator idxEnd, Initializer * init, OutIterator out ) {
+		void build( UntypedExpr * callExpr, InitExpander_old::IndexList::iterator idx, InitExpander_old::IndexList::iterator idxEnd, Initializer * init, OutIterator out ) {
 			if ( idx == idxEnd ) return;
 			Expression * index = *idx++;
@@ -275,5 +283,5 @@
 	// remaining elements.
 	// To accomplish this, generate switch statement, consuming all of expander's elements
-	Statement * InitImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) {
+	Statement * InitImpl_old::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) {
 		if ( ! init ) return nullptr;
 		CompoundStmt * block = new CompoundStmt();
@@ -288,11 +296,94 @@
 	}
 
-	Statement * ExprImpl::buildListInit( UntypedExpr *, std::list< Expression * > & ) {
+	Statement * ExprImpl_old::buildListInit( UntypedExpr *, std::list< Expression * > & ) {
 		return nullptr;
 	}
 
-	Statement * InitExpander::buildListInit( UntypedExpr * dst ) {
+	Statement * InitExpander_old::buildListInit( UntypedExpr * dst ) {
 		return expander->buildListInit( dst, indices );
 	}
+
+class InitExpander_new::ExpanderImpl {
+public:
+	virtual ~ExpanderImpl() = default;
+	virtual std::vector< ast::ptr< ast::Expr > > next( IndexList & indices ) = 0;
+	virtual ast::ptr< ast::Stmt > buildListInit( 
+		const ast::UntypedExpr * callExpr, IndexList & indices ) = 0;
+};
+
+namespace {
+	class InitImpl_new final : public InitExpander_new::ExpanderImpl {
+		ast::ptr< ast::Init > init;
+	public:
+		InitImpl_new( const ast::Init * i ) : init( i ) {}
+
+		std::vector< ast::ptr< ast::Expr > > next( InitExpander_new::IndexList & ) override {
+			return makeInitList( init );
+		}
+		
+		ast::ptr< ast::Stmt > buildListInit( 
+			const ast::UntypedExpr * callExpr, InitExpander_new::IndexList & indices 
+		) override {
+			#warning unimplemented
+			(void)callExpr; (void)indices;
+			assert(false);
+			return {};
+		}
+	};
+
+	class ExprImpl_new final : public InitExpander_new::ExpanderImpl {
+		ast::ptr< ast::Expr > arg;
+	public:
+		ExprImpl_new( const ast::Expr * a ) : arg( a ) {}
+
+		std::vector< ast::ptr< ast::Expr > > next( 
+			InitExpander_new::IndexList & indices 
+		) override {
+			#warning unimplemented
+			(void)indices;
+			assert(false);
+			return {};
+		}
+		
+		ast::ptr< ast::Stmt > buildListInit( 
+			const ast::UntypedExpr *, InitExpander_new::IndexList & 
+		) override { 
+			return {};
+		}
+	};
+} // anonymous namespace
+
+InitExpander_new::InitExpander_new( const ast::Init * init )
+: expander( new InitImpl_new{ init } ), crnt(), indices() {}
+
+InitExpander_new::InitExpander_new( const ast::Expr * expr )
+: expander( new ExprImpl_new{ expr } ), crnt(), indices() {}
+
+std::vector< ast::ptr< ast::Expr > > InitExpander_new::operator* () { return crnt; }
+
+InitExpander_new & InitExpander_new::operator++ () {
+	crnt = expander->next( indices );
+	return *this;
+}
+
+/// builds statement which has the same semantics as a C-style list initializer (for array 
+/// initializers) using callExpr as the base expression to perform initialization
+ast::ptr< ast::Stmt > InitExpander_new::buildListInit( const ast::UntypedExpr * callExpr ) {
+	return expander->buildListInit( callExpr, indices );
+}
+
+void InitExpander_new::addArrayIndex( const ast::Expr * index, const ast::Expr * dimension ) {
+	indices.emplace_back( index );
+	indices.emplace_back( dimension );
+}
+
+void InitExpander_new::clearArrayIndices() { indices.clear(); }
+
+bool InitExpander_new::addReference() {
+	for ( ast::ptr< ast::Expr > & expr : crnt ) {
+		expr = new ast::AddressExpr{ expr };
+	}
+	return ! crnt.empty();
+}
 
 	Type * getTypeofThis( FunctionType * ftype ) {
Index: src/InitTweak/InitTweak.h
===================================================================
--- src/InitTweak/InitTweak.h	(revision 234b1cb4afd88ccf2b1f3e001a2eae5dc12ca39b)
+++ src/InitTweak/InitTweak.h	(revision b8524ca1420ff28d69347f46888a20baa805f797)
@@ -44,4 +44,5 @@
 	/// transform Initializer into an argument list that can be passed to a call expression
 	std::list< Expression * > makeInitList( Initializer * init );
+	std::vector< ast::ptr< ast::Expr > > makeInitList( const ast::Init * init );
 
 	/// True if the resolver should try to construct dwt
@@ -101,15 +102,15 @@
 	bool isConstExpr( Initializer * init );
 
-	class InitExpander {
+	class InitExpander_old {
 	public:
 		// expand by stepping through init to get each list of arguments
-		InitExpander( Initializer * init );
+		InitExpander_old( Initializer * init );
 
 		// always expand to expr
-		InitExpander( Expression * expr );
+		InitExpander_old( Expression * expr );
 
 		// iterator-like interface
 		std::list< Expression * > operator*();
-		InitExpander & operator++();
+		InitExpander_old & operator++();
 
 		// builds statement which has the same semantics as a C-style list initializer
@@ -130,4 +131,36 @@
 		IndexList indices;
 	};
+
+	class InitExpander_new {
+	public:
+		using IndexList = std::vector< ast::ptr< ast::Expr > >;
+		class ExpanderImpl;
+
+	private:
+		std::shared_ptr< ExpanderImpl > expander;
+		std::vector< ast::ptr< ast::Expr > > crnt;
+		// invariant: list of size 2N (elements come in pairs [index, dimension])
+		IndexList indices;
+
+	public:
+		/// Expand by stepping through init to get each list of arguments
+		InitExpander_new( const ast::Init * init );
+
+		/// Always expand to expression
+		InitExpander_new( const ast::Expr * expr );
+
+		std::vector< ast::ptr< ast::Expr > > operator* ();
+		InitExpander_new & operator++ ();
+
+		/// builds statement which has the same semantics as a C-style list initializer (for array 
+		/// initializers) using callExpr as the base expression to perform initialization
+		ast::ptr< ast::Stmt > buildListInit( const ast::UntypedExpr * callExpr );
+
+		void addArrayIndex( const ast::Expr * index, const ast::Expr * dimension );
+
+		void clearArrayIndices();
+
+		bool addReference();
+	};
 } // namespace
 
Index: src/ResolvExpr/CandidateFinder.cpp
===================================================================
--- src/ResolvExpr/CandidateFinder.cpp	(revision 234b1cb4afd88ccf2b1f3e001a2eae5dc12ca39b)
+++ src/ResolvExpr/CandidateFinder.cpp	(revision b8524ca1420ff28d69347f46888a20baa805f797)
@@ -57,5 +57,5 @@
 		// cast away reference from expr
 		cost.incReference();
-		return new ast::CastExpr{ expr->location, expr, expr->result->stripReferences() };
+		return new ast::CastExpr{ expr, expr->result->stripReferences() };
 	}
 	
@@ -126,5 +126,5 @@
 			ast::ptr< ast::Type > newType = paramType;
 			env.apply( newType );
-			return new ast::CastExpr{ arg->location, arg, newType };
+			return new ast::CastExpr{ arg, newType };
 
 			// xxx - *should* be able to resolve this cast, but at the moment pointers are not 
@@ -793,6 +793,5 @@
 			
 			if ( aggrType.as< ast::ReferenceType >() ) {
-				aggrExpr = 
-					new ast::CastExpr{ aggrExpr->location, aggrExpr, aggrType->stripReferences() };
+				aggrExpr = new ast::CastExpr{ aggrExpr, aggrType->stripReferences() };
 			}
 
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 234b1cb4afd88ccf2b1f3e001a2eae5dc12ca39b)
+++ src/ResolvExpr/Resolver.cc	(revision b8524ca1420ff28d69347f46888a20baa805f797)
@@ -1109,5 +1109,5 @@
 		
 		// set up and resolve expression cast to void
-		ast::CastExpr * untyped = new ast::CastExpr{ expr->location, expr };
+		ast::CastExpr * untyped = new ast::CastExpr{ expr };
 		CandidateRef choice = findUnfinishedKindExpression( 
 			untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() );
@@ -1161,5 +1161,5 @@
 		) {
 			assert( untyped && type );
-			ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped->location, untyped, type };
+			ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped, type };
 			ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, symtab );
 			removeExtraneousCast( newExpr, symtab );
Index: src/SymTab/Autogen.cc
===================================================================
--- src/SymTab/Autogen.cc	(revision 234b1cb4afd88ccf2b1f3e001a2eae5dc12ca39b)
+++ src/SymTab/Autogen.cc	(revision b8524ca1420ff28d69347f46888a20baa805f797)
@@ -24,4 +24,5 @@
 #include <vector>                  // for vector
 
+#include "AST/Decl.hpp"
 #include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign
 #include "Common/PassVisitor.h"    // for PassVisitor
@@ -209,4 +210,8 @@
 	}
 
+	bool isUnnamedBitfield( const ast::ObjectDecl * obj ) {
+		return obj && obj->name.empty() && obj->bitfieldWidth;
+	}
+
 	/// inserts a forward declaration for functionDecl into declsToAdd
 	void addForwardDecl( FunctionDecl * functionDecl, std::list< Declaration * > & declsToAdd ) {
@@ -388,5 +393,5 @@
 
 	void StructFuncGenerator::makeMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool forward ) {
-		InitTweak::InitExpander srcParam( src );
+		InitTweak::InitExpander_old srcParam( src );
 
 		// assign to destination
Index: src/SymTab/Autogen.h
===================================================================
--- src/SymTab/Autogen.h	(revision 234b1cb4afd88ccf2b1f3e001a2eae5dc12ca39b)
+++ src/SymTab/Autogen.h	(revision b8524ca1420ff28d69347f46888a20baa805f797)
@@ -17,8 +17,16 @@
 
 #include <cassert>                // for assert
+#include <iterator>               // for back_inserter
 #include <string>                 // for string
 
+#include "AST/Decl.hpp"
+#include "AST/Expr.hpp"
+#include "AST/Init.hpp"
+#include "AST/Node.hpp"
+#include "AST/Stmt.hpp"
+#include "AST/Type.hpp"
 #include "CodeGen/OperatorTable.h"
 #include "Common/UniqueName.h"    // for UniqueName
+#include "Common/utility.h"       // for splice
 #include "InitTweak/InitTweak.h"  // for InitExpander
 #include "SynTree/Constant.h"     // for Constant
@@ -36,4 +44,5 @@
 	/// returns true if obj's name is the empty string and it has a bitfield width
 	bool isUnnamedBitfield( ObjectDecl * obj );
+	bool isUnnamedBitfield( const ast::ObjectDecl * obj );
 
 	/// generate the type of an assignment function for paramType.
@@ -49,12 +58,21 @@
 	FunctionType * genCopyType( Type * paramType, bool maybePolymorphic = true );
 
+	/// Enum for loop direction
+	enum LoopDirection { LoopBackward, LoopForward };
+
 	/// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls.
 	template< typename OutputIterator >
-	Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast = nullptr, bool forward = true );
+	Statement * genCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast = nullptr, bool forward = true );
+
+	template< typename OutIter >
+	ast::ptr< ast::Stmt > genCall(
+		InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 
+		const CodeLocation & loc, const std::string & fname, OutIter && out, 
+		const ast::Type * type, const ast::Type * addCast, LoopDirection forward = LoopForward );
 
 	/// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types.
 	/// optionally returns a statement which must be inserted prior to the containing loop, if there is one
 	template< typename OutputIterator >
-	Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, Type * addCast = nullptr ) {
+	Statement * genScalarCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, Type * addCast = nullptr ) {
 		bool isReferenceCtorDtor = false;
 		if ( dynamic_cast< ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) {
@@ -106,8 +124,65 @@
 	}
 
+	/// inserts into out a generated call expression to function fname with arguments dstParam and 
+	/// srcParam. Should only be called with non-array types.
+	/// optionally returns a statement which must be inserted prior to the containing loop, if 
+	/// there is one
+	template< typename OutIter >
+	ast::ptr< ast::Stmt > genScalarCall( 
+		InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 
+		const CodeLocation & loc, std::string fname, OutIter && out, const ast::Type * type, 
+		const ast::Type * addCast = nullptr
+	) {
+		bool isReferenceCtorDtor = false;
+		if ( dynamic_cast< const ast::ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) {
+			// reference constructors are essentially application of the rebind operator.
+			// apply & to both arguments, do not need a cast
+			fname = "?=?";
+			dstParam = new ast::AddressExpr{ dstParam };
+			addCast = nullptr;
+			isReferenceCtorDtor = true;
+		}
+
+		// want to be able to generate assignment, ctor, and dtor generically, so fname is one of
+		// "?=?", "?{}", or "^?{}"
+		ast::UntypedExpr * fExpr = new ast::UntypedExpr{ loc, new ast::NameExpr{ loc, fname } };
+
+		if ( addCast ) {
+			// cast to T& with qualifiers removed, so that qualified objects can be constructed and 
+			// destructed with the same functions as non-qualified objects. Unfortunately, lvalue 
+			// is considered a qualifier - for AddressExpr to resolve, its argument must have an 
+			// lvalue-qualified type, so remove all qualifiers except lvalue.
+			// xxx -- old code actually removed lvalue too...
+			ast::ptr< ast::Type > guard = addCast;  // prevent castType from mutating addCast
+			ast::ptr< ast::Type > castType = addCast;
+			ast::remove_qualifiers( 
+				castType, 
+				ast::CV::Const | ast::CV::Volatile | ast::CV::Restrict | ast::CV::Atomic );
+			dstParam = new ast::CastExpr{ dstParam, new ast::ReferenceType{ castType } };
+		}
+		fExpr->args.emplace_back( dstParam );
+
+		const ast::Stmt * listInit = srcParam.buildListInit( fExpr );
+
+		// fetch next set of arguments
+		++srcParam;
+
+		// return if adding reference fails -- will happen on default ctor and dtor
+		if ( isReferenceCtorDtor && ! srcParam.addReference() ) return listInit;
+
+		std::vector< ast::ptr< ast::Expr > > args = *srcParam;
+		splice( fExpr->args, args );
+
+		*out++ = new ast::ExprStmt{ loc, fExpr };
+
+		srcParam.clearArrayIndices();
+		
+		return listInit;
+	}
+
 	/// 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 genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, Type * addCast = nullptr, bool forward = true ) {
+	void genArrayCall( InitTweak::InitExpander_old & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, Type * addCast = nullptr, bool forward = true ) {
 		static UniqueName indexName( "_index" );
 
@@ -170,6 +245,76 @@
 	}
 
+	/// 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 OutIter >
+	void genArrayCall(
+		InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 
+		const CodeLocation & loc, const std::string & fname, OutIter && out, 
+		const ast::ArrayType * array, const ast::Type * addCast = nullptr, 
+		LoopDirection forward = LoopForward 
+	) {
+		static UniqueName indexName( "_index" );
+
+		// for a flexible array member nothing is done -- user must define own assignment
+		if ( ! array->dimension ) return;
+
+		if ( addCast ) {
+			// peel off array layer from cast
+			addCast = strict_dynamic_cast< const ast::ArrayType * >( addCast )->base;
+		}
+
+		ast::ptr< ast::Expr > begin, end, cmp, update;
+
+		if ( forward ) {
+			// generate: for ( int i = 0; i < N; ++i )
+			begin = ast::ConstantExpr::from_int( loc, 0 );
+			end = array->dimension;
+			cmp = new ast::NameExpr{ loc, "?<?" };
+			update = new ast::NameExpr{ loc, "++?" };
+		} else {
+			// generate: for ( int i = N-1; i >= 0; --i )
+			begin = new ast::UntypedExpr{ 
+				loc, new ast::NameExpr{ loc, "?-?" }, 
+				{ array->dimension, ast::ConstantExpr::from_int( loc, 1 ) } };
+			end = ast::ConstantExpr::from_int( loc, 0 );
+			cmp = new ast::NameExpr{ loc, "?>=?" };
+			update = new ast::NameExpr{ loc, "--?" };
+		}
+
+		ast::ptr< ast::DeclWithType > index = new ast::ObjectDecl{ 
+			loc, indexName.newName(), new ast::BasicType{ ast::BasicType::SignedInt }, 
+			new ast::SingleInit{ loc, begin } };
+		
+		ast::ptr< ast::Expr > cond = new ast::UntypedExpr{
+			loc, cmp, { new ast::VariableExpr{ loc, index }, end } };
+		
+		ast::ptr< ast::Expr > inc = new ast::UntypedExpr{
+			loc, update, { new ast::VariableExpr{ loc, index } } };
+		
+		ast::ptr< ast::Expr > dstIndex = new ast::UntypedExpr{
+			loc, new ast::NameExpr{ loc, "?[?]" }, 
+			{ dstParam, new ast::VariableExpr{ loc, index } } };
+		
+		// srcParam must keep track of the array indices to build the source parameter and/or 
+		// array list initializer
+		srcParam.addArrayIndex( new ast::VariableExpr{ loc, index }, array->dimension );
+
+		// for stmt's body, eventually containing call
+		ast::CompoundStmt * body = new ast::CompoundStmt{ loc };
+		ast::ptr< ast::Stmt > listInit = genCall( 
+			srcParam, dstIndex, loc, fname, std::back_inserter( body->kids ), array->base, addCast, 
+			forward );
+		
+		// block containing the stmt and index variable
+		ast::CompoundStmt * block = new ast::CompoundStmt{ loc };
+		block->push_back( new ast::DeclStmt{ loc, index } );
+		if ( listInit ) { block->push_back( listInit ); }
+		block->push_back( new ast::ForStmt{ loc, {}, cond, inc, body } );
+
+		*out++ = block;
+	}
+
 	template< typename OutputIterator >
-	Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast, bool forward ) {
+	Statement * genCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast, bool forward ) {
 		if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
 			genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward );
@@ -180,4 +325,21 @@
 	}
 
+	template< typename OutIter >
+	ast::ptr< ast::Stmt > genCall(
+		InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 
+		const CodeLocation & loc, const std::string & fname, OutIter && out, 
+		const ast::Type * type, const ast::Type * addCast, LoopDirection forward
+	) {
+		if ( auto at = dynamic_cast< const ast::ArrayType * >( type ) ) {
+			genArrayCall( 
+				srcParam, dstParam, loc, fname, std::forward< OutIter >(out), at, addCast, 
+				forward );
+			return {};
+		} else {
+			return genScalarCall( 
+				srcParam, dstParam, loc, fname, std::forward< OutIter >( out ), type, addCast );
+		}
+	}
+
 	/// inserts into out a generated call expression to function fname with arguments dstParam
 	/// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the
@@ -185,5 +347,5 @@
 	/// ImplicitCtorDtorStmt node.
 	template< typename OutputIterator >
-	void genImplicitCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
+	void genImplicitCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
 		ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );
 		assert( obj );
@@ -213,4 +375,38 @@
 		}
 	}
+
+	static inline ast::ptr< ast::Stmt > genImplicitCall( 
+		InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 
+		const CodeLocation & loc, const std::string & fname, const ast::ObjectDecl * obj, 
+		LoopDirection forward = LoopForward 
+	) {
+		// unnamed bit fields are not copied as they cannot be accessed
+		if ( isUnnamedBitfield( obj ) ) return {};
+
+		ast::ptr< ast::Type > addCast = nullptr;
+		if ( (fname == "?{}" || fname == "^?{}") && ( ! obj || ( obj && ! obj->bitfieldWidth ) ) ) {
+			assert( dstParam->result );
+			addCast = dstParam->result;
+		}
+
+		std::vector< ast::ptr< ast::Stmt > > stmts;
+		genCall( 
+			srcParam, dstParam, loc, fname, back_inserter( stmts ), obj->type, addCast, forward );
+
+		if ( stmts.empty() ) {
+			return {};
+		} else if ( stmts.size() == 1 ) {
+			const ast::Stmt * callStmt = stmts.front();
+			if ( addCast ) {
+				// implicitly generated ctor/dtor calls should be wrapped so that later passes are 
+				// aware they were generated.
+				callStmt = new ast::ImplicitCtorDtorStmt{ callStmt->location, callStmt };
+			}
+			return callStmt;
+		} else {
+			assert( false );
+			return {};
+		}
+	}
 } // namespace SymTab
 
Index: src/Tuples/Explode.cc
===================================================================
--- src/Tuples/Explode.cc	(revision 234b1cb4afd88ccf2b1f3e001a2eae5dc12ca39b)
+++ src/Tuples/Explode.cc	(revision b8524ca1420ff28d69347f46888a20baa805f797)
@@ -133,8 +133,7 @@
 			if ( first ) {
 				castAdded = true;
-				const ast::Expr * tuple = new ast::TupleExpr(
-					tupleExpr->location, std::move( exprs ) );
-				return new ast::CastExpr( tuple->location,
-					tuple, new ast::ReferenceType( tuple->result.get(), ast::CV::Qualifiers() ) );
+				const ast::Expr * tuple = new ast::TupleExpr{
+					tupleExpr->location, std::move( exprs ) };
+				return new ast::CastExpr{ tuple, new ast::ReferenceType{ tuple->result } };
 			} else {
 				return new ast::TupleExpr( tupleExpr->location, std::move( exprs ) );
@@ -145,6 +144,5 @@
 		} else {
 			castAdded = true;
-			return new ast::CastExpr( expr->location, expr,
-				new ast::ReferenceType( expr->result, ast::CV::Qualifiers() ) );
+			return new ast::CastExpr{ expr, new ast::ReferenceType{ expr->result } };
 		}
 	}
@@ -164,5 +162,5 @@
 			castAdded = false;
 			const ast::Type * newType = getReferenceBase( newNode->result );
-			return new ast::CastExpr( newNode->location, node, newType );
+			return new ast::CastExpr{ newNode->location, node, newType };
 		}
 		return newNode;
@@ -183,6 +181,5 @@
 	expr = expr->accept( exploder );
 	if ( ! exploder.pass.foundUniqueExpr ) {
-		expr = new ast::CastExpr( expr->location, expr,
-			new ast::ReferenceType( expr->result, ast::CV::Qualifiers() ) );
+		expr = new ast::CastExpr{ expr, new ast::ReferenceType{ expr->result } };
 	}
 	return expr;
Index: src/Tuples/Explode.h
===================================================================
--- src/Tuples/Explode.h	(revision 234b1cb4afd88ccf2b1f3e001a2eae5dc12ca39b)
+++ src/Tuples/Explode.h	(revision b8524ca1420ff28d69347f46888a20baa805f797)
@@ -211,5 +211,5 @@
 			// Cast a reference away to a value-type to allow further explosion.
 			if ( dynamic_cast< const ast::ReferenceType *>( local->result.get() ) ) {
-				local = new ast::CastExpr( local->location, local, tupleType );
+				local = new ast::CastExpr{ local, tupleType };
 			}
 			// Now we have to go across the tuple via indexing.
Index: src/Tuples/TupleAssignment.cc
===================================================================
--- src/Tuples/TupleAssignment.cc	(revision 234b1cb4afd88ccf2b1f3e001a2eae5dc12ca39b)
+++ src/Tuples/TupleAssignment.cc	(revision b8524ca1420ff28d69347f46888a20baa805f797)
@@ -464,5 +464,5 @@
 					// resolve ctor/dtor for the new object
 					ast::ptr< ast::Init > ctorInit = ResolvExpr::resolveCtorInit( 
-							InitTweak::genCtorInit( ret ), spotter.crntFinder.symtab );
+							InitTweak::genCtorInit( location, ret ), spotter.crntFinder.symtab );
 					// remove environments from subexpressions of stmtExpr
 					ast::Pass< EnvRemover > rm{ env };
@@ -550,6 +550,5 @@
 					// is && and RHS is lvalue
 					auto lhsType = lhsCand->expr->result.strict_as< ast::ReferenceType >();
-					rhsCand->expr = new ast::CastExpr{ 
-						rhsCand->expr->location, rhsCand->expr, lhsType->base };
+					rhsCand->expr = new ast::CastExpr{ rhsCand->expr, lhsType->base };
 					ast::ptr< ast::ObjectDecl > lobj = newObject( lhsNamer, lhsCand->expr );
 					ast::ptr< ast::ObjectDecl > robj = newObject( rhsNamer, rhsCand->expr );
@@ -604,6 +603,5 @@
 					if ( ! lhsCand->expr.as< ast::CastExpr >() ) {
 						lhsCand->expr = new ast::CastExpr{ 
-							lhsCand->expr->location, lhsCand->expr, 
-							new ast::ReferenceType{ lhsCand->expr->result } };
+							lhsCand->expr, new ast::ReferenceType{ lhsCand->expr->result } };
 					}
 
@@ -616,6 +614,5 @@
 						if ( ! cand->expr->result.as< ast::ReferenceType >() ) {
 							cand->expr = new ast::CastExpr{
-								cand->expr->location, cand->expr, 
-								new ast::ReferenceType{ cand->expr->result } };
+								cand->expr, new ast::ReferenceType{ cand->expr->result } };
 						}
 					}
