Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/CodeGen/CodeGenerator.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -309,8 +309,7 @@
 							UntypedExpr * newExpr = new UntypedExpr( new NameExpr( "*?" ) );
 							newExpr->get_args().push_back( *arg );
-							assert( (*arg)->get_results().size() == 1 );
-							Type * type = InitTweak::getPointerBase( (*arg)->get_results().front() );
+							Type * type = InitTweak::getPointerBase( (*arg)->get_result() );
 							assert( type );
-							newExpr->get_results().push_back( type->clone() );
+							newExpr->set_result( type->clone() );
 							*arg = newExpr;
 						} // if
@@ -527,10 +526,10 @@
 		extension( castExpr );
 		output << "(";
-		if ( castExpr->get_results().empty() ) {
+		if ( castExpr->get_result()->isVoid() ) {
 			output << "(void)" ;
-		} else if ( ! castExpr->get_results().front()->get_isLvalue() ) {
+		} else if ( ! castExpr->get_result()->get_isLvalue() ) {
 			// at least one result type of cast, but not an lvalue
 			output << "(";
-			output << genType( castExpr->get_results().front(), "" );
+			output << genType( castExpr->get_result(), "" );
 			output << ")";
 		} else {
Index: c/ControlStruct/LabelTypeChecker.cc
===================================================================
--- src/ControlStruct/LabelTypeChecker.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ 	(revision )
@@ -1,86 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// LabelTypeChecker.cc -- 
-//
-// Author           : Rodolfo G. Esteves
-// Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Rob Schluntz
-// Last Modified On : Wed Jun 24 16:24:48 2015
-// Update Count     : 3
-//
-
-#include <list>
-#include <cassert>
-
-#include "SynTree/Type.h"
-#include "SynTree/Statement.h"
-#include "SynTree/Expression.h"
-#include "SynTree/Declaration.h"
-
-#include "LabelTypeChecker.h"
-
-namespace ControlStruct {
-	void LabelTypeChecker::visit(UntypedExpr *untypedExpr) {
-		assert( untypedExpr != 0 );
-		NameExpr *fname;
-		if ( ((fname = dynamic_cast<NameExpr *>(untypedExpr->get_function())) != 0) 
-			 && fname->get_name() == std::string("&&") )
-			std::cerr << "Taking the label of an address." << std::endl;
-		else {
-			acceptAll( untypedExpr->get_results(), *this );
-			acceptAll( untypedExpr->get_args(), *this );
-		} // if
-		return;
-	}
-
-	void LabelTypeChecker::visit(CompoundStmt *compoundStmt) {
-		index.enterScope();
-		acceptAll( compoundStmt->get_kids(), *this );
-		index.leaveScope();
-	}
-
-	void LabelTypeChecker::visit(DeclStmt *declStmt) {
-		declStmt->accept( index );
-
-		//ObjectDecl *odecl = 0;
-		// if ( ( odecl = dynamic_cast<ObjectDecl *>(declStmt->get_decl()) ) != 0 ) {
-		return;
-	}
-
-	void LabelTypeChecker::visit(BranchStmt *branchStmt) {
-		if ( branchStmt->get_type() != BranchStmt::Goto ) return;
-		Expression *target;
-		if ( (target = branchStmt->get_computedTarget()) == 0 ) return;
-
-		NameExpr *name;
-		if ( ((name = dynamic_cast<NameExpr *>(target)) == 0) )
-			return; // Not a name expression
-	
-		std::list< DeclarationWithType * > interps;
-		index.lookupId(name->get_name(), interps);
-		if ( interps.size() != 1)
-			// in case of multiple declarations
-			throw SemanticError("Illegal label expression: " + name->get_name() );
-
-		PointerType *ptr;
-		if ( (ptr = dynamic_cast<PointerType *>(interps.front()->get_type())) != 0 )
-			if ( dynamic_cast<VoidType *>(ptr->get_base()) != 0 )
-				return;
-			else
-				throw SemanticError("Wrong type of parameter for computed goto");
-		else
-			throw SemanticError("Wrong type of parameter for computed goto");
-
-		return;
-	}
-} // namespace ControlStruct
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: c/ControlStruct/LabelTypeChecker.h
===================================================================
--- src/ControlStruct/LabelTypeChecker.h	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ 	(revision )
@@ -1,45 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// LabelTypeChecker.h -- 
-//
-// Author           : Rodolfo G. Esteves
-// Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Jan 25 21:22:30 2016
-// Update Count     : 4
-//
-
-#ifndef LABEL_TYPE_H
-#define LABEL_TYPE_H
-
-#include "SynTree/Visitor.h"
-#include "SymTab/Indexer.h"
-#include "SynTree/Statement.h"
-
-#include "Common/utility.h"
-
-namespace ControlStruct {
-	class LabelTypeChecker : public Visitor {
-	  public:
-		//LabelTypeChecker() {
-
-		virtual void visit( CompoundStmt *compoundStmt );
-		virtual void visit( DeclStmt *declStmt );
-		virtual void visit( BranchStmt *branchStmt );
-		virtual void visit( UntypedExpr *untypedExpr );
-	  private:
-		SymTab::Indexer index;
-	};
-} // namespace ControlStruct
-
-#endif // LABEL_TYPE_H
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: src/ControlStruct/Mutate.cc
===================================================================
--- src/ControlStruct/Mutate.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/ControlStruct/Mutate.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -23,5 +23,4 @@
 #include "MLEMutator.h"
 #include "ForExprMutator.h"
-#include "LabelTypeChecker.h"
 //#include "ExceptMutator.h"
 
@@ -41,10 +40,8 @@
 
 		//ExceptMutator exc;
-		// LabelTypeChecker lbl;
 
 		mutateAll( translationUnit, formut );
 		acceptAll( translationUnit, lfix );
 		//mutateAll( translationUnit, exc );
-		//acceptAll( translationUnit, lbl );
 	}
 } // namespace CodeGen
Index: src/ControlStruct/module.mk
===================================================================
--- src/ControlStruct/module.mk	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/ControlStruct/module.mk	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -6,5 +6,5 @@
 ## file "LICENCE" distributed with Cforall.
 ##
-## module.mk -- 
+## module.mk --
 ##
 ## Author           : Richard C. Bilson
@@ -19,5 +19,4 @@
         ControlStruct/MLEMutator.cc \
 	ControlStruct/Mutate.cc \
-	ControlStruct/ForExprMutator.cc \
-	ControlStruct/LabelTypeChecker.cc
+	ControlStruct/ForExprMutator.cc
 
Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/GenPoly/Box.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -782,6 +782,6 @@
 
 			// add size/align for generic types to parameter list
-			if ( appExpr->get_function()->get_results().empty() ) return;
-			FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() );
+			if ( ! appExpr->get_function()->has_result() ) return;
+			FunctionType *funcType = getFunctionType( appExpr->get_function()->get_result() );
 			assert( funcType );
 
@@ -799,6 +799,6 @@
 			for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) {
 				VariableExpr *fnArgBase = getBaseVar( *fnArg );
-				if ( ! fnArgBase || fnArgBase->get_results().empty() ) continue;
-				passArgTypeVars( appExpr, (*fnParm)->get_type(), fnArgBase->get_results().front(), arg, exprTyVars, seenTypes );
+				if ( ! fnArgBase ) continue; // xxx - previously had check for non-empty fnArgBase results
+				passArgTypeVars( appExpr, (*fnParm)->get_type(), fnArgBase->get_result(), arg, exprTyVars, seenTypes );
 			}
 		}
@@ -890,5 +890,5 @@
 			Type * adapteeType = new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) );
 			appExpr->get_args().push_front( new CastExpr( appExpr->get_function(), adapteeType ) );
-			appExpr->set_function( new NameExpr( adapterName ) );
+			appExpr->set_function( new NameExpr( adapterName ) ); // xxx - result is never set on NameExpr
 
 			return ret;
@@ -896,10 +896,10 @@
 
 		void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) {
-			assert( ! arg->get_results().empty() );
+			assert( arg->has_result() );
 			if ( isPolyType( param, exprTyVars ) ) {
-				if ( isPolyType( arg->get_results().front() ) ) {
+				if ( isPolyType( arg->get_result() ) ) {
 					// if the argument's type is polymorphic, we don't need to box again!
 					return;
-				} else if ( arg->get_results().front()->get_isLvalue() ) {
+				} else if ( arg->get_result()->get_isLvalue() ) {
 					// VariableExpr and MemberExpr are lvalues; need to check this isn't coming from the second arg of a comma expression though (not an lvalue)
 					// xxx - need to test that this code is still reachable
@@ -987,5 +987,5 @@
 					UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
 					deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
-					deref->get_results().push_back( arg->get_type()->clone() );
+					deref->set_result( arg->get_type()->clone() );
 					return deref;
 				} // if
@@ -1124,5 +1124,5 @@
 			} // if
 			addAssign->get_args().push_back( new NameExpr( sizeofName( mangleType( polyType ) ) ) );
-			addAssign->get_results().front() = appExpr->get_results().front()->clone();
+			addAssign->set_result( appExpr->get_result()->clone() );
 			if ( appExpr->get_env() ) {
 				addAssign->set_env( appExpr->get_env() );
@@ -1138,8 +1138,8 @@
 				if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
 					if ( varExpr->get_var()->get_name() == "?[?]" ) {
-						assert( ! appExpr->get_results().empty() );
+						assert( appExpr->has_result() );
 						assert( appExpr->get_args().size() == 2 );
-						Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env );
-						Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env );
+						Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result(), scopeTyVars, env );
+						Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_result(), scopeTyVars, env );
 						assert( ! baseType1 || ! baseType2 ); // the arguments cannot both be polymorphic pointers
 						UntypedExpr *ret = 0;
@@ -1161,5 +1161,5 @@
 						} // if
 						if ( baseType1 || baseType2 ) {
-							ret->get_results().push_front( appExpr->get_results().front()->clone() );
+							ret->set_result( appExpr->get_result()->clone() );
 							if ( appExpr->get_env() ) {
 								ret->set_env( appExpr->get_env() );
@@ -1171,10 +1171,10 @@
 						} // if
 					} else if ( varExpr->get_var()->get_name() == "*?" ) {
-						assert( ! appExpr->get_results().empty() );
+						assert( appExpr->has_result() );
 						assert( ! appExpr->get_args().empty() );
-						if ( isPolyType( appExpr->get_results().front(), scopeTyVars, env ) ) {
+						if ( isPolyType( appExpr->get_result(), scopeTyVars, env ) ) {
 							Expression *ret = appExpr->get_args().front();
-							delete ret->get_results().front();
-							ret->get_results().front() = appExpr->get_results().front()->clone();
+							delete ret->get_result();
+							ret->set_result( appExpr->get_result()->clone() );
 							if ( appExpr->get_env() ) {
 								ret->set_env( appExpr->get_env() );
@@ -1186,8 +1186,8 @@
 						} // if
 					} else if ( varExpr->get_var()->get_name() == "?++" || varExpr->get_var()->get_name() == "?--" ) {
-						assert( ! appExpr->get_results().empty() );
+						assert( appExpr->has_result() );
 						assert( appExpr->get_args().size() == 1 );
-						if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) {
-							Type *tempType = appExpr->get_results().front()->clone();
+						if ( Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ) ) {
+							Type *tempType = appExpr->get_result()->clone();
 							if ( env ) {
 								env->apply( tempType );
@@ -1206,19 +1206,19 @@
 						} // if
 					} else if ( varExpr->get_var()->get_name() == "++?" || varExpr->get_var()->get_name() == "--?" ) {
-						assert( ! appExpr->get_results().empty() );
+						assert( appExpr->has_result() );
 						assert( appExpr->get_args().size() == 1 );
-						if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) {
+						if ( Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ) ) {
 							return makeIncrDecrExpr( appExpr, baseType, varExpr->get_var()->get_name() == "++?" );
 						} // if
 					} else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) {
-						assert( ! appExpr->get_results().empty() );
+						assert( appExpr->has_result() );
 						assert( appExpr->get_args().size() == 2 );
-						Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env );
-						Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env );
+						Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result(), scopeTyVars, env );
+						Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_result(), scopeTyVars, env );
 						if ( baseType1 && baseType2 ) {
 							UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) );
 							divide->get_args().push_back( appExpr );
 							divide->get_args().push_back( new SizeofExpr( baseType1->clone() ) );
-							divide->get_results().push_front( appExpr->get_results().front()->clone() );
+							divide->set_result( appExpr->get_result()->clone() );
 							if ( appExpr->get_env() ) {
 								divide->set_env( appExpr->get_env() );
@@ -1238,7 +1238,7 @@
 						} // if
 					} else if ( varExpr->get_var()->get_name() == "?+=?" || varExpr->get_var()->get_name() == "?-=?" ) {
-						assert( ! appExpr->get_results().empty() );
+						assert( appExpr->has_result() );
 						assert( appExpr->get_args().size() == 2 );
-						Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env );
+						Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env );
 						if ( baseType ) {
 							UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
@@ -1266,9 +1266,7 @@
 			useRetval = oldUseRetval;
 
-			assert( ! appExpr->get_function()->get_results().empty() );
-			PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() );
-			assert( pointer );
-			FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() );
-			assert( function );
+			assert( appExpr->get_function()->has_result() );
+			PointerType *pointer = safe_dynamic_cast< PointerType *>( appExpr->get_function()->get_result() );
+			FunctionType *function = safe_dynamic_cast< FunctionType *>( pointer->get_base() );
 
 			if ( Expression *newExpr = handleIntrinsics( appExpr ) ) {
@@ -1308,5 +1306,5 @@
 
 		Expression *Pass1::mutate( UntypedExpr *expr ) {
-			if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) {
+			if ( expr->has_result() && isPolyType( expr->get_result(), scopeTyVars, env ) ) {
 				if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
 					if ( name->get_name() == "*?" ) {
@@ -1322,17 +1320,15 @@
 
 		Expression *Pass1::mutate( AddressExpr *addrExpr ) {
-			assert( ! addrExpr->get_arg()->get_results().empty() );
+			assert( addrExpr->get_arg()->has_result() && ! addrExpr->get_arg()->get_result()->isVoid() );
 
 			bool needs = false;
 			if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) {
-				if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) {
+				if ( expr->has_result() && isPolyType( expr->get_result(), scopeTyVars, env ) ) {
 					if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
 						if ( name->get_name() == "*?" ) {
 							if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) {
-								assert( ! appExpr->get_function()->get_results().empty() );
-								PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() );
-								assert( pointer );
-								FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() );
-								assert( function );
+								assert( appExpr->get_function()->has_result() );
+								PointerType *pointer = safe_dynamic_cast< PointerType *>( appExpr->get_function()->get_result() );
+								FunctionType *function = safe_dynamic_cast< FunctionType *>( pointer->get_base() );
 								needs = needsAdapter( function, scopeTyVars );
 							} // if
@@ -1343,10 +1339,10 @@
 			// isPolyType check needs to happen before mutating addrExpr arg, so pull it forward
 			// out of the if condition.
-			bool polytype = isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env );
+			bool polytype = isPolyType( addrExpr->get_arg()->get_result(), scopeTyVars, env );
 			addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
 			if ( polytype || needs ) {
 				Expression *ret = addrExpr->get_arg();
-				delete ret->get_results().front();
-				ret->get_results().front() = addrExpr->get_results().front()->clone();
+				delete ret->get_result();
+				ret->set_result( addrExpr->get_result()->clone() );
 				addrExpr->set_arg( 0 );
 				delete addrExpr;
@@ -1386,5 +1382,5 @@
 		Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
 			if ( retval && returnStmt->get_expr() ) {
-				assert( ! returnStmt->get_expr()->get_results().empty() );
+				assert( returnStmt->get_expr()->has_result() && ! returnStmt->get_expr()->get_result()->isVoid() );
 				// ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous.
 				// if ( returnStmt->get_expr()->get_results().front()->get_isLvalue() ) {
@@ -1466,5 +1462,5 @@
 				// replace return statement with appropriate assignment to out parameter
 				Expression *retParm = new NameExpr( retval->get_name() );
-				retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
+				retParm->set_result( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
 				assignExpr->get_args().push_back( retParm );
 				assignExpr->get_args().push_back( returnStmt->get_expr() );
Index: src/GenPoly/Lvalue.cc
===================================================================
--- src/GenPoly/Lvalue.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/GenPoly/Lvalue.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Lvalue.cc -- 
+// Lvalue.cc --
 //
 // Author           : Richard C. Bilson
@@ -41,5 +41,5 @@
 		  public:
 			Pass1();
-  
+
 			virtual Expression *mutate( ApplicationExpr *appExpr );
 			virtual Statement *mutate( ReturnStmt *appExpr );
@@ -99,16 +99,12 @@
 			appExpr->get_function()->acceptMutator( *this );
 			mutateAll( appExpr->get_args(), *this );
-  
-			assert( ! appExpr->get_function()->get_results().empty() );
 
-			PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
-			assert( pointer );
-			FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
-			assert( function );
+			PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
+			FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
 
 			Type *funType = isLvalueRet( function );
 			if ( funType && ! isIntrinsicApp( appExpr ) ) {
 				Expression *expr = appExpr;
-				Type *appType = appExpr->get_results().front();
+				Type *appType = appExpr->get_result();
 				if ( isPolyType( funType ) && ! isPolyType( appType ) ) {
 					// make sure cast for polymorphic type is inside dereference
@@ -116,6 +112,6 @@
 				}
 				UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
-				deref->get_results().push_back( appType->clone() );
-				appExpr->get_results().front() = new PointerType( Type::Qualifiers(), appType );
+				deref->set_result( appType->clone() );
+				appExpr->set_result( new PointerType( Type::Qualifiers(), appType ) );
 				deref->get_args().push_back( expr );
 				return deref;
@@ -127,6 +123,5 @@
 		Statement * Pass1::mutate(ReturnStmt *retStmt) {
 			if ( retval && retStmt->get_expr() ) {
-				assert( ! retStmt->get_expr()->get_results().empty() );
-				if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
+				if ( retStmt->get_expr()->get_result()->get_isLvalue() ) {
 					// ***** Code Removal ***** because casts may be stripped already
 
@@ -155,5 +150,5 @@
 				retParm->set_type( new PointerType( Type::Qualifiers(), retParm->get_type() ) );
 			} // if
-  
+
 			Visitor::visit( funType );
 		}
Index: src/GenPoly/Specialize.cc
===================================================================
--- src/GenPoly/Specialize.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/GenPoly/Specialize.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -147,6 +147,6 @@
 
 	Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) {
-		assert( ! actual->get_results().empty() ); // using front, should have this assert
-		if ( needsSpecialization( formalType, actual->get_results().front(), env ) ) {
+		assert( actual->has_result() );
+		if ( needsSpecialization( formalType, actual->get_result(), env ) ) {
 			FunctionType *funType;
 			if ( ( funType = getFunctionType( formalType ) ) ) {
@@ -171,6 +171,6 @@
 	void Specialize::handleExplicitParams( ApplicationExpr *appExpr ) {
 		// create thunks for the explicit parameters
-		assert( ! appExpr->get_function()->get_results().empty() );
-		FunctionType *function = getFunctionType( appExpr->get_function()->get_results().front() );
+		assert( appExpr->get_function()->has_result() );
+		FunctionType *function = getFunctionType( appExpr->get_function()->get_result() );
 		assert( function );
 		std::list< DeclarationWithType* >::iterator formal;
@@ -200,6 +200,6 @@
 	Expression * Specialize::mutate( AddressExpr *addrExpr ) {
 		addrExpr->get_arg()->acceptMutator( *this );
-		assert( ! addrExpr->get_results().empty() );
-		addrExpr->set_arg( doSpecialization( addrExpr->get_results().front(), addrExpr->get_arg() ) );
+		assert( addrExpr->has_result() );
+		addrExpr->set_arg( doSpecialization( addrExpr->get_result(), addrExpr->get_arg() ) );
 		return addrExpr;
 	}
@@ -207,9 +207,9 @@
 	Expression * Specialize::mutate( CastExpr *castExpr ) {
 		castExpr->get_arg()->acceptMutator( *this );
-		if ( castExpr->get_results().empty() ) {
+		if ( castExpr->get_result()->isVoid() ) {
 			// can't specialize if we don't have a return value
 			return castExpr;
 		}
-		Expression *specialized = doSpecialization( castExpr->get_results().front(), castExpr->get_arg() );
+		Expression *specialized = doSpecialization( castExpr->get_result(), castExpr->get_arg() );
 		if ( specialized != castExpr->get_arg() ) {
 			// assume here that the specialization incorporates the cast
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/InitTweak/FixInit.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -391,6 +391,6 @@
 				CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *impCpCtorExpr->get_env() << std::endl; )
 				// xxx - need to handle tuple arguments
-				assert( ! arg->get_results().empty() );
-				Type * result = arg->get_results().front();
+				assert( arg->has_result() );
+				Type * result = arg->get_result();
 				if ( skipCopyConstruct( result ) ) continue; // skip certain non-copyable types
 				// type may involve type variables, so apply type substitution to get temporary variable's actual type
@@ -423,5 +423,7 @@
 			// level. Trying to pass that environment along.
 			callExpr->set_env( impCpCtorExpr->get_env()->clone() );
-			for ( Type * result : appExpr->get_results() ) {
+			Type * result = appExpr->get_result();
+			if ( ! result->isVoid() ) {
+				// need to flatten result type and construct each
 				result = result->clone();
 				impCpCtorExpr->get_env()->apply( result );
@@ -479,8 +481,8 @@
 				// know the result type of the assignment is the type of the LHS (minus the pointer), so
 				// add that onto the assignment expression so that later steps have the necessary information
-				assign->add_result( returnDecl->get_type()->clone() );
+				assign->set_result( returnDecl->get_type()->clone() );
 
 				Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) );
-				if ( callExpr->get_results().front()->get_isLvalue() ) {
+				if ( callExpr->get_result()->get_isLvalue() ) {
 					// lvalue returning functions are funny. Lvalue.cc inserts a *? in front of any lvalue returning
 					// non-intrinsic function. Add an AddressExpr to the call to negate the derefence and change the
@@ -500,5 +502,5 @@
 					UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) );
 					deref->get_args().push_back( retExpr );
-					deref->add_result( resultType );
+					deref->set_result( resultType );
 					retExpr = deref;
 				} // if
@@ -939,6 +941,6 @@
 		Expression * FixCtorExprs::mutate( ConstructorExpr * ctorExpr ) {
 			static UniqueName tempNamer( "_tmp_ctor_expr" );
-			assert( ctorExpr->get_results().size() == 1 );
-			ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, ctorExpr->get_results().front()->clone(), nullptr );
+			assert( ctorExpr->has_result() && ctorExpr->get_result()->size() == 1 );
+			ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, ctorExpr->get_result()->clone(), nullptr );
 			addDeclaration( tmp );
 
@@ -952,5 +954,5 @@
 			assign->get_args().push_back( new VariableExpr( tmp ) );
 			assign->get_args().push_back( firstArg );
-			cloneAll( ctorExpr->get_results(), assign->get_results() );
+			assign->set_result( ctorExpr->get_result()->clone() );
 			firstArg = assign;
 
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/InitTweak/InitTweak.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -340,6 +340,5 @@
 		return allofCtorDtor( stmt, []( Expression * callExpr ){
 			if ( ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) {
-				assert( ! appExpr->get_function()->get_results().empty() );
-				FunctionType *funcType = GenPoly::getFunctionType( appExpr->get_function()->get_results().front() );
+				FunctionType *funcType = GenPoly::getFunctionType( appExpr->get_function()->get_result() );
 				assert( funcType );
 				return funcType->get_parameters().size() == 1;
Index: src/Makefile.in
===================================================================
--- src/Makefile.in	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/Makefile.in	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -104,5 +104,4 @@
 	ControlStruct/driver_cfa_cpp-Mutate.$(OBJEXT) \
 	ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT) \
-	ControlStruct/driver_cfa_cpp-LabelTypeChecker.$(OBJEXT) \
 	GenPoly/driver_cfa_cpp-Box.$(OBJEXT) \
 	GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT) \
@@ -361,6 +360,5 @@
 	ControlStruct/LabelGenerator.cc ControlStruct/LabelFixer.cc \
 	ControlStruct/MLEMutator.cc ControlStruct/Mutate.cc \
-	ControlStruct/ForExprMutator.cc \
-	ControlStruct/LabelTypeChecker.cc GenPoly/Box.cc \
+	ControlStruct/ForExprMutator.cc GenPoly/Box.cc \
 	GenPoly/GenPoly.cc GenPoly/PolyMutator.cc \
 	GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc GenPoly/Specialize.cc \
@@ -535,7 +533,4 @@
 	ControlStruct/$(DEPDIR)/$(am__dirstamp)
 ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT):  \
-	ControlStruct/$(am__dirstamp) \
-	ControlStruct/$(DEPDIR)/$(am__dirstamp)
-ControlStruct/driver_cfa_cpp-LabelTypeChecker.$(OBJEXT):  \
 	ControlStruct/$(am__dirstamp) \
 	ControlStruct/$(DEPDIR)/$(am__dirstamp)
@@ -791,5 +786,4 @@
 	-rm -f ControlStruct/driver_cfa_cpp-LabelFixer.$(OBJEXT)
 	-rm -f ControlStruct/driver_cfa_cpp-LabelGenerator.$(OBJEXT)
-	-rm -f ControlStruct/driver_cfa_cpp-LabelTypeChecker.$(OBJEXT)
 	-rm -f ControlStruct/driver_cfa_cpp-MLEMutator.$(OBJEXT)
 	-rm -f ControlStruct/driver_cfa_cpp-Mutate.$(OBJEXT)
@@ -896,5 +890,4 @@
 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelGenerator.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-MLEMutator.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Po@am__quote@
@@ -1211,18 +1204,4 @@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-ForExprMutator.obj `if test -f 'ControlStruct/ForExprMutator.cc'; then $(CYGPATH_W) 'ControlStruct/ForExprMutator.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ForExprMutator.cc'; fi`
 
-ControlStruct/driver_cfa_cpp-LabelTypeChecker.o: ControlStruct/LabelTypeChecker.cc
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-LabelTypeChecker.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Tpo -c -o ControlStruct/driver_cfa_cpp-LabelTypeChecker.o `test -f 'ControlStruct/LabelTypeChecker.cc' || echo '$(srcdir)/'`ControlStruct/LabelTypeChecker.cc
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='ControlStruct/LabelTypeChecker.cc' object='ControlStruct/driver_cfa_cpp-LabelTypeChecker.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-LabelTypeChecker.o `test -f 'ControlStruct/LabelTypeChecker.cc' || echo '$(srcdir)/'`ControlStruct/LabelTypeChecker.cc
-
-ControlStruct/driver_cfa_cpp-LabelTypeChecker.obj: ControlStruct/LabelTypeChecker.cc
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-LabelTypeChecker.obj -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Tpo -c -o ControlStruct/driver_cfa_cpp-LabelTypeChecker.obj `if test -f 'ControlStruct/LabelTypeChecker.cc'; then $(CYGPATH_W) 'ControlStruct/LabelTypeChecker.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/LabelTypeChecker.cc'; fi`
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelTypeChecker.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='ControlStruct/LabelTypeChecker.cc' object='ControlStruct/driver_cfa_cpp-LabelTypeChecker.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-LabelTypeChecker.obj `if test -f 'ControlStruct/LabelTypeChecker.cc'; then $(CYGPATH_W) 'ControlStruct/LabelTypeChecker.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/LabelTypeChecker.cc'; fi`
-
 GenPoly/driver_cfa_cpp-Box.o: GenPoly/Box.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-Box.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Tpo -c -o GenPoly/driver_cfa_cpp-Box.o `test -f 'GenPoly/Box.cc' || echo '$(srcdir)/'`GenPoly/Box.cc
Index: src/ResolvExpr/Alternative.cc
===================================================================
--- src/ResolvExpr/Alternative.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/ResolvExpr/Alternative.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Alternative.cc -- 
+// Alternative.cc --
 //
 // Author           : Richard C. Bilson
@@ -12,5 +12,5 @@
 // Last Modified On : Sat May 16 23:54:23 2015
 // Update Count     : 2
-// 
+//
 
 #include "Alternative.h"
@@ -54,6 +54,7 @@
 			expr->print( os, indent );
 			os << "(types:" << std::endl;
-			printAll( expr->get_results(), os, indent + 4 );
-			os << ")" << std::endl;
+			os << std::string( indent+4, ' ' );
+			expr->get_result()->print( os, indent + 4 );
+			os << std::endl << ")" << std::endl;
 		} else {
 			os << "Null expression!" << std::endl;
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -100,8 +100,8 @@
 				PruneStruct current( candidate );
 				std::string mangleName;
-				for ( std::list< Type* >::const_iterator retType = candidate->expr->get_results().begin(); retType != candidate->expr->get_results().end(); ++retType ) {
-					Type *newType = (*retType)->clone();
+				{
+					Type * newType = candidate->expr->get_result()->clone();
 					candidate->env.apply( newType );
-					mangleName += SymTab::Mangler::mangle( newType );
+					mangleName = SymTab::Mangler::mangle( newType );
 					delete newType;
 				}
@@ -132,11 +132,8 @@
 				if ( ! target->second.isAmbiguous ) {
 					Alternative &alt = *target->second.candidate;
-					for ( std::list< Type* >::iterator result = alt.expr->get_results().begin(); result != alt.expr->get_results().end(); ++result ) {
-						alt.env.applyFree( *result );
-					}
+					alt.env.applyFree( alt.expr->get_result() );
 					*out++ = alt;
 				}
 			}
-
 		}
 
@@ -149,19 +146,5 @@
 
 		void renameTypes( Expression *expr ) {
-			for ( std::list< Type* >::iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) {
-				(*i)->accept( global_renamer );
-			}
-		}
-
-		// flatten tuple type into list of types
-		template< typename OutputIterator >
-		void flatten( Type * type, OutputIterator out ) {
-			if ( TupleType * tupleType = dynamic_cast< TupleType * >( type ) ) {
-				for ( Type * t : *tupleType ) {
-					flatten( t, out );
-				}
-			} else {
-				*out++ = type;
-			}
+			expr->get_result()->accept( global_renamer );
 		}
 	}
@@ -195,5 +178,5 @@
 		for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) {
 			if ( adjust ) {
-				adjustExprTypeList( i->expr->get_results().begin(), i->expr->get_results().end(), i->env, indexer );
+				adjustExprType( i->expr->get_result(), i->env, indexer );
 			}
 		}
@@ -265,5 +248,5 @@
 	Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
 		ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( alt.expr );
-		PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
+		PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
 		FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
 
@@ -282,9 +265,12 @@
 				(*actualExpr)->print( std::cerr, 8 );
 				std::cerr << "--- results are" << std::endl;
-				printAll( (*actualExpr)->get_results(), std::cerr, 8 );
+				(*actualExpr)->get_result()->print( std::cerr, 8 );
 			)
 			std::list< DeclarationWithType* >::iterator startFormal = formal;
 			Cost actualCost;
-			for ( std::list< Type* >::iterator actualType = (*actualExpr)->get_results().begin(); actualType != (*actualExpr)->get_results().end(); ++actualType ) {
+			std::list< Type * > flatActualTypes;
+			flatten( (*actualExpr)->get_result(), back_inserter( flatActualTypes ) );
+			for ( std::list< Type* >::iterator actualType = flatActualTypes.begin(); actualType != flatActualTypes.end(); ++actualType ) {
+
 
 				// tuple handling code
@@ -399,6 +385,7 @@
 
 		for ( AltList::const_iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
-			std::list< Type* > & actualTypes = actualExpr->expr->get_results();
-			for ( std::list< Type* >::iterator actualType = actualTypes.begin(); actualType != actualTypes.end(); ++actualType ) {
+			std::list< Type * > flatActualTypes;
+			flatten( actualExpr->expr->get_result(), back_inserter( flatActualTypes ) );
+			for ( std::list< Type* >::iterator actualType = flatActualTypes.begin(); actualType != flatActualTypes.end(); ++actualType, ++formalType ) {
 				if ( formalType == formalTypes.end() ) {
 					// the type of the formal parameter may be a tuple type. To make this easier to work with,
@@ -416,5 +403,5 @@
 				PRINT(
 					std::cerr << "formal type is ";
-					(*formal)->get_type()->print( std::cerr );
+					(*formalType)->print( std::cerr );
 					std::cerr << std::endl << "actual type is ";
 					(*actualType)->print( std::cerr );
@@ -424,5 +411,4 @@
 					return false;
 				}
-				++formalType;
 			}
 		}
@@ -532,7 +518,6 @@
 				//if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue;
 				Expression *varExpr = new VariableExpr( candDecl );
-				deleteAll( varExpr->get_results() );
-				varExpr->get_results().clear();
-				varExpr->get_results().push_front( adjType->clone() );
+				delete varExpr->get_result();
+				varExpr->set_result( adjType->clone() );
 				PRINT(
 					std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " ";
@@ -606,5 +591,5 @@
 				PointerType pt( Type::Qualifiers(), v.clone() );
 				UntypedExpr *vexpr = untypedExpr->clone();
-				vexpr->get_results().push_front( pt.clone() );
+				vexpr->set_result( pt.clone() );
 				alternatives.push_back( Alternative( vexpr, env, Cost()) );
 				return;
@@ -634,5 +619,5 @@
 				// check if the type is pointer to function
 				PointerType *pointer;
-				if ( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) {
+				if ( ( pointer = dynamic_cast< PointerType* >( func->expr->get_result() ) ) ) {
 					if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
 						for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
@@ -670,6 +655,5 @@
 						// check if the type is pointer to function
 						PointerType *pointer;
-						if ( funcOp->expr->get_results().size() == 1
-							&& ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) {
+						if ( ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result() ) ) ) {
 							if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
 								for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
@@ -696,5 +680,5 @@
 			PRINT(
 				ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( withFunc->expr );
-				PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
+				PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
 				FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
 				std::cerr << "Case +++++++++++++" << std::endl;
@@ -719,8 +703,6 @@
 
 	bool isLvalue( Expression *expr ) {
-		for ( std::list< Type* >::const_iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) {
-			if ( !(*i)->get_isLvalue() ) return false;
-		} // for
-		return true;
+		// xxx - recurse into tuples?
+		return expr->has_result() && expr->get_result()->get_isLvalue();
 	}
 
@@ -736,9 +718,8 @@
 
 	void AlternativeFinder::visit( CastExpr *castExpr ) {
-		for ( std::list< Type* >::iterator i = castExpr->get_results().begin(); i != castExpr->get_results().end(); ++i ) {
-			*i = resolveTypeof( *i, indexer );
-			SymTab::validateType( *i, &indexer );
-			adjustExprType( *i, env, indexer );
-		} // for
+		Type *& toType = castExpr->get_result();
+		toType = resolveTypeof( toType, indexer );
+		SymTab::validateType( toType, &indexer );
+		adjustExprType( toType, env, indexer );
 
 		AlternativeFinder finder( indexer, env );
@@ -754,15 +735,10 @@
 			// that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
 			// to.
-			int discardedValues = (*i).expr->get_results().size() - castExpr->get_results().size();
+			int discardedValues = (*i).expr->get_result()->size() - castExpr->get_result()->size();
 			if ( discardedValues < 0 ) continue;
-			std::list< Type* >::iterator candidate_end = (*i).expr->get_results().begin();
-			std::advance( candidate_end, castExpr->get_results().size() );
+			// xxx - may need to go into tuple types and extract relavent types and use unifyList
 			// unification run for side-effects
-			unifyList( castExpr->get_results().begin(), castExpr->get_results().end(),
-					   (*i).expr->get_results().begin(), candidate_end,
-			           i->env, needAssertions, haveAssertions, openVars, indexer );
-			Cost thisCost = castCostList( (*i).expr->get_results().begin(), candidate_end,
-										  castExpr->get_results().begin(), castExpr->get_results().end(),
-										  indexer, i->env );
+			unify( castExpr->get_result(), (*i).expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer );
+			Cost thisCost = castCost( (*i).expr->get_result(), castExpr->get_result(), indexer, i->env );
 			if ( thisCost != Cost::infinity ) {
 				// count one safe conversion for each value that is thrown away
@@ -787,10 +763,8 @@
 
 		for ( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) {
-			if ( agg->expr->get_results().size() == 1 ) {
-				if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_results().front() ) ) {
-					addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
-				} else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_results().front() ) ) {
-					addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
-				} // if
+			if ( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_result() ) ) {
+				addAggMembers( structInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
+			} else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_result() ) ) {
+				addAggMembers( unionInst, agg->expr, agg->cost, agg->env, memberExpr->get_member() );
 			} // if
 		} // for
@@ -923,5 +897,5 @@
 			alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) );
 			for ( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) {
-				alternatives.back().expr->get_results().push_back( (*i)->get_type()->clone() );
+				alternatives.back().expr->set_result( (*i)->get_type()->clone() );
 			} // for
 		} // if
@@ -946,6 +920,6 @@
 							finder.find( attrExpr->get_expr() );
 							for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) {
-								if ( choice->expr->get_results().size() == 1 ) {
-									resolveAttr(*i, function, choice->expr->get_results().front(), choice->env );
+								if ( choice->expr->get_result()->size() == 1 ) {
+									resolveAttr(*i, function, choice->expr->get_result(), choice->env );
 								} // fi
 							} // for
@@ -989,16 +963,8 @@
 					AssertionSet needAssertions, haveAssertions;
 					Alternative newAlt( 0, third->env, first->cost + second->cost + third->cost );
-					std::list< Type* > commonTypes;
-					if ( unifyList( second->expr->get_results().begin(), second->expr->get_results().end(), third->expr->get_results().begin(), third->expr->get_results().end(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) {
+					Type* commonType;
+					if ( unify( second->expr->get_result(), third->expr->get_result(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
 						ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() );
-						std::list< Type* >::const_iterator original = second->expr->get_results().begin();
-						std::list< Type* >::const_iterator commonType = commonTypes.begin();
-						for ( ; original != second->expr->get_results().end() && commonType != commonTypes.end(); ++original, ++commonType ) {
-							if ( *commonType ) {
-								newExpr->get_results().push_back( *commonType );
-							} else {
-								newExpr->get_results().push_back( (*original)->clone() );
-							} // if
-						} // for
+						newExpr->set_result( commonType ? commonType : second->expr->get_result()->clone() );
 						newAlt.expr = newExpr;
 						inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
@@ -1028,9 +994,12 @@
 			TupleExpr *newExpr = new TupleExpr;
 			makeExprList( *i, newExpr->get_exprs() );
-			for ( std::list< Expression* >::const_iterator resultExpr = newExpr->get_exprs().begin(); resultExpr != newExpr->get_exprs().end(); ++resultExpr ) {
-				for ( std::list< Type* >::const_iterator resultType = (*resultExpr)->get_results().begin(); resultType != (*resultExpr)->get_results().end(); ++resultType ) {
-					newExpr->get_results().push_back( (*resultType)->clone() );
-				} // for
+			TupleType *tupleType = new TupleType( Type::Qualifiers(true, true, true, true, true, true) );
+			Type::Qualifiers &qualifiers = tupleType->get_qualifiers();
+			for ( Expression * resultExpr : newExpr->get_exprs() ) {
+				Type * type = resultExpr->get_result()->clone();
+				tupleType->get_types().push_back( type );
+				qualifiers &= type->get_qualifiers();
 			} // for
+			newExpr->set_result( tupleType );
 
 			TypeEnvironment compositeEnv;
@@ -1057,4 +1026,8 @@
 		alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );
 	}
+
+	void AlternativeFinder::visit( TupleAssignExpr *tupleAssignExpr ) {
+		alternatives.push_back( Alternative( tupleAssignExpr->clone(), env, Cost::zero ) );
+	}
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/AlternativeFinder.h
===================================================================
--- src/ResolvExpr/AlternativeFinder.h	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/ResolvExpr/AlternativeFinder.h	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -68,4 +68,5 @@
 		virtual void visit( ConstructorExpr * ctorExpr );
 		virtual void visit( TupleIndexExpr *tupleExpr );
+		virtual void visit( TupleAssignExpr *tupleExpr );
 		/// Runs a new alternative finder on each element in [begin, end)
 		/// and writes each alternative finder to out.
Index: src/ResolvExpr/AlternativePrinter.cc
===================================================================
--- src/ResolvExpr/AlternativePrinter.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/ResolvExpr/AlternativePrinter.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// AlternativePrinter.cc -- 
+// AlternativePrinter.cc --
 //
 // Author           : Richard C. Bilson
@@ -33,5 +33,5 @@
 		for ( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
 			os << "Alternative " << count++ << " ==============" << std::endl;
-			printAll( i->expr->get_results(), os );
+			i->expr->get_result()->print( os );
 			//    i->print( os );
 			os << std::endl;
Index: src/ResolvExpr/ResolveTypeof.cc
===================================================================
--- src/ResolvExpr/ResolveTypeof.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/ResolvExpr/ResolveTypeof.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// ResolveTypeof.cc -- 
+// ResolveTypeof.cc --
 //
 // Author           : Richard C. Bilson
@@ -58,13 +58,6 @@
 		if ( typeofType->get_expr() ) {
 			Expression *newExpr = resolveInVoidContext( typeofType->get_expr(), indexer );
-			assert( newExpr->get_results().size() > 0 );
-			Type *newType;
-			if ( newExpr->get_results().size() > 1 ) {
-				TupleType *tupleType = new TupleType( Type::Qualifiers() );
-				cloneAll( newExpr->get_results(), tupleType->get_types() );
-				newType = tupleType;
-			} else {
-				newType = newExpr->get_results().front()->clone();
-			} // if
+			assert( newExpr->has_result() && ! newExpr->get_result()->isVoid() );
+			Type *newType = newExpr->get_result();
 			delete typeofType;
 			return newType;
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/ResolvExpr/Resolver.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -19,4 +19,5 @@
 #include "RenameVars.h"
 #include "ResolveTypeof.h"
+#include "typeops.h"
 #include "SynTree/Statement.h"
 #include "SynTree/Type.h"
@@ -67,5 +68,5 @@
 	  void resolveSingleAggrInit( Declaration *, InitIterator &, InitIterator & );
 	  void fallbackInit( ConstructorInit * ctorInit );
-		std::list< Type * > functionReturn;
+		Type * functionReturn;
 		Type *initContext;
 		Type *switchType;
@@ -155,5 +156,5 @@
 			const TypeEnvironment *newEnv = 0;
 			for ( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
-				if ( i->expr->get_results().size() == 1 && isIntegralType( i->expr->get_results().front() ) ) {
+				if ( i->expr->get_result()->size() == 1 && isIntegralType( i->expr->get_result() ) ) {
 					if ( newExpr ) {
 						throw SemanticError( "Too many interpretations for case control expression", untyped );
@@ -232,11 +233,7 @@
 		Type *new_type = resolveTypeof( functionDecl->get_type(), *this );
 		functionDecl->set_type( new_type );
-		std::list< Type * > oldFunctionReturn = functionReturn;
-		functionReturn.clear();
-		for ( std::list< DeclarationWithType * >::const_iterator i = functionDecl->get_functionType()->get_returnVals().begin(); i != functionDecl->get_functionType()->get_returnVals().end(); ++i ) {
-			functionReturn.push_back( (*i)->get_type() );
-		} // for
+		ValueGuard< Type * > oldFunctionReturn( functionReturn );
+		functionReturn = ResolvExpr::extractResultType( functionDecl->get_functionType() );
 		SymTab::Indexer::visit( functionDecl );
-		functionReturn = oldFunctionReturn;
 	}
 
@@ -336,6 +333,5 @@
 	void Resolver::visit( ReturnStmt *returnStmt ) {
 		if ( returnStmt->get_expr() ) {
-			CastExpr *castExpr = new CastExpr( returnStmt->get_expr() );
-			cloneAll( functionReturn, castExpr->get_results() );
+			CastExpr *castExpr = new CastExpr( returnStmt->get_expr(), functionReturn->clone() );
 			Expression *newExpr = findSingleExpression( castExpr, *this );
 			delete castExpr;
@@ -382,5 +378,5 @@
 				if ( isCharType( at->get_base() ) ) {
 					// check if the resolved type is char *
-					if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_results().front() ) ) {
+					if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) {
 						if ( isCharType( pt->get_base() ) ) {
 							// strip cast if we're initializing a char[] with a char *, e.g.  char x[] = "hello";
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/ResolvExpr/Unify.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -588,4 +588,19 @@
 	}
 
+	// xxx - compute once and store in the FunctionType?
+	Type * extractResultType( FunctionType * function ) {
+		if ( function->get_returnVals().size() == 0 ) {
+			return new VoidType( Type::Qualifiers() );
+		} else if ( function->get_returnVals().size() == 1 ) {
+			return function->get_returnVals().front()->get_type()->clone();
+		} else {
+			TupleType * tupleType = new TupleType( Type::Qualifiers() );
+			for ( DeclarationWithType * decl : function->get_returnVals() ) {
+				tupleType->get_types().push_back( decl->get_type()->clone() );
+			} // for
+			return tupleType;
+		}
+	}
+
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/typeops.h
===================================================================
--- src/ResolvExpr/typeops.h	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/ResolvExpr/typeops.h	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// typeops.h -- 
+// typeops.h --
 //
 // Author           : Richard C. Bilson
@@ -30,10 +30,10 @@
 		typedef typename InputIterator::value_type SetType;
 		typedef typename std::list< typename SetType::value_type > ListType;
-  
+
 		if ( begin == end )	{
 			*out++ = ListType();
 			return;
 		} // if
-  
+
 		InputIterator current = begin;
 		begin++;
@@ -41,5 +41,5 @@
 		std::list< ListType > recursiveResult;
 		combos( begin, end, back_inserter( recursiveResult ) );
-  
+
 		for ( typename std::list< ListType >::const_iterator i = recursiveResult.begin(); i != recursiveResult.end(); ++i ) {
 			for ( typename ListType::const_iterator j = current->begin(); j != current->end(); ++j ) {
@@ -52,5 +52,5 @@
 		} // for
 	}
-  
+
 	// in AdjustExprType.cc
 	/// Replaces array types with the equivalent pointer, and function types with a pointer-to-function
@@ -144,4 +144,7 @@
 	}
 
+	/// creates the type represented by the list of returnVals in a FunctionType. The caller owns the return value.
+	Type * extractResultType( FunctionType * functionType );
+
 	// in CommonType.cc
 	Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
@@ -152,4 +155,16 @@
 	// in Occurs.cc
 	bool occurs( Type *type, std::string varName, const TypeEnvironment &env );
+
+	// flatten tuple type into list of types
+	template< typename OutputIterator >
+	void flatten( Type * type, OutputIterator out ) {
+		if ( TupleType * tupleType = dynamic_cast< TupleType * >( type ) ) {
+			for ( Type * t : tupleType->get_types() ) {
+				flatten( t, out );
+			}
+		} else {
+			*out++ = type;
+		}
+	}
 } // namespace ResolvExpr
 
Index: src/SymTab/Autogen.cc
===================================================================
--- src/SymTab/Autogen.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/SymTab/Autogen.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -116,6 +116,7 @@
 		// This happens before function pointer type conversion, so need to do it manually here
 		VariableExpr * assignVarExpr = new VariableExpr( assignDecl );
-		Type *& assignVarExprType = assignVarExpr->get_results().front();
+		Type * assignVarExprType = assignVarExpr->get_result();
 		assignVarExprType = new PointerType( Type::Qualifiers(), assignVarExprType );
+		assignVarExpr->set_result( assignVarExprType );
 		ApplicationExpr * assignExpr = new ApplicationExpr( assignVarExpr );
 		assignExpr->get_args().push_back( new VariableExpr( dstParam ) );
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/SymTab/Indexer.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -40,8 +40,8 @@
 
 namespace SymTab {
-	template< typename Container, typename VisitorType >
-	inline void acceptAllNewScope( Container &container, VisitorType &visitor ) {
+	template< typename TreeType, typename VisitorType >
+	inline void acceptNewScope( TreeType *tree, VisitorType &visitor ) {
 		visitor.enterScope();
-		acceptAll( container, visitor );
+		maybeAccept( tree, visitor );
 		visitor.leaveScope();
 	}
@@ -337,5 +337,5 @@
 
 	void Indexer::visit( ApplicationExpr *applicationExpr ) {
-		acceptAllNewScope( applicationExpr->get_results(), *this );
+		acceptNewScope( applicationExpr->get_result(), *this );
 		maybeAccept( applicationExpr->get_function(), *this );
 		acceptAll( applicationExpr->get_args(), *this );
@@ -343,48 +343,48 @@
 
 	void Indexer::visit( UntypedExpr *untypedExpr ) {
-		acceptAllNewScope( untypedExpr->get_results(), *this );
+		acceptNewScope( untypedExpr->get_result(), *this );
 		acceptAll( untypedExpr->get_args(), *this );
 	}
 
 	void Indexer::visit( NameExpr *nameExpr ) {
-		acceptAllNewScope( nameExpr->get_results(), *this );
+		acceptNewScope( nameExpr->get_result(), *this );
 	}
 
 	void Indexer::visit( AddressExpr *addressExpr ) {
-		acceptAllNewScope( addressExpr->get_results(), *this );
+		acceptNewScope( addressExpr->get_result(), *this );
 		maybeAccept( addressExpr->get_arg(), *this );
 	}
 
 	void Indexer::visit( LabelAddressExpr *labAddressExpr ) {
-		acceptAllNewScope( labAddressExpr->get_results(), *this );
+		acceptNewScope( labAddressExpr->get_result(), *this );
 		maybeAccept( labAddressExpr->get_arg(), *this );
 	}
 
 	void Indexer::visit( CastExpr *castExpr ) {
-		acceptAllNewScope( castExpr->get_results(), *this );
+		acceptNewScope( castExpr->get_result(), *this );
 		maybeAccept( castExpr->get_arg(), *this );
 	}
 
 	void Indexer::visit( UntypedMemberExpr *memberExpr ) {
-		acceptAllNewScope( memberExpr->get_results(), *this );
+		acceptNewScope( memberExpr->get_result(), *this );
 		maybeAccept( memberExpr->get_aggregate(), *this );
 	}
 
 	void Indexer::visit( MemberExpr *memberExpr ) {
-		acceptAllNewScope( memberExpr->get_results(), *this );
+		acceptNewScope( memberExpr->get_result(), *this );
 		maybeAccept( memberExpr->get_aggregate(), *this );
 	}
 
 	void Indexer::visit( VariableExpr *variableExpr ) {
-		acceptAllNewScope( variableExpr->get_results(), *this );
+		acceptNewScope( variableExpr->get_result(), *this );
 	}
 
 	void Indexer::visit( ConstantExpr *constantExpr ) {
-		acceptAllNewScope( constantExpr->get_results(), *this );
+		acceptNewScope( constantExpr->get_result(), *this );
 		maybeAccept( constantExpr->get_constant(), *this );
 	}
 
 	void Indexer::visit( SizeofExpr *sizeofExpr ) {
-		acceptAllNewScope( sizeofExpr->get_results(), *this );
+		acceptNewScope( sizeofExpr->get_result(), *this );
 		if ( sizeofExpr->get_isType() ) {
 			maybeAccept( sizeofExpr->get_type(), *this );
@@ -395,5 +395,5 @@
 
 	void Indexer::visit( AlignofExpr *alignofExpr ) {
-		acceptAllNewScope( alignofExpr->get_results(), *this );
+		acceptNewScope( alignofExpr->get_result(), *this );
 		if ( alignofExpr->get_isType() ) {
 			maybeAccept( alignofExpr->get_type(), *this );
@@ -404,10 +404,10 @@
 
 	void Indexer::visit( UntypedOffsetofExpr *offsetofExpr ) {
-		acceptAllNewScope( offsetofExpr->get_results(), *this );
+		acceptNewScope( offsetofExpr->get_result(), *this );
 		maybeAccept( offsetofExpr->get_type(), *this );
 	}
 
 	void Indexer::visit( OffsetofExpr *offsetofExpr ) {
-		acceptAllNewScope( offsetofExpr->get_results(), *this );
+		acceptNewScope( offsetofExpr->get_result(), *this );
 		maybeAccept( offsetofExpr->get_type(), *this );
 		maybeAccept( offsetofExpr->get_member(), *this );
@@ -415,10 +415,10 @@
 
 	void Indexer::visit( OffsetPackExpr *offsetPackExpr ) {
-		acceptAllNewScope( offsetPackExpr->get_results(), *this );
+		acceptNewScope( offsetPackExpr->get_result(), *this );
 		maybeAccept( offsetPackExpr->get_type(), *this );
 	}
 
 	void Indexer::visit( AttrExpr *attrExpr ) {
-		acceptAllNewScope( attrExpr->get_results(), *this );
+		acceptNewScope( attrExpr->get_result(), *this );
 		if ( attrExpr->get_isType() ) {
 			maybeAccept( attrExpr->get_type(), *this );
@@ -429,5 +429,5 @@
 
 	void Indexer::visit( LogicalExpr *logicalExpr ) {
-		acceptAllNewScope( logicalExpr->get_results(), *this );
+		acceptNewScope( logicalExpr->get_result(), *this );
 		maybeAccept( logicalExpr->get_arg1(), *this );
 		maybeAccept( logicalExpr->get_arg2(), *this );
@@ -435,5 +435,5 @@
 
 	void Indexer::visit( ConditionalExpr *conditionalExpr ) {
-		acceptAllNewScope( conditionalExpr->get_results(), *this );
+		acceptNewScope( conditionalExpr->get_result(), *this );
 		maybeAccept( conditionalExpr->get_arg1(), *this );
 		maybeAccept( conditionalExpr->get_arg2(), *this );
@@ -442,5 +442,5 @@
 
 	void Indexer::visit( CommaExpr *commaExpr ) {
-		acceptAllNewScope( commaExpr->get_results(), *this );
+		acceptNewScope( commaExpr->get_result(), *this );
 		maybeAccept( commaExpr->get_arg1(), *this );
 		maybeAccept( commaExpr->get_arg2(), *this );
@@ -448,10 +448,10 @@
 
 	void Indexer::visit( TupleExpr *tupleExpr ) {
-		acceptAllNewScope( tupleExpr->get_results(), *this );
+		acceptNewScope( tupleExpr->get_result(), *this );
 		acceptAll( tupleExpr->get_exprs(), *this );
 	}
 
 	void Indexer::visit( TupleAssignExpr *tupleExpr ) {
-		acceptAllNewScope( tupleExpr->get_results(), *this );
+		acceptNewScope( tupleExpr->get_result(), *this );
 		enterScope();
 		acceptAll( tupleExpr->get_tempDecls(), *this );
@@ -461,5 +461,5 @@
 
 	void Indexer::visit( TypeExpr *typeExpr ) {
-		acceptAllNewScope( typeExpr->get_results(), *this );
+		acceptNewScope( typeExpr->get_result(), *this );
 		maybeAccept( typeExpr->get_type(), *this );
 	}
@@ -472,5 +472,5 @@
 
 	void Indexer::visit( UntypedValofExpr *valofExpr ) {
-		acceptAllNewScope( valofExpr->get_results(), *this );
+		acceptNewScope( valofExpr->get_result(), *this );
 		maybeAccept( valofExpr->get_body(), *this );
 	}
Index: src/SynTree/AddressExpr.cc
===================================================================
--- src/SynTree/AddressExpr.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/SynTree/AddressExpr.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -19,7 +19,7 @@
 
 AddressExpr::AddressExpr( Expression *arg, Expression *_aname ) : Expression( _aname ), arg( arg ) {
-	for ( std::list< Type* >::const_iterator i = arg->get_results().begin(); i != arg->get_results().end(); ++i ) {
-		get_results().push_back( new PointerType( Type::Qualifiers(), (*i)->clone() ) );
-	} // for
+	if ( arg->has_result() ) {
+		set_result( new PointerType( Type::Qualifiers(), arg->get_result()->clone() ) );
+	}
 }
 
@@ -35,5 +35,5 @@
 	if ( arg ) {
 		os << std::string( indent+2, ' ' );
-    arg->print( os, indent+2 );
+		arg->print( os, indent+2 );
 	} // if
 }
Index: src/SynTree/ApplicationExpr.cc
===================================================================
--- src/SynTree/ApplicationExpr.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/SynTree/ApplicationExpr.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -21,5 +21,5 @@
 #include "TypeSubstitution.h"
 #include "Common/utility.h"
-
+#include "ResolvExpr/typeops.h"
 
 ParamEntry::ParamEntry( const ParamEntry &other ) :
@@ -43,12 +43,10 @@
 
 ApplicationExpr::ApplicationExpr( Expression *funcExpr ) : function( funcExpr ) {
-	PointerType *pointer = dynamic_cast< PointerType* >( funcExpr->get_results().front() );
-	assert( pointer );
-	FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
-	assert( function );
+	PointerType *pointer = safe_dynamic_cast< PointerType* >( funcExpr->get_result() );
+	FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
 
-	for ( std::list< DeclarationWithType* >::const_iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) {
-		get_results().push_back( (*i)->get_type()->clone() );
-	} // for
+	set_result( ResolvExpr::extractResultType( function ) );
+
+	assert( has_result() );
 }
 
Index: src/SynTree/CommaExpr.cc
===================================================================
--- src/SynTree/CommaExpr.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/SynTree/CommaExpr.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -23,8 +23,6 @@
 	// to false on all result types. Actually doing this causes some strange things
 	// to happen in later passes (particularly, Specialize, Lvalue, and Box). This needs to be looked into.
-	cloneAll( arg2->get_results(), get_results() );
-	// for ( Type *& type : get_results() ) {
-	// 	type->set_isLvalue( false );
-	// }
+	set_result( maybeClone( arg2->get_result() ) );
+	// get_type->set_isLvalue( false );
 }
 
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/SynTree/Expression.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -31,8 +31,7 @@
 
 
-Expression::Expression( Expression *_aname ) : env( 0 ), argName( _aname ) {}
-
-Expression::Expression( const Expression &other ) : env( maybeClone( other.env ) ), argName( maybeClone( other.get_argName() ) ), extension( other.extension ) {
-	cloneAll( other.results, results );
+Expression::Expression( Expression *_aname ) : result( 0 ), env( 0 ), argName( _aname ) {}
+
+Expression::Expression( const Expression &other ) : result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), argName( maybeClone( other.get_argName() ) ), extension( other.extension ) {
 }
 
@@ -40,13 +39,5 @@
 	delete env;
 	delete argName;	// xxx -- there's a problem in cloning ConstantExpr I still don't know how to fix
-	deleteAll( results );
-}
-
-void Expression::add_result( Type *t ) {
-	if ( TupleType *tuple = dynamic_cast< TupleType* >( t ) ) {
-		std::copy( tuple->get_types().begin(), tuple->get_types().end(), back_inserter( results ) );
-	} else {
-		results.push_back(t);
-	} // if
+	delete result;
 }
 
@@ -68,5 +59,5 @@
 
 ConstantExpr::ConstantExpr( Constant _c, Expression *_aname ) : Expression( _aname ), constant( _c ) {
-	add_result( constant.get_type()->clone() );
+	set_result( constant.get_type()->clone() );
 }
 
@@ -85,8 +76,7 @@
 	assert( var );
 	assert( var->get_type() );
-	add_result( var->get_type()->clone() );
-	for ( std::list< Type* >::iterator i = get_results().begin(); i != get_results().end(); ++i ) {
-		(*i)->set_isLvalue( true );
-	} // for
+	Type * type = var->get_type()->clone();
+	type->set_isLvalue( true );
+	set_result( type );
 }
 
@@ -110,10 +100,10 @@
 SizeofExpr::SizeofExpr( Expression *expr_, Expression *_aname ) :
 		Expression( _aname ), expr(expr_), type(0), isType(false) {
-	add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
+	set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
 }
 
 SizeofExpr::SizeofExpr( Type *type_, Expression *_aname ) :
 		Expression( _aname ), expr(0), type(type_), isType(true) {
-	add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
+	set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
 }
 
@@ -141,10 +131,10 @@
 AlignofExpr::AlignofExpr( Expression *expr_, Expression *_aname ) :
 		Expression( _aname ), expr(expr_), type(0), isType(false) {
-	add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
+	set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
 }
 
 AlignofExpr::AlignofExpr( Type *type_, Expression *_aname ) :
 		Expression( _aname ), expr(0), type(type_), isType(true) {
-	add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
+	set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
 }
 
@@ -172,5 +162,5 @@
 UntypedOffsetofExpr::UntypedOffsetofExpr( Type *type_, const std::string &member_, Expression *_aname ) :
 		Expression( _aname ), type(type_), member(member_) {
-	add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
+	set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
 }
 
@@ -197,5 +187,5 @@
 OffsetofExpr::OffsetofExpr( Type *type_, DeclarationWithType *member_, Expression *_aname ) :
 		Expression( _aname ), type(type_), member(member_) {
-	add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
+	set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
 }
 
@@ -229,5 +219,5 @@
 
 OffsetPackExpr::OffsetPackExpr( StructInstType *type_, Expression *aname_ ) : Expression( aname_ ), type( type_ ) {
-	add_result( new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0, false, false ) );
+	set_result( new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0, false, false ) );
 }
 
@@ -284,8 +274,9 @@
 
 CastExpr::CastExpr( Expression *arg_, Type *toType, Expression *_aname ) : Expression( _aname ), arg(arg_) {
-	add_result(toType);
+	set_result(toType);
 }
 
 CastExpr::CastExpr( Expression *arg_, Expression *_aname ) : Expression( _aname ), arg(arg_) {
+	set_result( new VoidType( Type::Qualifiers() ) );
 }
 
@@ -303,9 +294,11 @@
 	arg->print(os, indent+2);
 	os << std::endl << std::string( indent, ' ' ) << "to:" << std::endl;
-	if ( results.empty() ) {
-		os << std::string( indent+2, ' ' ) << "nothing" << std::endl;
+	os << std::string( indent+2, ' ' );
+	if ( result->isVoid() ) {
+		os << "nothing";
 	} else {
-		printAll(results, os, indent+2);
+		result->print( os, indent+2 );
 	} // if
+	os << std::endl;
 	Expression::print( os, indent );
 }
@@ -341,8 +334,6 @@
 MemberExpr::MemberExpr( DeclarationWithType *_member, Expression *_aggregate, Expression *_aname ) :
 		Expression( _aname ), member(_member), aggregate(_aggregate) {
-	add_result( member->get_type()->clone() );
-	for ( std::list< Type* >::iterator i = get_results().begin(); i != get_results().end(); ++i ) {
-		(*i)->set_isLvalue( true );
-	} // for
+	set_result( member->get_type()->clone() );
+	get_result()->set_isLvalue( true );
 }
 
@@ -419,5 +410,5 @@
 LogicalExpr::LogicalExpr( Expression *arg1_, Expression *arg2_, bool andp, Expression *_aname ) :
 		Expression( _aname ), arg1(arg1_), arg2(arg2_), isAnd(andp) {
-	add_result( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
+	set_result( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
 }
 
@@ -477,5 +468,6 @@
 ImplicitCopyCtorExpr::ImplicitCopyCtorExpr( ApplicationExpr * callExpr ) : callExpr( callExpr ) {
 	assert( callExpr );
-	cloneAll( callExpr->get_results(), results );
+	assert( callExpr->has_result() );
+	set_result( callExpr->get_result()->clone() );
 }
 
@@ -510,5 +502,5 @@
 	Expression * arg = InitTweak::getCallArg( callExpr, 0 );
 	assert( arg );
-	cloneAll( arg->get_results(), results );
+	set_result( maybeClone( arg->get_result() ) );
 }
 
@@ -530,5 +522,5 @@
 
 CompoundLiteralExpr::CompoundLiteralExpr( Type * type, Initializer * initializer ) : type( type ), initializer( initializer ) {
-	add_result( type->clone() );
+	set_result( type->clone() );
 }
 
@@ -570,5 +562,5 @@
 	if ( ! body.empty() ) {
 		if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( body.back() ) ) {
-			cloneAll( exprStmt->get_expr()->get_results(), get_results() );
+			set_result( maybeClone( exprStmt->get_expr()->get_result() ) );
 		}
 	}
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/SynTree/Expression.h	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -32,6 +32,7 @@
 	virtual ~Expression();
 
-	std::list<Type *>& get_results() { return results; }
-	void add_result( Type *t );
+	Type *& get_result() { return result; }
+	void set_result( Type *newValue ) { result = newValue; }
+	bool has_result() const { return result != nullptr; }
 
 	TypeSubstitution *get_env() const { return env; }
@@ -47,5 +48,5 @@
 	virtual void print( std::ostream &os, int indent = 0 ) const;
   protected:
-	std::list<Type *> results;
+	Type * result;
 	TypeSubstitution *env;
 	Expression* argName; // if expression is used as an argument, it can be "designated" by this name
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/SynTree/Mutator.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -178,5 +178,5 @@
 
 Expression *Mutator::mutate( ApplicationExpr *applicationExpr ) {
-	mutateAll( applicationExpr->get_results(), *this );
+	applicationExpr->set_result( maybeMutate( applicationExpr->get_result(), *this ) );
 	applicationExpr->set_function( maybeMutate( applicationExpr->get_function(), *this ) );
 	mutateAll( applicationExpr->get_args(), *this );
@@ -185,5 +185,5 @@
 
 Expression *Mutator::mutate( UntypedExpr *untypedExpr ) {
-	mutateAll( untypedExpr->get_results(), *this );
+	untypedExpr->set_result( maybeMutate( untypedExpr->get_result(), *this ) );
 	mutateAll( untypedExpr->get_args(), *this );
 	return untypedExpr;
@@ -191,10 +191,10 @@
 
 Expression *Mutator::mutate( NameExpr *nameExpr ) {
-	mutateAll( nameExpr->get_results(), *this );
+	nameExpr->set_result( maybeMutate( nameExpr->get_result(), *this ) );
 	return nameExpr;
 }
 
 Expression *Mutator::mutate( AddressExpr *addressExpr ) {
-	mutateAll( addressExpr->get_results(), *this );
+	addressExpr->set_result( maybeMutate( addressExpr->get_result(), *this ) );
 	addressExpr->set_arg( maybeMutate( addressExpr->get_arg(), *this ) );
 	return addressExpr;
@@ -202,5 +202,5 @@
 
 Expression *Mutator::mutate( LabelAddressExpr *labelAddressExpr ) {
-	mutateAll( labelAddressExpr->get_results(), *this );
+	labelAddressExpr->set_result( maybeMutate( labelAddressExpr->get_result(), *this ) );
 	labelAddressExpr->set_arg( maybeMutate( labelAddressExpr->get_arg(), *this ) );
 	return labelAddressExpr;
@@ -208,5 +208,5 @@
 
 Expression *Mutator::mutate( CastExpr *castExpr ) {
-	mutateAll( castExpr->get_results(), *this );
+	castExpr->set_result( maybeMutate( castExpr->get_result(), *this ) );
 	castExpr->set_arg( maybeMutate( castExpr->get_arg(), *this ) );
 	return castExpr;
@@ -214,5 +214,5 @@
 
 Expression *Mutator::mutate( UntypedMemberExpr *memberExpr ) {
-	mutateAll( memberExpr->get_results(), *this );
+	memberExpr->set_result( maybeMutate( memberExpr->get_result(), *this ) );
 	memberExpr->set_aggregate( maybeMutate( memberExpr->get_aggregate(), *this ) );
 	memberExpr->set_member( maybeMutate( memberExpr->get_member(), *this ) );
@@ -221,5 +221,5 @@
 
 Expression *Mutator::mutate( MemberExpr *memberExpr ) {
-	mutateAll( memberExpr->get_results(), *this );
+	memberExpr->set_result( maybeMutate( memberExpr->get_result(), *this ) );
 	memberExpr->set_aggregate( maybeMutate( memberExpr->get_aggregate(), *this ) );
 	return memberExpr;
@@ -227,10 +227,10 @@
 
 Expression *Mutator::mutate( VariableExpr *variableExpr ) {
-	mutateAll( variableExpr->get_results(), *this );
+	variableExpr->set_result( maybeMutate( variableExpr->get_result(), *this ) );
 	return variableExpr;
 }
 
 Expression *Mutator::mutate( ConstantExpr *constantExpr ) {
-	mutateAll( constantExpr->get_results(), *this );
+	constantExpr->set_result( maybeMutate( constantExpr->get_result(), *this ) );
 //  maybeMutate( constantExpr->get_constant(), *this )
 	return constantExpr;
@@ -238,5 +238,5 @@
 
 Expression *Mutator::mutate( SizeofExpr *sizeofExpr ) {
-	mutateAll( sizeofExpr->get_results(), *this );
+	sizeofExpr->set_result( maybeMutate( sizeofExpr->get_result(), *this ) );
 	if ( sizeofExpr->get_isType() ) {
 		sizeofExpr->set_type( maybeMutate( sizeofExpr->get_type(), *this ) );
@@ -248,5 +248,5 @@
 
 Expression *Mutator::mutate( AlignofExpr *alignofExpr ) {
-	mutateAll( alignofExpr->get_results(), *this );
+	alignofExpr->set_result( maybeMutate( alignofExpr->get_result(), *this ) );
 	if ( alignofExpr->get_isType() ) {
 		alignofExpr->set_type( maybeMutate( alignofExpr->get_type(), *this ) );
@@ -258,5 +258,5 @@
 
 Expression *Mutator::mutate( UntypedOffsetofExpr *offsetofExpr ) {
-	mutateAll( offsetofExpr->get_results(), *this );
+	offsetofExpr->set_result( maybeMutate( offsetofExpr->get_result(), *this ) );
 	offsetofExpr->set_type( maybeMutate( offsetofExpr->get_type(), *this ) );
 	return offsetofExpr;
@@ -264,5 +264,5 @@
 
 Expression *Mutator::mutate( OffsetofExpr *offsetofExpr ) {
-	mutateAll( offsetofExpr->get_results(), *this );
+	offsetofExpr->set_result( maybeMutate( offsetofExpr->get_result(), *this ) );
 	offsetofExpr->set_type( maybeMutate( offsetofExpr->get_type(), *this ) );
 	offsetofExpr->set_member( maybeMutate( offsetofExpr->get_member(), *this ) );
@@ -271,5 +271,5 @@
 
 Expression *Mutator::mutate( OffsetPackExpr *offsetPackExpr ) {
-	mutateAll( offsetPackExpr->get_results(), *this );
+	offsetPackExpr->set_result( maybeMutate( offsetPackExpr->get_result(), *this ) );
 	offsetPackExpr->set_type( maybeMutate( offsetPackExpr->get_type(), *this ) );
 	return offsetPackExpr;
@@ -277,5 +277,5 @@
 
 Expression *Mutator::mutate( AttrExpr *attrExpr ) {
-	mutateAll( attrExpr->get_results(), *this );
+	attrExpr->set_result( maybeMutate( attrExpr->get_result(), *this ) );
 	if ( attrExpr->get_isType() ) {
 		attrExpr->set_type( maybeMutate( attrExpr->get_type(), *this ) );
@@ -287,5 +287,5 @@
 
 Expression *Mutator::mutate( LogicalExpr *logicalExpr ) {
-	mutateAll( logicalExpr->get_results(), *this );
+	logicalExpr->set_result( maybeMutate( logicalExpr->get_result(), *this ) );
 	logicalExpr->set_arg1( maybeMutate( logicalExpr->get_arg1(), *this ) );
 	logicalExpr->set_arg2( maybeMutate( logicalExpr->get_arg2(), *this ) );
@@ -294,5 +294,5 @@
 
 Expression *Mutator::mutate( ConditionalExpr *conditionalExpr ) {
-	mutateAll( conditionalExpr->get_results(), *this );
+	conditionalExpr->set_result( maybeMutate( conditionalExpr->get_result(), *this ) );
 	conditionalExpr->set_arg1( maybeMutate( conditionalExpr->get_arg1(), *this ) );
 	conditionalExpr->set_arg2( maybeMutate( conditionalExpr->get_arg2(), *this ) );
@@ -302,5 +302,5 @@
 
 Expression *Mutator::mutate( CommaExpr *commaExpr ) {
-	mutateAll( commaExpr->get_results(), *this );
+	commaExpr->set_result( maybeMutate( commaExpr->get_result(), *this ) );
 	commaExpr->set_arg1( maybeMutate( commaExpr->get_arg1(), *this ) );
 	commaExpr->set_arg2( maybeMutate( commaExpr->get_arg2(), *this ) );
@@ -309,5 +309,5 @@
 
 Expression *Mutator::mutate( TypeExpr *typeExpr ) {
-	mutateAll( typeExpr->get_results(), *this );
+	typeExpr->set_result( maybeMutate( typeExpr->get_result(), *this ) );
 	typeExpr->set_type( maybeMutate( typeExpr->get_type(), *this ) );
 	return typeExpr;
@@ -329,5 +329,5 @@
 
 Expression* Mutator::mutate( ConstructorExpr *ctorExpr ) {
-	mutateAll( ctorExpr->get_results(), *this );
+	ctorExpr->set_result( maybeMutate( ctorExpr->get_result(), *this ) );
 	ctorExpr->set_callExpr( maybeMutate( ctorExpr->get_callExpr(), *this ) );
 	return ctorExpr;
@@ -335,5 +335,5 @@
 
 Expression *Mutator::mutate( CompoundLiteralExpr *compLitExpr ) {
-	mutateAll( compLitExpr->get_results(), *this );
+	compLitExpr->set_result( maybeMutate( compLitExpr->get_result(), *this ) );
 	compLitExpr->set_type( maybeMutate( compLitExpr->get_type(), *this ) );
 	compLitExpr->set_initializer( maybeMutate( compLitExpr->get_initializer(), *this ) );
@@ -342,5 +342,5 @@
 
 Expression *Mutator::mutate( UntypedValofExpr *valofExpr ) {
-	mutateAll( valofExpr->get_results(), *this );
+	valofExpr->set_result( maybeMutate( valofExpr->get_result(), *this ) );
 	return valofExpr;
 }
@@ -353,5 +353,5 @@
 
 Expression *Mutator::mutate( TupleExpr *tupleExpr ) {
-	mutateAll( tupleExpr->get_results(), *this );
+	tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) );
 	mutateAll( tupleExpr->get_exprs(), *this );
 	return tupleExpr;
@@ -359,5 +359,5 @@
 
 Expression *Mutator::mutate( TupleIndexExpr *tupleExpr ) {
-	mutateAll( tupleExpr->get_results(), *this );
+	tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) );
 	tupleExpr->set_tuple( maybeMutate( tupleExpr->get_tuple(), *this ) );
 	return tupleExpr;
@@ -365,5 +365,5 @@
 
 Expression *Mutator::mutate( MemberTupleExpr *tupleExpr ) {
-	mutateAll( tupleExpr->get_results(), *this );
+	tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) );
 	tupleExpr->set_member( maybeMutate( tupleExpr->get_member(), *this ) );
 	tupleExpr->set_aggregate( maybeMutate( tupleExpr->get_aggregate(), *this ) );
@@ -372,5 +372,5 @@
 
 Expression *Mutator::mutate( TupleAssignExpr *assignExpr ) {
-	mutateAll( assignExpr->get_results(), *this );
+	assignExpr->set_result( maybeMutate( assignExpr->get_result(), *this ) );
 	mutateAll( assignExpr->get_tempDecls(), *this );
 	mutateAll( assignExpr->get_assigns(), *this );
@@ -379,5 +379,5 @@
 
 Expression *Mutator::mutate( StmtExpr *stmtExpr ) {
-	mutateAll( stmtExpr->get_results(), *this );
+	stmtExpr->set_result( maybeMutate( stmtExpr->get_result(), *this ) );
 	stmtExpr->set_statements( maybeMutate( stmtExpr->get_statements(), *this ) );
 	return stmtExpr;
Index: src/SynTree/TupleExpr.cc
===================================================================
--- src/SynTree/TupleExpr.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/SynTree/TupleExpr.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -31,5 +31,5 @@
 
 void TupleExpr::print( std::ostream &os, int indent ) const {
-	os << std::string( indent, ' ' ) << "Tuple:" << std::endl;
+	os << "Tuple:" << std::endl;
 	printAll( exprs, os, indent+2 );
 	Expression::print( os, indent );
@@ -37,7 +37,7 @@
 
 TupleIndexExpr::TupleIndexExpr( Expression * tuple, unsigned int index ) {
-	// TupleType * type = safe_dynamic_cast< TypeType * >( tuple->get_ )
-	assert( tuple->get_results().size() >= index );
-	add_result( *std::next( tuple->get_results().begin(), index ) );
+	TupleType * type = safe_dynamic_cast< TupleType * >( tuple->get_result() );
+	assert( type->size() >= index );
+	set_result( *std::next( type->get_types().begin(), index ) );
 }
 
@@ -50,5 +50,5 @@
 
 void TupleIndexExpr::print( std::ostream &os, int indent ) const {
-	os << std::string( indent, ' ' ) << "Tuple Index Expression, with tuple:" << std::endl;
+	os << "Tuple Index Expression, with tuple:" << std::endl;
 	tuple->print( os, indent+2 );
 	os << std::string( indent+2, ' ' ) << "with index: " << index << std::endl;
@@ -57,5 +57,5 @@
 
 MemberTupleExpr::MemberTupleExpr( Expression * member, Expression * aggregate, Expression * _aname ) : Expression( _aname ) {
-	cloneAll( member->get_results(), get_results() ); // xxx - ???
+	set_result( maybeClone( member->get_result() ) ); // xxx - ???
 }
 
@@ -69,5 +69,5 @@
 
 void MemberTupleExpr::print( std::ostream &os, int indent ) const {
-	os << std::string( indent, ' ' ) << "Member Tuple Expression, with aggregate:" << std::endl;
+	os << "Member Tuple Expression, with aggregate:" << std::endl;
 	aggregate->print( os, indent+2 );
 	os << std::string( indent+2, ' ' ) << "with member: " << std::endl;
@@ -78,7 +78,10 @@
 
 TupleAssignExpr::TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls, Expression * _aname ) : Expression( _aname ), assigns( assigns ), tempDecls( tempDecls ) {
+	TupleType * type = new TupleType( Type::Qualifiers() );
 	for ( Expression * expr : assigns ) {
-		cloneAll( expr->get_results(), get_results() );
+		assert( expr->has_result() );
+		type->get_types().push_back( expr->get_result()->clone() );
 	}
+	set_result( type );
 }
 
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/SynTree/Type.h	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -27,4 +27,5 @@
 		Qualifiers( bool isConst, bool isVolatile, bool isRestrict, bool isLvalue, bool isAtomic, bool isAttribute ): isConst( isConst ), isVolatile( isVolatile ), isRestrict( isRestrict ), isLvalue( isLvalue ), isAtomic( isAtomic ), isAttribute( isAttribute ) {}
 
+		Qualifiers &operator&=( const Qualifiers &other );
 		Qualifiers &operator+=( const Qualifiers &other );
 		Qualifiers &operator-=( const Qualifiers &other );
@@ -65,4 +66,8 @@
 	std::list<TypeDecl*>& get_forall() { return forall; }
 
+	/// How many elemental types are represented by this type
+	virtual unsigned size() const { return 1; };
+	virtual bool isVoid() const { return size() == 0; }
+
 	virtual Type *clone() const = 0;
 	virtual void accept( Visitor &v ) = 0;
@@ -77,4 +82,6 @@
   public:
 	VoidType( const Type::Qualifiers &tq );
+
+	virtual unsigned size() const { return 0; };
 
 	virtual VoidType *clone() const { return new VoidType( *this ); }
@@ -357,4 +364,5 @@
 
 	std::list<Type*>& get_types() { return types; }
+	virtual unsigned size() const { return types.size(); };
 
 	iterator begin() { return types.begin(); }
@@ -425,4 +433,13 @@
 };
 
+inline Type::Qualifiers &Type::Qualifiers::operator&=( const Type::Qualifiers &other ) {
+	isConst &= other.isConst;
+	isVolatile &= other.isVolatile;
+	isRestrict &= other.isRestrict;
+	isLvalue &= other.isLvalue;
+	isAtomic &= other.isAtomic;
+	return *this;
+}
+
 inline Type::Qualifiers &Type::Qualifiers::operator+=( const Type::Qualifiers &other ) {
 	isConst |= other.isConst;
Index: src/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/SynTree/Visitor.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -150,5 +150,5 @@
 
 void Visitor::visit( ApplicationExpr *applicationExpr ) {
-	acceptAll( applicationExpr->get_results(), *this );
+	maybeAccept( applicationExpr->get_result(), *this );
 	maybeAccept( applicationExpr->get_function(), *this );
 	acceptAll( applicationExpr->get_args(), *this );
@@ -156,29 +156,29 @@
 
 void Visitor::visit( UntypedExpr *untypedExpr ) {
-	acceptAll( untypedExpr->get_results(), *this );
+	maybeAccept( untypedExpr->get_result(), *this );
 	acceptAll( untypedExpr->get_args(), *this );
 }
 
 void Visitor::visit( NameExpr *nameExpr ) {
-	acceptAll( nameExpr->get_results(), *this );
+	maybeAccept( nameExpr->get_result(), *this );
 }
 
 void Visitor::visit( AddressExpr *addressExpr ) {
-	acceptAll( addressExpr->get_results(), *this );
+	maybeAccept( addressExpr->get_result(), *this );
 	maybeAccept( addressExpr->get_arg(), *this );
 }
 
 void Visitor::visit( LabelAddressExpr *labAddressExpr ) {
-	acceptAll( labAddressExpr->get_results(), *this );
+	maybeAccept( labAddressExpr->get_result(), *this );
 	maybeAccept( labAddressExpr->get_arg(), *this );
 }
 
 void Visitor::visit( CastExpr *castExpr ) {
-	acceptAll( castExpr->get_results(), *this );
+	maybeAccept( castExpr->get_result(), *this );
 	maybeAccept( castExpr->get_arg(), *this );
 }
 
 void Visitor::visit( UntypedMemberExpr *memberExpr ) {
-	acceptAll( memberExpr->get_results(), *this );
+	maybeAccept( memberExpr->get_result(), *this );
 	maybeAccept( memberExpr->get_aggregate(), *this );
 	maybeAccept( memberExpr->get_member(), *this );
@@ -186,19 +186,19 @@
 
 void Visitor::visit( MemberExpr *memberExpr ) {
-	acceptAll( memberExpr->get_results(), *this );
+	maybeAccept( memberExpr->get_result(), *this );
 	maybeAccept( memberExpr->get_aggregate(), *this );
 }
 
 void Visitor::visit( VariableExpr *variableExpr ) {
-	acceptAll( variableExpr->get_results(), *this );
+	maybeAccept( variableExpr->get_result(), *this );
 }
 
 void Visitor::visit( ConstantExpr *constantExpr ) {
-	acceptAll( constantExpr->get_results(), *this );
+	maybeAccept( constantExpr->get_result(), *this );
 	maybeAccept( constantExpr->get_constant(), *this );
 }
 
 void Visitor::visit( SizeofExpr *sizeofExpr ) {
-	acceptAll( sizeofExpr->get_results(), *this );
+	maybeAccept( sizeofExpr->get_result(), *this );
 	if ( sizeofExpr->get_isType() ) {
 		maybeAccept( sizeofExpr->get_type(), *this );
@@ -209,5 +209,5 @@
 
 void Visitor::visit( AlignofExpr *alignofExpr ) {
-	acceptAll( alignofExpr->get_results(), *this );
+	maybeAccept( alignofExpr->get_result(), *this );
 	if ( alignofExpr->get_isType() ) {
 		maybeAccept( alignofExpr->get_type(), *this );
@@ -218,10 +218,10 @@
 
 void Visitor::visit( UntypedOffsetofExpr *offsetofExpr ) {
-	acceptAll( offsetofExpr->get_results(), *this );
+	maybeAccept( offsetofExpr->get_result(), *this );
 	maybeAccept( offsetofExpr->get_type(), *this );
 }
 
 void Visitor::visit( OffsetofExpr *offsetofExpr ) {
-	acceptAll( offsetofExpr->get_results(), *this );
+	maybeAccept( offsetofExpr->get_result(), *this );
 	maybeAccept( offsetofExpr->get_type(), *this );
 	maybeAccept( offsetofExpr->get_member(), *this );
@@ -229,10 +229,10 @@
 
 void Visitor::visit( OffsetPackExpr *offsetPackExpr ) {
-	acceptAll( offsetPackExpr->get_results(), *this );
+	maybeAccept( offsetPackExpr->get_result(), *this );
 	maybeAccept( offsetPackExpr->get_type(), *this );
 }
 
 void Visitor::visit( AttrExpr *attrExpr ) {
-	acceptAll( attrExpr->get_results(), *this );
+	maybeAccept( attrExpr->get_result(), *this );
 	if ( attrExpr->get_isType() ) {
 		maybeAccept( attrExpr->get_type(), *this );
@@ -243,5 +243,5 @@
 
 void Visitor::visit( LogicalExpr *logicalExpr ) {
-	acceptAll( logicalExpr->get_results(), *this );
+	maybeAccept( logicalExpr->get_result(), *this );
 	maybeAccept( logicalExpr->get_arg1(), *this );
 	maybeAccept( logicalExpr->get_arg2(), *this );
@@ -249,5 +249,5 @@
 
 void Visitor::visit( ConditionalExpr *conditionalExpr ) {
-	acceptAll( conditionalExpr->get_results(), *this );
+	maybeAccept( conditionalExpr->get_result(), *this );
 	maybeAccept( conditionalExpr->get_arg1(), *this );
 	maybeAccept( conditionalExpr->get_arg2(), *this );
@@ -256,5 +256,5 @@
 
 void Visitor::visit( CommaExpr *commaExpr ) {
-	acceptAll( commaExpr->get_results(), *this );
+	maybeAccept( commaExpr->get_result(), *this );
 	maybeAccept( commaExpr->get_arg1(), *this );
 	maybeAccept( commaExpr->get_arg2(), *this );
@@ -262,5 +262,5 @@
 
 void Visitor::visit( TypeExpr *typeExpr ) {
-	acceptAll( typeExpr->get_results(), *this );
+	maybeAccept( typeExpr->get_result(), *this );
 	maybeAccept( typeExpr->get_type(), *this );
 }
@@ -279,10 +279,10 @@
 
 void Visitor::visit( ConstructorExpr * ctorExpr ) {
-	acceptAll( ctorExpr->get_results(), *this );
+	maybeAccept( ctorExpr->get_result(), *this );
 	maybeAccept( ctorExpr->get_callExpr(), *this );
 }
 
 void Visitor::visit( CompoundLiteralExpr *compLitExpr ) {
-	acceptAll( compLitExpr->get_results(), *this );
+	maybeAccept( compLitExpr->get_result(), *this );
 	maybeAccept( compLitExpr->get_type(), *this );
 	maybeAccept( compLitExpr->get_initializer(), *this );
@@ -290,5 +290,5 @@
 
 void Visitor::visit( UntypedValofExpr *valofExpr ) {
-	acceptAll( valofExpr->get_results(), *this );
+	maybeAccept( valofExpr->get_result(), *this );
 	maybeAccept( valofExpr->get_body(), *this );
 }
@@ -300,15 +300,15 @@
 
 void Visitor::visit( TupleExpr *tupleExpr ) {
-	acceptAll( tupleExpr->get_results(), *this );
+	maybeAccept( tupleExpr->get_result(), *this );
 	acceptAll( tupleExpr->get_exprs(), *this );
 }
 
 void Visitor::visit( TupleIndexExpr *tupleExpr ) {
-	acceptAll( tupleExpr->get_results(), *this );
+	maybeAccept( tupleExpr->get_result(), *this );
 	maybeAccept( tupleExpr->get_tuple(), *this );
 }
 
 void Visitor::visit( MemberTupleExpr *tupleExpr ) {
-	acceptAll( tupleExpr->get_results(), *this );
+	maybeAccept( tupleExpr->get_result(), *this );
 	maybeAccept( tupleExpr->get_member(), *this );
 	maybeAccept( tupleExpr->get_aggregate(), *this );
@@ -316,5 +316,5 @@
 
 void Visitor::visit( TupleAssignExpr *assignExpr ) {
-	acceptAll( assignExpr->get_results(), *this );
+	maybeAccept( assignExpr->get_result(), *this );
 	acceptAll( assignExpr->get_tempDecls(), *this );
 	acceptAll( assignExpr->get_assigns(), *this );
@@ -322,5 +322,5 @@
 
 void Visitor::visit( StmtExpr *stmtExpr ) {
-	acceptAll( stmtExpr->get_results(), *this );
+	maybeAccept( stmtExpr->get_result(), *this );
 	maybeAccept( stmtExpr->get_statements(), *this );
 }
Index: src/Tuples/TupleAssignment.cc
===================================================================
--- src/Tuples/TupleAssignment.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/Tuples/TupleAssignment.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -88,7 +88,7 @@
 	bool isTuple( Expression *expr ) {
 		if ( ! expr ) return false;
-
+		assert( expr->has_result() );
 		// xxx - used to include cast to varExpr and call to isTupleVar, but this doesn't seem like it should be necessary
-		return dynamic_cast<TupleExpr *>(expr) || expr->get_results().size() > 1;
+		return dynamic_cast<TupleExpr *>(expr) || expr->get_result()->size() > 1;
 	}
 
@@ -102,5 +102,6 @@
 
 	bool isTupleExpr( Expression *expr ) {
-		return expr->get_results().size() > 1;
+		assert( expr->has_result() );
+		return expr->get_result()->size() > 1;
 	}
 
@@ -191,14 +192,6 @@
 
 	ObjectDecl * newObject( UniqueName & namer, Expression * expr ) {
-		Type * type;
-		assert( expr->get_results().size() >= 1 );
-		if ( expr->get_results().size() > 1 ) {
-			TupleType * tt = new TupleType( Type::Qualifiers() );
-			cloneAll( expr->get_results(), tt->get_types() );
-			type = tt;
-		} else {
-			type = expr->get_results().front()->clone();
-		}
-		return new ObjectDecl( namer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, type, new SingleInit( expr->clone() ) );
+		assert( expr->has_result() && ! expr->get_result()->isVoid() );
+		return new ObjectDecl( namer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, expr->get_result()->clone(), new SingleInit( expr->clone() ) );
 	}
 
Index: src/Tuples/TupleExpansion.cc
===================================================================
--- src/Tuples/TupleExpansion.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/Tuples/TupleExpansion.cc	(revision aa8f9dfd89cb8d2df9f8a3892703dfc427bce64a)
@@ -85,6 +85,7 @@
 			addDeclaration( decl );
 		}
+		Type::Qualifiers qualifiers = newType->get_qualifiers();
 		delete newType;
-		return new StructInstType( newType->get_qualifiers(), typeMap[mangleName] );
+		return new StructInstType( qualifiers, typeMap[mangleName] );
 	}
 
