Index: src/ResolvExpr/CurrentObject.cc
===================================================================
--- src/ResolvExpr/CurrentObject.cc	(revision 60aaa51d44506578dbfd9b89b996a9ca2a971c8a)
+++ src/ResolvExpr/CurrentObject.cc	(revision 2d11663e05da9b5f76704ffe64a5b46d0ec78c1a)
@@ -946,5 +946,78 @@
 	}
 
-	void CurrentObject::setNext( const ast::Designation * designation ) {
+	const Designation * CurrentObject::findNext( const Designation * designation ) {
+		using DesignatorChain = std::deque< ptr< Expr > >;
+		PRINT( std::cerr << "___findNext" << std::endl; )
+		
+		// find all the d's
+		std::vector< DesignatorChain > desigAlts{ {} }, newDesigAlts;
+		std::deque< const Type * > curTypes{ objStack.back()->getType() }, newTypes;
+		for ( const Expr * expr : designation->designators ) {
+			PRINT( std::cerr << "____untyped: " << expr << std::endl; )
+			auto dit = desigAlts.begin();
+			if ( auto nexpr = dynamic_cast< const NameExpr * >( expr ) ) {
+				for ( const Type * t : curTypes ) {
+					assert( dit != desigAlts.end() );
+
+					DesignatorChain & d = *dit;
+					PRINT( std::cerr << "____actual: " << t << std::endl; )
+					if ( auto refType = dynamic_cast< const ReferenceToType * >( t ) ) {
+						// concatenate identical field names
+						for ( const Decl * mem : refType->lookup( nexpr->name ) ) {
+							if ( auto field = dynamic_cast< const ObjectDecl * >( mem ) ) {
+								PRINT( std::cerr << "____alt: " << field->type << std::endl; )
+								DesignatorChain d2 = d;
+								d2.emplace_back( new VariableExpr{ expr->location, field } );
+								newDesigAlts.emplace_back( std::move( d2 ) );
+								newTypes.emplace_back( field->type );
+							}
+						}
+					}
+
+					++dit;
+				}
+			} else {
+				for ( const Type * t : curTypes ) {
+					assert( dit != desigAlts.end() );
+
+					DesignatorChain & d = *dit;
+					if ( auto at = dynamic_cast< const ArrayType * >( t ) ) {
+						PRINT( std::cerr << "____alt: " << at->get_base() << std::endl; )
+						d.emplace_back( expr );
+						newDesigAlts.emplace_back( d );
+						newTypes.emplace_back( at->base );
+					}
+				}
+			}
+
+			// reset queue
+			desigAlts = std::move( newDesigAlts );
+			newDesigAlts.clear();
+			curTypes = std::move( newTypes );
+			newTypes.clear();
+			assertf( desigAlts.size() == curTypes.size(), "Designator alternatives (%zu) and current types (%zu) out of sync", desigAlts.size(), curTypes.size() );
+		}
+
+		if ( desigAlts.size() > 1 ) {
+			SemanticError( designation, toString("Too many alternatives (", desigAlts.size(), ") for designation: ") );
+		} else if ( desigAlts.empty() ) {
+			SemanticError( designation, "No reasonable alternatives for designation: " );
+		}
+
+		DesignatorChain & d = desigAlts.back();
+		PRINT( for ( Expression * expr : d ) {
+			std::cerr << "____desig: " << expr << std::endl;
+		} ) // for
+		assertf( ! curTypes.empty(), "empty designator chosen");
+
+		// set new designators
+		assertf( ! objStack.empty(), "empty object stack when setting designation" );
+		Designation * actualDesignation = 
+			new Designation{ designation->location, DesignatorChain{d} };
+		objStack.back()->setPosition( d ); // destroys d
+		return actualDesignation;
+	}
+
+	void CurrentObject::setNext( const Designation * designation ) {
 		PRINT( std::cerr << "____setNext" << designation << std::endl; )
 		assertf( ! objStack.empty(), "obj stack empty in setNext" );
Index: src/ResolvExpr/CurrentObject.h
===================================================================
--- src/ResolvExpr/CurrentObject.h	(revision 60aaa51d44506578dbfd9b89b996a9ca2a971c8a)
+++ src/ResolvExpr/CurrentObject.h	(revision 2d11663e05da9b5f76704ffe64a5b46d0ec78c1a)
@@ -111,4 +111,6 @@
 		CurrentObject( const CodeLocation & loc, const Type * type );
 
+		/// resolves unresolved designation
+		const Designation * findNext( const Designation * designation );
 		/// sets current position using the resolved designation
 		void setNext( const ast::Designation * designation );
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 60aaa51d44506578dbfd9b89b996a9ca2a971c8a)
+++ src/ResolvExpr/Resolver.cc	(revision 2d11663e05da9b5f76704ffe64a5b46d0ec78c1a)
@@ -1227,7 +1227,7 @@
 		void previsit( const ast::WaitForStmt * );
 
-		const ast::SingleInit * previsit( const ast::SingleInit * );
-		const ast::ListInit * previsit( const ast::ListInit * );
-		void previsit( const ast::ConstructorInit * );
+		const ast::SingleInit *      previsit( const ast::SingleInit * );
+		const ast::ListInit *        previsit( const ast::ListInit * );
+		const ast::ConstructorInit * previsit( const ast::ConstructorInit * );
 	};
 
@@ -1510,7 +1510,14 @@
 			// iterate designations and initializers in pairs, moving the cursor to the current 
 			// designated object and resolving the initializer against that object
-			#warning unimplemented; Resolver port in progress
-			assert(false);
-		}
+			listInit = ast::mutate_field_index(
+				listInit, &ast::ListInit::designations, i, 
+				currentObject.findNext( listInit->designations[i] ) );
+			listInit = ast::mutate_field_index(
+				listInit, &ast::ListInit::initializers, i,
+				listInit->initializers[i]->accept( *visitor ) );
+		}
+
+		// move cursor out of brace-enclosed initializer-list
+		currentObject.exitListInit();
 
 		visit_children = false;
@@ -1518,8 +1525,23 @@
 	}
 
-	void Resolver_new::previsit( const ast::ConstructorInit * ctorInit ) {
-		#warning unimplemented; Resolver port in progress
-		(void)ctorInit;
-		assert(false);
+	const ast::ConstructorInit * Resolver_new::previsit( const ast::ConstructorInit * ctorInit ) {
+		visitor->maybe_accept( ctorInit, &ast::ConstructorInit::ctor );
+		visitor->maybe_accept( ctorInit, &ast::ConstructorInit::dtor );
+
+		// found a constructor - can get rid of C-style initializer
+		// xxx - Rob suggests this field is dead code
+		ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::init, nullptr );
+
+		// intrinsic single-parameter constructors and destructors do nothing. Since this was 
+		// implicitly generated, there's no way for it to have side effects, so get rid of it to 
+		// clean up generated code
+		if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->ctor ) ) {
+			ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::ctor, nullptr );
+		}
+		if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->dtor ) ) {
+			ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::dtor, nullptr );
+		}
+
+		return ctorInit;
 	}
 
