Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision 956a9c7709f7a1b604cbdfecffd5ca5b7f25c383)
+++ src/InitTweak/GenInit.cc	(revision 2be10237217d3203f88d37d1da72d6ec3736ab71)
@@ -145,5 +145,7 @@
 				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
+					// TODO: walk initializers and generate appropriate ctor if element has initializer.
+					// Initializer could be nested (depends on the depth of the array type on the object)
+
 					std::list< Expression * > args = makeInitList( objDecl->get_init() );
 					if ( args.empty() ) {
@@ -151,8 +153,8 @@
 						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
+						SymTab::genImplicitCall( NULL, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl );
+						SymTab::genImplicitCall( NULL, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false );
+
+						// Currently genArrayCall 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
@@ -160,5 +162,5 @@
 						// 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
+						// but it seems reasonable at the moment for this to be done by genArrayCall
 						// itself
 						assert( ctor.size() == 1 && dynamic_cast< ImplicitCtorDtorStmt * >( ctor.front() ) );
@@ -170,7 +172,8 @@
 						// we haven't exceeded size. This requires precomputing the size because it might be a side-effecting
 						// computation.
-						// may have fewer initializers than eleemnts in the array - need to default construct
+						// may have fewer initializers than elements in the array - need to default construct
 						// remaining elements.
 						// might be able to merge this with the case above.
+
 					}
 				} else {
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 956a9c7709f7a1b604cbdfecffd5ca5b7f25c383)
+++ src/ResolvExpr/Resolver.cc	(revision 2be10237217d3203f88d37d1da72d6ec3736ab71)
@@ -537,24 +537,25 @@
 		assert( callExpr );
 		Expression *& constructee = InitTweak::getCallArg( callExpr, 0 );
-		Type * type = 0;
-
-		// need to find the type of the first argument, which is unfortunately not uniform since array construction
-		// includes an untyped '+' expression.
-		if ( UntypedExpr * plusExpr = dynamic_cast< UntypedExpr * >( constructee ) ) {
-			// constructee is <array>+<index>
-			// get Variable <array>, then get the base type of the VariableExpr - this is the type that needs to be fixed
-			Expression * arr = InitTweak::getCallArg( plusExpr, 0 );
-			assert( dynamic_cast< VariableExpr * >( arr ) || dynamic_cast< MemberExpr *>( arr ) );
-			assert( arr && arr->get_results().size() == 1 );
-			type = arr->get_results().front()->clone();
-		} else {
-			// otherwise, constructing a plain object, which means the object's address is being taken.
-			// Need to get the type of the VariableExpr object, because the AddressExpr is rebuilt and uses the
-			// type of the VariableExpr to do so.
-			assert( constructee->get_results().size() == 1 );
-			AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee );
-			assert( addrExpr && addrExpr->get_results().size() == 1 );
-			type = addrExpr->get_results().front()->clone();
-		}
+
+		// the first argument will always be &<expr>
+		AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee );
+		assert( addrExpr );
+
+		// need to find the type of the first argument. In the case of an array,
+		// need to remove one ArrayType layer from the type for each subscript expression.
+		Expression * addressee = addrExpr->get_arg();
+		int numLayers = 0;
+		while ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * >( addressee ) ) {
+			assert( InitTweak::getFunctionName( untypedExpr ) == "?[?]" );
+			addressee = InitTweak::getCallArg( untypedExpr, 0 );
+			numLayers++;
+		}
+		assert( addressee->get_results().size() == 1 );
+		Type * type = addressee->get_results().front();
+		for ( int i = 0; i < numLayers; i++ ) {
+			type = InitTweak::getPointerBase( type );
+			assert( type && "Expected pointer or array type. May have generated too many ?[?] calls." );
+		}
+
 		// cast to T* with qualifiers removed.
 		// unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
@@ -562,9 +563,8 @@
 		// remove lvalue as a qualifier, this can change to
 		//   type->get_qualifiers() = Type::Qualifiers();
-		Type * base = InitTweak::getPointerBase( type );
-		assert( base );
-		base->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true);
-		// if pointer has lvalue qualifier, cast won't appear in output
-		type->set_isLvalue( false );
+		assert( type );
+		type = type->clone();
+		type->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true);
+		type = new PointerType( Type::Qualifiers(), type );
 		constructee = new CastExpr( constructee, type );
 
Index: src/SymTab/Autogen.cc
===================================================================
--- src/SymTab/Autogen.cc	(revision 956a9c7709f7a1b604cbdfecffd5ca5b7f25c383)
+++ src/SymTab/Autogen.cc	(revision 2be10237217d3203f88d37d1da72d6ec3736ab71)
@@ -62,36 +62,4 @@
 
 	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 ( isUnnamedBitfield( obj ) ) 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 );
-		}
-
-		Statement * callStmt = new ExprStmt( noLabels, fExpr );
-		if ( (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) ) ) {
-			// implicitly generated ctor/dtor calls should be wrapped
-			// so that later passes are aware they were generated.
-			// xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,
-			// because this causes the address to be taken at codegen, which is illegal in C.
-			callStmt = new ImplicitCtorDtorStmt( callStmt );
-		}
-		*out++ = callStmt;
-	}
-
-	template< typename OutputIterator >
 	void makeUnionFieldsAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, UnionInstType *unionType, OutputIterator out ) {
 		UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
@@ -220,20 +188,14 @@
 
 		// 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() ) );
+		UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
+		derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
+		Expression *dstselect = new MemberExpr( field, derefExpr );
+		genImplicitCall( src, dstselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
+
+		if ( isGeneric && returnVal ) {
+			UntypedExpr *derefRet = new UntypedExpr( new NameExpr( "*?" ) );
+			derefRet->get_args().push_back( new VariableExpr( returnVal ) );
+			Expression *retselect = new MemberExpr( field, derefRet );
+			genImplicitCall( src, retselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
 		} // if
 	}
Index: src/SymTab/Autogen.h
===================================================================
--- src/SymTab/Autogen.h	(revision 956a9c7709f7a1b604cbdfecffd5ca5b7f25c383)
+++ src/SymTab/Autogen.h	(revision 2be10237217d3203f88d37d1da72d6ec3736ab71)
@@ -24,80 +24,132 @@
 
 namespace SymTab {
-  /// Generates assignment operators, constructors, and destructor for aggregate types as required
-  void autogenerateRoutines( std::list< Declaration * > &translationUnit );
+	/// 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
+	/// returns true if obj's name is the empty string and it has a bitfield width
+	bool isUnnamedBitfield( ObjectDecl * obj );
 
-  /// 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" );
+	/// 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 >
+	void genCall( Expression * srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool forward = true );
 
-    // for a flexible array member nothing is done -- user must define own assignment
-    if ( ! array->get_dimension() ) return;
+	/// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types.
+	template< typename OutputIterator >
+	void genScalarCall( Expression *srcParam, Expression *dstParam, const std::string & fname, OutputIterator out ) {
+		// want to be able to generate assignment, ctor, and dtor generically,
+		// so fname is either ?=?, ?{}, or ^?{}
+		UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
 
-    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( "--?" );
-    }
+		// do something special for unnamed members
+		fExpr->get_args().push_back( new AddressExpr( dstParam ) );
 
-    ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), NULL );
+		if ( srcParam ) {
+			fExpr->get_args().push_back( srcParam );
+		}
 
-    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*>() ) );
+		*out++ = new ExprStmt( noLabels, fExpr );
+	}
 
-    UntypedExpr *cond = new UntypedExpr( cmp );
-    cond->get_args().push_back( new VariableExpr( index ) );
-    cond->get_args().push_back( end );
+	/// 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( Expression *srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool forward = true ) {
+		static UniqueName indexName( "_index" );
 
-    UntypedExpr *inc = new UntypedExpr( update );
-    inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
+		// for a flexible array member nothing is done -- user must define own assignment
+		if ( ! array->get_dimension() ) return ;
 
-    // want to be able to generate assignment, ctor, and dtor generically,
-    // so fname is either ?=?, ?{}, or ^?{}
-    UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
+		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( "--?" );
+		}
 
-    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 );
+		ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), NULL );
 
-    // 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 );
-    }
+		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*>() ) );
 
-    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 ) ) );
+		UntypedExpr *cond = new UntypedExpr( cmp );
+		cond->get_args().push_back( new VariableExpr( index ) );
+		cond->get_args().push_back( end );
 
-    Statement * stmt = block;
-    if ( fname == "?{}" || fname == "^?{}" ) {
-      // implicitly generated ctor/dtor calls should be wrapped
-      // so that later passes are aware they were generated
-      stmt = new ImplicitCtorDtorStmt( stmt );
-    }
-    *out++ = stmt;
-  }
+		UntypedExpr *inc = new UntypedExpr( update );
+		inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
+
+		UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
+		dstIndex->get_args().push_back( dstParam );
+		dstIndex->get_args().push_back( new VariableExpr( index ) );
+		dstParam = 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 ) );
+			srcParam = srcIndex;
+		}
+
+		// for stmt's body, eventually containing call
+		CompoundStmt * body = new CompoundStmt( noLabels );
+		genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), forward );
+
+		// block containing for stmt and index variable
+		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, body ) );
+
+		*out++ = block;
+	}
+
+	template< typename OutputIterator >
+	void genCall( Expression * srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool forward ) {
+		if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
+			genArrayCall( srcParam, dstParam, fname, out, at, forward );
+		} else {
+			genScalarCall( srcParam, dstParam, fname, out );
+		}
+	}
+
+	/// 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
+	/// object being constructed. The function wraps constructor and destructor calls in an
+	/// ImplicitCtorDtorStmt node.
+	template< typename OutputIterator >
+	void genImplicitCall( Expression * srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
+		ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );
+		assert( obj );
+		// unnamed bit fields are not copied as they cannot be accessed
+		if ( isUnnamedBitfield( obj ) ) return;
+
+		std::list< Statement * > stmts;
+		genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), forward );
+
+		// currently genCall should produce only one element, but if that changes then the next line needs to be updated to grab the statement which contains the call
+		assert( stmts.size() == 1 );
+		Statement * callStmt = stmts.front();
+		if ( (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) ) ) {
+			// implicitly generated ctor/dtor calls should be wrapped
+			// so that later passes are aware they were generated.
+			// xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,
+			// because this causes the address to be taken at codegen, which is illegal in C.
+			callStmt = new ImplicitCtorDtorStmt( callStmt );
+		}
+		*out++ = callStmt;
+	}
 } // namespace SymTab
 #endif // AUTOGEN_H
