Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision a8706fc00f87d52e8a2088039ea7e9d0d0ba8b7c)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision eba74ba03a2c29999def828ffaf6afc87e2b40d1)
@@ -21,5 +21,5 @@
 #include <list>                    // for _List_iterator, list, _List_const_...
 #include <map>                     // for _Rb_tree_iterator, map, _Rb_tree_c...
-#include <memory>                  // for allocator_traits<>::value_type, unique_ptr
+#include <memory>                  // for allocator_traits<>::value_type
 #include <utility>                 // for pair
 #include <vector>                  // for vector
@@ -35,4 +35,5 @@
 #include "ResolveTypeof.h"         // for resolveTypeof
 #include "Resolver.h"              // for resolveStmtExpr
+#include "Common/GC.h"             // for new_static_root
 #include "SymTab/Indexer.h"        // for Indexer
 #include "SymTab/Mangler.h"        // for Mangler
@@ -101,5 +102,5 @@
 		void addAnonConversions( const Alternative & alt );
 		/// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member
-		template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
+		template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string & name );
 		/// Adds alternatives for member expressions where the left side has tuple type
 		void addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
@@ -165,5 +166,4 @@
 					candidate->env.apply( newType );
 					mangleName = SymTab::Mangler::mangle( newType );
-					delete newType;
 				}
 				std::map< std::string, PruneStruct >::iterator mapPlace = selected.find( mangleName );
@@ -297,27 +297,21 @@
 		// adds anonymous member interpretations whenever an aggregate value type is seen.
 		// it's okay for the aggregate expression to have reference type -- cast it to the base type to treat the aggregate as the referenced value
-		std::unique_ptr<Expression> aggrExpr( alt.expr->clone() );
+		Expression* aggrExpr = alt.expr->clone();
 		alt.env.apply( aggrExpr->get_result() );
 		Type * aggrType = aggrExpr->get_result();
 		if ( dynamic_cast< ReferenceType * >( aggrType ) ) {
 			aggrType = aggrType->stripReferences();
-			aggrExpr.reset( new CastExpr( aggrExpr.release(), aggrType->clone() ) );
+			aggrExpr = new CastExpr{ aggrExpr, aggrType->clone() };
 		}
 
 		if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) {
-			NameExpr nameExpr( "" );
-			addAggMembers( structInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr );
+			addAggMembers( structInst, aggrExpr, alt.cost+Cost::safe, alt.env, "" );
 		} else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {
-			NameExpr nameExpr( "" );
-			addAggMembers( unionInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, &nameExpr );
+			addAggMembers( unionInst, aggrExpr, alt.cost+Cost::safe, alt.env, "" );
 		} // if
 	}
 
 	template< typename StructOrUnionType >
-	void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
-		// by this point, member must be a name expr
-		NameExpr * nameExpr = dynamic_cast< NameExpr * >( member );
-		if ( ! nameExpr ) return;
-		const std::string & name = nameExpr->get_name();
+	void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string & name ) {
 		std::list< Declaration* > members;
 		aggInst->lookup( name, members );
@@ -568,5 +562,4 @@
 
 				Expression *varExpr = data.combine( newerAlt.cvtCost );
-				delete varExpr->get_result();
 				varExpr->set_result( adjType->clone() );
 				PRINT(
@@ -585,6 +578,4 @@
 				(*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
 				inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out );
-			} else {
-				delete adjType;
 			}
 		}
@@ -634,5 +625,5 @@
 	struct ArgPack {
 		std::size_t parent;                ///< Index of parent pack
-		std::unique_ptr<Expression> expr;  ///< The argument stored here
+		Expression* expr;                  ///< The argument stored here
 		Cost cost;                         ///< The cost of this argument
 		TypeEnvironment env;               ///< Environment for this pack
@@ -681,5 +672,5 @@
 			std::list<Expression*> exprs;
 			const ArgPack* pack = this;
-			if ( expr ) { exprs.push_front( expr.release() ); }
+			if ( expr ) { exprs.push_front( expr ); }
 			while ( pack->tupleStart == 0 ) {
 				pack = &packs[pack->parent];
@@ -688,5 +679,5 @@
 			}
 			// reset pack to appropriate tuple
-			expr.reset( new TupleExpr( exprs ) );
+			expr = new TupleExpr{ exprs };
 			tupleStart = pack->tupleStart - 1;
 			parent = pack->parent;
@@ -741,5 +732,5 @@
 
 						results.emplace_back(
-							i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env),
+							i, expl.exprs[results[i].nextExpl], copy(results[i].env),
 							copy(results[i].need), copy(results[i].have),
 							copy(results[i].openVars), nextArg, nTuples, Cost::zero, nextExpl,
@@ -762,5 +753,5 @@
 							newResult.parent = i;
 							std::list<Expression*> emptyList;
-							newResult.expr.reset( new TupleExpr( emptyList ) );
+							newResult.expr = new TupleExpr{ emptyList };
 							argType = newResult.expr->get_result();
 						} else {
@@ -769,5 +760,5 @@
 							newResult.cost = results[i].cost;
 							newResult.tupleStart = results[i].tupleStart;
-							newResult.expr.reset( results[i].expr->clone() );
+							newResult.expr = results[i].expr->clone();
 							argType = newResult.expr->get_result();
 
@@ -819,5 +810,5 @@
 						// add new result
 						results.emplace_back(
-							i, expl.exprs.front().get(), move(env), copy(results[i].need),
+							i, expl.exprs.front(), move(env), copy(results[i].need),
 							copy(results[i].have), move(openVars), nextArg + 1,
 							nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
@@ -845,5 +836,5 @@
 			if ( results[i].hasExpl() ) {
 				const ExplodedActual& expl = results[i].getExpl( args );
-				Expression* expr = expl.exprs[results[i].nextExpl].get();
+				Expression* expr = expl.exprs[results[i].nextExpl];
 
 				TypeEnvironment env = results[i].env;
@@ -916,5 +907,5 @@
 
 				// consider only first exploded actual
-				Expression* expr = expl.exprs.front().get();
+				Expression* expr = expl.exprs.front();
 				Type* actualType = expr->result->clone();
 
@@ -1019,5 +1010,5 @@
 
 						results.emplace_back(
-							i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env),
+							i, expl.exprs[results[i].nextExpl], copy(results[i].env),
 							copy(results[i].need), copy(results[i].have),
 							copy(results[i].openVars), nextArg, 0, Cost::zero, nextExpl,
@@ -1055,5 +1046,5 @@
 						// add new result
 						results.emplace_back(
-							i, expl.exprs.front().get(), move(env), copy(results[i].need),
+							i, expl.exprs.front(), move(env), copy(results[i].need),
 							copy(results[i].have), move(openVars), nextArg + 1, 0,
 							expl.cost, expl.exprs.size() == 1 ? 0 : 1, j );
@@ -1089,8 +1080,8 @@
 
 		// find function operators
-		static NameExpr *opExpr = new NameExpr( "?()" );
+		static auto *opExpr = new_static_root<NameExpr>( "?()" );
 		AlternativeFinder funcOpFinder( indexer, env );
 		// it's ok if there aren't any defined function ops
-		funcOpFinder.maybeFind( opExpr);
+		funcOpFinder.maybeFind( opExpr );
 		PRINT(
 			std::cerr << "known function ops:" << std::endl;
@@ -1121,6 +1112,6 @@
 				)
 				// check if the type is pointer to function
-				if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->result->stripReferences() ) ) {
-					if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->base ) ) {
+				if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->get_result()->stripReferences() ) ) {
+					if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
 						Alternative newFunc( *func );
 						referenceToRvalueConversion( newFunc.expr, newFunc.cost );
@@ -1128,7 +1119,7 @@
 							std::back_inserter( candidates ) );
 					}
-				} else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->result->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
+				} else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
 					EqvClass eqvClass;
-					if ( func->env.lookup( typeInst->name, eqvClass ) && eqvClass.type ) {
+					if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
 						if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
 							Alternative newFunc( *func );
@@ -1159,7 +1150,7 @@
 					// check if type is a pointer to function
 					if ( PointerType* pointer = dynamic_cast<PointerType*>(
-							funcOp->expr->result->stripReferences() ) ) {
+							funcOp->expr->get_result()->stripReferences() ) ) {
 						if ( FunctionType* function =
-								dynamic_cast<FunctionType*>( pointer->base ) ) {
+								dynamic_cast<FunctionType*>( pointer->get_base() ) ) {
 							Alternative newFunc( *funcOp );
 							referenceToRvalueConversion( newFunc.expr, newFunc.cost );
@@ -1183,11 +1174,11 @@
 			PRINT(
 				ApplicationExpr *appExpr = strict_dynamic_cast< ApplicationExpr* >( withFunc.expr );
-				PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr->function->result );
-				FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer->base );
-				std::cerr << "Case +++++++++++++ " << appExpr->function << std::endl;
+				PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
+				FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer->get_base() );
+				std::cerr << "Case +++++++++++++ " << appExpr->get_function() << std::endl;
 				std::cerr << "formals are:" << std::endl;
-				printAll( function->parameters, std::cerr, 8 );
+				printAll( function->get_parameters(), std::cerr, 8 );
 				std::cerr << "actuals are:" << std::endl;
-				printAll( appExpr->args, std::cerr, 8 );
+				printAll( appExpr->get_args(), std::cerr, 8 );
 				std::cerr << "bindings are:" << std::endl;
 				withFunc.env.print( std::cerr, 8 );
@@ -1230,5 +1221,5 @@
 	bool isLvalue( Expression *expr ) {
 		// xxx - recurse into tuples?
-		return expr->result && ( expr->result->get_lvalue() || dynamic_cast< ReferenceType * >( expr->result ) );
+		return expr->result && ( expr->get_result()->get_lvalue() || dynamic_cast< ReferenceType * >( expr->get_result() ) );
 	}
 
@@ -1265,5 +1256,4 @@
 				componentExprs.push_back( restructureCast( idx, toType->getComponent( i ), isGenerated ) );
 			}
-			delete argExpr;
 			assert( componentExprs.size() > 0 );
 			// produce the tuple of casts
@@ -1346,4 +1336,13 @@
 	}
 
+	namespace {
+		/// Gets name from untyped member expression (member must be NameExpr)
+		const std::string& get_member_name( UntypedMemberExpr *memberExpr ) {
+			NameExpr * nameExpr = dynamic_cast< NameExpr * >( memberExpr->get_member() );
+			assert( nameExpr );
+			return nameExpr->get_name();
+		}
+	}
+
 	void AlternativeFinder::Finder::postvisit( UntypedMemberExpr *memberExpr ) {
 		AlternativeFinder funcFinder( indexer, env );
@@ -1354,11 +1353,10 @@
 			Expression * aggrExpr = agg->expr->clone();
 			referenceToRvalueConversion( aggrExpr, cost );
-			std::unique_ptr<Expression> guard( aggrExpr );
 
 			// find member of the given type
 			if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) {
-				addAggMembers( structInst, aggrExpr, cost, agg->env, memberExpr->get_member() );
+				addAggMembers( structInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );
 			} else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {
-				addAggMembers( unionInst, aggrExpr, cost, agg->env, memberExpr->get_member() );
+				addAggMembers( unionInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );
 			} else if ( TupleType * tupleType = dynamic_cast< TupleType * >( aggrExpr->get_result() ) ) {
 				addTupleMembers( tupleType, aggrExpr, cost, agg->env, memberExpr->get_member() );
@@ -1605,5 +1603,4 @@
 			alternatives.push_back( Alternative( new CommaExpr( newFirstArg->clone(), alt.expr->clone() ), alt.env, alt.cost ) );
 		} // for
-		delete newFirstArg;
 	}
 
