Index: src/SynTree/AddressExpr.cc
===================================================================
--- src/SynTree/AddressExpr.cc	(revision faddbd88e10faf4096d269d1ac28b46bfa0f57aa)
+++ src/SynTree/AddressExpr.cc	(revision 7756647eaf7d18e5f8c8c4841b9279a5f4e4f8dc)
@@ -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 faddbd88e10faf4096d269d1ac28b46bfa0f57aa)
+++ src/SynTree/ApplicationExpr.cc	(revision 7756647eaf7d18e5f8c8c4841b9279a5f4e4f8dc)
@@ -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 faddbd88e10faf4096d269d1ac28b46bfa0f57aa)
+++ src/SynTree/CommaExpr.cc	(revision 7756647eaf7d18e5f8c8c4841b9279a5f4e4f8dc)
@@ -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 faddbd88e10faf4096d269d1ac28b46bfa0f57aa)
+++ src/SynTree/Expression.cc	(revision 7756647eaf7d18e5f8c8c4841b9279a5f4e4f8dc)
@@ -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,37 @@
 	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;
+	os << std::string( indent+2, ' ' );
+	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 +335,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 +367,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 +374,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 +411,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 +469,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 +503,5 @@
 	Expression * arg = InitTweak::getCallArg( callExpr, 0 );
 	assert( arg );
-	cloneAll( arg->get_results(), results );
+	set_result( maybeClone( arg->get_result() ) );
 }
 
@@ -530,8 +523,9 @@
 
 CompoundLiteralExpr::CompoundLiteralExpr( Type * type, Initializer * initializer ) : type( type ), initializer( initializer ) {
-	add_result( type->clone() );
-}
-
-CompoundLiteralExpr::CompoundLiteralExpr( const CompoundLiteralExpr &other ) : Expression( other ), type( maybeClone( other.type ) ), initializer( maybeClone( other.initializer ) ) {}
+	assert( type && initializer );
+	set_result( type->clone() );
+}
+
+CompoundLiteralExpr::CompoundLiteralExpr( const CompoundLiteralExpr &other ) : Expression( other ), type( other.type->clone() ), initializer( other.initializer->clone() ) {}
 
 CompoundLiteralExpr::~CompoundLiteralExpr() {
@@ -542,6 +536,8 @@
 void CompoundLiteralExpr::print( std::ostream &os, int indent ) const {
 	os << "Compound Literal Expression: " << std::endl;
-	if ( type ) type->print( os, indent + 2 );
-	if ( initializer ) initializer->print( os, indent + 2 );
+	os << std::string( indent+2, ' ' );
+	type->print( os, indent + 2 );
+	os << std::string( indent+2, ' ' );
+	initializer->print( os, indent + 2 );
 }
 
@@ -557,10 +553,47 @@
 
 RangeExpr::RangeExpr( Expression *low, Expression *high ) : low( low ), high( high ) {}
-RangeExpr::RangeExpr( const RangeExpr &other ) : low( other.low->clone() ), high( other.high->clone() ) {}
+RangeExpr::RangeExpr( const RangeExpr &other ) : Expression( other ), low( other.low->clone() ), high( other.high->clone() ) {}
 void RangeExpr::print( std::ostream &os, int indent ) const {
-	os << std::string( indent, ' ' ) << "Range Expression: ";
+	os << "Range Expression: ";
 	low->print( os, indent );
 	os << " ... ";
 	high->print( os, indent );
+}
+
+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 ) : Expression( other ), statements( other.statements->clone() ) {}
+StmtExpr::~StmtExpr() {
+	delete statements;
+}
+void StmtExpr::print( std::ostream &os, int indent ) const {
+	os << "Statement Expression: " << std::endl << std::string( indent, ' ' );
+	statements->print( os, indent+2 );
+}
+
+
+UniqueExpr::UniqueExpr( Expression *expr ) : expr( new Expression* ) {
+	set_expr( expr );
+	assert( expr );
+	assert( expr->has_result() );
+	set_result( expr->get_result()->clone() );
+}
+UniqueExpr::UniqueExpr( const UniqueExpr &other ) : Expression( other ), expr( other.expr ) {
+}
+UniqueExpr::~UniqueExpr() {
+	if ( expr.unique() ) {
+		delete *expr;
+	}
+}
+void UniqueExpr::print( std::ostream &os, int indent ) const {
+	os << "Unique Expression: " << std::endl << std::string( indent+2, ' ' );
+	get_expr()->print( os, indent+2 );
 }
 
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision faddbd88e10faf4096d269d1ac28b46bfa0f57aa)
+++ src/SynTree/Expression.h	(revision 7756647eaf7d18e5f8c8c4841b9279a5f4e4f8dc)
@@ -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,118 @@
   private:
 	Expression *low, *high;
+};
+
+/// TupleExpr represents a tuple expression ( [a, b, c] )
+class TupleExpr : public Expression {
+  public:
+	TupleExpr( const std::list< Expression * > & exprs = std::list< Expression * >(), 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];, 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;, or a tuple ctor/dtor expression
+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;
+};
+
+class UniqueExpr : public Expression {
+public:
+	UniqueExpr( Expression * expr );
+	UniqueExpr( const UniqueExpr & other );
+	~UniqueExpr();
+
+	Expression * get_expr() const { return *expr; }
+	UniqueExpr * set_expr( Expression * newValue ) { *expr = newValue; return this; }
+
+	virtual UniqueExpr *clone() const { return new UniqueExpr( *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::shared_ptr< Expression * > expr;
 };
 
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision faddbd88e10faf4096d269d1ac28b46bfa0f57aa)
+++ src/SynTree/Mutator.cc	(revision 7756647eaf7d18e5f8c8c4841b9279a5f4e4f8dc)
@@ -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,42 @@
 	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;
+}
+
+Expression *Mutator::mutate( UniqueExpr *uniqueExpr ) {
+	uniqueExpr->set_result( maybeMutate( uniqueExpr->get_result(), *this ) );
+	uniqueExpr->set_expr( maybeMutate( uniqueExpr->get_expr(), *this ) );
+	return uniqueExpr;
 }
 
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision faddbd88e10faf4096d269d1ac28b46bfa0f57aa)
+++ src/SynTree/Mutator.h	(revision 7756647eaf7d18e5f8c8c4841b9279a5f4e4f8dc)
@@ -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,10 @@
 	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 Expression* mutate( UniqueExpr * uniqueExpr );
 
 	virtual Type* mutate( VoidType *basicType );
Index: src/SynTree/ReferenceToType.cc
===================================================================
--- src/SynTree/ReferenceToType.cc	(revision faddbd88e10faf4096d269d1ac28b46bfa0f57aa)
+++ src/SynTree/ReferenceToType.cc	(revision 7756647eaf7d18e5f8c8c4841b9279a5f4e4f8dc)
@@ -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 faddbd88e10faf4096d269d1ac28b46bfa0f57aa)
+++ src/SynTree/SynTree.h	(revision 7756647eaf7d18e5f8c8c4841b9279a5f4e4f8dc)
@@ -76,6 +76,4 @@
 class ConditionalExpr;
 class CommaExpr;
-class TupleExpr;
-class SolvedTupleExpr;
 class TypeExpr;
 class AsmExpr;
@@ -85,4 +83,10 @@
 class UntypedValofExpr;
 class RangeExpr;
+class TupleExpr;
+class TupleIndexExpr;
+class MemberTupleExpr;
+class TupleAssignExpr;
+class StmtExpr;
+class UniqueExpr;
 
 class Type;
Index: src/SynTree/TupleExpr.cc
===================================================================
--- src/SynTree/TupleExpr.cc	(revision faddbd88e10faf4096d269d1ac28b46bfa0f57aa)
+++ src/SynTree/TupleExpr.cc	(revision 7756647eaf7d18e5f8c8c4841b9279a5f4e4f8dc)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// TupleExpr.cc -- 
+// TupleExpr.cc --
 //
 // Author           : Richard C. Bilson
@@ -16,6 +16,14 @@
 #include "Expression.h"
 #include "Common/utility.h"
+#include "Type.h"
+#include "Declaration.h"
+#include "Tuples/Tuples.h"
 
-TupleExpr::TupleExpr( Expression *_aname ) : Expression( _aname ) {
+TupleExpr::TupleExpr( const std::list< Expression * > & exprs, Expression *_aname ) : Expression( _aname ), exprs( exprs ) {
+	if ( ! exprs.empty() ) {
+		if ( std::all_of( exprs.begin(), exprs.end(), [](Expression * expr) { return expr->get_result(); } ) ) {
+			set_result( Tuples::makeTupleType( exprs ) );
+		}
+	}
 }
 
@@ -29,22 +37,77 @@
 
 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 ) : tuple( tuple ), index( index )  {
+	TupleType * type = safe_dynamic_cast< TupleType * >( tuple->get_result() );
+	assert( type->size() > index );
+	set_result( (*std::next( type->get_types().begin(), index ))->clone() );
+	get_result()->set_isLvalue( type->get_isLvalue() );
 }
 
-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;
+	os << std::string( indent+2, ' ' );
+	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;
+	os << std::string( indent+2, ' ' );
+	aggregate->print( os, indent+2 );
+	os << std::string( indent+2, ' ' ) << "with member: " << std::endl;
+	os << std::string( indent+2, ' ' );
+	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 ) {
+	set_result( Tuples::makeTupleType( assigns ) );
+}
+
+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 << "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 faddbd88e10faf4096d269d1ac28b46bfa0f57aa)
+++ src/SynTree/TupleType.cc	(revision 7756647eaf7d18e5f8c8c4841b9279a5f4e4f8dc)
@@ -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 faddbd88e10faf4096d269d1ac28b46bfa0f57aa)
+++ src/SynTree/Type.h	(revision 7756647eaf7d18e5f8c8c4841b9279a5f4e4f8dc)
@@ -20,4 +20,5 @@
 #include "Visitor.h"
 #include "Mutator.h"
+#include "Common/utility.h"
 
 class Type {
@@ -27,4 +28,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 );
@@ -63,5 +65,11 @@
 	void set_isAtomic( bool newValue ) { tq.isAtomic = newValue; }
 	void set_isAttribute( bool newValue ) { tq.isAttribute = newValue; }
-	std::list<TypeDecl*>& get_forall() { return forall; }
+
+	typedef std::list<TypeDecl *> ForallList;
+	ForallList& 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;
@@ -71,5 +79,5 @@
   private:
 	Qualifiers tq;
-	std::list<TypeDecl*> forall;
+	ForallList forall;
 };
 
@@ -77,4 +85,6 @@
   public:
 	VoidType( const Type::Qualifiers &tq );
+
+	virtual unsigned size() const { return 0; };
 
 	virtual VoidType *clone() const { return new VoidType( *this ); }
@@ -234,4 +244,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 +359,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 ); }
@@ -442,4 +460,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/TypeSubstitution.cc
===================================================================
--- src/SynTree/TypeSubstitution.cc	(revision faddbd88e10faf4096d269d1ac28b46bfa0f57aa)
+++ src/SynTree/TypeSubstitution.cc	(revision 7756647eaf7d18e5f8c8c4841b9279a5f4e4f8dc)
@@ -72,23 +72,23 @@
 Type *TypeSubstitution::lookup( std::string formalType ) const {
 	TypeEnvType::const_iterator i = typeEnv.find( formalType );
-	
+
 	// break on not in substitution set
 	if ( i == typeEnv.end() ) return 0;
-	
+
 	// attempt to transitively follow TypeInstType links.
 	while ( TypeInstType *actualType = dynamic_cast< TypeInstType* >( i->second ) ) {
 		const std::string& typeName = actualType->get_name();
-		
+
 		// break cycles in the transitive follow
 		if ( formalType == typeName ) break;
-		
+
 		// Look for the type this maps to, returning previous mapping if none-such
 		i = typeEnv.find( typeName );
 		if ( i == typeEnv.end() ) return actualType;
 	}
-	
+
 	// return type from substitution set
 	return i->second;
-	
+
 #if 0
 	if ( i == typeEnv.end() ) {
@@ -149,5 +149,5 @@
 	// bind type variables from forall-qualifiers
 	if ( freeOnly ) {
-		for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
+		for ( Type::ForallList::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
 			boundVars.insert( (*tyvar )->get_name() );
 		} // for
@@ -163,5 +163,5 @@
 	// bind type variables from forall-qualifiers
 	if ( freeOnly ) {
-		for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
+		for ( Type::ForallList::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
 			boundVars.insert( (*tyvar )->get_name() );
 		} // for
Index: src/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision faddbd88e10faf4096d269d1ac28b46bfa0f57aa)
+++ src/SynTree/Visitor.cc	(revision 7756647eaf7d18e5f8c8c4841b9279a5f4e4f8dc)
@@ -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,36 @@
 	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 );
+}
+
+void Visitor::visit( UniqueExpr *uniqueExpr ) {
+	maybeAccept( uniqueExpr->get_result(), *this );
+	maybeAccept( uniqueExpr->get_expr(), *this );
 }
 
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision faddbd88e10faf4096d269d1ac28b46bfa0f57aa)
+++ src/SynTree/Visitor.h	(revision 7756647eaf7d18e5f8c8c4841b9279a5f4e4f8dc)
@@ -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,10 @@
 	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( UniqueExpr * uniqueExpr );
 
 	virtual void visit( VoidType *basicType );
