Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/CodeGen/CodeGenerator.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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 {
@@ -654,4 +653,10 @@
 		asmExpr->get_operand()->accept( *this );
 		output << " )";
+	}
+
+	void CodeGenerator::visit( StmtExpr * stmtExpr ) {
+		output << "(";
+		stmtExpr->get_statements()->accept( *this );
+		output << ")";
 	}
 
Index: src/CodeGen/CodeGenerator.h
===================================================================
--- src/CodeGen/CodeGenerator.h	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/CodeGen/CodeGenerator.h	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -73,4 +73,5 @@
 		virtual void visit( TypeExpr *typeExpr );
 		virtual void visit( AsmExpr * );
+		virtual void visit( StmtExpr * );
 
 		//*** Statements
Index: c/ControlStruct/LabelTypeChecker.cc
===================================================================
--- src/ControlStruct/LabelTypeChecker.cc	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ 	(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 fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ 	(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 fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/ControlStruct/Mutate.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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 fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/ControlStruct/module.mk	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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 fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/GenPoly/Box.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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 fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/GenPoly/Lvalue.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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 fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/GenPoly/Specialize.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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 fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/InitTweak/FixInit.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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 fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/InitTweak/InitTweak.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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;
@@ -388,5 +387,5 @@
 				return memberExpr->get_member()->get_name();
 			} else if ( UntypedMemberExpr * memberExpr = dynamic_cast< UntypedMemberExpr * > ( func ) ) {
-				return memberExpr->get_member();
+				return funcName( memberExpr->get_member() );
 			} else {
 				assertf( false, "Unexpected expression type being called as a function in call expression" );
@@ -451,10 +450,10 @@
 		// virtual void visit( LogicalExpr *logicalExpr );
 		// virtual void visit( ConditionalExpr *conditionalExpr );
-		virtual void visit( TupleExpr *tupleExpr ) { isConstExpr = false; }
-		virtual void visit( SolvedTupleExpr *tupleExpr ) { isConstExpr = false; }
 		virtual void visit( TypeExpr *typeExpr ) { isConstExpr = false; }
 		virtual void visit( AsmExpr *asmExpr ) { isConstExpr = false; }
 		virtual void visit( UntypedValofExpr *valofExpr ) { isConstExpr = false; }
 		virtual void visit( CompoundLiteralExpr *compLitExpr ) { isConstExpr = false; }
+		virtual void visit( TupleExpr *tupleExpr ) { isConstExpr = false; }
+		virtual void visit( TupleAssignExpr *tupleExpr ) { isConstExpr = false; }
 
 		bool isConstExpr;
Index: src/Makefile.in
===================================================================
--- src/Makefile.in	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/Makefile.in	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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) \
@@ -189,5 +188,5 @@
 	SynTree/driver_cfa_cpp-Attribute.$(OBJEXT) \
 	Tuples/driver_cfa_cpp-TupleAssignment.$(OBJEXT) \
-	Tuples/driver_cfa_cpp-NameMatcher.$(OBJEXT)
+	Tuples/driver_cfa_cpp-TupleExpansion.$(OBJEXT)
 am_driver_cfa_cpp_OBJECTS = $(am__objects_1)
 driver_cfa_cpp_OBJECTS = $(am_driver_cfa_cpp_OBJECTS)
@@ -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 \
@@ -402,5 +400,5 @@
 	SynTree/AddStmtVisitor.cc SynTree/TypeSubstitution.cc \
 	SynTree/Attribute.cc Tuples/TupleAssignment.cc \
-	Tuples/NameMatcher.cc
+	Tuples/TupleExpansion.cc
 MAINTAINERCLEANFILES = Parser/parser.output ${libdir}/${notdir \
 	${cfa_cpplib_PROGRAMS}}
@@ -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)
@@ -769,6 +764,6 @@
 Tuples/driver_cfa_cpp-TupleAssignment.$(OBJEXT):  \
 	Tuples/$(am__dirstamp) Tuples/$(DEPDIR)/$(am__dirstamp)
-Tuples/driver_cfa_cpp-NameMatcher.$(OBJEXT): Tuples/$(am__dirstamp) \
-	Tuples/$(DEPDIR)/$(am__dirstamp)
+Tuples/driver_cfa_cpp-TupleExpansion.$(OBJEXT):  \
+	Tuples/$(am__dirstamp) Tuples/$(DEPDIR)/$(am__dirstamp)
 driver/$(am__dirstamp):
 	@$(MKDIR_P) driver
@@ -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)
@@ -877,6 +871,6 @@
 	-rm -f SynTree/driver_cfa_cpp-Visitor.$(OBJEXT)
 	-rm -f SynTree/driver_cfa_cpp-VoidType.$(OBJEXT)
-	-rm -f Tuples/driver_cfa_cpp-NameMatcher.$(OBJEXT)
 	-rm -f Tuples/driver_cfa_cpp-TupleAssignment.$(OBJEXT)
+	-rm -f Tuples/driver_cfa_cpp-TupleExpansion.$(OBJEXT)
 
 distclean-compile:
@@ -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@
@@ -982,6 +975,6 @@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Visitor.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-VoidType.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp-TupleAssignment.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Po@am__quote@
 
 .cc.o:
@@ -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
@@ -2401,17 +2380,17 @@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-TupleAssignment.obj `if test -f 'Tuples/TupleAssignment.cc'; then $(CYGPATH_W) 'Tuples/TupleAssignment.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/TupleAssignment.cc'; fi`
 
-Tuples/driver_cfa_cpp-NameMatcher.o: Tuples/NameMatcher.cc
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-NameMatcher.o -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Tpo -c -o Tuples/driver_cfa_cpp-NameMatcher.o `test -f 'Tuples/NameMatcher.cc' || echo '$(srcdir)/'`Tuples/NameMatcher.cc
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='Tuples/NameMatcher.cc' object='Tuples/driver_cfa_cpp-NameMatcher.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 Tuples/driver_cfa_cpp-NameMatcher.o `test -f 'Tuples/NameMatcher.cc' || echo '$(srcdir)/'`Tuples/NameMatcher.cc
-
-Tuples/driver_cfa_cpp-NameMatcher.obj: Tuples/NameMatcher.cc
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-NameMatcher.obj -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Tpo -c -o Tuples/driver_cfa_cpp-NameMatcher.obj `if test -f 'Tuples/NameMatcher.cc'; then $(CYGPATH_W) 'Tuples/NameMatcher.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/NameMatcher.cc'; fi`
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='Tuples/NameMatcher.cc' object='Tuples/driver_cfa_cpp-NameMatcher.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 Tuples/driver_cfa_cpp-NameMatcher.obj `if test -f 'Tuples/NameMatcher.cc'; then $(CYGPATH_W) 'Tuples/NameMatcher.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/NameMatcher.cc'; fi`
+Tuples/driver_cfa_cpp-TupleExpansion.o: Tuples/TupleExpansion.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-TupleExpansion.o -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Tpo -c -o Tuples/driver_cfa_cpp-TupleExpansion.o `test -f 'Tuples/TupleExpansion.cc' || echo '$(srcdir)/'`Tuples/TupleExpansion.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='Tuples/TupleExpansion.cc' object='Tuples/driver_cfa_cpp-TupleExpansion.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 Tuples/driver_cfa_cpp-TupleExpansion.o `test -f 'Tuples/TupleExpansion.cc' || echo '$(srcdir)/'`Tuples/TupleExpansion.cc
+
+Tuples/driver_cfa_cpp-TupleExpansion.obj: Tuples/TupleExpansion.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-TupleExpansion.obj -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Tpo -c -o Tuples/driver_cfa_cpp-TupleExpansion.obj `if test -f 'Tuples/TupleExpansion.cc'; then $(CYGPATH_W) 'Tuples/TupleExpansion.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/TupleExpansion.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='Tuples/TupleExpansion.cc' object='Tuples/driver_cfa_cpp-TupleExpansion.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 Tuples/driver_cfa_cpp-TupleExpansion.obj `if test -f 'Tuples/TupleExpansion.cc'; then $(CYGPATH_W) 'Tuples/TupleExpansion.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/TupleExpansion.cc'; fi`
 
 .ll.cc:
Index: src/Parser/ExpressionNode.cc
===================================================================
--- src/Parser/ExpressionNode.cc	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/Parser/ExpressionNode.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -200,15 +200,13 @@
 }
 
-Expression *build_fieldSel( ExpressionNode *expr_node, NameExpr *member ) {
-	UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), maybeMoveBuild< Expression >(expr_node) );
-	delete member;
-	return ret;
-}
-
-Expression *build_pfieldSel( ExpressionNode *expr_node, NameExpr *member ) {
+Expression *build_fieldSel( ExpressionNode *expr_node, Expression *member ) {
+	UntypedMemberExpr *ret = new UntypedMemberExpr( member, maybeMoveBuild< Expression >(expr_node) );
+	return ret;
+}
+
+Expression *build_pfieldSel( ExpressionNode *expr_node, Expression *member ) {
 	UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
 	deref->get_args().push_back( maybeMoveBuild< Expression >(expr_node) );
-	UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), deref );
-	delete member;
+	UntypedMemberExpr *ret = new UntypedMemberExpr( member, deref );
 	return ret;
 }
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/Parser/ParseNode.h	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -165,6 +165,6 @@
 
 Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
-Expression * build_fieldSel( ExpressionNode * expr_node, NameExpr * member );
-Expression * build_pfieldSel( ExpressionNode * expr_node, NameExpr * member );
+Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
+Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
 Expression * build_addressOf( ExpressionNode * expr_node );
 Expression * build_sizeOfexpr( ExpressionNode * expr_node );
Index: src/Parser/parser.cc
===================================================================
--- src/Parser/parser.cc	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/Parser/parser.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -1023,78 +1023,78 @@
        0,   300,   300,   304,   311,   312,   313,   317,   318,   319,
      323,   324,   328,   329,   333,   334,   338,   342,   343,   354,
-     356,   358,   360,   365,   366,   372,   376,   378,   379,   381,
-     382,   384,   386,   388,   397,   398,   404,   405,   409,   410,
-     414,   418,   420,   422,   424,   429,   432,   434,   436,   441,
-     454,   456,   458,   460,   462,   464,   466,   468,   470,   472,
-     474,   481,   482,   488,   489,   490,   491,   495,   496,   498,
-     503,   504,   506,   508,   513,   514,   516,   521,   522,   524,
-     529,   530,   532,   534,   536,   541,   542,   544,   549,   550,
-     555,   556,   561,   562,   567,   568,   573,   574,   579,   580,
-     583,   585,   590,   595,   596,   598,   604,   605,   609,   610,
-     611,   612,   613,   614,   615,   616,   617,   618,   619,   620,
-     626,   628,   630,   632,   637,   638,   643,   644,   650,   651,
-     657,   658,   659,   660,   661,   662,   663,   664,   665,   675,
-     682,   684,   694,   695,   700,   702,   708,   710,   714,   715,
-     720,   725,   728,   730,   732,   742,   744,   755,   756,   758,
-     762,   764,   768,   769,   774,   775,   779,   784,   785,   789,
-     791,   797,   798,   802,   804,   806,   808,   814,   815,   819,
-     821,   826,   828,   830,   835,   837,   842,   844,   848,   851,
-     855,   858,   862,   864,   866,   868,   873,   875,   877,   882,
-     884,   886,   888,   890,   895,   897,   899,   901,   906,   918,
-     919,   924,   926,   931,   935,   937,   939,   941,   943,   949,
-     950,   956,   957,   961,   962,   967,   969,   975,   976,   978,
-     983,   988,   998,  1000,  1004,  1005,  1010,  1012,  1016,  1017,
-    1021,  1023,  1027,  1028,  1032,  1033,  1037,  1038,  1053,  1054,
-    1055,  1056,  1057,  1061,  1066,  1073,  1083,  1088,  1093,  1101,
-    1106,  1111,  1116,  1121,  1129,  1151,  1156,  1163,  1165,  1172,
-    1177,  1182,  1193,  1198,  1203,  1208,  1213,  1222,  1227,  1235,
-    1236,  1237,  1238,  1244,  1249,  1257,  1258,  1259,  1260,  1264,
-    1265,  1266,  1267,  1272,  1273,  1282,  1283,  1288,  1289,  1294,
-    1296,  1298,  1300,  1302,  1305,  1304,  1316,  1317,  1319,  1329,
-    1330,  1335,  1337,  1339,  1341,  1343,  1346,  1348,  1351,  1356,
-    1358,  1360,  1362,  1364,  1366,  1368,  1370,  1372,  1374,  1376,
-    1378,  1380,  1386,  1387,  1389,  1391,  1393,  1398,  1399,  1405,
-    1406,  1408,  1410,  1415,  1417,  1419,  1421,  1426,  1427,  1429,
-    1431,  1436,  1437,  1439,  1444,  1445,  1447,  1449,  1454,  1456,
-    1458,  1463,  1464,  1468,  1470,  1476,  1475,  1479,  1481,  1486,
-    1488,  1494,  1495,  1500,  1501,  1503,  1504,  1513,  1514,  1516,
-    1518,  1523,  1525,  1531,  1532,  1534,  1537,  1540,  1545,  1546,
-    1551,  1556,  1560,  1562,  1568,  1567,  1574,  1576,  1582,  1583,
-    1591,  1592,  1596,  1597,  1598,  1600,  1602,  1609,  1610,  1612,
-    1614,  1619,  1620,  1626,  1627,  1631,  1632,  1637,  1638,  1639,
-    1641,  1649,  1650,  1652,  1655,  1657,  1661,  1662,  1663,  1665,
-    1667,  1671,  1676,  1684,  1685,  1694,  1696,  1701,  1702,  1703,
-    1707,  1708,  1709,  1713,  1714,  1715,  1719,  1720,  1721,  1726,
-    1727,  1728,  1729,  1735,  1736,  1738,  1743,  1744,  1749,  1750,
-    1751,  1752,  1753,  1768,  1769,  1774,  1775,  1781,  1783,  1786,
-    1788,  1790,  1813,  1814,  1816,  1818,  1823,  1824,  1826,  1831,
-    1836,  1837,  1843,  1842,  1846,  1850,  1852,  1854,  1860,  1861,
-    1866,  1871,  1873,  1878,  1880,  1881,  1883,  1888,  1890,  1892,
-    1897,  1899,  1904,  1909,  1917,  1923,  1922,  1936,  1937,  1942,
-    1943,  1947,  1952,  1957,  1965,  1970,  1981,  1982,  1987,  1988,
-    1994,  1995,  1999,  2000,  2001,  2004,  2003,  2014,  2023,  2029,
-    2035,  2044,  2050,  2056,  2062,  2068,  2076,  2082,  2090,  2096,
-    2105,  2106,  2107,  2111,  2115,  2117,  2122,  2123,  2127,  2128,
-    2133,  2139,  2140,  2143,  2145,  2146,  2150,  2151,  2152,  2153,
-    2187,  2189,  2190,  2192,  2197,  2202,  2207,  2209,  2211,  2216,
-    2218,  2220,  2222,  2227,  2229,  2238,  2240,  2241,  2246,  2248,
-    2250,  2255,  2257,  2259,  2264,  2266,  2268,  2277,  2278,  2279,
-    2283,  2285,  2287,  2292,  2294,  2296,  2301,  2303,  2305,  2320,
-    2322,  2323,  2325,  2330,  2331,  2336,  2338,  2340,  2345,  2347,
-    2349,  2351,  2356,  2358,  2360,  2370,  2372,  2373,  2375,  2380,
-    2382,  2384,  2389,  2391,  2393,  2395,  2400,  2402,  2404,  2435,
-    2437,  2438,  2440,  2445,  2450,  2458,  2460,  2462,  2467,  2469,
-    2474,  2476,  2490,  2491,  2493,  2498,  2500,  2502,  2504,  2506,
-    2511,  2512,  2514,  2516,  2521,  2523,  2525,  2531,  2533,  2535,
-    2539,  2541,  2543,  2545,  2559,  2560,  2562,  2567,  2569,  2571,
-    2573,  2575,  2580,  2581,  2583,  2585,  2590,  2592,  2594,  2600,
-    2601,  2603,  2612,  2615,  2617,  2620,  2622,  2624,  2637,  2638,
-    2640,  2645,  2647,  2649,  2651,  2653,  2658,  2659,  2661,  2663,
-    2668,  2670,  2678,  2679,  2680,  2685,  2686,  2690,  2692,  2694,
-    2696,  2698,  2700,  2707,  2709,  2711,  2713,  2715,  2717,  2719,
-    2721,  2723,  2725,  2730,  2732,  2734,  2739,  2765,  2766,  2768,
-    2772,  2773,  2777,  2779,  2781,  2783,  2785,  2787,  2794,  2796,
-    2798,  2800,  2802,  2804,  2809,  2814,  2816,  2818,  2836,  2838,
-    2843,  2844
+     356,   358,   360,   365,   366,   372,   376,   378,   380,   382,
+     384,   386,   388,   390,   399,   400,   406,   407,   411,   412,
+     416,   420,   422,   424,   426,   431,   434,   436,   438,   443,
+     456,   458,   460,   462,   464,   466,   468,   470,   472,   474,
+     476,   483,   484,   490,   491,   492,   493,   497,   498,   500,
+     505,   506,   508,   510,   515,   516,   518,   523,   524,   526,
+     531,   532,   534,   536,   538,   543,   544,   546,   551,   552,
+     557,   558,   563,   564,   569,   570,   575,   576,   581,   582,
+     585,   587,   592,   597,   598,   600,   606,   607,   611,   612,
+     613,   614,   615,   616,   617,   618,   619,   620,   621,   622,
+     628,   630,   632,   634,   639,   640,   645,   646,   652,   653,
+     659,   660,   661,   662,   663,   664,   665,   666,   667,   677,
+     684,   686,   696,   697,   702,   704,   710,   712,   716,   717,
+     722,   727,   730,   732,   734,   744,   746,   757,   758,   760,
+     764,   766,   770,   771,   776,   777,   781,   786,   787,   791,
+     793,   799,   800,   804,   806,   808,   810,   816,   817,   821,
+     823,   828,   830,   832,   837,   839,   844,   846,   850,   853,
+     857,   860,   864,   866,   868,   870,   875,   877,   879,   884,
+     886,   888,   890,   892,   897,   899,   901,   903,   908,   920,
+     921,   926,   928,   933,   937,   939,   941,   943,   945,   951,
+     952,   958,   959,   963,   964,   969,   971,   977,   978,   980,
+     985,   990,  1000,  1002,  1006,  1007,  1012,  1014,  1018,  1019,
+    1023,  1025,  1029,  1030,  1034,  1035,  1039,  1040,  1055,  1056,
+    1057,  1058,  1059,  1063,  1068,  1075,  1085,  1090,  1095,  1103,
+    1108,  1113,  1118,  1123,  1131,  1153,  1158,  1165,  1167,  1174,
+    1179,  1184,  1195,  1200,  1205,  1210,  1215,  1224,  1229,  1237,
+    1238,  1239,  1240,  1246,  1251,  1259,  1260,  1261,  1262,  1266,
+    1267,  1268,  1269,  1274,  1275,  1284,  1285,  1290,  1291,  1296,
+    1298,  1300,  1302,  1304,  1307,  1306,  1318,  1319,  1321,  1331,
+    1332,  1337,  1339,  1341,  1343,  1345,  1348,  1350,  1353,  1358,
+    1360,  1362,  1364,  1366,  1368,  1370,  1372,  1374,  1376,  1378,
+    1380,  1382,  1388,  1389,  1391,  1393,  1395,  1400,  1401,  1407,
+    1408,  1410,  1412,  1417,  1419,  1421,  1423,  1428,  1429,  1431,
+    1433,  1438,  1439,  1441,  1446,  1447,  1449,  1451,  1456,  1458,
+    1460,  1465,  1466,  1470,  1472,  1478,  1477,  1481,  1483,  1488,
+    1490,  1496,  1497,  1502,  1503,  1505,  1506,  1515,  1516,  1518,
+    1520,  1525,  1527,  1533,  1534,  1536,  1539,  1542,  1547,  1548,
+    1553,  1558,  1562,  1564,  1570,  1569,  1576,  1578,  1584,  1585,
+    1593,  1594,  1598,  1599,  1600,  1602,  1604,  1611,  1612,  1614,
+    1616,  1621,  1622,  1628,  1629,  1633,  1634,  1639,  1640,  1641,
+    1643,  1651,  1652,  1654,  1657,  1659,  1663,  1664,  1665,  1667,
+    1669,  1673,  1678,  1686,  1687,  1696,  1698,  1703,  1704,  1705,
+    1709,  1710,  1711,  1715,  1716,  1717,  1721,  1722,  1723,  1728,
+    1729,  1730,  1731,  1737,  1738,  1740,  1745,  1746,  1751,  1752,
+    1753,  1754,  1755,  1770,  1771,  1776,  1777,  1783,  1785,  1788,
+    1790,  1792,  1815,  1816,  1818,  1820,  1825,  1826,  1828,  1833,
+    1838,  1839,  1845,  1844,  1848,  1852,  1854,  1856,  1862,  1863,
+    1868,  1873,  1875,  1880,  1882,  1883,  1885,  1890,  1892,  1894,
+    1899,  1901,  1906,  1911,  1919,  1925,  1924,  1938,  1939,  1944,
+    1945,  1949,  1954,  1959,  1967,  1972,  1983,  1984,  1989,  1990,
+    1996,  1997,  2001,  2002,  2003,  2006,  2005,  2016,  2025,  2031,
+    2037,  2046,  2052,  2058,  2064,  2070,  2078,  2084,  2092,  2098,
+    2107,  2108,  2109,  2113,  2117,  2119,  2124,  2125,  2129,  2130,
+    2135,  2141,  2142,  2145,  2147,  2148,  2152,  2153,  2154,  2155,
+    2189,  2191,  2192,  2194,  2199,  2204,  2209,  2211,  2213,  2218,
+    2220,  2222,  2224,  2229,  2231,  2240,  2242,  2243,  2248,  2250,
+    2252,  2257,  2259,  2261,  2266,  2268,  2270,  2279,  2280,  2281,
+    2285,  2287,  2289,  2294,  2296,  2298,  2303,  2305,  2307,  2322,
+    2324,  2325,  2327,  2332,  2333,  2338,  2340,  2342,  2347,  2349,
+    2351,  2353,  2358,  2360,  2362,  2372,  2374,  2375,  2377,  2382,
+    2384,  2386,  2391,  2393,  2395,  2397,  2402,  2404,  2406,  2437,
+    2439,  2440,  2442,  2447,  2452,  2460,  2462,  2464,  2469,  2471,
+    2476,  2478,  2492,  2493,  2495,  2500,  2502,  2504,  2506,  2508,
+    2513,  2514,  2516,  2518,  2523,  2525,  2527,  2533,  2535,  2537,
+    2541,  2543,  2545,  2547,  2561,  2562,  2564,  2569,  2571,  2573,
+    2575,  2577,  2582,  2583,  2585,  2587,  2592,  2594,  2596,  2602,
+    2603,  2605,  2614,  2617,  2619,  2622,  2624,  2626,  2639,  2640,
+    2642,  2647,  2649,  2651,  2653,  2655,  2660,  2661,  2663,  2665,
+    2670,  2672,  2680,  2681,  2682,  2687,  2688,  2692,  2694,  2696,
+    2698,  2700,  2702,  2709,  2711,  2713,  2715,  2717,  2719,  2721,
+    2723,  2725,  2727,  2732,  2734,  2736,  2741,  2767,  2768,  2770,
+    2774,  2775,  2779,  2781,  2783,  2785,  2787,  2789,  2796,  2798,
+    2800,  2802,  2804,  2806,  2811,  2816,  2818,  2820,  2838,  2840,
+    2845,  2846
 };
 #endif
@@ -5077,15 +5077,29 @@
     break;
 
+  case 27:
+
+/* Line 1806 of yacc.c  */
+#line 379 "parser.yy"
+    { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(1) - (7)].en), build_tuple( (yyvsp[(5) - (7)].en) ) ) ); }
+    break;
+
   case 28:
 
 /* Line 1806 of yacc.c  */
-#line 380 "parser.yy"
+#line 381 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(1) - (3)].en), build_varref( (yyvsp[(3) - (3)].tok) ) ) ); }
     break;
 
+  case 29:
+
+/* Line 1806 of yacc.c  */
+#line 383 "parser.yy"
+    { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(1) - (7)].en), build_tuple( (yyvsp[(5) - (7)].en) ) ) ); }
+    break;
+
   case 30:
 
 /* Line 1806 of yacc.c  */
-#line 383 "parser.yy"
+#line 385 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, (yyvsp[(1) - (2)].en) ) ); }
     break;
@@ -5094,5 +5108,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 385 "parser.yy"
+#line 387 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::DecrPost, (yyvsp[(1) - (2)].en) ) ); }
     break;
@@ -5101,5 +5115,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 387 "parser.yy"
+#line 389 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_compoundLiteral( (yyvsp[(2) - (7)].decl), new InitializerNode( (yyvsp[(5) - (7)].in), true ) ) ); }
     break;
@@ -5108,5 +5122,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 389 "parser.yy"
+#line 391 "parser.yy"
     {
 			Token fn;
@@ -5119,5 +5133,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 399 "parser.yy"
+#line 401 "parser.yy"
     { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) )); }
     break;
@@ -5126,5 +5140,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 404 "parser.yy"
+#line 406 "parser.yy"
     { (yyval.en) = 0; }
     break;
@@ -5133,5 +5147,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 410 "parser.yy"
+#line 412 "parser.yy"
     { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) ); }
     break;
@@ -5140,5 +5154,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 415 "parser.yy"
+#line 417 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(1) - (1)].tok) ) ); }
     break;
@@ -5147,5 +5161,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 419 "parser.yy"
+#line 421 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(3) - (3)].en), build_varref( (yyvsp[(1) - (3)].tok) ) ) ); }
     break;
@@ -5154,5 +5168,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 421 "parser.yy"
+#line 423 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(5) - (7)].en), build_varref( (yyvsp[(1) - (7)].tok) ) ) ); }
     break;
@@ -5161,5 +5175,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 423 "parser.yy"
+#line 425 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(3) - (3)].en), build_varref( (yyvsp[(1) - (3)].tok) ) ) ); }
     break;
@@ -5168,5 +5182,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 425 "parser.yy"
+#line 427 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(5) - (7)].en), build_varref( (yyvsp[(1) - (7)].tok) ) ) ); }
     break;
@@ -5175,5 +5189,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 433 "parser.yy"
+#line 435 "parser.yy"
     { (yyval.en) = (yyvsp[(1) - (1)].en); }
     break;
@@ -5182,5 +5196,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 435 "parser.yy"
+#line 437 "parser.yy"
     { (yyval.en) = new ExpressionNode( (yyvsp[(1) - (1)].constant) ); }
     break;
@@ -5189,5 +5203,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 437 "parser.yy"
+#line 439 "parser.yy"
     { (yyval.en) = (yyvsp[(2) - (2)].en)->set_extension( true ); }
     break;
@@ -5196,5 +5210,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 442 "parser.yy"
+#line 444 "parser.yy"
     {
 			switch ( (yyvsp[(1) - (2)].op) ) {
@@ -5214,5 +5228,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 455 "parser.yy"
+#line 457 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_unary_val( (yyvsp[(1) - (2)].op), (yyvsp[(2) - (2)].en) ) ); }
     break;
@@ -5221,5 +5235,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 457 "parser.yy"
+#line 459 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::Incr, (yyvsp[(2) - (2)].en) ) ); }
     break;
@@ -5228,5 +5242,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 459 "parser.yy"
+#line 461 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::Decr, (yyvsp[(2) - (2)].en) ) ); }
     break;
@@ -5235,5 +5249,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 461 "parser.yy"
+#line 463 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_sizeOfexpr( (yyvsp[(2) - (2)].en) ) ); }
     break;
@@ -5242,5 +5256,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 463 "parser.yy"
+#line 465 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_sizeOftype( (yyvsp[(3) - (4)].decl) ) ); }
     break;
@@ -5249,5 +5263,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 465 "parser.yy"
+#line 467 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_alignOfexpr( (yyvsp[(2) - (2)].en) ) ); }
     break;
@@ -5256,5 +5270,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 467 "parser.yy"
+#line 469 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_alignOftype( (yyvsp[(3) - (4)].decl) ) ); }
     break;
@@ -5263,5 +5277,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 469 "parser.yy"
+#line 471 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_offsetOf( (yyvsp[(3) - (6)].decl), build_varref( (yyvsp[(5) - (6)].tok) ) ) ); }
     break;
@@ -5270,5 +5284,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 471 "parser.yy"
+#line 473 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_attrexpr( build_varref( (yyvsp[(1) - (1)].tok) ), nullptr ) ); }
     break;
@@ -5277,5 +5291,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 473 "parser.yy"
+#line 475 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_attrexpr( build_varref( (yyvsp[(1) - (4)].tok) ), (yyvsp[(3) - (4)].en) ) ); }
     break;
@@ -5284,5 +5298,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 475 "parser.yy"
+#line 477 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_attrtype( build_varref( (yyvsp[(1) - (4)].tok) ), (yyvsp[(3) - (4)].decl) ) ); }
     break;
@@ -5291,5 +5305,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 481 "parser.yy"
+#line 483 "parser.yy"
     { (yyval.op) = OperKinds::PointTo; }
     break;
@@ -5298,5 +5312,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 482 "parser.yy"
+#line 484 "parser.yy"
     { (yyval.op) = OperKinds::AddressOf; }
     break;
@@ -5305,5 +5319,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 488 "parser.yy"
+#line 490 "parser.yy"
     { (yyval.op) = OperKinds::UnPlus; }
     break;
@@ -5312,5 +5326,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 489 "parser.yy"
+#line 491 "parser.yy"
     { (yyval.op) = OperKinds::UnMinus; }
     break;
@@ -5319,5 +5333,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 490 "parser.yy"
+#line 492 "parser.yy"
     { (yyval.op) = OperKinds::Neg; }
     break;
@@ -5326,16 +5340,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 491 "parser.yy"
+#line 493 "parser.yy"
     { (yyval.op) = OperKinds::BitNeg; }
     break;
 
   case 68:
-
-/* Line 1806 of yacc.c  */
-#line 497 "parser.yy"
-    { (yyval.en) = new ExpressionNode( build_cast( (yyvsp[(2) - (4)].decl), (yyvsp[(4) - (4)].en) ) ); }
-    break;
-
-  case 69:
 
 /* Line 1806 of yacc.c  */
@@ -5344,8 +5351,15 @@
     break;
 
+  case 69:
+
+/* Line 1806 of yacc.c  */
+#line 501 "parser.yy"
+    { (yyval.en) = new ExpressionNode( build_cast( (yyvsp[(2) - (4)].decl), (yyvsp[(4) - (4)].en) ) ); }
+    break;
+
   case 71:
 
 /* Line 1806 of yacc.c  */
-#line 505 "parser.yy"
+#line 507 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Mul, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5354,5 +5368,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 507 "parser.yy"
+#line 509 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Div, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5361,5 +5375,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 509 "parser.yy"
+#line 511 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Mod, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5368,5 +5382,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 515 "parser.yy"
+#line 517 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Plus, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5375,5 +5389,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 517 "parser.yy"
+#line 519 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Minus, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5382,5 +5396,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 523 "parser.yy"
+#line 525 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::LShift, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5389,5 +5403,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 525 "parser.yy"
+#line 527 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::RShift, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5396,5 +5410,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 531 "parser.yy"
+#line 533 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::LThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5403,5 +5417,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 533 "parser.yy"
+#line 535 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::GThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5410,5 +5424,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 535 "parser.yy"
+#line 537 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::LEThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5417,5 +5431,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 537 "parser.yy"
+#line 539 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::GEThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5424,5 +5438,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 543 "parser.yy"
+#line 545 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Eq, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5431,5 +5445,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 545 "parser.yy"
+#line 547 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Neq, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5438,5 +5452,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 551 "parser.yy"
+#line 553 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::BitAnd, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5445,5 +5459,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 557 "parser.yy"
+#line 559 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Xor, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5452,5 +5466,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 563 "parser.yy"
+#line 565 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::BitOr, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5459,5 +5473,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 569 "parser.yy"
+#line 571 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_and_or( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en), true ) ); }
     break;
@@ -5466,5 +5480,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 575 "parser.yy"
+#line 577 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_and_or( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en), false ) ); }
     break;
@@ -5473,5 +5487,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 581 "parser.yy"
+#line 583 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_cond( (yyvsp[(1) - (5)].en), (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].en) ) ); }
     break;
@@ -5480,5 +5494,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 584 "parser.yy"
+#line 586 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_cond( (yyvsp[(1) - (4)].en), (yyvsp[(1) - (4)].en), (yyvsp[(4) - (4)].en) ) ); }
     break;
@@ -5487,5 +5501,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 586 "parser.yy"
+#line 588 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_cond( (yyvsp[(1) - (5)].en), (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].en) ) ); }
     break;
@@ -5494,5 +5508,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 597 "parser.yy"
+#line 599 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_ptr( (yyvsp[(2) - (3)].op), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5501,5 +5515,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 599 "parser.yy"
+#line 601 "parser.yy"
     { (yyval.en) = ( (yyvsp[(2) - (2)].en) == 0 ) ? (yyvsp[(1) - (2)].en) : new ExpressionNode( build_binary_ptr( OperKinds::Assign, (yyvsp[(1) - (2)].en), (yyvsp[(2) - (2)].en) ) ); }
     break;
@@ -5508,5 +5522,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 604 "parser.yy"
+#line 606 "parser.yy"
     { (yyval.en) = nullptr; }
     break;
@@ -5515,5 +5529,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 609 "parser.yy"
+#line 611 "parser.yy"
     { (yyval.op) = OperKinds::Assign; }
     break;
@@ -5522,5 +5536,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 610 "parser.yy"
+#line 612 "parser.yy"
     { (yyval.op) = OperKinds::AtAssn; }
     break;
@@ -5529,5 +5543,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 611 "parser.yy"
+#line 613 "parser.yy"
     { (yyval.op) = OperKinds::MulAssn; }
     break;
@@ -5536,5 +5550,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 612 "parser.yy"
+#line 614 "parser.yy"
     { (yyval.op) = OperKinds::DivAssn; }
     break;
@@ -5543,5 +5557,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 613 "parser.yy"
+#line 615 "parser.yy"
     { (yyval.op) = OperKinds::ModAssn; }
     break;
@@ -5550,5 +5564,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 614 "parser.yy"
+#line 616 "parser.yy"
     { (yyval.op) = OperKinds::PlusAssn; }
     break;
@@ -5557,5 +5571,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 615 "parser.yy"
+#line 617 "parser.yy"
     { (yyval.op) = OperKinds::MinusAssn; }
     break;
@@ -5564,5 +5578,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 616 "parser.yy"
+#line 618 "parser.yy"
     { (yyval.op) = OperKinds::LSAssn; }
     break;
@@ -5571,5 +5585,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 617 "parser.yy"
+#line 619 "parser.yy"
     { (yyval.op) = OperKinds::RSAssn; }
     break;
@@ -5578,5 +5592,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 618 "parser.yy"
+#line 620 "parser.yy"
     { (yyval.op) = OperKinds::AndAssn; }
     break;
@@ -5585,5 +5599,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 619 "parser.yy"
+#line 621 "parser.yy"
     { (yyval.op) = OperKinds::ERAssn; }
     break;
@@ -5592,5 +5606,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 620 "parser.yy"
+#line 622 "parser.yy"
     { (yyval.op) = OperKinds::OrAssn; }
     break;
@@ -5599,5 +5613,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 627 "parser.yy"
+#line 629 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_tuple() ); }
     break;
@@ -5606,5 +5620,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 629 "parser.yy"
+#line 631 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_tuple( (yyvsp[(3) - (5)].en) ) ); }
     break;
@@ -5613,5 +5627,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 631 "parser.yy"
+#line 633 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( (yyvsp[(4) - (6)].en) ) ) ); }
     break;
@@ -5620,5 +5634,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 633 "parser.yy"
+#line 635 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_tuple( (ExpressionNode *)(yyvsp[(3) - (7)].en)->set_last( (yyvsp[(5) - (7)].en) ) ) ); }
     break;
@@ -5627,5 +5641,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 639 "parser.yy"
+#line 641 "parser.yy"
     { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) ); }
     break;
@@ -5634,5 +5648,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 645 "parser.yy"
+#line 647 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_comma( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5641,5 +5655,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 650 "parser.yy"
+#line 652 "parser.yy"
     { (yyval.en) = 0; }
     break;
@@ -5648,5 +5662,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 659 "parser.yy"
+#line 661 "parser.yy"
     { (yyval.sn) = (yyvsp[(1) - (1)].sn); }
     break;
@@ -5655,5 +5669,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 666 "parser.yy"
+#line 668 "parser.yy"
     {
 			Token fn;
@@ -5666,5 +5680,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 676 "parser.yy"
+#line 678 "parser.yy"
     {
 			(yyval.sn) = (yyvsp[(4) - (4)].sn)->add_label( (yyvsp[(1) - (4)].tok) );
@@ -5675,5 +5689,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 683 "parser.yy"
+#line 685 "parser.yy"
     { (yyval.sn) = new StatementNode( build_compound( (StatementNode *)0 ) ); }
     break;
@@ -5682,5 +5696,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 690 "parser.yy"
+#line 692 "parser.yy"
     { (yyval.sn) = new StatementNode( build_compound( (yyvsp[(5) - (7)].sn) ) ); }
     break;
@@ -5689,5 +5703,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 696 "parser.yy"
+#line 698 "parser.yy"
     { if ( (yyvsp[(1) - (3)].sn) != 0 ) { (yyvsp[(1) - (3)].sn)->set_last( (yyvsp[(3) - (3)].sn) ); (yyval.sn) = (yyvsp[(1) - (3)].sn); } }
     break;
@@ -5696,5 +5710,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 701 "parser.yy"
+#line 703 "parser.yy"
     { (yyval.sn) = new StatementNode( (yyvsp[(1) - (1)].decl) ); }
     break;
@@ -5703,5 +5717,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 703 "parser.yy"
+#line 705 "parser.yy"
     {	// mark all fields in list
 			for ( DeclarationNode *iter = (yyvsp[(2) - (2)].decl); iter != nullptr; iter = (DeclarationNode *)iter->get_next() )
@@ -5714,5 +5728,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 709 "parser.yy"
+#line 711 "parser.yy"
     { (yyval.sn) = new StatementNode( (yyvsp[(1) - (1)].decl) ); }
     break;
@@ -5721,5 +5735,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 716 "parser.yy"
+#line 718 "parser.yy"
     { if ( (yyvsp[(1) - (2)].sn) != 0 ) { (yyvsp[(1) - (2)].sn)->set_last( (yyvsp[(2) - (2)].sn) ); (yyval.sn) = (yyvsp[(1) - (2)].sn); } }
     break;
@@ -5728,5 +5742,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 721 "parser.yy"
+#line 723 "parser.yy"
     { (yyval.sn) = new StatementNode( build_expr( (yyvsp[(1) - (2)].en) ) ); }
     break;
@@ -5735,5 +5749,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 727 "parser.yy"
+#line 729 "parser.yy"
     { (yyval.sn) = new StatementNode( build_if( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn), nullptr ) ); }
     break;
@@ -5742,5 +5756,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 729 "parser.yy"
+#line 731 "parser.yy"
     { (yyval.sn) = new StatementNode( build_if( (yyvsp[(3) - (7)].en), (yyvsp[(5) - (7)].sn), (yyvsp[(7) - (7)].sn) ) ); }
     break;
@@ -5749,5 +5763,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 731 "parser.yy"
+#line 733 "parser.yy"
     { (yyval.sn) = new StatementNode( build_switch( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); }
     break;
@@ -5756,5 +5770,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 733 "parser.yy"
+#line 735 "parser.yy"
     {
 			StatementNode *sw = new StatementNode( build_switch( (yyvsp[(3) - (9)].en), (yyvsp[(8) - (9)].sn) ) );
@@ -5771,5 +5785,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 743 "parser.yy"
+#line 745 "parser.yy"
     { (yyval.sn) = new StatementNode( build_switch( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); }
     break;
@@ -5778,5 +5792,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 745 "parser.yy"
+#line 747 "parser.yy"
     {
 			StatementNode *sw = new StatementNode( build_switch( (yyvsp[(3) - (9)].en), (yyvsp[(8) - (9)].sn) ) );
@@ -5788,5 +5802,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 755 "parser.yy"
+#line 757 "parser.yy"
     { (yyval.en) = (yyvsp[(1) - (1)].en); }
     break;
@@ -5795,5 +5809,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 757 "parser.yy"
+#line 759 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_range( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5802,5 +5816,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 762 "parser.yy"
+#line 764 "parser.yy"
     { (yyval.sn) = new StatementNode( build_case( (yyvsp[(1) - (1)].en) ) ); }
     break;
@@ -5809,5 +5823,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 764 "parser.yy"
+#line 766 "parser.yy"
     { (yyval.sn) = (StatementNode *)((yyvsp[(1) - (3)].sn)->set_last( new StatementNode( build_case( (yyvsp[(3) - (3)].en) ) ) ) ); }
     break;
@@ -5816,5 +5830,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 768 "parser.yy"
+#line 770 "parser.yy"
     { (yyval.sn) = (yyvsp[(2) - (3)].sn); }
     break;
@@ -5823,5 +5837,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 769 "parser.yy"
+#line 771 "parser.yy"
     { (yyval.sn) = new StatementNode( build_default() ); }
     break;
@@ -5830,5 +5844,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 775 "parser.yy"
+#line 777 "parser.yy"
     { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (2)].sn)->set_last( (yyvsp[(2) - (2)].sn) )); }
     break;
@@ -5837,5 +5851,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 779 "parser.yy"
+#line 781 "parser.yy"
     { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new StatementNode( build_compound( (yyvsp[(2) - (2)].sn) ) ) ); }
     break;
@@ -5844,5 +5858,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 784 "parser.yy"
+#line 786 "parser.yy"
     { (yyval.sn) = 0; }
     break;
@@ -5851,5 +5865,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 790 "parser.yy"
+#line 792 "parser.yy"
     { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new StatementNode( build_compound( (yyvsp[(2) - (2)].sn) ) ) ); }
     break;
@@ -5858,5 +5872,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 792 "parser.yy"
+#line 794 "parser.yy"
     { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_last( (yyvsp[(2) - (3)].sn)->append_last_case( new StatementNode( build_compound( (yyvsp[(3) - (3)].sn) ) ) ) ) ); }
     break;
@@ -5865,5 +5879,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 797 "parser.yy"
+#line 799 "parser.yy"
     { (yyval.sn) = 0; }
     break;
@@ -5872,5 +5886,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 803 "parser.yy"
+#line 805 "parser.yy"
     { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( (yyvsp[(2) - (2)].sn) ); }
     break;
@@ -5879,5 +5893,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 805 "parser.yy"
+#line 807 "parser.yy"
     { (yyval.sn) = (yyvsp[(1) - (3)].sn)->append_last_case( new StatementNode( build_compound( (StatementNode *)(yyvsp[(2) - (3)].sn)->set_last( (yyvsp[(3) - (3)].sn) ) ) ) ); }
     break;
@@ -5886,5 +5900,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 807 "parser.yy"
+#line 809 "parser.yy"
     { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_last( (yyvsp[(2) - (3)].sn)->append_last_case( (yyvsp[(3) - (3)].sn) ))); }
     break;
@@ -5893,5 +5907,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 809 "parser.yy"
+#line 811 "parser.yy"
     { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (4)].sn)->set_last( (yyvsp[(2) - (4)].sn)->append_last_case( new StatementNode( build_compound( (StatementNode *)(yyvsp[(3) - (4)].sn)->set_last( (yyvsp[(4) - (4)].sn) ) ) ) ) ) ); }
     break;
@@ -5900,16 +5914,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 814 "parser.yy"
+#line 816 "parser.yy"
     { (yyval.sn) = new StatementNode( build_branch( BranchStmt::Break ) ); }
     break;
 
   case 179:
-
-/* Line 1806 of yacc.c  */
-#line 820 "parser.yy"
-    { (yyval.sn) = 0; }
-    break;
-
-  case 180:
 
 /* Line 1806 of yacc.c  */
@@ -5918,8 +5925,15 @@
     break;
 
+  case 180:
+
+/* Line 1806 of yacc.c  */
+#line 824 "parser.yy"
+    { (yyval.sn) = 0; }
+    break;
+
   case 181:
 
 /* Line 1806 of yacc.c  */
-#line 827 "parser.yy"
+#line 829 "parser.yy"
     { (yyval.sn) = new StatementNode( build_while( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); }
     break;
@@ -5928,5 +5942,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 829 "parser.yy"
+#line 831 "parser.yy"
     { (yyval.sn) = new StatementNode( build_while( (yyvsp[(5) - (7)].en), (yyvsp[(2) - (7)].sn), true ) ); }
     break;
@@ -5935,5 +5949,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 831 "parser.yy"
+#line 833 "parser.yy"
     { (yyval.sn) = new StatementNode( build_for( (yyvsp[(4) - (6)].fctl), (yyvsp[(6) - (6)].sn) ) ); }
     break;
@@ -5942,5 +5956,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 836 "parser.yy"
+#line 838 "parser.yy"
     { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (6)].en), (yyvsp[(4) - (6)].en), (yyvsp[(6) - (6)].en) ); }
     break;
@@ -5949,5 +5963,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 838 "parser.yy"
+#line 840 "parser.yy"
     { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (4)].decl), (yyvsp[(2) - (4)].en), (yyvsp[(4) - (4)].en) ); }
     break;
@@ -5956,5 +5970,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 843 "parser.yy"
+#line 845 "parser.yy"
     { (yyval.sn) = new StatementNode( build_branch( (yyvsp[(2) - (3)].tok), BranchStmt::Goto ) ); }
     break;
@@ -5963,5 +5977,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 847 "parser.yy"
+#line 849 "parser.yy"
     { (yyval.sn) = new StatementNode( build_computedgoto( (yyvsp[(3) - (4)].en) ) ); }
     break;
@@ -5970,5 +5984,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 850 "parser.yy"
+#line 852 "parser.yy"
     { (yyval.sn) = new StatementNode( build_branch( BranchStmt::Continue ) ); }
     break;
@@ -5977,5 +5991,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 854 "parser.yy"
+#line 856 "parser.yy"
     { (yyval.sn) = new StatementNode( build_branch( (yyvsp[(2) - (3)].tok), BranchStmt::Continue ) ); }
     break;
@@ -5984,5 +5998,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 857 "parser.yy"
+#line 859 "parser.yy"
     { (yyval.sn) = new StatementNode( build_branch( BranchStmt::Break ) ); }
     break;
@@ -5991,5 +6005,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 861 "parser.yy"
+#line 863 "parser.yy"
     { (yyval.sn) = new StatementNode( build_branch( (yyvsp[(2) - (3)].tok), BranchStmt::Break ) ); }
     break;
@@ -5998,16 +6012,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 863 "parser.yy"
+#line 865 "parser.yy"
     { (yyval.sn) = new StatementNode( build_return( (yyvsp[(2) - (3)].en) ) ); }
     break;
 
   case 193:
-
-/* Line 1806 of yacc.c  */
-#line 865 "parser.yy"
-    { (yyval.sn) = new StatementNode( build_throw( (yyvsp[(2) - (3)].en) ) ); }
-    break;
-
-  case 194:
 
 /* Line 1806 of yacc.c  */
@@ -6016,8 +6023,15 @@
     break;
 
+  case 194:
+
+/* Line 1806 of yacc.c  */
+#line 869 "parser.yy"
+    { (yyval.sn) = new StatementNode( build_throw( (yyvsp[(2) - (3)].en) ) ); }
+    break;
+
   case 195:
 
 /* Line 1806 of yacc.c  */
-#line 869 "parser.yy"
+#line 871 "parser.yy"
     { (yyval.sn) = new StatementNode( build_throw( (yyvsp[(2) - (5)].en) ) ); }
     break;
@@ -6026,5 +6040,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 874 "parser.yy"
+#line 876 "parser.yy"
     { (yyval.sn) = new StatementNode( build_try( (yyvsp[(2) - (3)].sn), (yyvsp[(3) - (3)].sn), 0 ) ); }
     break;
@@ -6033,5 +6047,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 876 "parser.yy"
+#line 878 "parser.yy"
     { (yyval.sn) = new StatementNode( build_try( (yyvsp[(2) - (3)].sn), 0, (yyvsp[(3) - (3)].sn) ) ); }
     break;
@@ -6040,5 +6054,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 878 "parser.yy"
+#line 880 "parser.yy"
     { (yyval.sn) = new StatementNode( build_try( (yyvsp[(2) - (4)].sn), (yyvsp[(3) - (4)].sn), (yyvsp[(4) - (4)].sn) ) ); }
     break;
@@ -6047,5 +6061,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 885 "parser.yy"
+#line 887 "parser.yy"
     { (yyval.sn) = new StatementNode( build_catch( 0, (yyvsp[(5) - (5)].sn), true ) ); }
     break;
@@ -6054,5 +6068,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 887 "parser.yy"
+#line 889 "parser.yy"
     { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (6)].sn)->set_last( new StatementNode( build_catch( 0, (yyvsp[(6) - (6)].sn), true ) ) ); }
     break;
@@ -6061,5 +6075,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 889 "parser.yy"
+#line 891 "parser.yy"
     { (yyval.sn) = new StatementNode( build_catch( 0, (yyvsp[(5) - (5)].sn), true ) ); }
     break;
@@ -6068,5 +6082,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 891 "parser.yy"
+#line 893 "parser.yy"
     { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (6)].sn)->set_last( new StatementNode( build_catch( 0, (yyvsp[(6) - (6)].sn), true ) ) ); }
     break;
@@ -6075,5 +6089,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 896 "parser.yy"
+#line 898 "parser.yy"
     { (yyval.sn) = new StatementNode( build_catch( (yyvsp[(5) - (9)].decl), (yyvsp[(8) - (9)].sn) ) ); }
     break;
@@ -6082,5 +6096,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 898 "parser.yy"
+#line 900 "parser.yy"
     { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (10)].sn)->set_last( new StatementNode( build_catch( (yyvsp[(6) - (10)].decl), (yyvsp[(9) - (10)].sn) ) ) ); }
     break;
@@ -6089,5 +6103,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 900 "parser.yy"
+#line 902 "parser.yy"
     { (yyval.sn) = new StatementNode( build_catch( (yyvsp[(5) - (9)].decl), (yyvsp[(8) - (9)].sn) ) ); }
     break;
@@ -6096,5 +6110,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 902 "parser.yy"
+#line 904 "parser.yy"
     { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (10)].sn)->set_last( new StatementNode( build_catch( (yyvsp[(6) - (10)].decl), (yyvsp[(9) - (10)].sn) ) ) ); }
     break;
@@ -6103,5 +6117,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 907 "parser.yy"
+#line 909 "parser.yy"
     {
 			(yyval.sn) = new StatementNode( build_finally( (yyvsp[(2) - (2)].sn) ) );
@@ -6112,5 +6126,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 920 "parser.yy"
+#line 922 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6122,5 +6136,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 925 "parser.yy"
+#line 927 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -6129,5 +6143,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 927 "parser.yy"
+#line 929 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6139,5 +6153,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 936 "parser.yy"
+#line 938 "parser.yy"
     { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (6)].flag), (yyvsp[(4) - (6)].constant), 0 ) ); }
     break;
@@ -6146,5 +6160,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 938 "parser.yy"
+#line 940 "parser.yy"
     { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (8)].flag), (yyvsp[(4) - (8)].constant), (yyvsp[(6) - (8)].en) ) ); }
     break;
@@ -6153,5 +6167,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 940 "parser.yy"
+#line 942 "parser.yy"
     { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (10)].flag), (yyvsp[(4) - (10)].constant), (yyvsp[(6) - (10)].en), (yyvsp[(8) - (10)].en) ) ); }
     break;
@@ -6160,5 +6174,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 942 "parser.yy"
+#line 944 "parser.yy"
     { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (12)].flag), (yyvsp[(4) - (12)].constant), (yyvsp[(6) - (12)].en), (yyvsp[(8) - (12)].en), (yyvsp[(10) - (12)].en) ) ); }
     break;
@@ -6167,5 +6181,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 944 "parser.yy"
+#line 946 "parser.yy"
     { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (14)].flag), (yyvsp[(5) - (14)].constant), 0, (yyvsp[(8) - (14)].en), (yyvsp[(10) - (14)].en), (yyvsp[(12) - (14)].label) ) ); }
     break;
@@ -6174,5 +6188,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 949 "parser.yy"
+#line 951 "parser.yy"
     { (yyval.flag) = false; }
     break;
@@ -6181,5 +6195,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 951 "parser.yy"
+#line 953 "parser.yy"
     { (yyval.flag) = true; }
     break;
@@ -6188,5 +6202,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 956 "parser.yy"
+#line 958 "parser.yy"
     { (yyval.en) = 0; }
     break;
@@ -6195,5 +6209,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 963 "parser.yy"
+#line 965 "parser.yy"
     { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) ); }
     break;
@@ -6202,5 +6216,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 968 "parser.yy"
+#line 970 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_asmexpr( 0, (yyvsp[(1) - (4)].constant), (yyvsp[(3) - (4)].en) ) ); }
     break;
@@ -6209,5 +6223,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 970 "parser.yy"
+#line 972 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_asmexpr( (yyvsp[(2) - (7)].en), (yyvsp[(4) - (7)].constant), (yyvsp[(6) - (7)].en) ) ); }
     break;
@@ -6216,5 +6230,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 975 "parser.yy"
+#line 977 "parser.yy"
     { (yyval.en) = 0; }
     break;
@@ -6223,5 +6237,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 977 "parser.yy"
+#line 979 "parser.yy"
     { (yyval.en) = new ExpressionNode( (yyvsp[(1) - (1)].constant) ); }
     break;
@@ -6230,5 +6244,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 979 "parser.yy"
+#line 981 "parser.yy"
     { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( new ExpressionNode( (yyvsp[(3) - (3)].constant) ) ); }
     break;
@@ -6237,5 +6251,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 984 "parser.yy"
+#line 986 "parser.yy"
     {
 			(yyval.label) = new LabelNode(); (yyval.label)->labels.push_back( *(yyvsp[(1) - (1)].tok) );
@@ -6247,5 +6261,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 989 "parser.yy"
+#line 991 "parser.yy"
     {
 			(yyval.label) = (yyvsp[(1) - (3)].label); (yyvsp[(1) - (3)].label)->labels.push_back( *(yyvsp[(3) - (3)].tok) );
@@ -6257,5 +6271,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 999 "parser.yy"
+#line 1001 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -6264,5 +6278,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1006 "parser.yy"
+#line 1008 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -6271,5 +6285,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1011 "parser.yy"
+#line 1013 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -6278,5 +6292,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1018 "parser.yy"
+#line 1020 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -6285,5 +6299,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1032 "parser.yy"
+#line 1034 "parser.yy"
     {}
     break;
@@ -6292,5 +6306,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1033 "parser.yy"
+#line 1035 "parser.yy"
     {}
     break;
@@ -6299,5 +6313,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1062 "parser.yy"
+#line 1064 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6309,5 +6323,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1069 "parser.yy"
+#line 1071 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6319,5 +6333,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1074 "parser.yy"
+#line 1076 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(5) - (6)].tok), TypedefTable::ID );
@@ -6329,5 +6343,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1084 "parser.yy"
+#line 1086 "parser.yy"
     {
 			typedefTable.setNextIdentifier( *(yyvsp[(2) - (3)].tok) );
@@ -6339,5 +6353,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1089 "parser.yy"
+#line 1091 "parser.yy"
     {
 			typedefTable.setNextIdentifier( *(yyvsp[(2) - (3)].tok) );
@@ -6349,5 +6363,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1094 "parser.yy"
+#line 1096 "parser.yy"
     {
 			typedefTable.setNextIdentifier( *(yyvsp[(3) - (4)].tok) );
@@ -6359,5 +6373,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1102 "parser.yy"
+#line 1104 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6369,5 +6383,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1107 "parser.yy"
+#line 1109 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6379,5 +6393,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1112 "parser.yy"
+#line 1114 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6389,5 +6403,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1117 "parser.yy"
+#line 1119 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6399,5 +6413,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1122 "parser.yy"
+#line 1124 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(5) - (5)].tok), TypedefTable::ID );
@@ -6409,5 +6423,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1130 "parser.yy"
+#line 1132 "parser.yy"
     {
 			(yyval.decl) = DeclarationNode::newFunction( (yyvsp[(3) - (8)].tok), DeclarationNode::newTuple( 0 ), (yyvsp[(6) - (8)].decl), 0, true );
@@ -6418,5 +6432,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1153 "parser.yy"
+#line 1155 "parser.yy"
     {
 			(yyval.decl) = DeclarationNode::newFunction( (yyvsp[(2) - (7)].tok), (yyvsp[(1) - (7)].decl), (yyvsp[(5) - (7)].decl), 0, true );
@@ -6427,5 +6441,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1157 "parser.yy"
+#line 1159 "parser.yy"
     {
 			(yyval.decl) = DeclarationNode::newFunction( (yyvsp[(2) - (7)].tok), (yyvsp[(1) - (7)].decl), (yyvsp[(5) - (7)].decl), 0, true );
@@ -6436,5 +6450,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1164 "parser.yy"
+#line 1166 "parser.yy"
     { (yyval.decl) = DeclarationNode::newTuple( (yyvsp[(3) - (5)].decl) ); }
     break;
@@ -6443,5 +6457,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1168 "parser.yy"
+#line 1170 "parser.yy"
     { (yyval.decl) = DeclarationNode::newTuple( (yyvsp[(3) - (9)].decl)->appendList( (yyvsp[(7) - (9)].decl) ) ); }
     break;
@@ -6450,5 +6464,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1173 "parser.yy"
+#line 1175 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::TD );
@@ -6460,5 +6474,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1178 "parser.yy"
+#line 1180 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::TD );
@@ -6470,5 +6484,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1183 "parser.yy"
+#line 1185 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(5) - (5)].tok), TypedefTable::TD );
@@ -6480,5 +6494,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1194 "parser.yy"
+#line 1196 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::TD );
@@ -6490,5 +6504,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1199 "parser.yy"
+#line 1201 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::TD );
@@ -6500,5 +6514,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1204 "parser.yy"
+#line 1206 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::TD );
@@ -6510,5 +6524,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1209 "parser.yy"
+#line 1211 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::TD );
@@ -6520,5 +6534,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1214 "parser.yy"
+#line 1216 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::TD );
@@ -6530,5 +6544,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1223 "parser.yy"
+#line 1225 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(2) - (4)].tok), TypedefTable::TD );
@@ -6540,5 +6554,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1228 "parser.yy"
+#line 1230 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(5) - (7)].tok), TypedefTable::TD );
@@ -6550,5 +6564,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1245 "parser.yy"
+#line 1247 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6560,5 +6574,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1250 "parser.yy"
+#line 1252 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6570,5 +6584,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1272 "parser.yy"
+#line 1274 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -6577,5 +6591,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1284 "parser.yy"
+#line 1286 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6584,5 +6598,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1295 "parser.yy"
+#line 1297 "parser.yy"
     { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Const ); }
     break;
@@ -6591,5 +6605,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1297 "parser.yy"
+#line 1299 "parser.yy"
     { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Restrict ); }
     break;
@@ -6598,5 +6612,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1299 "parser.yy"
+#line 1301 "parser.yy"
     { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Volatile ); }
     break;
@@ -6605,5 +6619,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1301 "parser.yy"
+#line 1303 "parser.yy"
     { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Lvalue ); }
     break;
@@ -6612,5 +6626,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1303 "parser.yy"
+#line 1305 "parser.yy"
     { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Atomic ); }
     break;
@@ -6619,5 +6633,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1305 "parser.yy"
+#line 1307 "parser.yy"
     {
 			typedefTable.enterScope();
@@ -6628,5 +6642,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1309 "parser.yy"
+#line 1311 "parser.yy"
     {
 			typedefTable.leaveScope();
@@ -6638,5 +6652,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1318 "parser.yy"
+#line 1320 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6645,5 +6659,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1320 "parser.yy"
+#line 1322 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -6652,5 +6666,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1331 "parser.yy"
+#line 1333 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6659,5 +6673,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1336 "parser.yy"
+#line 1338 "parser.yy"
     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Extern ); }
     break;
@@ -6666,5 +6680,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1338 "parser.yy"
+#line 1340 "parser.yy"
     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Static ); }
     break;
@@ -6673,5 +6687,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1340 "parser.yy"
+#line 1342 "parser.yy"
     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Auto ); }
     break;
@@ -6680,5 +6694,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1342 "parser.yy"
+#line 1344 "parser.yy"
     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Register ); }
     break;
@@ -6687,5 +6701,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1345 "parser.yy"
+#line 1347 "parser.yy"
     { (yyval.decl) = new DeclarationNode; (yyval.decl)->isInline = true; }
     break;
@@ -6694,5 +6708,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1347 "parser.yy"
+#line 1349 "parser.yy"
     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Fortran ); }
     break;
@@ -6701,5 +6715,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1350 "parser.yy"
+#line 1352 "parser.yy"
     { (yyval.decl) = new DeclarationNode; (yyval.decl)->isNoreturn = true; }
     break;
@@ -6708,5 +6722,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1352 "parser.yy"
+#line 1354 "parser.yy"
     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Threadlocal ); }
     break;
@@ -6715,5 +6729,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1357 "parser.yy"
+#line 1359 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Char ); }
     break;
@@ -6722,5 +6736,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1359 "parser.yy"
+#line 1361 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Double ); }
     break;
@@ -6729,5 +6743,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1361 "parser.yy"
+#line 1363 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Float ); }
     break;
@@ -6736,5 +6750,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1363 "parser.yy"
+#line 1365 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Int ); }
     break;
@@ -6743,5 +6757,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1365 "parser.yy"
+#line 1367 "parser.yy"
     { (yyval.decl) = DeclarationNode::newLength( DeclarationNode::Long ); }
     break;
@@ -6750,5 +6764,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1367 "parser.yy"
+#line 1369 "parser.yy"
     { (yyval.decl) = DeclarationNode::newLength( DeclarationNode::Short ); }
     break;
@@ -6757,5 +6771,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1369 "parser.yy"
+#line 1371 "parser.yy"
     { (yyval.decl) = DeclarationNode::newSignedNess( DeclarationNode::Signed ); }
     break;
@@ -6764,5 +6778,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1371 "parser.yy"
+#line 1373 "parser.yy"
     { (yyval.decl) = DeclarationNode::newSignedNess( DeclarationNode::Unsigned ); }
     break;
@@ -6771,5 +6785,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1373 "parser.yy"
+#line 1375 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Void ); }
     break;
@@ -6778,5 +6792,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1375 "parser.yy"
+#line 1377 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Bool ); }
     break;
@@ -6785,5 +6799,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1377 "parser.yy"
+#line 1379 "parser.yy"
     { (yyval.decl) = DeclarationNode::newComplexType( DeclarationNode::Complex ); }
     break;
@@ -6792,5 +6806,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1379 "parser.yy"
+#line 1381 "parser.yy"
     { (yyval.decl) = DeclarationNode::newComplexType( DeclarationNode::Imaginary ); }
     break;
@@ -6799,5 +6813,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1381 "parser.yy"
+#line 1383 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBuiltinType( DeclarationNode::Valist ); }
     break;
@@ -6806,5 +6820,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1388 "parser.yy"
+#line 1390 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -6813,5 +6827,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1390 "parser.yy"
+#line 1392 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6820,5 +6834,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1392 "parser.yy"
+#line 1394 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -6827,5 +6841,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1394 "parser.yy"
+#line 1396 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addType( (yyvsp[(1) - (3)].decl) ); }
     break;
@@ -6834,5 +6848,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1400 "parser.yy"
+#line 1402 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl)->addQualifiers( (yyvsp[(1) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -6841,5 +6855,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1407 "parser.yy"
+#line 1409 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -6848,5 +6862,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1409 "parser.yy"
+#line 1411 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6855,5 +6869,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1411 "parser.yy"
+#line 1413 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addType( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6862,5 +6876,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1416 "parser.yy"
+#line 1418 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (4)].decl); }
     break;
@@ -6869,5 +6883,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1418 "parser.yy"
+#line 1420 "parser.yy"
     { (yyval.decl) = DeclarationNode::newTypeof( (yyvsp[(3) - (4)].en) ); }
     break;
@@ -6876,5 +6890,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1420 "parser.yy"
+#line 1422 "parser.yy"
     { (yyval.decl) = DeclarationNode::newAttr( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].decl) ); }
     break;
@@ -6883,5 +6897,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1422 "parser.yy"
+#line 1424 "parser.yy"
     { (yyval.decl) = DeclarationNode::newAttr( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].en) ); }
     break;
@@ -6890,5 +6904,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1428 "parser.yy"
+#line 1430 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -6897,5 +6911,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1430 "parser.yy"
+#line 1432 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6904,5 +6918,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1432 "parser.yy"
+#line 1434 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -6911,5 +6925,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1438 "parser.yy"
+#line 1440 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -6918,5 +6932,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1440 "parser.yy"
+#line 1442 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6925,5 +6939,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1446 "parser.yy"
+#line 1448 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -6932,5 +6946,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1448 "parser.yy"
+#line 1450 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6939,5 +6953,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1450 "parser.yy"
+#line 1452 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -6946,5 +6960,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1455 "parser.yy"
+#line 1457 "parser.yy"
     { (yyval.decl) = DeclarationNode::newFromTypedef( (yyvsp[(1) - (1)].tok) ); }
     break;
@@ -6953,5 +6967,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1457 "parser.yy"
+#line 1459 "parser.yy"
     { (yyval.decl) = DeclarationNode::newFromTypedef( (yyvsp[(2) - (2)].tok) )->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -6960,5 +6974,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1459 "parser.yy"
+#line 1461 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6967,5 +6981,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1469 "parser.yy"
+#line 1471 "parser.yy"
     { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (4)].aggKey), 0, 0, (yyvsp[(3) - (4)].decl), true ); }
     break;
@@ -6974,5 +6988,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1471 "parser.yy"
+#line 1473 "parser.yy"
     {
 			typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) );
@@ -6984,5 +6998,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1476 "parser.yy"
+#line 1478 "parser.yy"
     { typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) ); }
     break;
@@ -6991,5 +7005,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1478 "parser.yy"
+#line 1480 "parser.yy"
     { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (6)].aggKey), (yyvsp[(2) - (6)].tok), 0, (yyvsp[(5) - (6)].decl), true ); }
     break;
@@ -6998,5 +7012,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1480 "parser.yy"
+#line 1482 "parser.yy"
     { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (7)].aggKey), 0, (yyvsp[(3) - (7)].en), (yyvsp[(6) - (7)].decl), false ); }
     break;
@@ -7005,5 +7019,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1482 "parser.yy"
+#line 1484 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl); }
     break;
@@ -7012,5 +7026,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1487 "parser.yy"
+#line 1489 "parser.yy"
     { (yyval.aggKey) = DeclarationNode::Struct; }
     break;
@@ -7019,5 +7033,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1489 "parser.yy"
+#line 1491 "parser.yy"
     { (yyval.aggKey) = DeclarationNode::Union; }
     break;
@@ -7026,5 +7040,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1494 "parser.yy"
+#line 1496 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -7033,5 +7047,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1496 "parser.yy"
+#line 1498 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl) != 0 ? (yyvsp[(1) - (2)].decl)->appendList( (yyvsp[(2) - (2)].decl) ) : (yyvsp[(2) - (2)].decl); }
     break;
@@ -7040,5 +7054,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1502 "parser.yy"
+#line 1504 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl)->set_extension( true ); }
     break;
@@ -7047,5 +7061,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1505 "parser.yy"
+#line 1507 "parser.yy"
     {	// mark all fields in list
 			for ( DeclarationNode *iter = (yyvsp[(2) - (3)].decl); iter != nullptr; iter = (DeclarationNode *)iter->get_next() )
@@ -7058,5 +7072,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1515 "parser.yy"
+#line 1517 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addName( (yyvsp[(2) - (2)].tok) ); }
     break;
@@ -7065,5 +7079,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1517 "parser.yy"
+#line 1519 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(1) - (3)].decl)->cloneType( (yyvsp[(3) - (3)].tok) ) ); }
     break;
@@ -7072,5 +7086,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1519 "parser.yy"
+#line 1521 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->appendList( (yyvsp[(1) - (2)].decl)->cloneType( 0 ) ); }
     break;
@@ -7079,5 +7093,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1524 "parser.yy"
+#line 1526 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7086,5 +7100,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1526 "parser.yy"
+#line 1528 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (4)].decl)->appendList( (yyvsp[(1) - (4)].decl)->cloneBaseType( (yyvsp[(4) - (4)].decl) ) ); }
     break;
@@ -7093,5 +7107,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1531 "parser.yy"
+#line 1533 "parser.yy"
     { (yyval.decl) = DeclarationNode::newName( 0 ); /* XXX */ }
     break;
@@ -7100,5 +7114,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1533 "parser.yy"
+#line 1535 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBitfield( (yyvsp[(1) - (1)].en) ); }
     break;
@@ -7107,5 +7121,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1536 "parser.yy"
+#line 1538 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addBitfield( (yyvsp[(2) - (2)].en) ); }
     break;
@@ -7114,5 +7128,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1539 "parser.yy"
+#line 1541 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addBitfield( (yyvsp[(2) - (2)].en) ); }
     break;
@@ -7121,5 +7135,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1545 "parser.yy"
+#line 1547 "parser.yy"
     { (yyval.en) = 0; }
     break;
@@ -7128,5 +7142,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1547 "parser.yy"
+#line 1549 "parser.yy"
     { (yyval.en) = (yyvsp[(1) - (1)].en); }
     break;
@@ -7135,5 +7149,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1552 "parser.yy"
+#line 1554 "parser.yy"
     { (yyval.en) = (yyvsp[(2) - (2)].en); }
     break;
@@ -7142,5 +7156,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1561 "parser.yy"
+#line 1563 "parser.yy"
     { (yyval.decl) = DeclarationNode::newEnum( 0, (yyvsp[(3) - (5)].decl) ); }
     break;
@@ -7149,5 +7163,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1563 "parser.yy"
+#line 1565 "parser.yy"
     {
 			typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) );
@@ -7159,5 +7173,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1568 "parser.yy"
+#line 1570 "parser.yy"
     { typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) ); }
     break;
@@ -7166,5 +7180,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1570 "parser.yy"
+#line 1572 "parser.yy"
     { (yyval.decl) = DeclarationNode::newEnum( (yyvsp[(2) - (7)].tok), (yyvsp[(5) - (7)].decl) ); }
     break;
@@ -7173,5 +7187,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1575 "parser.yy"
+#line 1577 "parser.yy"
     { (yyval.decl) = DeclarationNode::newEnumConstant( (yyvsp[(1) - (2)].tok), (yyvsp[(2) - (2)].en) ); }
     break;
@@ -7180,5 +7194,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1577 "parser.yy"
+#line 1579 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (4)].decl)->appendList( DeclarationNode::newEnumConstant( (yyvsp[(3) - (4)].tok), (yyvsp[(4) - (4)].en) ) ); }
     break;
@@ -7187,5 +7201,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1582 "parser.yy"
+#line 1584 "parser.yy"
     { (yyval.en) = 0; }
     break;
@@ -7194,5 +7208,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1584 "parser.yy"
+#line 1586 "parser.yy"
     { (yyval.en) = (yyvsp[(2) - (2)].en); }
     break;
@@ -7201,5 +7215,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1591 "parser.yy"
+#line 1593 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -7208,16 +7222,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 1599 "parser.yy"
+#line 1601 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
     break;
 
   case 405:
-
-/* Line 1806 of yacc.c  */
-#line 1601 "parser.yy"
-    { (yyval.decl) = (yyvsp[(1) - (5)].decl)->addVarArgs(); }
-    break;
-
-  case 406:
 
 /* Line 1806 of yacc.c  */
@@ -7226,12 +7233,12 @@
     break;
 
+  case 406:
+
+/* Line 1806 of yacc.c  */
+#line 1605 "parser.yy"
+    { (yyval.decl) = (yyvsp[(1) - (5)].decl)->addVarArgs(); }
+    break;
+
   case 408:
-
-/* Line 1806 of yacc.c  */
-#line 1611 "parser.yy"
-    { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
-    break;
-
-  case 409:
 
 /* Line 1806 of yacc.c  */
@@ -7240,8 +7247,15 @@
     break;
 
+  case 409:
+
+/* Line 1806 of yacc.c  */
+#line 1615 "parser.yy"
+    { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
+    break;
+
   case 410:
 
 /* Line 1806 of yacc.c  */
-#line 1615 "parser.yy"
+#line 1617 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (9)].decl)->appendList( (yyvsp[(5) - (9)].decl) )->appendList( (yyvsp[(9) - (9)].decl) ); }
     break;
@@ -7250,5 +7264,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1621 "parser.yy"
+#line 1623 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
     break;
@@ -7257,5 +7271,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1626 "parser.yy"
+#line 1628 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -7264,16 +7278,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 1633 "parser.yy"
+#line 1635 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (5)].decl)->addVarArgs(); }
     break;
 
   case 419:
-
-/* Line 1806 of yacc.c  */
-#line 1640 "parser.yy"
-    { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
-    break;
-
-  case 420:
 
 /* Line 1806 of yacc.c  */
@@ -7282,8 +7289,15 @@
     break;
 
+  case 420:
+
+/* Line 1806 of yacc.c  */
+#line 1644 "parser.yy"
+    { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
+    break;
+
   case 422:
 
 /* Line 1806 of yacc.c  */
-#line 1651 "parser.yy"
+#line 1653 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addName( (yyvsp[(2) - (3)].tok) ); }
     break;
@@ -7292,5 +7306,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1654 "parser.yy"
+#line 1656 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addName( (yyvsp[(2) - (3)].tok) ); }
     break;
@@ -7299,5 +7313,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1656 "parser.yy"
+#line 1658 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addName( (yyvsp[(3) - (4)].tok) )->addQualifiers( (yyvsp[(1) - (4)].decl) ); }
     break;
@@ -7306,5 +7320,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1666 "parser.yy"
+#line 1668 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7313,5 +7327,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1672 "parser.yy"
+#line 1674 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7323,5 +7337,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1677 "parser.yy"
+#line 1679 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7333,5 +7347,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1686 "parser.yy"
+#line 1688 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7340,5 +7354,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1695 "parser.yy"
+#line 1697 "parser.yy"
     { (yyval.decl) = DeclarationNode::newName( (yyvsp[(1) - (1)].tok) ); }
     break;
@@ -7347,5 +7361,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1697 "parser.yy"
+#line 1699 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( DeclarationNode::newName( (yyvsp[(3) - (3)].tok) ) ); }
     break;
@@ -7354,5 +7368,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1722 "parser.yy"
+#line 1724 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7361,5 +7375,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1730 "parser.yy"
+#line 1732 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7368,5 +7382,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1735 "parser.yy"
+#line 1737 "parser.yy"
     { (yyval.in) = 0; }
     break;
@@ -7375,5 +7389,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1737 "parser.yy"
+#line 1739 "parser.yy"
     { (yyval.in) = (yyvsp[(2) - (2)].in); }
     break;
@@ -7382,5 +7396,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1739 "parser.yy"
+#line 1741 "parser.yy"
     { (yyval.in) = (yyvsp[(2) - (2)].in)->set_maybeConstructed( false ); }
     break;
@@ -7389,5 +7403,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1743 "parser.yy"
+#line 1745 "parser.yy"
     { (yyval.in) = new InitializerNode( (yyvsp[(1) - (1)].en) ); }
     break;
@@ -7396,5 +7410,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1744 "parser.yy"
+#line 1746 "parser.yy"
     { (yyval.in) = new InitializerNode( (yyvsp[(2) - (4)].in), true ); }
     break;
@@ -7403,5 +7417,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1749 "parser.yy"
+#line 1751 "parser.yy"
     { (yyval.in) = 0; }
     break;
@@ -7410,5 +7424,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1751 "parser.yy"
+#line 1753 "parser.yy"
     { (yyval.in) = (yyvsp[(2) - (2)].in)->set_designators( (yyvsp[(1) - (2)].en) ); }
     break;
@@ -7417,5 +7431,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1752 "parser.yy"
+#line 1754 "parser.yy"
     { (yyval.in) = (InitializerNode *)( (yyvsp[(1) - (3)].in)->set_last( (yyvsp[(3) - (3)].in) ) ); }
     break;
@@ -7424,5 +7438,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1754 "parser.yy"
+#line 1756 "parser.yy"
     { (yyval.in) = (InitializerNode *)( (yyvsp[(1) - (4)].in)->set_last( (yyvsp[(4) - (4)].in)->set_designators( (yyvsp[(3) - (4)].en) ) ) ); }
     break;
@@ -7431,5 +7445,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1770 "parser.yy"
+#line 1772 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(1) - (2)].tok) ) ); }
     break;
@@ -7438,5 +7452,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1776 "parser.yy"
+#line 1778 "parser.yy"
     { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (2)].en)->set_last( (yyvsp[(2) - (2)].en) ) ); }
     break;
@@ -7445,16 +7459,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 1782 "parser.yy"
+#line 1784 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(2) - (2)].tok) ) ); }
     break;
 
   case 468:
-
-/* Line 1806 of yacc.c  */
-#line 1785 "parser.yy"
-    { (yyval.en) = (yyvsp[(3) - (5)].en); }
-    break;
-
-  case 469:
 
 /* Line 1806 of yacc.c  */
@@ -7463,8 +7470,15 @@
     break;
 
+  case 469:
+
+/* Line 1806 of yacc.c  */
+#line 1789 "parser.yy"
+    { (yyval.en) = (yyvsp[(3) - (5)].en); }
+    break;
+
   case 470:
 
 /* Line 1806 of yacc.c  */
-#line 1789 "parser.yy"
+#line 1791 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_range( (yyvsp[(3) - (7)].en), (yyvsp[(5) - (7)].en) ) ); }
     break;
@@ -7473,5 +7487,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1791 "parser.yy"
+#line 1793 "parser.yy"
     { (yyval.en) = (yyvsp[(4) - (6)].en); }
     break;
@@ -7480,5 +7494,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1815 "parser.yy"
+#line 1817 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7487,5 +7501,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1817 "parser.yy"
+#line 1819 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -7494,5 +7508,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1819 "parser.yy"
+#line 1821 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -7501,5 +7515,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1825 "parser.yy"
+#line 1827 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7508,5 +7522,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1827 "parser.yy"
+#line 1829 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -7515,5 +7529,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1832 "parser.yy"
+#line 1834 "parser.yy"
     { (yyval.decl) = DeclarationNode::newFromTypeGen( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].en) ); }
     break;
@@ -7522,5 +7536,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1838 "parser.yy"
+#line 1840 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (4)].decl)->appendList( (yyvsp[(3) - (4)].decl) ); }
     break;
@@ -7529,5 +7543,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1843 "parser.yy"
+#line 1845 "parser.yy"
     { typedefTable.addToEnclosingScope( *(yyvsp[(2) - (2)].tok), TypedefTable::TD ); }
     break;
@@ -7536,5 +7550,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1845 "parser.yy"
+#line 1847 "parser.yy"
     { (yyval.decl) = DeclarationNode::newTypeParam( (yyvsp[(1) - (4)].tclass), (yyvsp[(2) - (4)].tok) )->addAssertions( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -7543,5 +7557,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1851 "parser.yy"
+#line 1853 "parser.yy"
     { (yyval.tclass) = DeclarationNode::Otype; }
     break;
@@ -7550,5 +7564,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1853 "parser.yy"
+#line 1855 "parser.yy"
     { (yyval.tclass) = DeclarationNode::Ftype; }
     break;
@@ -7557,5 +7571,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1855 "parser.yy"
+#line 1857 "parser.yy"
     { (yyval.tclass) = DeclarationNode::Dtype; }
     break;
@@ -7564,5 +7578,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1860 "parser.yy"
+#line 1862 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -7571,5 +7585,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1862 "parser.yy"
+#line 1864 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl) != 0 ? (yyvsp[(1) - (2)].decl)->appendList( (yyvsp[(2) - (2)].decl) ) : (yyvsp[(2) - (2)].decl); }
     break;
@@ -7578,5 +7592,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1867 "parser.yy"
+#line 1869 "parser.yy"
     {
 			typedefTable.openTrait( *(yyvsp[(2) - (5)].tok) );
@@ -7588,5 +7602,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1872 "parser.yy"
+#line 1874 "parser.yy"
     { (yyval.decl) = (yyvsp[(4) - (5)].decl); }
     break;
@@ -7595,5 +7609,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1874 "parser.yy"
+#line 1876 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -7602,5 +7616,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1879 "parser.yy"
+#line 1881 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_typevalue( (yyvsp[(1) - (1)].decl) ) ); }
     break;
@@ -7609,5 +7623,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1882 "parser.yy"
+#line 1884 "parser.yy"
     { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (3)].en)->set_last( new ExpressionNode( build_typevalue( (yyvsp[(3) - (3)].decl) ) ) ) ); }
     break;
@@ -7616,5 +7630,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1884 "parser.yy"
+#line 1886 "parser.yy"
     { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) )); }
     break;
@@ -7623,5 +7637,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1889 "parser.yy"
+#line 1891 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl); }
     break;
@@ -7630,5 +7644,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1891 "parser.yy"
+#line 1893 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addQualifiers( (yyvsp[(1) - (3)].decl) ); }
     break;
@@ -7637,5 +7651,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1893 "parser.yy"
+#line 1895 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl)->copyStorageClasses( (yyvsp[(1) - (3)].decl) ) ); }
     break;
@@ -7644,5 +7658,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1898 "parser.yy"
+#line 1900 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addAssertions( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -7651,5 +7665,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1900 "parser.yy"
+#line 1902 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (4)].decl)->addAssertions( (yyvsp[(2) - (4)].decl) )->addType( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -7658,5 +7672,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1905 "parser.yy"
+#line 1907 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(1) - (1)].tok), TypedefTable::TD );
@@ -7668,5 +7682,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1910 "parser.yy"
+#line 1912 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(1) - (6)].tok), TypedefTable::TG );
@@ -7678,5 +7692,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1918 "parser.yy"
+#line 1920 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(2) - (9)].tok), TypedefTable::ID );
@@ -7688,5 +7702,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1923 "parser.yy"
+#line 1925 "parser.yy"
     {
 			typedefTable.enterTrait( *(yyvsp[(2) - (8)].tok) );
@@ -7698,5 +7712,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1928 "parser.yy"
+#line 1930 "parser.yy"
     {
 			typedefTable.leaveTrait();
@@ -7709,5 +7723,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1938 "parser.yy"
+#line 1940 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -7716,5 +7730,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1948 "parser.yy"
+#line 1950 "parser.yy"
     {
 			typedefTable.addToEnclosingScope2( TypedefTable::ID );
@@ -7726,5 +7740,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1953 "parser.yy"
+#line 1955 "parser.yy"
     {
 			typedefTable.addToEnclosingScope2( TypedefTable::ID );
@@ -7736,5 +7750,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1958 "parser.yy"
+#line 1960 "parser.yy"
     {
 			typedefTable.addToEnclosingScope2( *(yyvsp[(5) - (5)].tok), TypedefTable::ID );
@@ -7746,5 +7760,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1966 "parser.yy"
+#line 1968 "parser.yy"
     {
 			typedefTable.addToEnclosingScope2( TypedefTable::ID );
@@ -7756,5 +7770,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1971 "parser.yy"
+#line 1973 "parser.yy"
     {
 			typedefTable.addToEnclosingScope2( TypedefTable::ID );
@@ -7766,5 +7780,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1981 "parser.yy"
+#line 1983 "parser.yy"
     {}
     break;
@@ -7773,5 +7787,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1983 "parser.yy"
+#line 1985 "parser.yy"
     { parseTree = parseTree != nullptr ? parseTree->appendList( (yyvsp[(1) - (1)].decl) ) : (yyvsp[(1) - (1)].decl);	}
     break;
@@ -7780,5 +7794,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1989 "parser.yy"
+#line 1991 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl) != nullptr ? (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ) : (yyvsp[(3) - (3)].decl); }
     break;
@@ -7787,5 +7801,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1994 "parser.yy"
+#line 1996 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -7794,5 +7808,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2002 "parser.yy"
+#line 2004 "parser.yy"
     {}
     break;
@@ -7801,5 +7815,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2004 "parser.yy"
+#line 2006 "parser.yy"
     {
 			linkageStack.push( linkage );				// handle nested extern "C"/"Cforall"
@@ -7811,5 +7825,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2009 "parser.yy"
+#line 2011 "parser.yy"
     {
 			linkage = linkageStack.top();
@@ -7822,5 +7836,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2015 "parser.yy"
+#line 2017 "parser.yy"
     {	// mark all fields in list
 			for ( DeclarationNode *iter = (yyvsp[(2) - (2)].decl); iter != nullptr; iter = (DeclarationNode *)iter->get_next() )
@@ -7833,5 +7847,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2030 "parser.yy"
+#line 2032 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7844,5 +7858,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2036 "parser.yy"
+#line 2038 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7855,5 +7869,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2045 "parser.yy"
+#line 2047 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7866,5 +7880,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2051 "parser.yy"
+#line 2053 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7877,5 +7891,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2057 "parser.yy"
+#line 2059 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7888,5 +7902,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2063 "parser.yy"
+#line 2065 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7899,5 +7913,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2069 "parser.yy"
+#line 2071 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7910,5 +7924,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2077 "parser.yy"
+#line 2079 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7921,5 +7935,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2083 "parser.yy"
+#line 2085 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7932,5 +7946,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2091 "parser.yy"
+#line 2093 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7943,5 +7957,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2097 "parser.yy"
+#line 2099 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7954,5 +7968,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2112 "parser.yy"
+#line 2114 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_range( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -7961,5 +7975,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2117 "parser.yy"
+#line 2119 "parser.yy"
     { delete (yyvsp[(3) - (5)].str); }
     break;
@@ -7968,5 +7982,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2122 "parser.yy"
+#line 2124 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -7975,5 +7989,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2129 "parser.yy"
+#line 2131 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7982,5 +7996,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2135 "parser.yy"
+#line 2137 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -7989,5 +8003,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2146 "parser.yy"
+#line 2148 "parser.yy"
     { delete (yyvsp[(3) - (4)].en); }
     break;
@@ -7996,23 +8010,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2150 "parser.yy"
+#line 2152 "parser.yy"
     { delete (yyvsp[(1) - (1)].tok); }
     break;
 
   case 557:
-
-/* Line 1806 of yacc.c  */
-#line 2151 "parser.yy"
-    { delete (yyvsp[(1) - (1)].decl); }
-    break;
-
-  case 558:
-
-/* Line 1806 of yacc.c  */
-#line 2152 "parser.yy"
-    { delete (yyvsp[(1) - (1)].decl); }
-    break;
-
-  case 559:
 
 /* Line 1806 of yacc.c  */
@@ -8021,19 +8021,26 @@
     break;
 
+  case 558:
+
+/* Line 1806 of yacc.c  */
+#line 2154 "parser.yy"
+    { delete (yyvsp[(1) - (1)].decl); }
+    break;
+
+  case 559:
+
+/* Line 1806 of yacc.c  */
+#line 2155 "parser.yy"
+    { delete (yyvsp[(1) - (1)].decl); }
+    break;
+
   case 560:
 
 /* Line 1806 of yacc.c  */
-#line 2188 "parser.yy"
+#line 2190 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
 
   case 562:
-
-/* Line 1806 of yacc.c  */
-#line 2191 "parser.yy"
-    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
-    break;
-
-  case 563:
 
 /* Line 1806 of yacc.c  */
@@ -8042,8 +8049,15 @@
     break;
 
+  case 563:
+
+/* Line 1806 of yacc.c  */
+#line 2195 "parser.yy"
+    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
+    break;
+
   case 564:
 
 /* Line 1806 of yacc.c  */
-#line 2198 "parser.yy"
+#line 2200 "parser.yy"
     {
 			typedefTable.setNextIdentifier( *(yyvsp[(1) - (1)].tok) );
@@ -8055,5 +8069,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2203 "parser.yy"
+#line 2205 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8062,5 +8076,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2208 "parser.yy"
+#line 2210 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8069,5 +8083,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2210 "parser.yy"
+#line 2212 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8076,5 +8090,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2212 "parser.yy"
+#line 2214 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8083,16 +8097,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2217 "parser.yy"
+#line 2219 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
     break;
 
   case 570:
-
-/* Line 1806 of yacc.c  */
-#line 2219 "parser.yy"
-    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
-    break;
-
-  case 571:
 
 /* Line 1806 of yacc.c  */
@@ -8101,8 +8108,15 @@
     break;
 
+  case 571:
+
+/* Line 1806 of yacc.c  */
+#line 2223 "parser.yy"
+    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
+    break;
+
   case 572:
 
 /* Line 1806 of yacc.c  */
-#line 2223 "parser.yy"
+#line 2225 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8111,5 +8125,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2228 "parser.yy"
+#line 2230 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -8118,5 +8132,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2230 "parser.yy"
+#line 2232 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8125,5 +8139,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2239 "parser.yy"
+#line 2241 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8132,5 +8146,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2242 "parser.yy"
+#line 2244 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8139,5 +8153,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2247 "parser.yy"
+#line 2249 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); }
     break;
@@ -8146,5 +8160,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2249 "parser.yy"
+#line 2251 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -8153,5 +8167,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2251 "parser.yy"
+#line 2253 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8160,5 +8174,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2256 "parser.yy"
+#line 2258 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8167,5 +8181,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2258 "parser.yy"
+#line 2260 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8174,16 +8188,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2260 "parser.yy"
+#line 2262 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
 
   case 584:
-
-/* Line 1806 of yacc.c  */
-#line 2265 "parser.yy"
-    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
-    break;
-
-  case 585:
 
 /* Line 1806 of yacc.c  */
@@ -8192,8 +8199,15 @@
     break;
 
+  case 585:
+
+/* Line 1806 of yacc.c  */
+#line 2269 "parser.yy"
+    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
+    break;
+
   case 586:
 
 /* Line 1806 of yacc.c  */
-#line 2269 "parser.yy"
+#line 2271 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8202,5 +8216,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2284 "parser.yy"
+#line 2286 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (4)].decl)->addIdList( (yyvsp[(3) - (4)].decl) ); }
     break;
@@ -8209,5 +8223,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2286 "parser.yy"
+#line 2288 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (6)].decl)->addIdList( (yyvsp[(5) - (6)].decl) ); }
     break;
@@ -8216,5 +8230,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2288 "parser.yy"
+#line 2290 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8223,5 +8237,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2293 "parser.yy"
+#line 2295 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8230,5 +8244,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2295 "parser.yy"
+#line 2297 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8237,16 +8251,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2297 "parser.yy"
+#line 2299 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
 
   case 596:
-
-/* Line 1806 of yacc.c  */
-#line 2302 "parser.yy"
-    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
-    break;
-
-  case 597:
 
 /* Line 1806 of yacc.c  */
@@ -8255,8 +8262,15 @@
     break;
 
+  case 597:
+
+/* Line 1806 of yacc.c  */
+#line 2306 "parser.yy"
+    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
+    break;
+
   case 598:
 
 /* Line 1806 of yacc.c  */
-#line 2306 "parser.yy"
+#line 2308 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8265,16 +8279,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2321 "parser.yy"
+#line 2323 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
 
   case 601:
-
-/* Line 1806 of yacc.c  */
-#line 2324 "parser.yy"
-    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
-    break;
-
-  case 602:
 
 /* Line 1806 of yacc.c  */
@@ -8283,8 +8290,15 @@
     break;
 
+  case 602:
+
+/* Line 1806 of yacc.c  */
+#line 2328 "parser.yy"
+    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
+    break;
+
   case 604:
 
 /* Line 1806 of yacc.c  */
-#line 2332 "parser.yy"
+#line 2334 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8293,5 +8307,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2337 "parser.yy"
+#line 2339 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8300,5 +8314,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2339 "parser.yy"
+#line 2341 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8307,5 +8321,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2341 "parser.yy"
+#line 2343 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8314,16 +8328,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2346 "parser.yy"
+#line 2348 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
     break;
 
   case 609:
-
-/* Line 1806 of yacc.c  */
-#line 2348 "parser.yy"
-    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
-    break;
-
-  case 610:
 
 /* Line 1806 of yacc.c  */
@@ -8332,8 +8339,15 @@
     break;
 
+  case 610:
+
+/* Line 1806 of yacc.c  */
+#line 2352 "parser.yy"
+    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
+    break;
+
   case 611:
 
 /* Line 1806 of yacc.c  */
-#line 2352 "parser.yy"
+#line 2354 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8342,5 +8356,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2357 "parser.yy"
+#line 2359 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); }
     break;
@@ -8349,5 +8363,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2359 "parser.yy"
+#line 2361 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -8356,5 +8370,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2361 "parser.yy"
+#line 2363 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8363,16 +8377,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2371 "parser.yy"
+#line 2373 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
 
   case 617:
-
-/* Line 1806 of yacc.c  */
-#line 2374 "parser.yy"
-    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
-    break;
-
-  case 618:
 
 /* Line 1806 of yacc.c  */
@@ -8381,8 +8388,15 @@
     break;
 
+  case 618:
+
+/* Line 1806 of yacc.c  */
+#line 2378 "parser.yy"
+    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
+    break;
+
   case 619:
 
 /* Line 1806 of yacc.c  */
-#line 2381 "parser.yy"
+#line 2383 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8391,5 +8405,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2383 "parser.yy"
+#line 2385 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8398,5 +8412,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2385 "parser.yy"
+#line 2387 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8405,16 +8419,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2390 "parser.yy"
+#line 2392 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
     break;
 
   case 623:
-
-/* Line 1806 of yacc.c  */
-#line 2392 "parser.yy"
-    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
-    break;
-
-  case 624:
 
 /* Line 1806 of yacc.c  */
@@ -8423,8 +8430,15 @@
     break;
 
+  case 624:
+
+/* Line 1806 of yacc.c  */
+#line 2396 "parser.yy"
+    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
+    break;
+
   case 625:
 
 /* Line 1806 of yacc.c  */
-#line 2396 "parser.yy"
+#line 2398 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8433,5 +8447,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2401 "parser.yy"
+#line 2403 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); }
     break;
@@ -8440,5 +8454,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2403 "parser.yy"
+#line 2405 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -8447,5 +8461,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2405 "parser.yy"
+#line 2407 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8454,16 +8468,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2436 "parser.yy"
+#line 2438 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
 
   case 631:
-
-/* Line 1806 of yacc.c  */
-#line 2439 "parser.yy"
-    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
-    break;
-
-  case 632:
 
 /* Line 1806 of yacc.c  */
@@ -8472,8 +8479,15 @@
     break;
 
+  case 632:
+
+/* Line 1806 of yacc.c  */
+#line 2443 "parser.yy"
+    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
+    break;
+
   case 633:
 
 /* Line 1806 of yacc.c  */
-#line 2446 "parser.yy"
+#line 2448 "parser.yy"
     {
 			typedefTable.setNextIdentifier( *(yyvsp[(1) - (1)].tok) );
@@ -8485,5 +8499,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2451 "parser.yy"
+#line 2453 "parser.yy"
     {
 			typedefTable.setNextIdentifier( *(yyvsp[(1) - (1)].tok) );
@@ -8495,5 +8509,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2459 "parser.yy"
+#line 2461 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8502,5 +8516,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2461 "parser.yy"
+#line 2463 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8509,5 +8523,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2463 "parser.yy"
+#line 2465 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8516,5 +8530,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2468 "parser.yy"
+#line 2470 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8523,5 +8537,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2470 "parser.yy"
+#line 2472 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -8530,5 +8544,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2475 "parser.yy"
+#line 2477 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); }
     break;
@@ -8537,16 +8551,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2477 "parser.yy"
+#line 2479 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
 
   case 643:
-
-/* Line 1806 of yacc.c  */
-#line 2492 "parser.yy"
-    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
-    break;
-
-  case 644:
 
 /* Line 1806 of yacc.c  */
@@ -8555,8 +8562,15 @@
     break;
 
+  case 644:
+
+/* Line 1806 of yacc.c  */
+#line 2496 "parser.yy"
+    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
+    break;
+
   case 645:
 
 /* Line 1806 of yacc.c  */
-#line 2499 "parser.yy"
+#line 2501 "parser.yy"
     { (yyval.decl) = DeclarationNode::newPointer( 0 ); }
     break;
@@ -8565,5 +8579,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2501 "parser.yy"
+#line 2503 "parser.yy"
     { (yyval.decl) = DeclarationNode::newPointer( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8572,5 +8586,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2503 "parser.yy"
+#line 2505 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8579,5 +8593,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2505 "parser.yy"
+#line 2507 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8586,16 +8600,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2507 "parser.yy"
+#line 2509 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
 
   case 651:
-
-/* Line 1806 of yacc.c  */
-#line 2513 "parser.yy"
-    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
-    break;
-
-  case 652:
 
 /* Line 1806 of yacc.c  */
@@ -8604,8 +8611,15 @@
     break;
 
+  case 652:
+
+/* Line 1806 of yacc.c  */
+#line 2517 "parser.yy"
+    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
+    break;
+
   case 653:
 
 /* Line 1806 of yacc.c  */
-#line 2517 "parser.yy"
+#line 2519 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8614,5 +8628,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2522 "parser.yy"
+#line 2524 "parser.yy"
     { (yyval.decl) = DeclarationNode::newFunction( 0, 0, (yyvsp[(3) - (5)].decl), 0 ); }
     break;
@@ -8621,5 +8635,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2524 "parser.yy"
+#line 2526 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -8628,5 +8642,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2526 "parser.yy"
+#line 2528 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8635,5 +8649,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2532 "parser.yy"
+#line 2534 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( 0, 0, false ); }
     break;
@@ -8642,5 +8656,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2534 "parser.yy"
+#line 2536 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( 0, 0, false )->addArray( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -8649,5 +8663,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2540 "parser.yy"
+#line 2542 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(3) - (5)].en), 0, false ); }
     break;
@@ -8656,5 +8670,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2542 "parser.yy"
+#line 2544 "parser.yy"
     { (yyval.decl) = DeclarationNode::newVarArray( 0 ); }
     break;
@@ -8663,5 +8677,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2544 "parser.yy"
+#line 2546 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addArray( DeclarationNode::newArray( (yyvsp[(4) - (6)].en), 0, false ) ); }
     break;
@@ -8670,16 +8684,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2546 "parser.yy"
+#line 2548 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addArray( DeclarationNode::newVarArray( 0 ) ); }
     break;
 
   case 665:
-
-/* Line 1806 of yacc.c  */
-#line 2561 "parser.yy"
-    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
-    break;
-
-  case 666:
 
 /* Line 1806 of yacc.c  */
@@ -8688,8 +8695,15 @@
     break;
 
+  case 666:
+
+/* Line 1806 of yacc.c  */
+#line 2565 "parser.yy"
+    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
+    break;
+
   case 667:
 
 /* Line 1806 of yacc.c  */
-#line 2568 "parser.yy"
+#line 2570 "parser.yy"
     { (yyval.decl) = DeclarationNode::newPointer( 0 ); }
     break;
@@ -8698,5 +8712,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2570 "parser.yy"
+#line 2572 "parser.yy"
     { (yyval.decl) = DeclarationNode::newPointer( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8705,5 +8719,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2572 "parser.yy"
+#line 2574 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8712,5 +8726,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2574 "parser.yy"
+#line 2576 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8719,16 +8733,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2576 "parser.yy"
+#line 2578 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
 
   case 673:
-
-/* Line 1806 of yacc.c  */
-#line 2582 "parser.yy"
-    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
-    break;
-
-  case 674:
 
 /* Line 1806 of yacc.c  */
@@ -8737,8 +8744,15 @@
     break;
 
+  case 674:
+
+/* Line 1806 of yacc.c  */
+#line 2586 "parser.yy"
+    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
+    break;
+
   case 675:
 
 /* Line 1806 of yacc.c  */
-#line 2586 "parser.yy"
+#line 2588 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8747,5 +8761,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2591 "parser.yy"
+#line 2593 "parser.yy"
     { (yyval.decl) = DeclarationNode::newFunction( 0, 0, (yyvsp[(3) - (5)].decl), 0 ); }
     break;
@@ -8754,5 +8768,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2593 "parser.yy"
+#line 2595 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -8761,5 +8775,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2595 "parser.yy"
+#line 2597 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8768,5 +8782,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2602 "parser.yy"
+#line 2604 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8775,5 +8789,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2613 "parser.yy"
+#line 2615 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( 0, 0, false ); }
     break;
@@ -8782,5 +8796,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2616 "parser.yy"
+#line 2618 "parser.yy"
     { (yyval.decl) = DeclarationNode::newVarArray( (yyvsp[(3) - (6)].decl) ); }
     break;
@@ -8789,5 +8803,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2618 "parser.yy"
+#line 2620 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( 0, (yyvsp[(3) - (5)].decl), false ); }
     break;
@@ -8796,5 +8810,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2621 "parser.yy"
+#line 2623 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), false ); }
     break;
@@ -8803,5 +8817,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2623 "parser.yy"
+#line 2625 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(4) - (7)].decl), true ); }
     break;
@@ -8810,16 +8824,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2625 "parser.yy"
+#line 2627 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(3) - (7)].decl), true ); }
     break;
 
   case 689:
-
-/* Line 1806 of yacc.c  */
-#line 2639 "parser.yy"
-    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
-    break;
-
-  case 690:
 
 /* Line 1806 of yacc.c  */
@@ -8828,8 +8835,15 @@
     break;
 
+  case 690:
+
+/* Line 1806 of yacc.c  */
+#line 2643 "parser.yy"
+    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
+    break;
+
   case 691:
 
 /* Line 1806 of yacc.c  */
-#line 2646 "parser.yy"
+#line 2648 "parser.yy"
     { (yyval.decl) = DeclarationNode::newPointer( 0 ); }
     break;
@@ -8838,5 +8852,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2648 "parser.yy"
+#line 2650 "parser.yy"
     { (yyval.decl) = DeclarationNode::newPointer( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8845,5 +8859,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2650 "parser.yy"
+#line 2652 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8852,5 +8866,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2652 "parser.yy"
+#line 2654 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8859,16 +8873,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2654 "parser.yy"
+#line 2656 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
 
   case 697:
-
-/* Line 1806 of yacc.c  */
-#line 2660 "parser.yy"
-    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
-    break;
-
-  case 698:
 
 /* Line 1806 of yacc.c  */
@@ -8877,8 +8884,15 @@
     break;
 
+  case 698:
+
+/* Line 1806 of yacc.c  */
+#line 2664 "parser.yy"
+    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
+    break;
+
   case 699:
 
 /* Line 1806 of yacc.c  */
-#line 2664 "parser.yy"
+#line 2666 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8887,5 +8901,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2669 "parser.yy"
+#line 2671 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -8894,5 +8908,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2671 "parser.yy"
+#line 2673 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8901,5 +8915,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2681 "parser.yy"
+#line 2683 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -8908,5 +8922,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2691 "parser.yy"
+#line 2693 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8915,5 +8929,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2693 "parser.yy"
+#line 2695 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     break;
@@ -8922,5 +8936,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2695 "parser.yy"
+#line 2697 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8929,5 +8943,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2697 "parser.yy"
+#line 2699 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     break;
@@ -8936,5 +8950,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2699 "parser.yy"
+#line 2701 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8943,5 +8957,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2701 "parser.yy"
+#line 2703 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     break;
@@ -8950,5 +8964,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2708 "parser.yy"
+#line 2710 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     break;
@@ -8957,5 +8971,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2710 "parser.yy"
+#line 2712 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -8964,5 +8978,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2712 "parser.yy"
+#line 2714 "parser.yy"
     { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     break;
@@ -8971,5 +8985,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2714 "parser.yy"
+#line 2716 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( (yyvsp[(2) - (3)].decl) )->addNewArray( (yyvsp[(1) - (3)].decl) ); }
     break;
@@ -8978,5 +8992,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2716 "parser.yy"
+#line 2718 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -8985,5 +8999,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2718 "parser.yy"
+#line 2720 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     break;
@@ -8992,5 +9006,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2720 "parser.yy"
+#line 2722 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -8999,5 +9013,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2722 "parser.yy"
+#line 2724 "parser.yy"
     { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     break;
@@ -9006,5 +9020,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2724 "parser.yy"
+#line 2726 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( (yyvsp[(2) - (3)].decl) )->addNewArray( (yyvsp[(1) - (3)].decl) ); }
     break;
@@ -9013,5 +9027,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2726 "parser.yy"
+#line 2728 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -9020,5 +9034,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2731 "parser.yy"
+#line 2733 "parser.yy"
     { (yyval.decl) = DeclarationNode::newVarArray( (yyvsp[(3) - (6)].decl) ); }
     break;
@@ -9027,5 +9041,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2733 "parser.yy"
+#line 2735 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), false ); }
     break;
@@ -9034,5 +9048,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2738 "parser.yy"
+#line 2740 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), true ); }
     break;
@@ -9041,5 +9055,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2740 "parser.yy"
+#line 2742 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(4) - (7)].decl)->addQualifiers( (yyvsp[(3) - (7)].decl) ), true ); }
     break;
@@ -9048,5 +9062,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2767 "parser.yy"
+#line 2769 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -9055,5 +9069,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2778 "parser.yy"
+#line 2780 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -9062,5 +9076,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2780 "parser.yy"
+#line 2782 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     break;
@@ -9069,5 +9083,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2782 "parser.yy"
+#line 2784 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -9076,5 +9090,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2784 "parser.yy"
+#line 2786 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     break;
@@ -9083,5 +9097,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2786 "parser.yy"
+#line 2788 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -9090,5 +9104,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2788 "parser.yy"
+#line 2790 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     break;
@@ -9097,5 +9111,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2795 "parser.yy"
+#line 2797 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     break;
@@ -9104,5 +9118,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2797 "parser.yy"
+#line 2799 "parser.yy"
     { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     break;
@@ -9111,5 +9125,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2799 "parser.yy"
+#line 2801 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -9118,5 +9132,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2801 "parser.yy"
+#line 2803 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     break;
@@ -9125,5 +9139,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2803 "parser.yy"
+#line 2805 "parser.yy"
     { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     break;
@@ -9132,5 +9146,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2805 "parser.yy"
+#line 2807 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -9139,5 +9153,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2810 "parser.yy"
+#line 2812 "parser.yy"
     { (yyval.decl) = DeclarationNode::newTuple( (yyvsp[(3) - (5)].decl) ); }
     break;
@@ -9146,16 +9160,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2815 "parser.yy"
+#line 2817 "parser.yy"
     { (yyval.decl) = DeclarationNode::newFunction( 0, DeclarationNode::newTuple( 0 ), (yyvsp[(4) - (5)].decl), 0 ); }
     break;
 
   case 746:
-
-/* Line 1806 of yacc.c  */
-#line 2817 "parser.yy"
-    { (yyval.decl) = DeclarationNode::newFunction( 0, (yyvsp[(1) - (6)].decl), (yyvsp[(4) - (6)].decl), 0 ); }
-    break;
-
-  case 747:
 
 /* Line 1806 of yacc.c  */
@@ -9164,8 +9171,15 @@
     break;
 
+  case 747:
+
+/* Line 1806 of yacc.c  */
+#line 2821 "parser.yy"
+    { (yyval.decl) = DeclarationNode::newFunction( 0, (yyvsp[(1) - (6)].decl), (yyvsp[(4) - (6)].decl), 0 ); }
+    break;
+
   case 750:
 
 /* Line 1806 of yacc.c  */
-#line 2843 "parser.yy"
+#line 2845 "parser.yy"
     { (yyval.en) = 0; }
     break;
@@ -9174,5 +9188,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2845 "parser.yy"
+#line 2847 "parser.yy"
     { (yyval.en) = (yyvsp[(2) - (2)].en); }
     break;
@@ -9181,5 +9195,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 9184 "Parser/parser.cc"
+#line 9198 "Parser/parser.cc"
       default: break;
     }
@@ -9412,5 +9426,5 @@
 
 /* Line 2067 of yacc.c  */
-#line 2848 "parser.yy"
+#line 2850 "parser.yy"
 
 // ----end of grammar----
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/Parser/parser.yy	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -377,7 +377,9 @@
 		{ $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); }
 	| postfix_expression '.' '[' push field_list pop ']' // CFA, tuple field selector
+		{ $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $5 ) ) ); }
 	| postfix_expression ARROW no_attr_identifier
 		{ $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); }
 	| postfix_expression ARROW '[' push field_list pop ']' // CFA, tuple field selector
+			{ $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $5 ) ) ); }
 	| postfix_expression ICR
 	  	{ $$ = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, $1 ) ); }
Index: src/ResolvExpr/Alternative.cc
===================================================================
--- src/ResolvExpr/Alternative.cc	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/ResolvExpr/Alternative.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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 fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -38,6 +38,5 @@
 #include "SynTree/TypeSubstitution.h"
 #include "SymTab/Validate.h"
-#include "Tuples/TupleAssignment.h"
-#include "Tuples/NameMatcher.h"
+#include "Tuples/Tuples.h"
 #include "Common/utility.h"
 #include "InitTweak/InitTweak.h"
@@ -64,4 +63,12 @@
 	}
 
+	Cost sumCost( const AltList &in ) {
+		Cost total;
+		for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
+			total += i->cost;
+		}
+		return total;
+	}
+
 	namespace {
 		void printAlts( const AltList &list, std::ostream &os, int indent = 0 ) {
@@ -76,12 +83,4 @@
 				out.push_back( i->expr->clone() );
 			}
-		}
-
-		Cost sumCost( const AltList &in ) {
-			Cost total;
-			for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
-				total += i->cost;
-			}
-			return total;
 		}
 
@@ -101,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;
 				}
@@ -133,31 +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;
 				}
 			}
-
-		}
-
-		template< typename InputIterator, typename OutputIterator >
-		void findMinCost( InputIterator begin, InputIterator end, OutputIterator out ) {
-			AltList alternatives;
-
-			// select the alternatives that have the minimum parameter cost
-			Cost minCost = Cost::infinity;
-			for ( AltList::iterator i = begin; i != end; ++i ) {
-				if ( i->cost < minCost ) {
-					minCost = i->cost;
-					i->cost = i->cvtCost;
-					alternatives.clear();
-					alternatives.push_back( *i );
-				} else if ( i->cost == minCost ) {
-					i->cost = i->cvtCost;
-					alternatives.push_back( *i );
-				}
-			}
-			std::copy( alternatives.begin(), alternatives.end(), out );
 		}
 
@@ -170,7 +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 );
-			}
+			expr->get_result()->accept( global_renamer );
 		}
 	}
@@ -204,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 );
 			}
 		}
@@ -241,5 +215,19 @@
 
 	template< typename StructOrUnionType >
-	void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string &name ) {
+	void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
+
+		// // member must be either a tuple expression or a name expr
+		// if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( memberExpr->get_member() ) ) {
+		//  addAggMembers( structInst, agg->expr, agg->cost, nameExpr->get_name() );
+		// } else {
+		//  TupleExpr * tupleExpr = safe_dynamic_cast< TupleExpr * >( memberExpr->get_member() );
+		//  // xxx - ...
+		//  assert( false );
+		// }
+		// if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * >( memberExpr->get_member() ) ) {
+
+		// }
+		NameExpr * nameExpr = safe_dynamic_cast< NameExpr * >( member );
+		const std::string & name = nameExpr->get_name();
 		std::list< Declaration* > members;
 		aggInst->lookup( name, members );
@@ -259,10 +247,7 @@
 
 	Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
-		ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( alt.expr );
-		assert( appExpr );
-		PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
-		assert( pointer );
-		FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
-		assert( function );
+		ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( alt.expr );
+		PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
+		FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
 
 		Cost convCost( 0, 0, 0 );
@@ -270,29 +255,50 @@
 		std::list< DeclarationWithType* >::iterator formal = formals.begin();
 		std::list< Expression* >& actuals = appExpr->get_args();
+
+		std::list< Type * > formalTypes;
+		std::list< Type * >::iterator formalType = formalTypes.end();
+
 		for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
+
 			PRINT(
 				std::cerr << "actual expression:" << std::endl;
 				(*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 actual = (*actualExpr)->get_results().begin(); actual != (*actualExpr)->get_results().end(); ++actual ) {
-				if ( formal == formals.end() ) {
-					if ( function->get_isVarArgs() ) {
-						convCost += Cost( 1, 0, 0 );
-						break;
-					} else {
-						return Cost::infinity;
+			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
+				if ( formalType == formalTypes.end() ) {
+					// the type of the formal parameter may be a tuple type. To make this easier to work with,
+					// flatten the tuple type and traverse the resulting list of types, incrementing the formal
+					// iterator once its types have been extracted. Once a particular formal parameter's type has
+					// been exhausted load the next formal parameter's type.
+					if ( formal == formals.end() ) {
+						if ( function->get_isVarArgs() ) {
+							convCost += Cost( 1, 0, 0 );
+							break;
+						} else {
+							return Cost::infinity;
+						}
 					}
+					formalTypes.clear();
+					flatten( (*formal)->get_type(), back_inserter( formalTypes ) );
+					formalType = formalTypes.begin();
+					++formal;
 				}
+
 				PRINT(
 					std::cerr << std::endl << "converting ";
-					(*actual)->print( std::cerr, 8 );
+					(*actualType)->print( std::cerr, 8 );
 					std::cerr << std::endl << " to ";
 					(*formal)->get_type()->print( std::cerr, 8 );
 				)
-				Cost newCost = conversionCost( *actual, (*formal)->get_type(), indexer, alt.env );
+				Cost newCost = conversionCost( *actualType, *formalType, indexer, alt.env );
 				PRINT(
 					std::cerr << std::endl << "cost is" << newCost << std::endl;
@@ -305,7 +311,7 @@
 				actualCost += newCost;
 
-				convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actual, alt.env, indexer ), 0 );
-
-				formal++;
+				convCost += Cost( 0, polyCost( *formalType, alt.env, indexer ) + polyCost( *actualType, alt.env, indexer ), 0 );
+
+				formalType++;
 			}
 			if ( actualCost != Cost( 0, 0, 0 ) ) {
@@ -373,31 +379,43 @@
 		resultEnv.extractOpenVars( openVars );
 
-		/*
-		  Tuples::NameMatcher matcher( formals );
-		  try {
-		  matcher.match( actuals );
-		  } catch ( Tuples::NoMatch &e ) {
-		  std::cerr << "Alternative doesn't match: " << e.message << std::endl;
-		  }
-		*/
 		std::list< DeclarationWithType* >::iterator formal = formals.begin();
+
+		std::list< Type * > formalTypes;
+		std::list< Type * >::iterator formalType = formalTypes.end();
+
 		for ( AltList::const_iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
-			for ( std::list< Type* >::iterator actual = actualExpr->expr->get_results().begin(); actual != actualExpr->expr->get_results().end(); ++actual ) {
-				if ( formal == formals.end() ) {
-					return isVarArgs;
+			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,
+					// flatten the tuple type and traverse the resulting list of types, incrementing the formal
+					// iterator once its types have been extracted. Once a particular formal parameter's type has
+					// been exhausted load the next formal parameter's type.
+					if ( formal == formals.end() ) {
+						return isVarArgs;
+					}
+					formalTypes.clear();
+					flatten( (*formal)->get_type(), back_inserter( formalTypes ) );
+					formalType = formalTypes.begin();
+					++formal;
 				}
 				PRINT(
 					std::cerr << "formal type is ";
-					(*formal)->get_type()->print( std::cerr );
+					(*formalType)->print( std::cerr );
 					std::cerr << std::endl << "actual type is ";
-					(*actual)->print( std::cerr );
+					(*actualType)->print( std::cerr );
 					std::cerr << std::endl;
 				)
-				if ( ! unify( (*formal)->get_type(), *actual, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
+				if ( ! unify( *formalType, *actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
 					return false;
 				}
-				formal++;
-			}
-		}
+			}
+		}
+
+		// xxx - a tuple type was not completely matched
+		// partially handle the tuple with default arguments??
+		if ( formalType != formalTypes.end() ) return false;
+
 		// Handling of default values
 		while ( formal != formals.end() ) {
@@ -500,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() << " ";
@@ -574,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;
@@ -587,9 +604,7 @@
 		combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) );
 
-		Tuples::TupleAssignSpotter tassign( this );
-		if ( tassign.isTupleAssignment( untypedExpr, possibilities ) ) {
-			// take care of possible tuple assignments, or discard expression
-			return;
-		} // else ...
+		// take care of possible tuple assignments
+		// if not tuple assignment, assignment is taken care of as a normal function call
+		Tuples::handleTupleAssignment( *this, untypedExpr, possibilities );
 
 		AltList candidates;
@@ -604,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 ) {
@@ -640,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 ) {
@@ -665,10 +679,7 @@
 
 			PRINT(
-				ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( withFunc->expr );
-				assert( appExpr );
-				PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
-				assert( pointer );
-				FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
-				assert( function );
+				ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( withFunc->expr );
+				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;
 				std::cerr << "formals are:" << std::endl;
@@ -692,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();
 	}
 
@@ -709,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 );
@@ -727,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
@@ -760,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
@@ -791,7 +792,9 @@
 			renameTypes( alternatives.back().expr );
 			if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) {
-				addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, "" );
+				NameExpr nameExpr( "" );
+				addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
 			} else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) {
-				addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, "" );
+				NameExpr nameExpr( "" );
+				addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
 			} // if
 		} // for
@@ -894,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
@@ -917,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
@@ -960,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 ) );
@@ -999,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;
@@ -1024,4 +1022,12 @@
 		}
 	}
+
+	void AlternativeFinder::visit( TupleIndexExpr *tupleExpr ) {
+		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 fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/ResolvExpr/AlternativeFinder.h	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -67,11 +67,13 @@
 		virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr );
 		virtual void visit( ConstructorExpr * ctorExpr );
-	  public:  // xxx - temporary hack - should make Tuples::TupleAssignment a friend
+		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.
 		template< typename InputIterator, typename OutputIterator >
 		void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out );
 
-	  private:
 		/// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member
-		template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string &name );
+		template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
 		/// Adds alternatives for offsetof expressions, given the base type and name of the member
 		template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name );
@@ -89,4 +91,26 @@
 
 	Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env );
+
+	template< typename InputIterator, typename OutputIterator >
+	void findMinCost( InputIterator begin, InputIterator end, OutputIterator out ) {
+		AltList alternatives;
+
+		// select the alternatives that have the minimum parameter cost
+		Cost minCost = Cost::infinity;
+		for ( InputIterator i = begin; i != end; ++i ) {
+			if ( i->cost < minCost ) {
+				minCost = i->cost;
+				i->cost = i->cvtCost;
+				alternatives.clear();
+				alternatives.push_back( *i );
+			} else if ( i->cost == minCost ) {
+				i->cost = i->cvtCost;
+				alternatives.push_back( *i );
+			}
+		}
+		std::copy( alternatives.begin(), alternatives.end(), out );
+	}
+
+	Cost sumCost( const AltList &in );
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/AlternativePrinter.cc
===================================================================
--- src/ResolvExpr/AlternativePrinter.cc	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/ResolvExpr/AlternativePrinter.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/ResolvExpr/ConversionCost.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -236,5 +236,5 @@
 			std::list< Type* >::const_iterator srcIt = tupleType->get_types().begin();
 			std::list< Type* >::const_iterator destIt = destAsTuple->get_types().begin();
-			while ( srcIt != tupleType->get_types().end() ) {
+			while ( srcIt != tupleType->get_types().end() && destIt != destAsTuple->get_types().end() ) {
 				Cost newCost = conversionCost( *srcIt++, *destIt++, indexer, env );
 				if ( newCost == Cost::infinity ) {
Index: src/ResolvExpr/ResolveTypeof.cc
===================================================================
--- src/ResolvExpr/ResolveTypeof.cc	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/ResolvExpr/ResolveTypeof.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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 fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/ResolvExpr/Resolver.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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 fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/ResolvExpr/Unify.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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 fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/ResolvExpr/typeops.h	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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 fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/SymTab/Autogen.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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 fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/SymTab/Indexer.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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,15 +448,18 @@
 
 	void Indexer::visit( TupleExpr *tupleExpr ) {
-		acceptAllNewScope( tupleExpr->get_results(), *this );
+		acceptNewScope( tupleExpr->get_result(), *this );
 		acceptAll( tupleExpr->get_exprs(), *this );
 	}
 
-	void Indexer::visit( SolvedTupleExpr *tupleExpr ) {
-		acceptAllNewScope( tupleExpr->get_results(), *this );
-		acceptAll( tupleExpr->get_exprs(), *this );
+	void Indexer::visit( TupleAssignExpr *tupleExpr ) {
+		acceptNewScope( tupleExpr->get_result(), *this );
+		enterScope();
+		acceptAll( tupleExpr->get_tempDecls(), *this );
+		acceptAll( tupleExpr->get_assigns(), *this );
+		leaveScope();
 	}
 
 	void Indexer::visit( TypeExpr *typeExpr ) {
-		acceptAllNewScope( typeExpr->get_results(), *this );
+		acceptNewScope( typeExpr->get_result(), *this );
 		maybeAccept( typeExpr->get_type(), *this );
 	}
@@ -469,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/SymTab/Indexer.h
===================================================================
--- src/SymTab/Indexer.h	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/SymTab/Indexer.h	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -64,9 +64,9 @@
 		virtual void visit( ConditionalExpr *conditionalExpr );
 		virtual void visit( CommaExpr *commaExpr );
-		virtual void visit( TupleExpr *tupleExpr );
-		virtual void visit( SolvedTupleExpr *tupleExpr );
 		virtual void visit( TypeExpr *typeExpr );
 		virtual void visit( AsmExpr *asmExpr );
 		virtual void visit( UntypedValofExpr *valofExpr );
+		virtual void visit( TupleExpr *tupleExpr );
+		virtual void visit( TupleAssignExpr *tupleExpr );
 
 		virtual void visit( TraitInstType *contextInst );
Index: src/SynTree/AddressExpr.cc
===================================================================
--- src/SynTree/AddressExpr.cc	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/SynTree/AddressExpr.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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 fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/SynTree/ApplicationExpr.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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 fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/SynTree/CommaExpr.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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 fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/SynTree/Expression.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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,31 +294,36 @@
 	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
-	Expression::print( os, indent );
-}
-
-UntypedMemberExpr::UntypedMemberExpr( std::string _member, Expression *_aggregate, Expression *_aname ) :
+	os << std::endl;
+	Expression::print( os, indent );
+}
+
+UntypedMemberExpr::UntypedMemberExpr( Expression * _member, Expression *_aggregate, Expression *_aname ) :
 		Expression( _aname ), member(_member), aggregate(_aggregate) {}
 
 UntypedMemberExpr::UntypedMemberExpr( const UntypedMemberExpr &other ) :
-		Expression( other ), member( other.member ), aggregate( maybeClone( other.aggregate ) ) {
+		Expression( other ), member( maybeClone( other.member ) ), aggregate( maybeClone( other.aggregate ) ) {
 }
 
 UntypedMemberExpr::~UntypedMemberExpr() {
 	delete aggregate;
+	delete member;
 }
 
 void UntypedMemberExpr::print( std::ostream &os, int indent ) const {
-	os << "Untyped Member Expression, with field: " << get_member();
+	os << "Untyped Member Expression, with field: " << std::endl;
+	get_member()->print(os, indent+4);
+	os << std::string( indent+2, ' ' );
 
 	Expression *agg = get_aggregate();
-	os << ", from aggregate: ";
+	os << "from aggregate: " << std::endl;
 	if (agg != 0) {
-		os << std::string( indent + 2, ' ' );
-		agg->print(os, indent + 2);
+		os << std::string( indent + 4, ' ' );
+		agg->print(os, indent + 4);
 	}
 	os << std::string( indent+2, ' ' );
@@ -338,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 );
 }
 
@@ -372,6 +366,6 @@
 }
 
-
-UntypedExpr::UntypedExpr( Expression *_function, Expression *_aname ) : Expression( _aname ), function( _function ) {}
+UntypedExpr::UntypedExpr( Expression *_function, const std::list<Expression *> &_args, Expression *_aname ) :
+		Expression( _aname ), function(_function), args(_args) {}
 
 UntypedExpr::UntypedExpr( const UntypedExpr &other ) :
@@ -379,7 +373,4 @@
 	cloneAll( other.args, args );
 }
-
-UntypedExpr::UntypedExpr( Expression *_function, std::list<Expression *> &_args, Expression *_aname ) :
-		Expression( _aname ), function(_function), args(_args) {}
 
 UntypedExpr::~UntypedExpr() {
@@ -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() );
 }
 
@@ -565,4 +557,22 @@
 }
 
+StmtExpr::StmtExpr( CompoundStmt *statements ) : statements( statements ) {
+	assert( statements );
+	std::list< Statement * > & body = statements->get_kids();
+	if ( ! body.empty() ) {
+		if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( body.back() ) ) {
+			set_result( maybeClone( exprStmt->get_expr()->get_result() ) );
+		}
+	}
+}
+StmtExpr::StmtExpr( const StmtExpr &other ) : statements( other.statements->clone() ) {}
+StmtExpr::~StmtExpr() {
+	delete statements;
+}
+void StmtExpr::print( std::ostream &os, int indent ) const {
+	os << std::string( indent, ' ' ) << "Statement Expression: " << std::endl;
+	statements->print( os, indent+2 );
+}
+
 std::ostream & operator<<( std::ostream & out, const Expression * expr ) {
 	expr->print( out );
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/SynTree/Expression.h	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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
@@ -98,7 +99,6 @@
 class UntypedExpr : public Expression {
   public:
-	UntypedExpr( Expression *function, Expression *_aname = nullptr );
+	UntypedExpr( Expression *function, const std::list<Expression *> &args = std::list< Expression * >(), Expression *_aname = nullptr );
 	UntypedExpr( const UntypedExpr &other );
-	UntypedExpr( Expression *function, std::list<Expression *> &args, Expression *_aname = nullptr );
 	virtual ~UntypedExpr();
 
@@ -200,10 +200,10 @@
 class UntypedMemberExpr : public Expression {
   public:
-	UntypedMemberExpr( std::string member, Expression *aggregate, Expression *_aname = nullptr );
+	UntypedMemberExpr( Expression *member, Expression *aggregate, Expression *_aname = nullptr );
 	UntypedMemberExpr( const UntypedMemberExpr &other );
 	virtual ~UntypedMemberExpr();
 
-	std::string get_member() const { return member; }
-	void set_member( const std::string &newValue ) { member = newValue; }
+	Expression * get_member() const { return member; }
+	void set_member( Expression * newValue ) { member = newValue; }
 	Expression *get_aggregate() const { return aggregate; }
 	void set_aggregate( Expression *newValue ) { aggregate = newValue; }
@@ -214,5 +214,5 @@
 	virtual void print( std::ostream &os, int indent = 0 ) const;
   private:
-	std::string member;
+	Expression *member;
 	Expression *aggregate;
 };
@@ -483,40 +483,4 @@
 };
 
-/// TupleExpr represents a tuple expression ( [a, b, c] )
-class TupleExpr : public Expression {
-  public:
-	TupleExpr( Expression *_aname = nullptr );
-	TupleExpr( const TupleExpr &other );
-	virtual ~TupleExpr();
-
-	void set_exprs( std::list<Expression*> newValue ) { exprs = newValue; }
-	std::list<Expression*>& get_exprs() { return exprs; }
-
-	virtual TupleExpr *clone() const { return new TupleExpr( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 ) const;
-  private:
-	std::list<Expression*> exprs;
-};
-
-/// SolvedTupleExpr represents a TupleExpr whose components have been type-resolved. It is effectively a shell for the code generator to work on
-class SolvedTupleExpr : public Expression {
-  public:
-	SolvedTupleExpr( Expression *_aname = nullptr ) : Expression( _aname ) {}
-	SolvedTupleExpr( std::list<Expression *> &, Expression *_aname = nullptr );
-	SolvedTupleExpr( const SolvedTupleExpr &other );
-	virtual ~SolvedTupleExpr() {}
-
-	std::list<Expression*> &get_exprs() { return exprs; }
-
-	virtual SolvedTupleExpr *clone() const { return new SolvedTupleExpr( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 ) const;
-  private:
-	std::list<Expression*> exprs;
-};
-
 /// TypeExpr represents a type used in an expression (e.g. as a type generator parameter)
 class TypeExpr : public Expression {
@@ -618,5 +582,5 @@
 	CompoundLiteralExpr( Type * type, Initializer * initializer );
 	CompoundLiteralExpr( const CompoundLiteralExpr &other );
-	~CompoundLiteralExpr();
+	virtual ~CompoundLiteralExpr();
 
 	Type * get_type() const { return type; }
@@ -670,4 +634,101 @@
   private:
 	Expression *low, *high;
+};
+
+/// TupleExpr represents a tuple expression ( [a, b, c] )
+class TupleExpr : public Expression {
+  public:
+	TupleExpr( Expression *_aname = nullptr );
+	TupleExpr( const TupleExpr &other );
+	virtual ~TupleExpr();
+
+	void set_exprs( std::list<Expression*> newValue ) { exprs = newValue; }
+	std::list<Expression*>& get_exprs() { return exprs; }
+
+	virtual TupleExpr *clone() const { return new TupleExpr( *this ); }
+	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const;
+  private:
+	std::list<Expression*> exprs;
+};
+
+/// TupleIndexExpr represents an element selection operation on a tuple value, e.g. t.3 after processing by the expression analyzer
+class TupleIndexExpr : public Expression {
+  public:
+	TupleIndexExpr( Expression * tuple, unsigned int index );
+	TupleIndexExpr( const TupleIndexExpr &other );
+	virtual ~TupleIndexExpr();
+
+	Expression * get_tuple() const { return tuple; }
+	int get_index() const { return index; }
+	TupleIndexExpr * set_tuple( Expression *newValue ) { tuple = newValue; return this; }
+	TupleIndexExpr * set_index( unsigned int newValue ) { index = newValue; return this; }
+
+	virtual TupleIndexExpr *clone() const { return new TupleIndexExpr( *this ); }
+	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const;
+  private:
+	Expression * tuple;
+	unsigned int index;
+};
+
+/// MemberTupleExpr represents a tuple member selection operation on a struct type, e.g. s.[a, b, c] after processing by the expression analyzer
+class MemberTupleExpr : public Expression {
+  public:
+	MemberTupleExpr( Expression * member, Expression * aggregate, Expression * _aname = nullptr );
+	MemberTupleExpr( const MemberTupleExpr &other );
+	virtual ~MemberTupleExpr();
+
+	Expression * get_member() const { return member; }
+	Expression * get_aggregate() const { return aggregate; }
+	MemberTupleExpr * set_member( Expression *newValue ) { member = newValue; return this; }
+	MemberTupleExpr * set_aggregate( Expression *newValue ) { aggregate = newValue; return this; }
+
+	virtual MemberTupleExpr *clone() const { return new MemberTupleExpr( *this ); }
+	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const;
+  private:
+	Expression * member;
+	Expression * aggregate;
+};
+
+/// TupleAssignExpr represents a multiple assignment operation, where both sides of the assignment have tuple type, e.g. [a, b, c] = [d, e, f];, or a mass assignment operation, where the left hand side has tuple type and the right hand side does not, e.g. [a, b, c] = 5.0;
+class TupleAssignExpr : public Expression {
+  public:
+	TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls, Expression * _aname = nullptr );
+	TupleAssignExpr( const TupleAssignExpr &other );
+	virtual ~TupleAssignExpr();
+
+	std::list< Expression * > & get_assigns() { return assigns; }
+	std::list< ObjectDecl * > & get_tempDecls() { return tempDecls; }
+
+	virtual TupleAssignExpr *clone() const { return new TupleAssignExpr( *this ); }
+	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const;
+  private:
+	std::list< Expression * > assigns; // assignment expressions that use tempDecls
+	std::list< ObjectDecl * > tempDecls; // temporaries for address of lhs exprs
+};
+
+/// StmtExpr represents a GCC 'statement expression', e.g. ({ int x = 5; x; })
+class StmtExpr : public Expression {
+public:
+	StmtExpr( CompoundStmt *statements );
+	StmtExpr( const StmtExpr & other );
+	virtual ~StmtExpr();
+
+	CompoundStmt * get_statements() const { return statements; }
+	StmtExpr * set_statements( CompoundStmt * newValue ) { statements = newValue; return this; }
+
+	virtual StmtExpr *clone() const { return new StmtExpr( *this ); }
+	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const;
+private:
+	CompoundStmt * statements;
 };
 
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/SynTree/Mutator.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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,22 +214,23 @@
 
 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 ) );
+	return memberExpr;
+}
+
+Expression *Mutator::mutate( MemberExpr *memberExpr ) {
+	memberExpr->set_result( maybeMutate( memberExpr->get_result(), *this ) );
 	memberExpr->set_aggregate( maybeMutate( memberExpr->get_aggregate(), *this ) );
 	return memberExpr;
 }
 
-Expression *Mutator::mutate( MemberExpr *memberExpr ) {
-	mutateAll( memberExpr->get_results(), *this );
-	memberExpr->set_aggregate( maybeMutate( memberExpr->get_aggregate(), *this ) );
-	return memberExpr;
-}
-
 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;
@@ -237,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 ) );
@@ -247,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 ) );
@@ -257,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;
@@ -263,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 ) );
@@ -270,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;
@@ -276,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 ) );
@@ -286,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 ) );
@@ -293,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 ) );
@@ -301,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 ) );
@@ -307,18 +308,6 @@
 }
 
-Expression *Mutator::mutate( TupleExpr *tupleExpr ) {
-	mutateAll( tupleExpr->get_results(), *this );
-	mutateAll( tupleExpr->get_exprs(), *this );
-	return tupleExpr;
-}
-
-Expression *Mutator::mutate( SolvedTupleExpr *tupleExpr ) {
-	mutateAll( tupleExpr->get_results(), *this );
-	mutateAll( tupleExpr->get_exprs(), *this );
-	return tupleExpr;
-}
-
 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;
@@ -340,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;
@@ -346,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 ) );
@@ -353,5 +342,5 @@
 
 Expression *Mutator::mutate( UntypedValofExpr *valofExpr ) {
-	mutateAll( valofExpr->get_results(), *this );
+	valofExpr->set_result( maybeMutate( valofExpr->get_result(), *this ) );
 	return valofExpr;
 }
@@ -361,4 +350,36 @@
 	rangeExpr->set_high( maybeMutate( rangeExpr->get_high(), *this ) );
 	return rangeExpr;
+}
+
+Expression *Mutator::mutate( TupleExpr *tupleExpr ) {
+	tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) );
+	mutateAll( tupleExpr->get_exprs(), *this );
+	return tupleExpr;
+}
+
+Expression *Mutator::mutate( TupleIndexExpr *tupleExpr ) {
+	tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) );
+	tupleExpr->set_tuple( maybeMutate( tupleExpr->get_tuple(), *this ) );
+	return tupleExpr;
+}
+
+Expression *Mutator::mutate( MemberTupleExpr *tupleExpr ) {
+	tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) );
+	tupleExpr->set_member( maybeMutate( tupleExpr->get_member(), *this ) );
+	tupleExpr->set_aggregate( maybeMutate( tupleExpr->get_aggregate(), *this ) );
+	return tupleExpr;
+}
+
+Expression *Mutator::mutate( TupleAssignExpr *assignExpr ) {
+	assignExpr->set_result( maybeMutate( assignExpr->get_result(), *this ) );
+	mutateAll( assignExpr->get_tempDecls(), *this );
+	mutateAll( assignExpr->get_assigns(), *this );
+	return assignExpr;
+}
+
+Expression *Mutator::mutate( StmtExpr *stmtExpr ) {
+	stmtExpr->set_result( maybeMutate( stmtExpr->get_result(), *this ) );
+	stmtExpr->set_statements( maybeMutate( stmtExpr->get_statements(), *this ) );
+	return stmtExpr;
 }
 
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/SynTree/Mutator.h	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -71,6 +71,4 @@
 	virtual Expression* mutate( ConditionalExpr *conditionalExpr );
 	virtual Expression* mutate( CommaExpr *commaExpr );
-	virtual Expression* mutate( TupleExpr *tupleExpr );
-	virtual Expression* mutate( SolvedTupleExpr *tupleExpr );
 	virtual Expression* mutate( TypeExpr *typeExpr );
 	virtual Expression* mutate( AsmExpr *asmExpr );
@@ -80,4 +78,9 @@
 	virtual Expression* mutate( UntypedValofExpr *valofExpr );
 	virtual Expression* mutate( RangeExpr *rangeExpr );
+	virtual Expression* mutate( TupleExpr *tupleExpr );
+	virtual Expression* mutate( TupleIndexExpr *tupleExpr );
+	virtual Expression* mutate( MemberTupleExpr *tupleExpr );
+	virtual Expression* mutate( TupleAssignExpr *assignExpr );
+	virtual Expression* mutate( StmtExpr * stmtExpr );
 
 	virtual Type* mutate( VoidType *basicType );
Index: src/SynTree/ReferenceToType.cc
===================================================================
--- src/SynTree/ReferenceToType.cc	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/SynTree/ReferenceToType.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -56,4 +56,6 @@
 	}
 } // namespace
+
+StructInstType::StructInstType( const Type::Qualifiers & tq, StructDecl * baseStruct ) : Parent( tq, baseStruct->get_name() ), baseStruct( baseStruct ) {}
 
 std::string StructInstType::typeString() const { return "struct"; }
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/SynTree/SynTree.h	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -76,6 +76,4 @@
 class ConditionalExpr;
 class CommaExpr;
-class TupleExpr;
-class SolvedTupleExpr;
 class TypeExpr;
 class AsmExpr;
@@ -85,4 +83,9 @@
 class UntypedValofExpr;
 class RangeExpr;
+class TupleExpr;
+class TupleIndexExpr;
+class MemberTupleExpr;
+class TupleAssignExpr;
+class StmtExpr;
 
 class Type;
Index: src/SynTree/TupleExpr.cc
===================================================================
--- src/SynTree/TupleExpr.cc	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/SynTree/TupleExpr.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// TupleExpr.cc -- 
+// TupleExpr.cc --
 //
 // Author           : Richard C. Bilson
@@ -16,4 +16,6 @@
 #include "Expression.h"
 #include "Common/utility.h"
+#include "Type.h"
+#include "Declaration.h"
 
 TupleExpr::TupleExpr( Expression *_aname ) : Expression( _aname ) {
@@ -29,22 +31,78 @@
 
 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 );
 }
 
-SolvedTupleExpr::SolvedTupleExpr( std::list<Expression *> &_exprs, Expression *_aname ) : Expression( _aname ) {
-	std::copy(_exprs.begin(), _exprs.end(), back_inserter(exprs));
+TupleIndexExpr::TupleIndexExpr( Expression * tuple, unsigned int index ) {
+	TupleType * type = safe_dynamic_cast< TupleType * >( tuple->get_result() );
+	assert( type->size() >= index );
+	set_result( *std::next( type->get_types().begin(), index ) );
 }
 
-SolvedTupleExpr::SolvedTupleExpr( const SolvedTupleExpr &other ) : Expression( other ) {
-	cloneAll( other.exprs, exprs );
+TupleIndexExpr::TupleIndexExpr( const TupleIndexExpr &other ) : Expression( other ), tuple( other.tuple->clone() ), index( other.index ) {
 }
 
-void SolvedTupleExpr::print( std::ostream &os, int indent ) const {
-	os << std::string( indent, ' ' ) << "Solved Tuple:" << std::endl;
-	printAll( exprs, os, indent+2 );
+TupleIndexExpr::~TupleIndexExpr() {
+	delete tuple;
+}
+
+void TupleIndexExpr::print( std::ostream &os, int indent ) const {
+	os << "Tuple Index Expression, with tuple:" << std::endl;
+	tuple->print( os, indent+2 );
+	os << std::string( indent+2, ' ' ) << "with index: " << index << std::endl;
 	Expression::print( os, indent );
 }
+
+MemberTupleExpr::MemberTupleExpr( Expression * member, Expression * aggregate, Expression * _aname ) : Expression( _aname ) {
+	set_result( maybeClone( member->get_result() ) ); // xxx - ???
+}
+
+MemberTupleExpr::MemberTupleExpr( const MemberTupleExpr &other ) : Expression( other ), member( other.member->clone() ), aggregate( other.aggregate->clone() ) {
+}
+
+MemberTupleExpr::~MemberTupleExpr() {
+	delete member;
+	delete aggregate;
+}
+
+void MemberTupleExpr::print( std::ostream &os, int indent ) const {
+	os << "Member Tuple Expression, with aggregate:" << std::endl;
+	aggregate->print( os, indent+2 );
+	os << std::string( indent+2, ' ' ) << "with member: " << std::endl;
+	member->print( os, indent+2 );
+	Expression::print( os, indent );
+}
+
+
+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 ) {
+		assert( expr->has_result() );
+		type->get_types().push_back( expr->get_result()->clone() );
+	}
+	set_result( type );
+}
+
+TupleAssignExpr::TupleAssignExpr( const TupleAssignExpr &other ) : Expression( other ), tempDecls( other.tempDecls ) /* temporary */ {
+	cloneAll( other.assigns, assigns );
+	// xxx - clone needs to go into assigns and replace tempDecls
+}
+
+TupleAssignExpr::~TupleAssignExpr() {
+	deleteAll( assigns );
+	// deleteAll( tempDecls );
+}
+
+void TupleAssignExpr::print( std::ostream &os, int indent ) const {
+	os << std::string( indent, ' ' ) << "Tuple Assignment Expression, with temporaries:" << std::endl;
+	printAll( tempDecls, os, indent+4 );
+	os << std::string( indent+2, ' ' ) << "with assignments: " << std::endl;
+	printAll( assigns, os, indent+4 );
+	Expression::print( os, indent );
+}
+
+
 
 // Local Variables: //
Index: src/SynTree/TupleType.cc
===================================================================
--- src/SynTree/TupleType.cc	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/SynTree/TupleType.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// TupleType.cc -- 
+// TupleType.cc --
 //
 // Author           : Richard C. Bilson
@@ -17,5 +17,5 @@
 #include "Common/utility.h"
 
-TupleType::TupleType( const Type::Qualifiers &tq ) : Type( tq ) {
+TupleType::TupleType( const Type::Qualifiers &tq, const std::list< Type * > & types ) : Type( tq ), types( types ) {
 }
 
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/SynTree/Type.h	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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 ); }
@@ -234,4 +241,5 @@
   public:
 	StructInstType( const Type::Qualifiers &tq, const std::string &name ) : Parent( tq, name ), baseStruct( 0 ) {}
+	StructInstType( const Type::Qualifiers &tq, StructDecl * baseStruct );
 	StructInstType( const StructInstType &other ) : Parent( other ), baseStruct( other.baseStruct ) {}
 
@@ -348,9 +356,16 @@
 class TupleType : public Type {
   public:
-	TupleType( const Type::Qualifiers &tq );
+	TupleType( const Type::Qualifiers &tq, const std::list< Type * > & types = std::list< Type * >() );
 	TupleType( const TupleType& );
 	virtual ~TupleType();
 
+	typedef std::list<Type*> value_type;
+	typedef value_type::iterator iterator;
+
 	std::list<Type*>& get_types() { return types; }
+	virtual unsigned size() const { return types.size(); };
+
+	iterator begin() { return types.begin(); }
+	iterator end() { return types.end(); }
 
 	virtual TupleType *clone() const { return new TupleType( *this ); }
@@ -418,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 fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/SynTree/Visitor.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -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,48 +156,49 @@
 
 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 );
 }
 
 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 );
@@ -208,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 );
@@ -217,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 );
@@ -228,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 );
@@ -242,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 );
@@ -248,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 );
@@ -255,21 +256,11 @@
 
 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 );
 }
 
-void Visitor::visit( TupleExpr *tupleExpr ) {
-	acceptAll( tupleExpr->get_results(), *this );
-	acceptAll( tupleExpr->get_exprs(), *this );
-}
-
-void Visitor::visit( SolvedTupleExpr *tupleExpr ) {
-	acceptAll( tupleExpr->get_results(), *this );
-	acceptAll( tupleExpr->get_exprs(), *this );
-}
-
 void Visitor::visit( TypeExpr *typeExpr ) {
-	acceptAll( typeExpr->get_results(), *this );
+	maybeAccept( typeExpr->get_result(), *this );
 	maybeAccept( typeExpr->get_type(), *this );
 }
@@ -288,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 );
@@ -299,5 +290,5 @@
 
 void Visitor::visit( UntypedValofExpr *valofExpr ) {
-	acceptAll( valofExpr->get_results(), *this );
+	maybeAccept( valofExpr->get_result(), *this );
 	maybeAccept( valofExpr->get_body(), *this );
 }
@@ -306,4 +297,31 @@
 	maybeAccept( rangeExpr->get_low(), *this );
 	maybeAccept( rangeExpr->get_high(), *this );
+}
+
+void Visitor::visit( TupleExpr *tupleExpr ) {
+	maybeAccept( tupleExpr->get_result(), *this );
+	acceptAll( tupleExpr->get_exprs(), *this );
+}
+
+void Visitor::visit( TupleIndexExpr *tupleExpr ) {
+	maybeAccept( tupleExpr->get_result(), *this );
+	maybeAccept( tupleExpr->get_tuple(), *this );
+}
+
+void Visitor::visit( MemberTupleExpr *tupleExpr ) {
+	maybeAccept( tupleExpr->get_result(), *this );
+	maybeAccept( tupleExpr->get_member(), *this );
+	maybeAccept( tupleExpr->get_aggregate(), *this );
+}
+
+void Visitor::visit( TupleAssignExpr *assignExpr ) {
+	maybeAccept( assignExpr->get_result(), *this );
+	acceptAll( assignExpr->get_tempDecls(), *this );
+	acceptAll( assignExpr->get_assigns(), *this );
+}
+
+void Visitor::visit( StmtExpr *stmtExpr ) {
+	maybeAccept( stmtExpr->get_result(), *this );
+	maybeAccept( stmtExpr->get_statements(), *this );
 }
 
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/SynTree/Visitor.h	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -71,6 +71,4 @@
 	virtual void visit( ConditionalExpr *conditionalExpr );
 	virtual void visit( CommaExpr *commaExpr );
-	virtual void visit( TupleExpr *tupleExpr );
-	virtual void visit( SolvedTupleExpr *tupleExpr );
 	virtual void visit( TypeExpr *typeExpr );
 	virtual void visit( AsmExpr *asmExpr );
@@ -80,4 +78,9 @@
 	virtual void visit( UntypedValofExpr *valofExpr );
 	virtual void visit( RangeExpr *rangeExpr );
+	virtual void visit( TupleExpr *tupleExpr );
+	virtual void visit( TupleIndexExpr *tupleExpr );
+	virtual void visit( MemberTupleExpr *tupleExpr );
+	virtual void visit( TupleAssignExpr *assignExpr );
+	virtual void visit( StmtExpr * stmtExpr );
 
 	virtual void visit( VoidType *basicType );
Index: c/Tuples/NameMatcher.cc
===================================================================
--- src/Tuples/NameMatcher.cc	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ 	(revision )
@@ -1,67 +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.
-//
-// NameMatcher.cc -- 
-//
-// Author           : Rodolfo G. Esteves
-// Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Mon May 18 15:00:06 2015
-// Update Count     : 1
-//
-
-#include "NameMatcher.h"
-#include "NameMatcher.h"
-
-namespace Tuples {
-	NameMatcher::NameMatcher( std::list< DeclarationWithType* > &formals ) : current( 0 ) {
-		int cnt = 0;
-		for ( std::list< DeclarationWithType *>::const_iterator f = formals.begin(); f != formals.end(); ++f ) {
-			table.insert( std::pair< std::string, int >( (*f)->get_name(), cnt++ ) );
-			index.push_back(*f);
-		} // for
-		exprs.reserve( index.size() );
-	}
-
-	NameMatcher::~NameMatcher() {}
-
-	void NameMatcher::match( ResolvExpr::AltList &alternatives ) throw (NoMatch) {
-		if ( alternatives.size() != index.size() )
-			throw NoMatch("Length of actuals and formals differ");
-
-		for ( ResolvExpr::AltList::const_iterator a = alternatives.begin(); a != alternatives.end(); ++a ) {
-			if ( a->expr->get_argName() != 0 )
-				if ( NameExpr *name = dynamic_cast<NameExpr *>( a->expr->get_argName() ) ) {
-					if ( table.find( name->get_name() ) != table.end() ) {
-						std::cerr << "Rearranging to " << table[ name->get_name() ] << "position in the list." << std::endl;
-						exprs[ table[ name->get_name() ] ] = &(*a);
-					} else
-						throw NoMatch( name->get_name() + "no such  designation" );
-				} /*else if ( TupleExpr *tup = dynamic_cast<TupleExpr *>( a->expr->get_argName() ) )
-					std::cerr << "Designated expression" << std::endl; */
-			exprs.push_back( &(*a) );
-		} // for
-
-		/*std::cerr << "In matcher/match: ";
-		  if ( exprs.size() != index.size() )
-		  std::cerr << "exprs and index differ in length" << std::endl;
-		  else
-		  std::cerr << "is all good." << std::endl;
-		*/
-	}
-
-	ResolvExpr::Alternative &NameMatcher::get_next() throw (NoMoreElements) {
-		if ( current++ >= (int)(index.size()) )
-			throw NoMoreElements();
-		return *(new ResolvExpr::Alternative());
-	}
-} // namespace Tuples
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: c/Tuples/NameMatcher.h
===================================================================
--- src/Tuples/NameMatcher.h	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ 	(revision )
@@ -1,62 +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.
-//
-// NameMatcher.h -- 
-//
-// Author           : Rodolfo G. Esteves
-// Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Mon May 18 15:01:37 2015
-// Update Count     : 3
-//
-
-#ifndef _NAMEMATCHER_H_
-#define _NAMEMATCHER_H_
-
-#include <map>
-#include <vector>
-#include <string>
-
-#include "SynTree/SynTree.h"
-#include "SynTree/Mutator.h"
-
-#include "SynTree/Type.h"
-#include "SynTree/Declaration.h"
-#include "SynTree/Expression.h"
-#include "SynTree/Statement.h"
-
-#include "ResolvExpr/Alternative.h"
-
-namespace Tuples {
-	struct NoMoreElements {};
-	struct NoMatch {
-		NoMatch( std::string msg ) : message( msg ) {}
-		std::string message;
-	};
-
-	class NameMatcher {
-	  public:
-		NameMatcher( std::list< DeclarationWithType* >& );
-		~NameMatcher();
-
-		void match( ResolvExpr::AltList &alternatives ) throw (NoMatch) ;
-		ResolvExpr::Alternative &get_next() throw (NoMoreElements);
-
-	  private:
-		int current;
-		std::vector< DeclarationWithType* > index;
-		std::vector< const ResolvExpr::Alternative * > exprs;
-		std::map< std::string, int> table;
-	};
-} // namespace Tuples
-
-#endif // _NAMEMATCHER_H_
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: src/Tuples/TupleAssignment.cc
===================================================================
--- src/Tuples/TupleAssignment.cc	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/Tuples/TupleAssignment.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// TupleAssignment.cc -- 
+// TupleAssignment.cc --
 //
 // Author           : Rodolfo G. Esteves
@@ -18,5 +18,6 @@
 #include "ResolvExpr/typeops.h"
 #include "SynTree/Expression.h"
-#include "TupleAssignment.h"
+#include "SynTree/Initializer.h"
+#include "Tuples.h"
 #include "Common/SemanticError.h"
 
@@ -27,383 +28,213 @@
 #include <cassert>
 #include <set>
+#include <unordered_set>
 
 namespace Tuples {
-	TupleAssignSpotter::TupleAssignSpotter( ResolvExpr::AlternativeFinder *f = 0 )
-		: currentFinder(f), matcher(0), hasMatched( false ) {}
-
-	bool TupleAssignSpotter::pointsToTuple( Expression *expr ) {
+	class TupleAssignSpotter {
+	  public:
+		// dispatcher for Tuple (multiple and mass) assignment operations
+		TupleAssignSpotter( ResolvExpr::AlternativeFinder & );
+		void spot( UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities );
+
+	  private:
+		void match();
+		// records for assignment generation
+		struct Options {
+			void print( std::ostream & );
+			int size() const { return options.size(); }
+			bool empty() const { return options.empty(); }
+			typedef std::list< ResolvExpr::AltList >::iterator iterator;
+			iterator begin() { return options.begin(); }
+			iterator end() { return options.end(); }
+
+			std::list< ResolvExpr::AltList > options;
+		};
+
+		struct Matcher {
+		  public:
+			Matcher( TupleAssignSpotter &spotter, Expression *_lhs, Expression *_rhs );
+			virtual ~Matcher() {}
+			virtual void match( std::list< Expression * > &out ) = 0;
+			std::list< Expression * > lhs, rhs;
+			TupleAssignSpotter &spotter;
+			std::list< ObjectDecl * > tmpDecls;
+		};
+
+		struct MassAssignMatcher : public Matcher {
+		  public:
+			MassAssignMatcher( TupleAssignSpotter &spotter, Expression *lhs, Expression *rhs ) : Matcher( spotter, lhs, rhs ) {
+				this->rhs.push_back( rhs );
+			}
+			virtual void match( std::list< Expression * > &out );
+		};
+
+		struct MultipleAssignMatcher : public Matcher {
+		  public:
+			MultipleAssignMatcher( TupleAssignSpotter &spot, Expression *lhs, Expression *rhs );
+			virtual void match( std::list< Expression * > &out );
+		};
+
+		ResolvExpr::AlternativeFinder &currentFinder;
+		// Expression *rhs, *lhs;
+		Matcher *matcher = nullptr;
+		Options options;
+	};
+
+	bool isTupleVar( DeclarationWithType *decl ) {
+		return dynamic_cast< TupleType * >( decl->get_type() );
+	}
+
+	/// true if expr is an expression of tuple type, i.e. a tuple expression, tuple variable, or MRV (multiple-return-value) function
+	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_result()->size() > 1;
+	}
+
+	bool pointsToTuple( Expression *expr ) {
 		// also check for function returning tuple of reference types
-		if (AddressExpr *addr = dynamic_cast<AddressExpr *>(expr) )
-			if ( isTuple(addr->get_arg() ) )
-				return true;
+		if ( AddressExpr *addr = dynamic_cast< AddressExpr * >( expr) ) {
+			return isTuple( addr->get_arg() );
+		}
 		return false;
 	}
 
-	bool TupleAssignSpotter::isTupleVar( DeclarationWithType *decl ) {
-		if ( dynamic_cast<TupleType *>(decl->get_type()) )
-			return true;
-		return false;
-	}
-
-	bool TupleAssignSpotter::isTuple( Expression *expr, bool isRight ) {
-		// true if `expr' is an expression returning a tuple: tuple, tuple variable or MRV function
-		if ( ! expr ) return false;
-
-		if ( dynamic_cast<TupleExpr *>(expr) )
-			return true;
-		else if ( VariableExpr *var = dynamic_cast<VariableExpr *>(expr) ) {
-			if ( isTupleVar(var->get_var()) )
-				return true;
-		}
-
-		return false;
-	}
-
-	bool TupleAssignSpotter::match() {
-		assert ( matcher != 0 );
-
-		std::list< Expression * > new_assigns;
-		if ( ! matcher->match(new_assigns) )
-			return false;
-
-		if ( new_assigns.empty() ) return false;
-		/*return */matcher->solve( new_assigns );
-		if ( dynamic_cast<TupleAssignSpotter::MultipleAssignMatcher *>( matcher ) ) {
-			// now resolve new assignments
-			std::list< Expression * > solved_assigns;
-			ResolvExpr::AltList solved_alts;
-			assert( currentFinder != 0 );
-
-			ResolvExpr::AltList current;
-			for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) {
-				//try {
-				ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() );
-				finder.findWithAdjustment(*i);
-				// prune expressions that don't coincide with
-				ResolvExpr::AltList alts = finder.get_alternatives();
-				assert( alts.size() == 1 );
-				assert(alts.front().expr != 0 );
-				current.push_back( finder.get_alternatives().front() );
-				solved_assigns.push_back( alts.front().expr->clone() );
-				//solved_assigns.back()->print(std::cerr);
-				/*} catch( ... ) {
-				  continue; // no reasonable alternative found
-				  }*/
-			}
-			options.add_option( current );
-
-			return true;
-		} else { // mass assignment
-			//if ( new_assigns.empty() ) return false;
-			std::list< Expression * > solved_assigns;
-			ResolvExpr::AltList solved_alts;
-			assert( currentFinder != 0 );
-
-			ResolvExpr::AltList current;
-			if ( optMass.empty() ) {
-				for ( std::list< Expression * >::size_type i = 0; i != new_assigns.size(); ++i )
-					optMass.push_back( ResolvExpr::AltList() );
-			}
-			int cnt = 0;
-			for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i, cnt++ ) {
-
-				ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() );
-				finder.findWithAdjustment(*i);
-				ResolvExpr::AltList alts = finder.get_alternatives();
-				assert( alts.size() == 1 );
-				assert(alts.front().expr != 0 );
-				current.push_back( finder.get_alternatives().front() );
-				optMass[cnt].push_back( finder.get_alternatives().front() );
-				solved_assigns.push_back( alts.front().expr->clone() );
-			}
-
-			return true;
-		}
-
-		return false;
-	}
-
-	bool TupleAssignSpotter::isMVR( Expression *expr ) {
-		if ( expr->get_results().size() > 1 ) {
-			// MVR processing
-			return true;
-		}
-		return false;
-	}
-
-	bool TupleAssignSpotter::isTupleAssignment( UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities ) {
+	bool isTupleExpr( Expression *expr ) {
+		assert( expr->has_result() );
+		return expr->get_result()->size() > 1;
+	}
+
+	void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities ) {
+		TupleAssignSpotter spotter( currentFinder );
+		spotter.spot( expr, possibilities );
+	}
+
+	TupleAssignSpotter::TupleAssignSpotter( ResolvExpr::AlternativeFinder &f )
+		: currentFinder(f) {}
+
+	void TupleAssignSpotter::spot( UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities ) {
 		if (  NameExpr *assgnop = dynamic_cast< NameExpr * >(expr->get_function()) ) {
-
 			if ( assgnop->get_name() == std::string("?=?") ) {
-
 				for ( std::list<ResolvExpr::AltList>::iterator ali = possibilities.begin(); ali != possibilities.end(); ++ali ) {
 					assert( ali->size() == 2 );
-					ResolvExpr::AltList::iterator opit = ali->begin();
-					ResolvExpr::Alternative op1 = *opit, op2 = *(++opit);
-
+					ResolvExpr::Alternative op1 = ali->front(), op2 = ali->back();
+
+					MultipleAssignMatcher multiMatcher( *this, op1.expr, op2.expr );
+					MassAssignMatcher massMatcher( *this, op1.expr, op2.expr );
 					if ( pointsToTuple(op1.expr) ) { // also handles tuple vars
-						if ( isTuple( op2.expr, true ) )
-							matcher = new MultipleAssignMatcher(op1.expr, op2.expr);
-						else if ( isMVR( op2.expr ) ) {
-							// handle MVR differently
-						} else
+						if ( isTuple( op2.expr ) ) {
+							matcher = &multiMatcher;
+						} else {
 							// mass assignment
-							matcher = new MassAssignMatcher(op1.expr, op2.expr);
-
-						std::list< ResolvExpr::AltList > options;
-						if ( match() )
-							/*
-							  if ( hasMatched ) {
-							  // throw SemanticError("Ambiguous tuple assignment");
-							  } else {*/
-							// Matched for the first time
-							hasMatched = true;
-						/*} */
-					} /* else if ( isTuple( op2 ) )
-						 throw SemanticError("Inapplicable tuple assignment.");
-					  */
-				}
-
-				if ( hasMatched ) {
-					if ( dynamic_cast<TupleAssignSpotter::MultipleAssignMatcher *>( matcher ) ) {
-						//options.print( std::cerr );
-						std::list< ResolvExpr::AltList >best = options.get_best();
-						if ( best.size() == 1 ) {
-							std::list<Expression *> solved_assigns;
-							for ( ResolvExpr::AltList::iterator i = best.front().begin(); i != best.front().end(); ++i ) {
-								solved_assigns.push_back( i->expr );
-							}
-							/* assigning cost zero? */
-							currentFinder->get_alternatives().push_front( ResolvExpr::Alternative(new SolvedTupleExpr(solved_assigns/*, SolvedTupleExpr::MULTIPLE*/), currentFinder->get_environ(), ResolvExpr::Cost() ) );
+							matcher = &massMatcher;
 						}
-					} else {
-						assert( ! optMass.empty() );
-						ResolvExpr::AltList winners;
-						for ( std::vector< ResolvExpr::AltList >::iterator i = optMass.begin(); i != optMass.end(); ++i )
-							findMinCostAlt( i->begin(), i->end(), back_inserter(winners) );
-
-						std::list< Expression *> solved_assigns;
-						for ( ResolvExpr::AltList::iterator i = winners.begin(); i != winners.end(); ++i )
-							solved_assigns.push_back( i->expr );
-						currentFinder->get_alternatives().push_front( ResolvExpr::Alternative(new SolvedTupleExpr(solved_assigns/*, SolvedTupleExpr::MASS*/), currentFinder->get_environ(), ResolvExpr::Cost() ) );
+						match();
+					} else if ( isTuple( op2.expr ) ) {
+						throw SemanticError("Cannot assign a tuple value into a non-tuple lvalue.", expr);
 					}
 				}
 			}
 		}
-		return hasMatched;
-	}
-
-	void TupleAssignSpotter::Matcher::init( Expression *_lhs, Expression *_rhs ) {
-		lhs.clear();
-		if (AddressExpr *addr = dynamic_cast<AddressExpr *>(_lhs) )
+	}
+
+	void TupleAssignSpotter::match() {
+		assert ( matcher != 0 );
+
+		std::list< Expression * > new_assigns;
+		matcher->match( new_assigns );
+
+		if ( new_assigns.empty() ) return;
+		ResolvExpr::AltList current;
+		// now resolve new assignments
+		for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) {
+			ResolvExpr::AlternativeFinder finder( currentFinder.get_indexer(), currentFinder.get_environ() );
+			finder.findWithAdjustment(*i);
+			// prune expressions that don't coincide with
+			ResolvExpr::AltList alts = finder.get_alternatives();
+			assert( alts.size() == 1 );
+			assert( alts.front().expr != 0 );
+			current.push_back( alts.front() );
+		}
+
+		// extract expressions from the assignment alternatives to produce a list of assignments that
+		// together form a single alternative
+		std::list< Expression *> solved_assigns;
+		for ( ResolvExpr::Alternative & alt : current ) {
+			solved_assigns.push_back( alt.expr->clone() );
+		}
+		// xxx - need to do this??
+		// TypeEnvironment compositeEnv;
+		// simpleCombineEnvironments( i->begin(), i->end(), compositeEnv );
+		currentFinder.get_alternatives().push_front( ResolvExpr::Alternative(new TupleAssignExpr(solved_assigns, matcher->tmpDecls), currentFinder.get_environ(), ResolvExpr::sumCost( current ) ) );
+	}
+
+	TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, Expression *lhs, Expression *rhs ) : spotter(spotter) {
+		// xxx - shouldn't need to be &<tuple-expr>, just &<lvalue-tuple-type>
+		if (AddressExpr *addr = dynamic_cast<AddressExpr *>(lhs) )
 			if ( TupleExpr *tuple = dynamic_cast<TupleExpr *>(addr->get_arg()) )
-				std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(lhs) );
-
-		rhs.clear();
-	}
-
-	TupleAssignSpotter::Matcher::Matcher( /*TupleAssignSpotter &spot,*/ Expression *_lhs, Expression *_rhs ) /*: own_spotter(spot) */{
-		init(_lhs,_rhs);
-	}
-
-	TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( Expression *_lhs, Expression *_rhs )/* : own_spotter(spot) */{
-		init(_lhs,_rhs);
-
-		if ( TupleExpr *tuple = dynamic_cast<TupleExpr *>(_rhs) )
-			std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(rhs) );
-	}
-
-	UntypedExpr *TupleAssignSpotter::Matcher::createAssgn( Expression *left, Expression *right ) {
-		if ( left && right ) {
-			std::list< Expression * > args;
-			args.push_back(new AddressExpr(left->clone()));  args.push_back(right->clone());
-			return new UntypedExpr(new NameExpr("?=?"), args);
-		} else
-			throw 0; // xxx - diagnose the problem
-	}
-
-	bool TupleAssignSpotter::MassAssignMatcher::match( std::list< Expression * > &out ) {
-		if ( lhs.empty() || (rhs.size() != 1) ) return false;
-
-		for ( std::list< Expression * >::iterator l = lhs.begin(); l != lhs.end(); l++ ) {
-			std::list< Expression * > args;
-			args.push_back( new AddressExpr(*l) );
-			args.push_back( rhs.front() );
-			out.push_back( new UntypedExpr(new NameExpr("?=?"), args) );
-		}
-
-		return true;
-	}
-
-	bool TupleAssignSpotter::MassAssignMatcher::solve( std::list< Expression * > &assigns ) {
-		/*
-		  std::list< Expression * > solved_assigns;
-		  ResolvExpr::AltList solved_alts;
-		  assert( currentFinder != 0 );
-
-		  ResolvExpr::AltList current;
-		  if ( optMass.empty() ) {
-		  for ( std::list< Expression * >::size_type i = 0; i != new_assigns.size(); ++i )
-		  optMass.push_back( ResolvExpr::AltList() );
-		  }
-		  int cnt = 0;
-		  for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i, cnt++ ) {
-
-		  ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() );
-		  finder.findWithAdjustment(*i);
-		  ResolvExpr::AltList alts = finder.get_alternatives();
-		  assert( alts.size() == 1 );
-		  assert(alts.front().expr != 0 );
-		  current.push_back( finder.get_alternatives().front() );
-		  optMass[cnt].push_back( finder.get_alternatives().front() );
-		  solved_assigns.push_back( alts.front().expr->clone() );
-		  }
-		*/
-		return true;
-	}
-
-	bool TupleAssignSpotter::MultipleAssignMatcher::match( std::list< Expression * > &out ) {
-		// need more complicated matching
+				std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(this->lhs) );
+	}
+
+	TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( TupleAssignSpotter &spotter, Expression *lhs, Expression *rhs ) : Matcher( spotter, lhs, rhs ) {
+
+		if ( TupleExpr *tuple = dynamic_cast<TupleExpr *>(rhs) )
+			std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(this->rhs) );
+	}
+
+	UntypedExpr * createAssgn( ObjectDecl *left, ObjectDecl *right ) {
+		assert( left && right );
+		std::list< Expression * > args;
+		args.push_back( new AddressExpr( new UntypedExpr( new NameExpr("*?"), std::list< Expression * >{ new VariableExpr( left ) } ) ) );
+		args.push_back( new VariableExpr( right ) );
+		return new UntypedExpr( new NameExpr( "?=?" ), args );
+	}
+
+	ObjectDecl * newObject( UniqueName & namer, Expression * expr ) {
+		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() ) );
+	}
+
+	void TupleAssignSpotter::MassAssignMatcher::match( std::list< Expression * > &out ) {
+		static UniqueName lhsNamer( "__massassign_L" );
+		static UniqueName rhsNamer( "__massassign_R" );
+		assert ( ! lhs.empty() && rhs.size() == 1);
+
+		ObjectDecl * rtmp = newObject( rhsNamer, rhs.front() );
+		for ( Expression * l : lhs ) {
+			ObjectDecl * ltmp = newObject( lhsNamer, new AddressExpr( l ) );
+			out.push_back( createAssgn( ltmp, rtmp ) );
+			tmpDecls.push_back( ltmp );
+		}
+		tmpDecls.push_back( rtmp );
+	}
+
+	void TupleAssignSpotter::MultipleAssignMatcher::match( std::list< Expression * > &out ) {
+		static UniqueName lhsNamer( "__multassign_L" );
+		static UniqueName rhsNamer( "__multassign_R" );
+		// xxx - need more complicated matching?
 		if ( lhs.size() == rhs.size() ) {
-			zipWith( lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), back_inserter(out), TupleAssignSpotter::Matcher::createAssgn );
-			return true;
-		} //else
-		//std::cerr << "The length of (left, right) is: (" << lhs.size() << "," << rhs.size() << ")" << std::endl;*/
-		return false;
-	}
-
-	bool TupleAssignSpotter::MultipleAssignMatcher::solve( std::list< Expression * > &assigns ) {
-		/*
-		  std::list< Expression * > solved_assigns;
-		  ResolvExpr::AltList solved_alts;
-		  assert( currentFinder != 0 );
-
-		  ResolvExpr::AltList current;
-		  for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) {
-		  //try {
-		  ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() );
-		  finder.findWithAdjustment(*i);
-		  // prune expressions that don't coincide with
-		  ResolvExpr::AltList alts = finder.get_alternatives();
-		  assert( alts.size() == 1 );
-		  assert(alts.front().expr != 0 );
-		  current.push_back( finder.get_alternatives().front() );
-		  solved_assigns.push_back( alts.front().expr->clone() );
-		  //solved_assigns.back()->print(std::cerr);
-		  //} catch( ... ) {
-		  //continue; // no reasonable alternative found
-		  //}
-		  }
-		  options.add_option( current );
-		*/
-
-		return true;
-	}
-
-	void TupleAssignSpotter::Options::add_option( ResolvExpr::AltList &opt ) {
-		using namespace std;
-
-		options.push_back( opt );
-		/*
-		  vector< Cost > costs;
-		  costs.reserve( opt.size() );
-		  transform( opt.begin(), opt.end(), back_inserter(costs), ptr_fun(extract_cost) );
-		*/
-		// transpose matrix
-		if ( costMatrix.empty() )
-			for ( unsigned int i = 0; i< opt.size(); ++i)
-				costMatrix.push_back( vector<ResolvExpr::Cost>() );
-
-		int cnt = 0;
-		for ( ResolvExpr::AltList::iterator i = opt.begin(); i != opt.end(); ++i, cnt++ )
-			costMatrix[cnt].push_back( i->cost );
-
-		return;
-	}
-
-	std::list< ResolvExpr::AltList > TupleAssignSpotter::Options::get_best() {
-		using namespace std;
-		using namespace ResolvExpr;
-		list< ResolvExpr::AltList > ret;
-		list< multiset<int> > solns;
-		for ( vector< vector<Cost> >::iterator i = costMatrix.begin(); i != costMatrix.end(); ++i ) {
-			list<int> current;
-			findMinCost( i->begin(), i->end(), back_inserter(current) );
-			solns.push_back( multiset<int>(current.begin(), current.end()) );
-		}
-		// need to combine
-		multiset<int> result;
-		lift_intersection( solns.begin(), solns.end(), inserter( result, result.begin() ) );
-		if ( result.size() != 1 )
-			throw SemanticError("Ambiguous tuple expression");
-		ret.push_back(get_option( *(result.begin() )));
-		return ret;
+			std::list< ObjectDecl * > ltmp;
+			std::list< ObjectDecl * > rtmp;
+			std::transform( lhs.begin(), lhs.end(), back_inserter( ltmp ), []( Expression * expr ){
+				return newObject( lhsNamer, new AddressExpr( expr ) );
+			});
+			std::transform( rhs.begin(), rhs.end(), back_inserter( rtmp ), []( Expression * expr ){
+				return newObject( rhsNamer, expr );
+			});
+			zipWith( ltmp.begin(), ltmp.end(), rtmp.begin(), rtmp.end(), back_inserter(out), createAssgn );
+			tmpDecls.splice( tmpDecls.end(), ltmp );
+			tmpDecls.splice( tmpDecls.end(), rtmp );
+		}
 	}
 
 	void TupleAssignSpotter::Options::print( std::ostream &ostr ) {
-		using namespace std;
-
-		for ( vector< vector < ResolvExpr::Cost > >::iterator i = costMatrix.begin(); i != costMatrix.end(); ++i ) {
-			for ( vector < ResolvExpr::Cost >::iterator j = i->begin(); j != i->end(); ++j )
-				ostr << *j << " " ;
+		for ( ResolvExpr::AltList & l : options ) {
+			for ( ResolvExpr::Alternative & alt : l ) {
+				alt.print( ostr );
+				ostr << " ";
+			}
 			ostr << std::endl;
 		} // for
-		return;
-	}
-
-	ResolvExpr::Cost extract_cost( ResolvExpr::Alternative &alt ) {
-		return alt.cost;
-	}
-
-	template< typename InputIterator, typename OutputIterator >
-	void TupleAssignSpotter::Options::findMinCost( InputIterator begin, InputIterator end, OutputIterator out ) {
-		using namespace ResolvExpr;
-		std::list<int> alternatives;
-
-		// select the alternatives that have the minimum parameter cost
-		Cost minCost = Cost::infinity;
-		unsigned int index = 0;
-		for ( InputIterator i = begin; i != end; ++i, index++ ) {
-			if ( *i < minCost ) {
-				minCost = *i;
-				alternatives.clear();
-				alternatives.push_back( index );
-			} else if ( *i == minCost ) {
-				alternatives.push_back( index );
-			}
-		}
-		std::copy( alternatives.begin(), alternatives.end(), out );
-	}
-
-	template< class InputIterator, class OutputIterator >
-	void TupleAssignSpotter::Options::lift_intersection( InputIterator begin, InputIterator end, OutputIterator out ) {
-		if ( begin == end ) return;
-		InputIterator test = begin;
-
-		if (++test == end)
-			{ copy(begin->begin(), begin->end(), out); return; }
-
-
-		std::multiset<int> cur; // InputIterator::value_type::value_type
-		copy( begin->begin(), begin->end(), inserter( cur, cur.begin() ) );
-
-		while ( test != end ) {
-			std::multiset<int> temp;
-			set_intersection( cur.begin(), cur.end(), test->begin(), test->end(), inserter(temp,temp.begin()) );
-			cur.clear();
-			copy( temp.begin(), temp.end(), inserter(cur,cur.begin()));
-			++test;
-		}
-
-		copy( cur.begin(), cur.end(), out );
-		return;
-	}
-
-	ResolvExpr::AltList TupleAssignSpotter::Options::get_option( std::list< ResolvExpr::AltList >::size_type index ) {
-		if ( index >= options.size() )
-			throw 0; // XXX
-		std::list< ResolvExpr::AltList >::iterator it = options.begin();
-		for ( std::list< ResolvExpr::AltList >::size_type i = 0; i < index; ++i, ++it );
-		return *it;
 	}
 } // namespace Tuples
Index: c/Tuples/TupleAssignment.h
===================================================================
--- src/Tuples/TupleAssignment.h	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ 	(revision )
@@ -1,136 +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.
-//
-// TupleAssignment.h -- 
-//
-// Author           : Rodolfo G. Esteves
-// Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Mon May 18 15:04:02 2015
-// Update Count     : 2
-//
-
-#ifndef _TUPLE_ASSIGNMENT_H_
-#define _TUPLE_ASSIGNMENT_H_
-
-#include <string>
-#include <vector>
-#include "ResolvExpr/AlternativeFinder.h"
-
-#include "SynTree/Expression.h"
-#include "SynTree/Declaration.h"
-#include "SynTree/Type.h"
-
-namespace Tuples {
-	class TupleAssignSpotter {
-	  public:
-		// dispatcher for Tuple (multiple and mass) assignment operations
-		TupleAssignSpotter( ResolvExpr::AlternativeFinder * );
-		~TupleAssignSpotter() { delete matcher; matcher = 0; }
-
-		bool pointsToTuple( Expression * );
-		static bool isTupleVar( DeclarationWithType * );
-		bool isTuple( Expression *, bool isRight = false );
-		bool isMVR( Expression * );
-		bool isTupleAssignment( UntypedExpr *, std::list<ResolvExpr::AltList> & );
-		bool match();
-	  private:
-		// records for assignment generation
-		class Options {
-		  public:
-			void add_option( ResolvExpr::AltList &opt );
-			std::list< ResolvExpr::AltList > get_best();
-			void print( std::ostream & );
-			int size() const { return options.size(); }
-			ResolvExpr::AltList get_option( std::list< ResolvExpr::AltList >::size_type index );
-
-			// should really use the one in ResolvExpr/AlternativeFinder, but it's too coupled with the object
-			template< typename InputIterator, typename OutputIterator >
-			void findMinCost( InputIterator begin, InputIterator end, OutputIterator out );
-
-			template< typename InputIterator, typename OutputIterator >
-			void lift_intersection( InputIterator begin, InputIterator end, OutputIterator out );
-		  private:
-			std::list< ResolvExpr::AltList > options;
-			std::vector< std::vector< ResolvExpr::Cost > > costMatrix;
-		};
-
-		class Matcher {
-		  public:
-			Matcher( /*TupleAssignSpotter &spot, */Expression *_lhs, Expression *_rhs );
-			virtual ~Matcher() {}
-			virtual bool match( std::list< Expression * > &out ) = 0;
-			virtual bool solve( std::list< Expression * > &assigns ) = 0;
-			static UntypedExpr *createAssgn( Expression *left, Expression *right );
-		  protected:
-			Matcher() /*: own_spotter( TupleAssignSpotter(0) ) */{}
-			void init(/* TupleAssignSpotter &, */Expression *_lhs, Expression *_rhs );
-			std::list< Expression * > lhs, rhs;
-			//TupleAssignSpotter &own_spotter;
-		};
-
-		class MassAssignMatcher : public Matcher {
-		  public:
-			MassAssignMatcher( Expression *_lhs, Expression *_rhs ) : Matcher( _lhs, _rhs ) {
-				rhs.push_back( _rhs );
-			}
-			virtual bool match( std::list< Expression * > &out );
-			virtual bool solve( std::list< Expression * > &assigns );
-		  private:
-			//std::vector< ResolvExpr::AltList > optMass;
-		};
-
-		class MultipleAssignMatcher : public Matcher {
-		  public:
-			MultipleAssignMatcher( Expression *_lhs, Expression *_rhs );
-			virtual bool match( std::list< Expression * > &out );
-			virtual bool solve( std::list< Expression * > &assigns );
-		  private:
-			//Options options;
-		};
-
-		friend class Matcher;
-
-		ResolvExpr::AlternativeFinder *currentFinder;
-		//std::list<Expression *> rhs, lhs;
-		Expression *rhs, *lhs;
-		Matcher *matcher;
-		bool hasMatched;
-		Options options;
-		std::vector< ResolvExpr::AltList > optMass;
-	};
-
-	ResolvExpr::Cost extract_cost( ResolvExpr::Alternative & );
-
-	template< typename InputIterator, typename OutputIterator >
-	void findMinCostAlt( InputIterator begin, InputIterator end, OutputIterator out ) {
-		using namespace ResolvExpr;
-		AltList alternatives;
-
-		// select the alternatives that have the minimum parameter cost
-		Cost minCost = Cost::infinity;
-		for ( AltList::iterator i = begin; i != end; ++i ) {
-			if ( i->cost < minCost ) {
-				minCost = i->cost;
-				i->cost = i->cvtCost;
-				alternatives.clear();
-				alternatives.push_back( *i );
-			} else if ( i->cost == minCost ) {
-				i->cost = i->cvtCost;
-				alternatives.push_back( *i );
-			}
-		}
-		std::copy( alternatives.begin(), alternatives.end(), out );
-	}
-} // namespace Tuples
-
-#endif // _TUPLE_ASSIGNMENT_H_
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: src/Tuples/TupleExpansion.cc
===================================================================
--- src/Tuples/TupleExpansion.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
+++ src/Tuples/TupleExpansion.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -0,0 +1,99 @@
+//
+// 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.
+//
+// TupleAssignment.cc --
+//
+// Author           : Rodolfo G. Esteves
+// Created On       : Mon May 18 07:44:20 2015
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon May 18 15:02:53 2015
+// Update Count     : 2
+//
+
+#include <iterator>
+#include <iostream>
+#include <cassert>
+#include "Tuples.h"
+#include "GenPoly/DeclMutator.h"
+#include "SynTree/Mutator.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+#include "SymTab/Mangler.h"
+#include "Common/ScopedMap.h"
+
+namespace Tuples {
+	class TupleAssignExpander : public Mutator {
+	public:
+		virtual Expression * mutate( TupleAssignExpr * tupleExpr );
+	};
+
+	class TupleTypeReplacer : public GenPoly::DeclMutator {
+	  public:
+		typedef GenPoly::DeclMutator Parent;
+
+		virtual Type * mutate( TupleType * tupleType );
+
+		virtual CompoundStmt * mutate( CompoundStmt * stmt ) {
+			typeMap.beginScope();
+			stmt = Parent::mutate( stmt );
+			typeMap.endScope();
+			return stmt;
+		}
+	  private:
+		ScopedMap< std::string, StructDecl * > typeMap;
+	};
+
+	void expandTuples( std::list< Declaration * > & translationUnit ) {
+		TupleAssignExpander expander;
+		mutateAll( translationUnit, expander );
+
+		TupleTypeReplacer replacer;
+		replacer.mutateDeclarationList( translationUnit );
+	}
+
+	Expression * TupleAssignExpander::mutate( TupleAssignExpr * tupleExpr ) {
+		CompoundStmt * compoundStmt = new CompoundStmt( noLabels );
+		std::list< Statement * > & stmts = compoundStmt->get_kids();
+		for ( ObjectDecl * obj : tupleExpr->get_tempDecls() ) {
+			stmts.push_back( new DeclStmt( noLabels, obj ) );
+		}
+		for ( Expression * assign : tupleExpr->get_assigns() ) {
+			stmts.push_back( new ExprStmt( noLabels, assign ) );
+		}
+		tupleExpr->get_tempDecls().clear();
+		tupleExpr->get_assigns().clear();
+		delete tupleExpr;
+		return new StmtExpr( compoundStmt );
+	}
+
+	Type * TupleTypeReplacer::mutate( TupleType * tupleType ) {
+		std::string mangleName = SymTab::Mangler::mangleType( tupleType );
+		TupleType * newType = safe_dynamic_cast< TupleType * > ( Parent::mutate( tupleType ) );
+		if ( ! typeMap.count( mangleName ) ) {
+			// generate struct type to replace tuple type
+			StructDecl * decl = new StructDecl( "_tuple_type_" + mangleName );
+			decl->set_body( true );
+			int cnt = 0;
+			for ( Type * t : *newType ) {
+				decl->get_members().push_back( new ObjectDecl( "field_"+std::to_string(++cnt), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, t->clone(), nullptr ) );
+			}
+			typeMap[mangleName] = decl;
+			addDeclaration( decl );
+		}
+		Type::Qualifiers qualifiers = newType->get_qualifiers();
+		delete newType;
+		return new StructInstType( qualifiers, typeMap[mangleName] );
+	}
+
+} // namespace Tuples
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
+
Index: src/Tuples/Tuples.h
===================================================================
--- src/Tuples/Tuples.h	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
+++ src/Tuples/Tuples.h	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -0,0 +1,41 @@
+//
+// 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.
+//
+// Tuples.h --
+//
+// Author           : Rodolfo G. Esteves
+// Created On       : Mon May 18 07:44:20 2015
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon May 18 15:04:02 2015
+// Update Count     : 2
+//
+
+#ifndef _TUPLES_H_
+#define _TUPLE_H_
+
+#include <string>
+#include <vector>
+#include "ResolvExpr/AlternativeFinder.h"
+
+#include "SynTree/Expression.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+
+namespace Tuples {
+	// TupleAssignment.cc
+	void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * assign, std::list<ResolvExpr::AltList> & possibilities );
+
+	// TupleExpansion.cc
+	void expandTuples( std::list< Declaration * > & translationUnit );
+} // namespace Tuples
+
+#endif // _TUPLE_ASSIGNMENT_H_
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/Tuples/module.mk
===================================================================
--- src/Tuples/module.mk	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/Tuples/module.mk	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -6,5 +6,5 @@
 ## file "LICENCE" distributed with Cforall.
 ##
-## module.mk -- 
+## module.mk --
 ##
 ## Author           : Richard C. Bilson
@@ -16,3 +16,3 @@
 
 SRC += 	Tuples/TupleAssignment.cc \
-	Tuples/NameMatcher.cc
+	Tuples/TupleExpansion.cc
Index: src/main.cc
===================================================================
--- src/main.cc	(revision fc4a0fa1644cfe82d2b775fe96dcfda5a4565501)
+++ src/main.cc	(revision 12bc63ab6d1bb10cdf0105eb5df31eab3153a60b)
@@ -42,4 +42,5 @@
 #include "Common/UnimplementedError.h"
 #include "../config.h"
+#include "Tuples/Tuples.h"
 
 using namespace std;
@@ -265,4 +266,6 @@
 		OPTPRINT( "convertLvalue" )
 		GenPoly::convertLvalue( translationUnit );
+		OPTPRINT( "expandTuples" ); // xxx - is this the right place for this?
+		Tuples::expandTuples( translationUnit );
 
 		if ( bboxp ) {
