Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/CodeGen/CodeGenerator.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : 
-// Last Modified On : Sun Jul 31 08:42:18 2016
-// Update Count     : 345
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Thu Aug  4 13:35:30 2016
+// Update Count     : 352
 //
 
@@ -48,5 +48,5 @@
 	}
 
-	void CodeGenerator::extension( Expression *expr ) {
+	void CodeGenerator::extension( Expression * expr ) {
 		if ( expr->get_extension() ) {
 			output << "__extension__ ";
@@ -54,5 +54,5 @@
 	} // extension
 
-	void CodeGenerator::extension( Declaration *decl ) {
+	void CodeGenerator::extension( Declaration * decl ) {
 		if ( decl->get_extension() ) {
 			output << "__extension__ ";
@@ -73,5 +73,5 @@
 	}
 
-	ostream & operator<<( ostream & output, CodeGenerator::LabelPrinter &printLabels ) {
+	ostream & operator<<( ostream & output, CodeGenerator::LabelPrinter & printLabels ) {
 		std::list< Label > & labs = *printLabels.labels;
 		// l.unique(); // assumes a sorted list. Why not use set? Does order matter?
@@ -79,21 +79,21 @@
 			output << l.get_name() + ": ";
 			printLabels.cg.genAttributes( l.get_attributes() );
-		}
+		} // for
 		return output;
 	}
 
-	CodeGenerator::CodeGenerator( std::ostream &os ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ), printLabels( *this ) {}
-
-	CodeGenerator::CodeGenerator( std::ostream &os, std::string init, int indentation, bool infunp )
+	CodeGenerator::CodeGenerator( std::ostream & os ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ), printLabels( *this ) {}
+
+	CodeGenerator::CodeGenerator( std::ostream & os, std::string init, int indentation, bool infunp )
 			: indent( *this), cur_indent( indentation ), insideFunction( infunp ), output( os ), printLabels( *this ) {
 		//output << std::string( init );
 	}
 
-	CodeGenerator::CodeGenerator( std::ostream &os, char *init, int indentation, bool infunp )
+	CodeGenerator::CodeGenerator( std::ostream & os, char * init, int indentation, bool infunp )
 			: indent( *this ), cur_indent( indentation ), insideFunction( infunp ), output( os ), printLabels( *this ) {
 		//output << std::string( init );
 	}
 
-	string mangleName( DeclarationWithType *decl ) {
+	string mangleName( DeclarationWithType * decl ) {
 		if ( decl->get_mangleName() != "" ) {
 			// need to incorporate scope level in order to differentiate names for destructors
@@ -112,14 +112,14 @@
 					genCommaList( attr->get_parameters().begin(), attr->get_parameters().end() );
 					output << ")";
-				}
+				} // if
 				output << ",";
-			}
+			} // for
 			output << ")) ";
-		}
+		} // if
 	}
 
 
 	//*** Declarations
-	void CodeGenerator::visit( FunctionDecl *functionDecl ) {
+	void CodeGenerator::visit( FunctionDecl * functionDecl ) {
 		extension( functionDecl );
 		genAttributes( functionDecl->get_attributes() );
@@ -146,6 +146,8 @@
 	}
 
-	void CodeGenerator::visit( ObjectDecl *objectDecl ) {
+	void CodeGenerator::visit( ObjectDecl * objectDecl ) {
 		extension( objectDecl );
+		genAttributes( objectDecl->get_attributes() );
+
 		handleStorageClass( objectDecl );
 		output << genType( objectDecl->get_type(), mangleName( objectDecl ) );
@@ -162,12 +164,12 @@
 	}
 
-	void CodeGenerator::handleAggregate( AggregateDecl *aggDecl ) {
+	void CodeGenerator::handleAggregate( AggregateDecl * aggDecl ) {
 		if ( aggDecl->get_name() != "" )
 			output << aggDecl->get_name();
 
-		std::list< Declaration * > &memb = aggDecl->get_members();
+		std::list< Declaration * > & memb = aggDecl->get_members();
 		if ( ! memb.empty() ) {
 //		if ( aggDecl->has_body() ) {
-//			std::list< Declaration * > &memb = aggDecl->get_members();
+//			std::list< Declaration * > & memb = aggDecl->get_members();
 			output << " {" << endl;
 
@@ -185,5 +187,5 @@
 	}
 
-	void CodeGenerator::visit( StructDecl *structDecl ) {
+	void CodeGenerator::visit( StructDecl * structDecl ) {
 		extension( structDecl );
 		output << "struct ";
@@ -191,5 +193,5 @@
 	}
 
-	void CodeGenerator::visit( UnionDecl *unionDecl ) {
+	void CodeGenerator::visit( UnionDecl * unionDecl ) {
 		extension( unionDecl );
 		output << "union ";
@@ -197,5 +199,5 @@
 	}
 
-	void CodeGenerator::visit( EnumDecl *enumDecl ) {
+	void CodeGenerator::visit( EnumDecl * enumDecl ) {
 		extension( enumDecl );
 		output << "enum ";
@@ -211,5 +213,5 @@
 			cur_indent += CodeGenerator::tabsize;
 			for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
-				ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
+				ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i );
 				assert( obj );
 				output << indent << mangleName( obj );
@@ -227,7 +229,7 @@
 	}
 
-	void CodeGenerator::visit( TraitDecl *traitDecl ) {}
-
-	void CodeGenerator::visit( TypedefDecl *typeDecl ) {
+	void CodeGenerator::visit( TraitDecl * traitDecl ) {}
+
+	void CodeGenerator::visit( TypedefDecl * typeDecl ) {
 		assert( false && "Typedefs are removed and substituted in earlier passes." );
 		//output << "typedef ";
@@ -235,5 +237,5 @@
 	}
 
-	void CodeGenerator::visit( TypeDecl *typeDecl ) {
+	void CodeGenerator::visit( TypeDecl * typeDecl ) {
 		// really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes,
 		// still to be done
@@ -263,29 +265,29 @@
 	}
 
-	void CodeGenerator::visit( SingleInit *init ) {
+	void CodeGenerator::visit( SingleInit * init ) {
 		printDesignators( init->get_designators() );
 		init->get_value()->accept( *this );
 	}
 
-	void CodeGenerator::visit( ListInit *init ) {
+	void CodeGenerator::visit( ListInit * init ) {
 		printDesignators( init->get_designators() );
 		output << "{ ";
-		if ( init->begin_initializers() == init->end_initializers() ) {
+		if ( init->begin() == init->end() ) {
 			// illegal to leave initializer list empty for scalar initializers, but always legal to have 0
 			output << "0";
 		} else {
-			genCommaList( init->begin_initializers(), init->end_initializers() );
-		}
+			genCommaList( init->begin(), init->end() );
+		} // if
 		output << " }";
 	}
 
-	void CodeGenerator::visit( Constant *constant ) {
+	void CodeGenerator::visit( Constant * constant ) {
 		output << constant->get_value() ;
 	}
 
 	//*** Expressions
-	void CodeGenerator::visit( ApplicationExpr *applicationExpr ) {
+	void CodeGenerator::visit( ApplicationExpr * applicationExpr ) {
 		extension( applicationExpr );
-		if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) {
+		if ( VariableExpr * varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) {
 			OperatorInfo opInfo;
 			if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( varExpr->get_var()->get_name(), opInfo ) ) {
@@ -299,10 +301,10 @@
 					{
 						assert( arg != applicationExpr->get_args().end() );
-						if ( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
+						if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
 							// remove & from first assignment/ctor argument
 							*arg = addrExpr->get_arg();
 						} else {
 							// no address-of operator, so must be a pointer - add dereference
-							UntypedExpr *newExpr = new UntypedExpr( new NameExpr( "*?" ) );
+							UntypedExpr * newExpr = new UntypedExpr( new NameExpr( "*?" ) );
 							newExpr->get_args().push_back( *arg );
 							assert( (*arg)->get_results().size() == 1 );
@@ -352,5 +354,5 @@
 						// no constructors with 0 or more than 2 parameters
 						assert( false );
-					}
+					} // if
 					break;
 
@@ -401,7 +403,7 @@
 	}
 
-	void CodeGenerator::visit( UntypedExpr *untypedExpr ) {
+	void CodeGenerator::visit( UntypedExpr * untypedExpr ) {
 		extension( untypedExpr );
-		if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
+		if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
 			OperatorInfo opInfo;
 			if ( operatorLookup( nameExpr->get_name(), opInfo ) ) {
@@ -472,5 +474,5 @@
 				} // switch
 			} else {
-				if ( nameExpr->get_name() == "Range" ) { // case V1 ... V2 or case V1~V2
+				if ( nameExpr->get_name() == "..." ) { // case V1 ... V2 or case V1~V2
 					assert( untypedExpr->get_args().size() == 2 );
 					(*untypedExpr->get_args().begin())->accept( *this );
@@ -492,5 +494,11 @@
 	}
 
-	void CodeGenerator::visit( NameExpr *nameExpr ) {
+	void CodeGenerator::visit( RangeExpr * rangeExpr ) {
+		rangeExpr->get_low()->accept( *this );
+		output << " ... ";
+		rangeExpr->get_high()->accept( *this );
+	}
+
+	void CodeGenerator::visit( NameExpr * nameExpr ) {
 		extension( nameExpr );
 		OperatorInfo opInfo;
@@ -503,9 +511,9 @@
 	}
 
-	void CodeGenerator::visit( AddressExpr *addressExpr ) {
+	void CodeGenerator::visit( AddressExpr * addressExpr ) {
 		extension( addressExpr );
 		output << "(&";
 		// this hack makes sure that we don't convert "constant_zero" to "0" if we're taking its address
-		if ( VariableExpr *variableExpr = dynamic_cast< VariableExpr* >( addressExpr->get_arg() ) ) {
+		if ( VariableExpr * variableExpr = dynamic_cast< VariableExpr* >( addressExpr->get_arg() ) ) {
 			output << mangleName( variableExpr->get_var() );
 		} else {
@@ -515,5 +523,5 @@
 	}
 
-	void CodeGenerator::visit( CastExpr *castExpr ) {
+	void CodeGenerator::visit( CastExpr * castExpr ) {
 		extension( castExpr );
 		output << "(";
@@ -533,9 +541,9 @@
 	}
 
-	void CodeGenerator::visit( UntypedMemberExpr *memberExpr ) {
+	void CodeGenerator::visit( UntypedMemberExpr * memberExpr ) {
 		assert( false );
 	}
 
-	void CodeGenerator::visit( MemberExpr *memberExpr ) {
+	void CodeGenerator::visit( MemberExpr * memberExpr ) {
 		extension( memberExpr );
 		memberExpr->get_aggregate()->accept( *this );
@@ -543,5 +551,5 @@
 	}
 
-	void CodeGenerator::visit( VariableExpr *variableExpr ) {
+	void CodeGenerator::visit( VariableExpr * variableExpr ) {
 		extension( variableExpr );
 		OperatorInfo opInfo;
@@ -553,5 +561,5 @@
 	}
 
-	void CodeGenerator::visit( ConstantExpr *constantExpr ) {
+	void CodeGenerator::visit( ConstantExpr * constantExpr ) {
 		assert( constantExpr->get_constant() );
 		extension( constantExpr );
@@ -559,5 +567,5 @@
 	}
 
-	void CodeGenerator::visit( SizeofExpr *sizeofExpr ) {
+	void CodeGenerator::visit( SizeofExpr * sizeofExpr ) {
 		extension( sizeofExpr );
 		output << "sizeof(";
@@ -570,5 +578,5 @@
 	}
 
-	void CodeGenerator::visit( AlignofExpr *alignofExpr ) {
+	void CodeGenerator::visit( AlignofExpr * alignofExpr ) {
 		// use GCC extension to avoid bumping std to C11
 		extension( alignofExpr );
@@ -582,9 +590,9 @@
 	}
 
-	void CodeGenerator::visit( UntypedOffsetofExpr *offsetofExpr ) {
+	void CodeGenerator::visit( UntypedOffsetofExpr * offsetofExpr ) {
 		assert( false && "UntypedOffsetofExpr should not reach code generation." );
 	}
 
-	void CodeGenerator::visit( OffsetofExpr *offsetofExpr ) {
+	void CodeGenerator::visit( OffsetofExpr * offsetofExpr ) {
 		// use GCC builtin
 		output << "__builtin_offsetof(";
@@ -594,9 +602,9 @@
 	}
 
-	void CodeGenerator::visit( OffsetPackExpr *offsetPackExpr ) {
+	void CodeGenerator::visit( OffsetPackExpr * offsetPackExpr ) {
 		assert( false && "OffsetPackExpr should not reach code generation." );
 	}
 
-	void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
+	void CodeGenerator::visit( LogicalExpr * logicalExpr ) {
 		extension( logicalExpr );
 		output << "(";
@@ -611,5 +619,5 @@
 	}
 
-	void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) {
+	void CodeGenerator::visit( ConditionalExpr * conditionalExpr ) {
 		extension( conditionalExpr );
 		output << "(";
@@ -622,5 +630,5 @@
 	}
 
-	void CodeGenerator::visit( CommaExpr *commaExpr ) {
+	void CodeGenerator::visit( CommaExpr * commaExpr ) {
 		extension( commaExpr );
 		output << "(";
@@ -631,9 +639,9 @@
 	}
 
-	void CodeGenerator::visit( TupleExpr *tupleExpr ) {}
-
-	void CodeGenerator::visit( TypeExpr *typeExpr ) {}
-
-	void CodeGenerator::visit( AsmExpr *asmExpr ) {
+	void CodeGenerator::visit( TupleExpr * tupleExpr ) {}
+
+	void CodeGenerator::visit( TypeExpr * typeExpr ) {}
+
+	void CodeGenerator::visit( AsmExpr * asmExpr ) {
 		if ( asmExpr->get_inout() ) {
 			output << "[ ";
@@ -648,5 +656,5 @@
 
 	//*** Statements
-	void CodeGenerator::visit( CompoundStmt *compoundStmt ) {
+	void CodeGenerator::visit( CompoundStmt * compoundStmt ) {
 		std::list<Statement*> ks = compoundStmt->get_kids();
 		output << "{" << endl;
@@ -662,5 +670,5 @@
 				output << endl;
 			} // if
-		}
+		} // for
 		cur_indent -= CodeGenerator::tabsize;
 
@@ -668,5 +676,5 @@
 	}
 
-	void CodeGenerator::visit( ExprStmt *exprStmt ) {
+	void CodeGenerator::visit( ExprStmt * exprStmt ) {
 		assert( exprStmt );
 		// cast the top-level expression to void to reduce gcc warnings.
@@ -676,5 +684,5 @@
 	}
 
-	void CodeGenerator::visit( AsmStmt *asmStmt ) {
+	void CodeGenerator::visit( AsmStmt * asmStmt ) {
 		output << "asm ";
 		if ( asmStmt->get_voltile() ) output << "volatile ";
@@ -699,5 +707,5 @@
 	}
 
-	void CodeGenerator::visit( IfStmt *ifStmt ) {
+	void CodeGenerator::visit( IfStmt * ifStmt ) {
 		output << "if ( ";
 		ifStmt->get_condition()->accept( *this );
@@ -712,5 +720,5 @@
 	}
 
-	void CodeGenerator::visit( SwitchStmt *switchStmt ) {
+	void CodeGenerator::visit( SwitchStmt * switchStmt ) {
 		output << "switch ( " ;
 		switchStmt->get_condition()->accept( *this );
@@ -719,13 +727,10 @@
 		output << "{" << std::endl;
 		cur_indent += CodeGenerator::tabsize;
-
-		acceptAll( switchStmt->get_branches(), *this );
-
+		acceptAll( switchStmt->get_statements(), *this );
 		cur_indent -= CodeGenerator::tabsize;
-
 		output << indent << "}";
 	}
 
-	void CodeGenerator::visit( CaseStmt *caseStmt ) {
+	void CodeGenerator::visit( CaseStmt * caseStmt ) {
 		output << indent;
 		if ( caseStmt->isDefault()) {
@@ -748,5 +753,5 @@
 	}
 
-	void CodeGenerator::visit( BranchStmt *branchStmt ) {
+	void CodeGenerator::visit( BranchStmt * branchStmt ) {
 		switch ( branchStmt->get_type()) {
 		  case BranchStmt::Goto:
@@ -771,5 +776,5 @@
 
 
-	void CodeGenerator::visit( ReturnStmt *returnStmt ) {
+	void CodeGenerator::visit( ReturnStmt * returnStmt ) {
 		output << "return ";
 		maybeAccept( returnStmt->get_expr(), *this );
@@ -777,5 +782,5 @@
 	}
 
-	void CodeGenerator::visit( WhileStmt *whileStmt ) {
+	void CodeGenerator::visit( WhileStmt * whileStmt ) {
 		if ( whileStmt->get_isDoWhile() ) {
 			output << "do" ;
@@ -799,5 +804,5 @@
 	}
 
-	void CodeGenerator::visit( ForStmt *forStmt ) {
+	void CodeGenerator::visit( ForStmt * forStmt ) {
 		// initialization is always hoisted, so don't bother doing anything with that
 		output << "for (;";
@@ -821,10 +826,10 @@
 	}
 
-	void CodeGenerator::visit( NullStmt *nullStmt ) {
+	void CodeGenerator::visit( NullStmt * nullStmt ) {
 		//output << indent << CodeGenerator::printLabels( nullStmt->get_labels() );
 		output << "/* null statement */ ;";
 	}
 
-	void CodeGenerator::visit( DeclStmt *declStmt ) {
+	void CodeGenerator::visit( DeclStmt * declStmt ) {
 		declStmt->get_decl()->accept( *this );
 
@@ -834,5 +839,5 @@
 	}
 
-	void CodeGenerator::handleStorageClass( Declaration *decl ) {
+	void CodeGenerator::handleStorageClass( Declaration * decl ) {
 		switch ( decl->get_storageClass() ) {
 		  case DeclarationNode::Extern:
Index: src/CodeGen/CodeGenerator.h
===================================================================
--- src/CodeGen/CodeGenerator.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/CodeGen/CodeGenerator.h	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 30 11:10:42 2016
-// Update Count     : 37
+// Last Modified On : Thu Aug  4 13:37:07 2016
+// Update Count     : 38
 //
 
@@ -54,4 +54,5 @@
 		virtual void visit( ApplicationExpr *applicationExpr );
 		virtual void visit( UntypedExpr *untypedExpr );
+		virtual void visit( RangeExpr * rangeExpr );
 		virtual void visit( NameExpr *nameExpr );
 		virtual void visit( AddressExpr *addressExpr );
Index: src/ControlStruct/CaseRangeMutator.cc
===================================================================
--- src/ControlStruct/CaseRangeMutator.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ 	(revision )
@@ -1,89 +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.
-//
-// CaseRangeMutator.cc -- 
-//
-// Author           : Rodolfo G. Esteves
-// Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : 
-// Last Modified On : Sun Jul 31 12:16:28 2016
-// Update Count     : 32
-//
-
-#include <list>
-#include <cassert>
-#include <cstdlib>
-#include <iterator>
-
-#include "Common/utility.h"
-
-#include "SynTree/Statement.h"
-#include "SynTree/Expression.h"
-#include "SynTree/Constant.h"
-#include "SynTree/Type.h"
-#include "CaseRangeMutator.h"
-
-namespace ControlStruct {
-	Statement *CaseRangeMutator::mutate( SwitchStmt *switchStmt ) {
-		std::list< Statement * > &cases = switchStmt->get_branches();
-
-		// a `for' would be more natural... all this contortions are because `replace' invalidates the iterator
-		std::list< Statement * >::iterator i = cases.begin();
-		while ( i != cases.end() ) {
-			(*i)->acceptMutator( *this );
-
-			if ( ! newCaseLabels.empty() ) {
-				std::cout << "FRED" << std::endl;
-				std::list< Statement * > newCases;
-
-				// transform( newCaseLabels.begin(), newCaseLabels.end(), bnd1st( ptr_fun( ctor< CaseStmt, Label, Expression * > ) ) );
-
-				for ( std::list< Expression * >::iterator j = newCaseLabels.begin(); j != newCaseLabels.end(); j++ ) {
-					std::list< Label > emptyLabels;
-					std::list< Statement * > emptyStmts;
-					newCases.push_back( new CaseStmt( emptyLabels, *j, emptyStmts ) );
-				} // for
-
-				if ( CaseStmt *currentCase = dynamic_cast< CaseStmt * >( *i ) )
-					if ( ! currentCase->get_statements().empty() ) {
-						CaseStmt *lastCase = dynamic_cast< CaseStmt * >( newCases.back() );
-						if ( lastCase == 0 ) { throw ( 0 ); /* FIXME */ } // something is very wrong, as I just made these, and they were all cases
-						// transfer the statement block ( if any ) to the new list:
-						lastCase->set_statements( currentCase->get_statements() );
-					} // if
-				std::list< Statement * >::iterator j = i;
-				advance( j, 1 );
-				replace( cases, i, newCases );
-				i = j;
-				newCaseLabels.clear();
-			} else
-				i++;
-		} // while
-
-		return switchStmt;
-	} // CaseRangeMutator::mutate
-
-	Statement *CaseRangeMutator::mutate( CaseStmt *caseStmt ) {
-		// case list, e.g., case 1, 3, 5:
-		if ( TupleExpr *tcond = dynamic_cast< TupleExpr * >( caseStmt->get_condition() ) ) {
-			assert( ! tcond->get_exprs().empty() );
-			for ( std::list< Expression * >::iterator i = tcond->get_exprs().begin(); i != tcond->get_exprs().end(); i++ ) {
-				newCaseLabels.push_back( *i );			// do I need to clone them?
-			} // for
-		} // if
-
-		std::list< Statement * > &stmts = caseStmt->get_statements();
-		mutateAll( stmts, *this );
-
-		return caseStmt;
-	} // CaseRangeMutator::mutate
-} // namespace ControlStruct
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: src/ControlStruct/CaseRangeMutator.h
===================================================================
--- src/ControlStruct/CaseRangeMutator.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ 	(revision )
@@ -1,43 +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.
-//
-// CaseRangeMutator.h -- 
-//
-// Author           : Rodolfo G. Esteves
-// Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 30 23:41:57 2016
-// Update Count     : 5
-//
-
-#ifndef CASERNG_MUTATOR_H
-#define CASERNG_MUTATOR_H
-
-#include <list>
-
-#include "SynTree/Mutator.h"
-
-namespace ControlStruct {
-	/// expand case ranges and turn fallthru into a null statement
-	class CaseRangeMutator : public Mutator {
-	  public:
-		CaseRangeMutator() {}
-
-		virtual Statement *mutate( SwitchStmt * );
-		virtual Statement *mutate( CaseStmt * );
-	  private:
-		Expression *currentCondition;
-		std::list< Expression * > newCaseLabels;
-	};
-} // namespace ControlStruct
-
-#endif // CASERNG_MUTATOR_H
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: src/ControlStruct/MLEMutator.cc
===================================================================
--- src/ControlStruct/MLEMutator.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/ControlStruct/MLEMutator.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul 12 17:36:51 2016
-// Update Count     : 197
+// Last Modified On : Thu Aug  4 11:21:32 2016
+// Update Count     : 202
 //
 
@@ -128,5 +128,5 @@
 		Label brkLabel = generator->newLabel("switchBreak");
 		enclosingControlStructures.push_back( Entry(switchStmt, brkLabel) );
-		mutateAll( switchStmt->get_branches(), *this );
+		mutateAll( switchStmt->get_statements(), *this );
 
 		Entry &e = enclosingControlStructures.back();
@@ -138,13 +138,13 @@
 			// switch should be CastStmts), append the exit label + break to the last case statement; create a default
 			// case if there are no cases
-			std::list< Statement * > &branches = switchStmt->get_branches();
-			if ( branches.empty() ) {
-				branches.push_back( CaseStmt::makeDefault() );
-			} // if
-
-			if ( CaseStmt * c = dynamic_cast< CaseStmt * >( branches.back() ) ) {
+			std::list< Statement * > &statements = switchStmt->get_statements();
+			if ( statements.empty() ) {
+				statements.push_back( CaseStmt::makeDefault() );
+			} // if
+
+			if ( CaseStmt * c = dynamic_cast< CaseStmt * >( statements.back() ) ) {
 				std::list<Label> temp; temp.push_back( brkLabel );
 				c->get_statements().push_back( new BranchStmt( temp, Label("brkLabel"), BranchStmt::Break ) );
-			} else assert(0); // as of this point, all branches of a switch are still CaseStmts
+			} else assert(0); // as of this point, all statements of a switch are still CaseStmts
 		} // if
 
Index: src/ControlStruct/Mutate.cc
===================================================================
--- src/ControlStruct/Mutate.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/ControlStruct/Mutate.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul 12 17:37:45 2016
-// Update Count     : 8
+// Last Modified On : Thu Aug  4 11:39:08 2016
+// Update Count     : 9
 //
 
@@ -22,5 +22,4 @@
 #include "LabelFixer.h"
 #include "MLEMutator.h"
-#include "CaseRangeMutator.h"
 #include "ForExprMutator.h"
 #include "LabelTypeChecker.h"
@@ -41,7 +40,4 @@
 		LabelFixer lfix;
 
-		// expand case ranges and turn fallthru into a null statement
-		CaseRangeMutator ranges;
-
 		//ExceptMutator exc;
 		// LabelTypeChecker lbl;
@@ -49,5 +45,4 @@
 		mutateAll( translationUnit, formut );
 		acceptAll( translationUnit, lfix );
-		mutateAll( translationUnit, ranges );
 		//mutateAll( translationUnit, exc );
 		//acceptAll( translationUnit, lbl );
Index: src/ControlStruct/module.mk
===================================================================
--- src/ControlStruct/module.mk	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/ControlStruct/module.mk	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -11,6 +11,6 @@
 ## Created On       : Mon Jun  1 17:49:17 2015
 ## Last Modified By : Peter A. Buhr
-## Last Modified On : Tue Jul 12 17:40:31 2016
-## Update Count     : 2
+## Last Modified On : Thu Aug  4 11:38:06 2016
+## Update Count     : 3
 ###############################################################################
 
@@ -18,5 +18,4 @@
 	ControlStruct/LabelFixer.cc \
         ControlStruct/MLEMutator.cc \
-	ControlStruct/CaseRangeMutator.cc \
 	ControlStruct/Mutate.cc \
 	ControlStruct/ForExprMutator.cc \
Index: src/GenPoly/DeclMutator.cc
===================================================================
--- src/GenPoly/DeclMutator.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/GenPoly/DeclMutator.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,6 +10,6 @@
 // Created On       : Fri Nov 27 14:44:00 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul 12 17:38:46 2016
-// Update Count     : 2
+// Last Modified On : Thu Aug  4 11:16:43 2016
+// Update Count     : 3
 //
 
@@ -163,5 +163,5 @@
 	Statement* DeclMutator::mutate(SwitchStmt *switchStmt) {
 		switchStmt->set_condition( maybeMutate( switchStmt->get_condition(), *this ) );
-		mutateAll( switchStmt->get_branches(), *this );
+		mutateAll( switchStmt->get_statements(), *this );
 		return switchStmt;
 	}
Index: src/GenPoly/DeclMutator.h
===================================================================
--- src/GenPoly/DeclMutator.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/GenPoly/DeclMutator.h	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -28,7 +28,10 @@
 	class DeclMutator : public Mutator {
 	public:
+		typedef Mutator Parent;
+
 		DeclMutator();
 		virtual ~DeclMutator();
-		
+
+		using Parent::mutate;
 		virtual CompoundStmt* mutate(CompoundStmt *compoundStmt);
 		virtual Statement* mutate(IfStmt *ifStmt);
@@ -42,5 +45,5 @@
 		/// Mutates a list of declarations with this visitor
 		void mutateDeclarationList(std::list< Declaration* >& decls);
-		
+
 		/// Called on entry to a new scope; overriders should call this as a super-class call
 		virtual void doBeginScope();
Index: src/GenPoly/PolyMutator.cc
===================================================================
--- src/GenPoly/PolyMutator.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/GenPoly/PolyMutator.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul 12 17:39:32 2016
-// Update Count     : 12
+// Last Modified On : Thu Aug  4 11:26:22 2016
+// Update Count     : 16
 //
 
@@ -99,5 +99,5 @@
 
 	Statement * PolyMutator::mutate(SwitchStmt *switchStmt) {
-		mutateStatementList( switchStmt->get_branches() );
+		mutateStatementList( switchStmt->get_statements() );
 		switchStmt->set_condition( mutateExpression( switchStmt->get_condition() ) );
 		return switchStmt;
Index: src/GenPoly/Specialize.cc
===================================================================
--- src/GenPoly/Specialize.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/GenPoly/Specialize.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -31,4 +31,5 @@
 #include "Common/UniqueName.h"
 #include "Common/utility.h"
+#include "InitTweak/InitTweak.h"
 
 namespace GenPoly {
@@ -184,10 +185,13 @@
 		mutateAll( appExpr->get_args(), *this );
 
-		// create thunks for the inferred parameters
-		for ( InferredParams::iterator inferParam = appExpr->get_inferParams().begin(); inferParam != appExpr->get_inferParams().end(); ++inferParam ) {
-			inferParam->second.expr = doSpecialization( inferParam->second.formalType, inferParam->second.expr, &appExpr->get_inferParams() );
-		}
-
-		handleExplicitParams( appExpr );
+		if ( ! InitTweak::isIntrinsicCallExpr( appExpr ) ) {
+			// create thunks for the inferred parameters
+			// don't need to do this for intrinsic calls, because they aren't actually passed
+			for ( InferredParams::iterator inferParam = appExpr->get_inferParams().begin(); inferParam != appExpr->get_inferParams().end(); ++inferParam ) {
+				inferParam->second.expr = doSpecialization( inferParam->second.formalType, inferParam->second.expr, &appExpr->get_inferParams() );
+			}
+
+			handleExplicitParams( appExpr );
+		}
 
 		return appExpr;
Index: src/InitTweak/FixGlobalInit.cc
===================================================================
--- src/InitTweak/FixGlobalInit.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/InitTweak/FixGlobalInit.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -46,47 +46,4 @@
 		FunctionDecl * destroyFunction;
 	};
-
-	class ConstExprChecker : public Visitor {
-	public:
-		ConstExprChecker() : isConstExpr( true ) {}
-
-		virtual void visit( ApplicationExpr *applicationExpr ) { isConstExpr = false; }
-		virtual void visit( UntypedExpr *untypedExpr ) { isConstExpr = false; }
-		virtual void visit( NameExpr *nameExpr ) { isConstExpr = false; }
-		virtual void visit( CastExpr *castExpr ) { isConstExpr = false; }
-		virtual void visit( LabelAddressExpr *labAddressExpr ) { isConstExpr = false; }
-		virtual void visit( UntypedMemberExpr *memberExpr ) { isConstExpr = false; }
-		virtual void visit( MemberExpr *memberExpr ) { isConstExpr = false; }
-		virtual void visit( VariableExpr *variableExpr ) { isConstExpr = false; }
-		virtual void visit( ConstantExpr *constantExpr ) { /* bottom out */ }
-		// these might be okay?
-		// virtual void visit( SizeofExpr *sizeofExpr );
-		// virtual void visit( AlignofExpr *alignofExpr );
-		// virtual void visit( UntypedOffsetofExpr *offsetofExpr );
-		// virtual void visit( OffsetofExpr *offsetofExpr );
-		// virtual void visit( OffsetPackExpr *offsetPackExpr );
-		// virtual void visit( AttrExpr *attrExpr );
-		// virtual void visit( CommaExpr *commaExpr );
-		// 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; }
-
-		bool isConstExpr;
-	};
-
-	bool isConstExpr( Initializer * init ) {
-		if ( init ) {
-			ConstExprChecker checker;
-			init->accept( checker );
-			return checker.isConstExpr;
-		} // if
-		// for all intents and purposes, no initializer means const expr
-		return true;
-	}
 
 	void fixGlobalInit( std::list< Declaration * > & translationUnit, const std::string & name, bool inLibrary ) {
@@ -140,6 +97,4 @@
 		std::list< Statement * > & destroyStatements = destroyFunction->get_statements()->get_kids();
 
-		if ( ! tryConstruct( objDecl ) ) return; // don't construct @= or designated objects
-		if ( objDecl->get_storageClass() == DeclarationNode::Extern ) return;
 		// C allows you to initialize objects with constant expressions
 		// xxx - this is an optimization. Need to first resolve constructors before we decide
@@ -147,22 +102,27 @@
 		// if ( isConstExpr( objDecl->get_init() ) ) return;
 
-		if ( dynamic_cast< ArrayType * > ( objDecl->get_type() ) ) {
-			// xxx - initialize each element of the array
-		} else {
-			// steal initializer from object and attach it to a new temporary
-			ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, objDecl->get_type()->clone(), objDecl->get_init() );
-			objDecl->set_init( NULL );
-			initStatements.push_back( new DeclStmt( noLabels, newObj ) );
+		if ( ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() ) ) {
+			// a decision should have been made by the resolver, so ctor and init are not both non-NULL
+			assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() );
 
-			// copy construct objDecl using temporary
-			UntypedExpr * init = new UntypedExpr( new NameExpr( "?{}" ) );
-			init->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
-			init->get_args().push_back( new VariableExpr( newObj ) );
-			initStatements.push_back( new ImplicitCtorDtorStmt( new ExprStmt( noLabels, init ) ) );
-
-			// add destructor calls to global destroy function
-			UntypedExpr * destroy = new UntypedExpr( new NameExpr( "^?{}" ) );
-			destroy->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
-			destroyStatements.push_front( new ImplicitCtorDtorStmt( new ExprStmt( noLabels, destroy ) ) );
+			Statement * dtor = ctorInit->get_dtor();
+			if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) {
+				// don't need to call intrinsic dtor, because it does nothing, but
+				// non-intrinsic dtors must be called
+				destroyStatements.push_front( dtor );
+				ctorInit->set_dtor( NULL );
+			} // if
+			if ( Statement * ctor = ctorInit->get_ctor() ) {
+				initStatements.push_back( ctor );
+				objDecl->set_init( NULL );
+				ctorInit->set_ctor( NULL );
+			} else if ( Initializer * init = ctorInit->get_init() ) {
+				objDecl->set_init( init );
+				ctorInit->set_init( NULL );
+			} else {
+				// no constructor and no initializer, which is okay
+				objDecl->set_init( NULL );
+			} // if
+			delete ctorInit;
 		} // if
 	}
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/InitTweak/FixInit.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -18,6 +18,7 @@
 #include <iterator>
 #include <algorithm>
+#include "InitTweak.h"
 #include "FixInit.h"
-#include "InitTweak.h"
+#include "FixGlobalInit.h"
 #include "ResolvExpr/Resolver.h"
 #include "ResolvExpr/typeops.h"
@@ -25,4 +26,5 @@
 #include "SynTree/Type.h"
 #include "SynTree/Expression.h"
+#include "SynTree/Attribute.h"
 #include "SynTree/Statement.h"
 #include "SynTree/Initializer.h"
@@ -83,4 +85,5 @@
 		};
 
+		// debug
 		struct printSet {
 			typedef ObjDeclCollector::ObjectSet ObjectSet;
@@ -159,4 +162,6 @@
 
 			virtual DeclarationWithType * mutate( ObjectDecl *objDecl );
+
+			std::list< Declaration * > staticDtorDecls;
 		};
 
@@ -171,5 +176,8 @@
 	} // namespace
 
-	void fix( std::list< Declaration * > & translationUnit ) {
+	void fix( std::list< Declaration * > & translationUnit, const std::string & filename, bool inLibrary ) {
+		// fixes ConstructorInit for global variables. should happen before fixInitializers.
+		InitTweak::fixGlobalInit( translationUnit, filename, inLibrary );
+
 		InsertImplicitCalls::insert( translationUnit );
 		ResolveCopyCtors::resolveImplicitCalls( translationUnit );
@@ -194,5 +202,19 @@
 		void FixInit::fixInitializers( std::list< Declaration * > & translationUnit ) {
 			FixInit fixer;
-			mutateAll( translationUnit, fixer );
+
+			// can't use mutateAll, because need to insert declarations at top-level
+			// can't use DeclMutator, because sometimes need to insert IfStmt, etc.
+			SemanticError errors;
+			for ( std::list< Declaration * >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
+				try {
+					*i = maybeMutate( *i, fixer );
+					translationUnit.splice( i, fixer.staticDtorDecls );
+				} catch( SemanticError &e ) {
+					errors.append( e );
+				} // try
+			} // for
+			if ( ! errors.isEmpty() ) {
+				throw errors;
+			} // if
 		}
 
@@ -422,16 +444,27 @@
 				if ( Statement * ctor = ctorInit->get_ctor() ) {
 					if ( objDecl->get_storageClass() == DeclarationNode::Static ) {
+						// originally wanted to take advantage of gcc nested functions, but
+						// we get memory errors with this approach. To remedy this, the static
+						// variable is hoisted when the destructor needs to be called.
+						//
 						// generate:
-						// static bool __objName_uninitialized = true;
-						// if (__objName_uninitialized) {
-						//   __ctor(__objName);
-						//   void dtor_atexit() {
-						//     __dtor(__objName);
+						// static T __objName_static_varN;
+						// void __objName_dtor_atexitN() {
+						//   __dtor__...;
+						// }
+						// int f(...) {
+						//   ...
+						//   static bool __objName_uninitialized = true;
+						//   if (__objName_uninitialized) {
+						//     __ctor(__objName);
+						//     __objName_uninitialized = false;
+						//     atexit(__objName_dtor_atexitN);
 						//   }
-						//   on_exit(dtorOnExit, &__objName);
-						//   __objName_uninitialized = false;
+						//   ...
 						// }
 
-						// generate first line
+						static UniqueName dtorCallerNamer( "_dtor_atexit" );
+
+						// static bool __objName_uninitialized = true
 						BasicType * boolType = new BasicType( Type::Qualifiers(), BasicType::Bool );
 						SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant( boolType->clone(), "1" ) ), noDesignators );
@@ -439,13 +472,4 @@
 						isUninitializedVar->fixUniqueId();
 
-						// void dtor_atexit(...) {...}
-						FunctionDecl * dtorCaller = new FunctionDecl( objDecl->get_mangleName() + "_dtor_atexit", DeclarationNode::NoStorageClass, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false );
-						dtorCaller->fixUniqueId();
-						dtorCaller->get_statements()->get_kids().push_back( ctorInit->get_dtor()->clone() );
-
-						// on_exit(dtor_atexit);
-						UntypedExpr * callAtexit = new UntypedExpr( new NameExpr( "atexit" ) );
-						callAtexit->get_args().push_back( new VariableExpr( dtorCaller ) );
-
 						// __objName_uninitialized = false;
 						UntypedExpr * setTrue = new UntypedExpr( new NameExpr( "?=?" ) );
@@ -457,6 +481,4 @@
 						std::list< Statement * > & body = initStmts->get_kids();
 						body.push_back( ctor );
-						body.push_back( new DeclStmt( noLabels, dtorCaller ) );
-						body.push_back( new ExprStmt( noLabels, callAtexit ) );
 						body.push_back( new ExprStmt( noLabels, setTrue ) );
 
@@ -465,4 +487,43 @@
 						stmtsToAddAfter.push_back( new DeclStmt( noLabels, isUninitializedVar ) );
 						stmtsToAddAfter.push_back( ifStmt );
+
+						if ( ctorInit->get_dtor() ) {
+							// if the object has a non-trivial destructor, have to
+							// hoist it and the object into the global space and
+							// call the destructor function with atexit.
+
+							Statement * dtorStmt = ctorInit->get_dtor()->clone();
+
+							// void __objName_dtor_atexitN(...) {...}
+							FunctionDecl * dtorCaller = new FunctionDecl( objDecl->get_mangleName() + dtorCallerNamer.newName(), DeclarationNode::Static, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false );
+							dtorCaller->fixUniqueId();
+							dtorCaller->get_statements()->get_kids().push_back( dtorStmt );
+
+							// atexit(dtor_atexit);
+							UntypedExpr * callAtexit = new UntypedExpr( new NameExpr( "atexit" ) );
+							callAtexit->get_args().push_back( new VariableExpr( dtorCaller ) );
+
+							body.push_back( new ExprStmt( noLabels, callAtexit ) );
+
+							// hoist variable and dtor caller decls to list of decls that will be added into global scope
+							staticDtorDecls.push_back( objDecl );
+							staticDtorDecls.push_back( dtorCaller );
+
+							// need to rename object uniquely since it now appears
+							// at global scope and there could be multiple function-scoped
+							// static variables with the same name in different functions.
+							static UniqueName staticNamer( "_static_var" );
+							objDecl->set_mangleName( objDecl->get_mangleName() + staticNamer.newName() );
+
+							objDecl->set_init( NULL );
+							ctorInit->set_ctor( NULL );
+							delete ctorInit;
+
+							// xxx - temporary hack: need to return a declaration, but want to hoist the current object out of this scope
+							// create a new object which is never used
+							static UniqueName dummyNamer( "_dummy" );
+							ObjectDecl * dummy = new ObjectDecl( dummyNamer.newName(), DeclarationNode::Static, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ), 0, std::list< Attribute * >{ new Attribute("unused") } );
+							return dummy;
+						}
 					} else {
 						stmtsToAddAfter.push_back( ctor );
@@ -524,5 +585,5 @@
 					assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() );
 					Statement * dtor = ctorInit->get_dtor();
-					if ( dtor && ! isInstrinsicSingleArgCallStmt( dtor ) ) {
+					if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) {
 						// don't need to call intrinsic dtor, because it does nothing, but
 						// non-intrinsic dtors must be called
Index: src/InitTweak/FixInit.h
===================================================================
--- src/InitTweak/FixInit.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/InitTweak/FixInit.h	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -27,5 +27,5 @@
   /// replace constructor initializers with expression statements
   /// and unwrap basic C-style initializers
-	void fix( std::list< Declaration * > & translationUnit );
+	void fix( std::list< Declaration * > & translationUnit, const std::string & name, bool inLibrary );
 } // namespace
 
Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/InitTweak/GenInit.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -26,4 +26,5 @@
 #include "SymTab/Autogen.h"
 #include "GenPoly/PolyMutator.h"
+#include "GenPoly/DeclMutator.h"
 
 namespace InitTweak {
@@ -55,28 +56,57 @@
 	  public:
 		/// create constructor and destructor statements for object declarations.
-		/// Destructors are inserted directly into the code, whereas constructors
-		/// will be added in after the resolver has run so that the initializer expression
-		/// is only removed if a constructor is found
+		/// the actual call statements will be added in after the resolver has run
+		/// so that the initializer expression is only removed if a constructor is found
+		/// and the same destructor call is inserted in all of the appropriate locations.
 		static void generateCtorDtor( std::list< Declaration * > &translationUnit );
-
-		CtorDtor() : inFunction( false ) {}
 
 		virtual DeclarationWithType * mutate( ObjectDecl * );
 		virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
-		virtual Declaration* mutate( StructDecl *aggregateDecl );
-		virtual Declaration* mutate( UnionDecl *aggregateDecl );
-		virtual Declaration* mutate( EnumDecl *aggregateDecl );
-		virtual Declaration* mutate( TraitDecl *aggregateDecl );
-		virtual TypeDecl* mutate( TypeDecl *typeDecl );
-		virtual Declaration* mutate( TypedefDecl *typeDecl );
-
-		virtual Type * mutate( FunctionType *funcType );
+		// should not traverse into any of these declarations to find objects
+		// that need to be constructed or destructed
+		virtual Declaration* mutate( StructDecl *aggregateDecl ) { return aggregateDecl; }
+		virtual Declaration* mutate( UnionDecl *aggregateDecl ) { return aggregateDecl; }
+		virtual Declaration* mutate( EnumDecl *aggregateDecl ) { return aggregateDecl; }
+		virtual Declaration* mutate( TraitDecl *aggregateDecl ) { return aggregateDecl; }
+		virtual TypeDecl* mutate( TypeDecl *typeDecl ) { return typeDecl; }
+		virtual Declaration* mutate( TypedefDecl *typeDecl ) { return typeDecl; }
+
+		virtual Type * mutate( FunctionType *funcType ) { return funcType; }
 
 	  protected:
-		bool inFunction;
+	};
+
+	class HoistArrayDimension : public GenPoly::DeclMutator {
+	  public:
+		typedef GenPoly::DeclMutator Parent;
+
+		/// hoist dimension from array types in object declaration so that it uses a single
+		/// const variable of type size_t, so that side effecting array dimensions are only
+		/// computed once.
+		static void hoistArrayDimension( std::list< Declaration * > & translationUnit );
+
+	  private:
+		virtual DeclarationWithType * mutate( ObjectDecl * objectDecl );
+		virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
+		// should not traverse into any of these declarations to find objects
+		// that need to be constructed or destructed
+		virtual Declaration* mutate( StructDecl *aggregateDecl ) { return aggregateDecl; }
+		virtual Declaration* mutate( UnionDecl *aggregateDecl ) { return aggregateDecl; }
+		virtual Declaration* mutate( EnumDecl *aggregateDecl ) { return aggregateDecl; }
+		virtual Declaration* mutate( TraitDecl *aggregateDecl ) { return aggregateDecl; }
+		virtual TypeDecl* mutate( TypeDecl *typeDecl ) { return typeDecl; }
+		virtual Declaration* mutate( TypedefDecl *typeDecl ) { return typeDecl; }
+
+		virtual Type* mutate( FunctionType *funcType ) { return funcType; }
+
+		void hoist( Type * type );
+
+		DeclarationNode::StorageClass storageclass = DeclarationNode::NoStorageClass;
+		bool inFunction = false;
 	};
 
 	void genInit( std::list< Declaration * > & translationUnit ) {
 		ReturnFixer::makeReturnTemp( translationUnit );
+		HoistArrayDimension::hoistArrayDimension( translationUnit );
 		CtorDtor::generateCtorDtor( translationUnit );
 	}
@@ -124,4 +154,53 @@
 	}
 
+	// precompute array dimension expression, because constructor generation may duplicate it,
+	// which would be incorrect if it is a side-effecting computation.
+	void HoistArrayDimension::hoistArrayDimension( std::list< Declaration * > & translationUnit ) {
+		HoistArrayDimension hoister;
+		hoister.mutateDeclarationList( translationUnit );
+	}
+
+	DeclarationWithType * HoistArrayDimension::mutate( ObjectDecl * objectDecl ) {
+		storageclass = objectDecl->get_storageClass();
+		DeclarationWithType * temp = Parent::mutate( objectDecl );
+		hoist( objectDecl->get_type() );
+		storageclass = DeclarationNode::NoStorageClass;
+		return temp;
+	}
+
+	void HoistArrayDimension::hoist( Type * type ) {
+		// if in function, generate const size_t var
+		static UniqueName dimensionName( "_array_dim" );
+
+		// C doesn't allow variable sized arrays at global scope or for static variables,
+		// so don't hoist dimension.
+		if ( ! inFunction ) return;
+		if ( storageclass == DeclarationNode::Static ) return;
+
+		if ( ArrayType * arrayType = dynamic_cast< ArrayType * >( type ) ) {
+			if ( ! arrayType->get_dimension() ) return; // xxx - recursive call to hoist?
+
+			// don't need to hoist dimension if it's a constexpr - only need to if there's potential
+			// for side effects.
+			if ( isConstExpr( arrayType->get_dimension() ) ) return;
+
+			ObjectDecl * arrayDimension = new ObjectDecl( dimensionName.newName(), storageclass, LinkageSpec::C, 0, SymTab::SizeType->clone(), new SingleInit( arrayType->get_dimension() ) );
+			arrayDimension->get_type()->set_isConst( true );
+
+			arrayType->set_dimension( new VariableExpr( arrayDimension ) );
+			addDeclaration( arrayDimension );
+
+			hoist( arrayType->get_base() );
+			return;
+		}
+	}
+
+	DeclarationWithType * HoistArrayDimension::mutate( FunctionDecl *functionDecl ) {
+		bool oldInFunc = inFunction;
+		inFunction = true;
+		DeclarationWithType * decl = Parent::mutate( functionDecl );
+		inFunction = oldInFunc;
+		return decl;
+	}
 
 	void CtorDtor::generateCtorDtor( std::list< Declaration * > & translationUnit ) {
@@ -130,60 +209,34 @@
 	}
 
-	namespace {
-		Expression * makeCtorDtorExpr( std::string name, ObjectDecl * objDecl, std::list< Expression * > args ) {
-			UntypedExpr * expr = new UntypedExpr( new NameExpr( name ) );
-			expr->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
-			expr->get_args().splice( expr->get_args().end(), args );
-			return expr;
-		}
-	}
-
 	DeclarationWithType * CtorDtor::mutate( ObjectDecl * objDecl ) {
-		// hands off if designated or if @=
+		// hands off if designated, if @=, or if extern
 		if ( tryConstruct( objDecl ) ) {
-			if ( inFunction ) {
-				if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) {
-					// call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array
-					// TODO: walk initializer and generate appropriate copy ctor if element has initializer
-					std::list< Expression * > args = makeInitList( objDecl->get_init() );
-					if ( args.empty() ) {
-						std::list< Statement * > ctor;
-						std::list< Statement * > dtor;
-
-						SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "?{}", back_inserter( ctor ) );
-						SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "^?{}", front_inserter( dtor ), false );
-
-						// Currently makeArrayFunction produces a single Statement - a CompoundStmt
-						// which  wraps everything that needs to happen. As such, it's technically
-						// possible to use a Statement ** in the above calls, but this is inherently
-						// unsafe, so instead we take the slightly less efficient route, but will be
-						// immediately informed if somehow the above assumption is broken. In this case,
-						// we could always wrap the list of statements at this point with a CompoundStmt,
-						// but it seems reasonable at the moment for this to be done by makeArrayFunction
-						// itself
-						assert( ctor.size() == 1 && dynamic_cast< ImplicitCtorDtorStmt * >( ctor.front() ) );
-						assert( dtor.size() == 1 && dynamic_cast< ImplicitCtorDtorStmt * >( dtor.front() ) );
-						objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) );
-					} else {
-						// array came with an initializer list: initialize each element
-						// may have more initializers than elements in the array - need to check at each index that
-						// we haven't exceeded size. This requires precomputing the size because it might be a side-effecting
-						// computation.
-						// may have fewer initializers than eleemnts in the array - need to default construct
-						// remaining elements.
-						// might be able to merge this with the case above.
-					}
-				} else {
-					// it's sufficient to attempt to call the ctor/dtor for the given object and its initializer
-					Expression * ctor = makeCtorDtorExpr( "?{}", objDecl, makeInitList( objDecl->get_init() ) );
-					Expression * dtor = makeCtorDtorExpr( "^?{}", objDecl, std::list< Expression * >() );
-
-					// need to remember init expression, in case no ctors exist
-					// if ctor does exist, want to use ctor expression instead of init
-					// push this decision to the resolver
-					ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor );
-					ExprStmt * dtorStmt = new ExprStmt( noLabels, dtor );
-					objDecl->set_init( new ConstructorInit( new ImplicitCtorDtorStmt( ctorStmt ), new ImplicitCtorDtorStmt( dtorStmt ), objDecl->get_init() ) );
-				}
+			// call into genImplicitCall from Autogen.h to generate calls to ctor/dtor
+			// for each constructable object
+			std::list< Statement * > ctor;
+			std::list< Statement * > dtor;
+
+			InitExpander srcParam( objDecl->get_init() );
+			InitExpander nullParam( (Initializer *)NULL );
+			SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl );
+			SymTab::genImplicitCall( nullParam, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false );
+
+			// Currently genImplicitCall produces a single Statement - a CompoundStmt
+			// which  wraps everything that needs to happen. As such, it's technically
+			// possible to use a Statement ** in the above calls, but this is inherently
+			// unsafe, so instead we take the slightly less efficient route, but will be
+			// immediately informed if somehow the above assumption is broken. In this case,
+			// we could always wrap the list of statements at this point with a CompoundStmt,
+			// but it seems reasonable at the moment for this to be done by genImplicitCall
+			// itself. It is possible that genImplicitCall produces no statements (e.g. if
+			// an array type does not have a dimension). In this case, it's fine to ignore
+			// the object for the purposes of construction.
+			assert( ctor.size() == dtor.size() && ctor.size() <= 1 );
+			if ( ctor.size() == 1 ) {
+				// need to remember init expression, in case no ctors exist
+				// if ctor does exist, want to use ctor expression instead of init
+				// push this decision to the resolver
+				assert( dynamic_cast< ImplicitCtorDtorStmt * > ( ctor.front() ) && dynamic_cast< ImplicitCtorDtorStmt * > ( dtor.front() ) );
+				objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) );
 			}
 		}
@@ -193,22 +246,8 @@
 	DeclarationWithType * CtorDtor::mutate( FunctionDecl *functionDecl ) {
 		// parameters should not be constructed and destructed, so don't mutate FunctionType
-		bool oldInFunc = inFunction;
 		mutateAll( functionDecl->get_oldDecls(), *this );
-		inFunction = true;
 		functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
-		inFunction = oldInFunc;
 		return functionDecl;
 	}
-
-	// should not traverse into any of these declarations to find objects
-	// that need to be constructed or destructed
-	Declaration* CtorDtor::mutate( StructDecl *aggregateDecl ) { return aggregateDecl; }
-	Declaration* CtorDtor::mutate( UnionDecl *aggregateDecl ) { return aggregateDecl; }
-	Declaration* CtorDtor::mutate( EnumDecl *aggregateDecl ) { return aggregateDecl; }
-	Declaration* CtorDtor::mutate( TraitDecl *aggregateDecl ) { return aggregateDecl; }
-	TypeDecl* CtorDtor::mutate( TypeDecl *typeDecl ) { return typeDecl; }
-	Declaration* CtorDtor::mutate( TypedefDecl *typeDecl ) { return typeDecl; }
-	Type* CtorDtor::mutate( FunctionType *funcType ) { return funcType; }
-
 } // namespace InitTweak
 
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/InitTweak/InitTweak.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -1,2 +1,3 @@
+#include <algorithm>
 #include "InitTweak.h"
 #include "SynTree/Visitor.h"
@@ -4,4 +5,5 @@
 #include "SynTree/Initializer.h"
 #include "SynTree/Expression.h"
+#include "SynTree/Attribute.h"
 #include "GenPoly/GenPoly.h"
 
@@ -20,7 +22,6 @@
 		};
 
-		class InitExpander : public Visitor {
+		class InitFlattener : public Visitor {
 			public:
-			InitExpander() {}
 			virtual void visit( SingleInit * singleInit );
 			virtual void visit( ListInit * listInit );
@@ -28,12 +29,12 @@
 		};
 
-		void InitExpander::visit( SingleInit * singleInit ) {
+		void InitFlattener::visit( SingleInit * singleInit ) {
 			argList.push_back( singleInit->get_value()->clone() );
 		}
 
-		void InitExpander::visit( ListInit * listInit ) {
-			// xxx - for now, assume no nested list inits
-			std::list<Initializer*>::iterator it = listInit->begin_initializers();
-			for ( ; it != listInit->end_initializers(); ++it ) {
+		void InitFlattener::visit( ListInit * listInit ) {
+			// flatten nested list inits
+			std::list<Initializer*>::iterator it = listInit->begin();
+			for ( ; it != listInit->end(); ++it ) {
 				(*it)->accept( *this );
 			}
@@ -42,7 +43,7 @@
 
 	std::list< Expression * > makeInitList( Initializer * init ) {
-		InitExpander expander;
-		maybeAccept( init, expander );
-		return expander.argList;
+		InitFlattener flattener;
+		maybeAccept( init, flattener );
+		return flattener.argList;
 	}
 
@@ -53,48 +54,254 @@
 	}
 
+	class InitExpander::ExpanderImpl {
+	public:
+		virtual std::list< Expression * > next( std::list< Expression * > & indices ) = 0;
+		virtual Statement * buildListInit( UntypedExpr * callExpr, std::list< Expression * > & indices ) = 0;
+	};
+
+	class InitImpl : public InitExpander::ExpanderImpl {
+	public:
+		InitImpl( Initializer * init ) : init( init ) {}
+
+		virtual std::list< Expression * > next( std::list< Expression * > & indices ) {
+			// this is wrong, but just a placeholder for now
+			// if ( ! flattened ) flatten( indices );
+			// return ! inits.empty() ? makeInitList( inits.front() ) : std::list< Expression * >();
+			return makeInitList( init );
+		}
+
+		virtual Statement * buildListInit( UntypedExpr * callExpr, std::list< Expression * > & indices );
+	private:
+		Initializer * init;
+	};
+
+	class ExprImpl : public InitExpander::ExpanderImpl {
+	public:
+		ExprImpl( Expression * expr ) : arg( expr ) {}
+
+		virtual std::list< Expression * > next( std::list< Expression * > & indices ) {
+			std::list< Expression * > ret;
+			Expression * expr = maybeClone( arg );
+			if ( expr ) {
+				for ( std::list< Expression * >::reverse_iterator it = indices.rbegin(); it != indices.rend(); ++it ) {
+					// go through indices and layer on subscript exprs ?[?]
+					++it;
+					UntypedExpr * subscriptExpr = new UntypedExpr( new NameExpr( "?[?]") );
+					subscriptExpr->get_args().push_back( expr );
+					subscriptExpr->get_args().push_back( (*it)->clone() );
+					expr = subscriptExpr;
+				}
+				ret.push_back( expr );
+			}
+			return ret;
+		}
+
+		virtual Statement * buildListInit( UntypedExpr * callExpr, std::list< Expression * > & indices );
+	private:
+		Expression * arg;
+	};
+
+	InitExpander::InitExpander( Initializer * init ) : expander( new InitImpl( init ) ) {}
+
+	InitExpander::InitExpander( Expression * expr ) : expander( new ExprImpl( expr ) ) {}
+
+	std::list< Expression * > InitExpander::operator*() {
+		return cur;
+	}
+
+	InitExpander & InitExpander::operator++() {
+		cur = expander->next( indices );
+		return *this;
+	}
+
+	// use array indices list to build switch statement
+	void InitExpander::addArrayIndex( Expression * index, Expression * dimension ) {
+		indices.push_back( index );
+		indices.push_back( dimension );
+	}
+
+	void InitExpander::clearArrayIndices() {
+		indices.clear();
+	}
+
+	namespace {
+		/// given index i, dimension d, initializer init, and callExpr f, generates
+		///   if (i < d) f(..., init)
+		///   ++i;
+		/// so that only elements within the range of the array are constructed
+		template< typename OutIterator >
+		void buildCallExpr( UntypedExpr * callExpr, Expression * index, Expression * dimension, Initializer * init, OutIterator out ) {
+			UntypedExpr * cond = new UntypedExpr( new NameExpr( "?<?") );
+			cond->get_args().push_back( index->clone() );
+			cond->get_args().push_back( dimension->clone() );
+
+			std::list< Expression * > args = makeInitList( init );
+			callExpr->get_args().splice( callExpr->get_args().end(), args );
+
+			*out++ = new IfStmt( noLabels, cond, new ExprStmt( noLabels, callExpr ), NULL );
+
+			UntypedExpr * increment = new UntypedExpr( new NameExpr( "++?" ) );
+			increment->get_args().push_back( new AddressExpr( index->clone() ) );
+			*out++ = new ExprStmt( noLabels, increment );
+		}
+
+		template< typename OutIterator >
+		void build( UntypedExpr * callExpr, InitExpander::IndexList::iterator idx, InitExpander::IndexList::iterator idxEnd, Initializer * init, OutIterator out ) {
+			if ( idx == idxEnd ) return;
+			Expression * index = *idx++;
+			assert( idx != idxEnd );
+			Expression * dimension = *idx++;
+
+			// xxx - may want to eventually issue a warning here if we can detect
+			// that the number of elements exceeds to dimension of the array
+			if ( idx == idxEnd ) {
+				if ( ListInit * listInit = dynamic_cast< ListInit * >( init ) ) {
+					for ( Initializer * init : *listInit ) {
+						buildCallExpr( callExpr->clone(), index, dimension, init, out );
+					}
+				} else {
+					buildCallExpr( callExpr->clone(), index, dimension, init, out );
+				}
+			} else {
+				std::list< Statement * > branches;
+
+				unsigned long cond = 0;
+				ListInit * listInit = dynamic_cast< ListInit * >( init );
+				if ( ! listInit ) {
+					// xxx - this shouldn't be an error, but need a way to
+					// terminate without creating output, so should catch this error
+					throw SemanticError( "unbalanced list initializers" );
+				}
+
+				static UniqueName targetLabel( "L__autogen__" );
+				Label switchLabel( targetLabel.newName(), 0, std::list< Attribute * >{ new Attribute("unused") } );
+				for ( Initializer * init : *listInit ) {
+					Expression * condition;
+					// check for designations
+					// if ( init-> ) {
+						condition = new ConstantExpr( Constant::from_ulong( cond ) );
+						++cond;
+					// } else {
+					// 	condition = // ... take designation
+					// 	cond = // ... take designation+1
+					// }
+					std::list< Statement * > stmts;
+					build( callExpr, idx, idxEnd, init, back_inserter( stmts ) );
+					stmts.push_back( new BranchStmt( noLabels, switchLabel, BranchStmt::Break ) );
+					CaseStmt * caseStmt = new CaseStmt( noLabels, condition, stmts );
+					branches.push_back( caseStmt );
+				}
+				*out++ = new SwitchStmt( noLabels, index->clone(), branches );
+				*out++ = new NullStmt( std::list<Label>{ switchLabel } );
+			}
+		}
+	}
+
+	// if array came with an initializer list: initialize each element
+	// may have more initializers than elements in the array - need to check at each index that
+	// we haven't exceeded size.
+	// may have fewer initializers than elements in the array - need to default construct
+	// remaining elements.
+	// To accomplish this, generate switch statement, consuming all of expander's elements
+	Statement * InitImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) {
+		if ( ! init ) return NULL;
+		CompoundStmt * block = new CompoundStmt( noLabels );
+		build( dst, indices.begin(), indices.end(), init, back_inserter( block->get_kids() ) );
+		if ( block->get_kids().empty() ) {
+			delete block;
+			return NULL;
+		} else {
+			init = NULL; // init was consumed in creating the list init
+			return block;
+		}
+	}
+
+	Statement * ExprImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) {
+		return NULL;
+	}
+
+	Statement * InitExpander::buildListInit( UntypedExpr * dst ) {
+		return expander->buildListInit( dst, indices );
+	}
+
 	bool tryConstruct( ObjectDecl * objDecl ) {
 		return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) &&
 			(objDecl->get_init() == NULL ||
 				( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() )) &&
-			! isDesignated( objDecl->get_init() );
+			! isDesignated( objDecl->get_init() )
+			&& objDecl->get_storageClass() != DeclarationNode::Extern;
+	}
+
+	class CallFinder : public Visitor {
+	public:
+		typedef Visitor Parent;
+		CallFinder( const std::list< std::string > & names ) : names( names ) {}
+
+		virtual void visit( ApplicationExpr * appExpr ) {
+			handleCallExpr( appExpr );
+		}
+
+		virtual void visit( UntypedExpr * untypedExpr ) {
+			handleCallExpr( untypedExpr );
+		}
+
+		std::list< Expression * > * matches;
+	private:
+		const std::list< std::string > names;
+
+		template< typename CallExpr >
+		void handleCallExpr( CallExpr * expr ) {
+			Parent::visit( expr );
+			std::string fname = getFunctionName( expr );
+			if ( std::find( names.begin(), names.end(), fname ) != names.end() ) {
+				matches->push_back( expr );
+			}
+		}
+	};
+
+	void collectCtorDtorCalls( Statement * stmt, std::list< Expression * > & matches ) {
+		static CallFinder finder( std::list< std::string >{ "?{}", "^?{}" } );
+		finder.matches = &matches;
+		maybeAccept( stmt, finder );
 	}
 
 	Expression * getCtorDtorCall( Statement * stmt ) {
-		if ( stmt == NULL ) return NULL;
-		if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( stmt ) ) {
-			return exprStmt->get_expr();
-		} else if ( CompoundStmt * compoundStmt = dynamic_cast< CompoundStmt * >( stmt ) ) {
-			// could also be a compound statement with a loop, in the case of an array
-			if( compoundStmt->get_kids().size() == 2 ) {
-				// loop variable and loop
-				ForStmt * forStmt = dynamic_cast< ForStmt * >( compoundStmt->get_kids().back() );
-				assert( forStmt && forStmt->get_body() );
-				return getCtorDtorCall( forStmt->get_body() );
-			} else if ( compoundStmt->get_kids().size() == 1 ) {
-				// should be the call statement, but in any case there's only one option
-				return getCtorDtorCall( compoundStmt->get_kids().front() );
-			} else {
-				assert( false && "too many statements in compoundStmt for getCtorDtorCall" );
-			}
-		} if ( ImplicitCtorDtorStmt * impCtorDtorStmt = dynamic_cast< ImplicitCtorDtorStmt * > ( stmt ) ) {
-			return getCtorDtorCall( impCtorDtorStmt->get_callStmt() );
-		} else {
-			// should never get here
-			assert( false && "encountered unknown call statement" );
-		}
-	}
-
-	bool isInstrinsicSingleArgCallStmt( Statement * stmt ) {
-		Expression * callExpr = getCtorDtorCall( stmt );
-		if ( ! callExpr ) return false;
-		ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( callExpr );
-		assert( appExpr );
-		VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() );
+		std::list< Expression * > matches;
+		collectCtorDtorCalls( stmt, matches );
+		assert( matches.size() <= 1 );
+		return matches.size() == 1 ? matches.front() : NULL;
+	}
+
+	namespace {
+		VariableExpr * getCalledFunction( ApplicationExpr * appExpr ) {
+			assert( appExpr );
+			// xxx - it's possible this can be other things, e.g. MemberExpr, so this is insufficient
+			return dynamic_cast< VariableExpr * >( appExpr->get_function() );
+		}
+	}
+
+	ApplicationExpr * isIntrinsicCallExpr( Expression * expr ) {
+		ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr );
+		if ( ! appExpr ) return NULL;
+		VariableExpr * function = getCalledFunction( appExpr );
 		assert( function );
 		// check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor
 		// will call all member dtors, and some members may have a user defined dtor.
-		FunctionType * funcType = GenPoly::getFunctionType( function->get_var()->get_type() );
-		assert( funcType );
-		return function->get_var()->get_linkage() == LinkageSpec::Intrinsic && funcType->get_parameters().size() == 1;
+		return function->get_var()->get_linkage() == LinkageSpec::Intrinsic ? appExpr : NULL;
+	}
+
+	bool isIntrinsicSingleArgCallStmt( Statement * stmt ) {
+		std::list< Expression * > callExprs;
+		collectCtorDtorCalls( stmt, callExprs );
+		// if ( callExprs.empty() ) return false; // xxx - do I still need this check?
+		return std::all_of( callExprs.begin(), callExprs.end(), []( Expression * callExpr ){
+			if ( ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) {
+				assert( ! appExpr->get_function()->get_results().empty() );
+				FunctionType *funcType = GenPoly::getFunctionType( appExpr->get_function()->get_results().front() );
+				assert( funcType );
+				return funcType->get_parameters().size() == 1;
+			}
+			return false;
+		});
 	}
 
@@ -160,3 +367,56 @@
 		else return NULL;
 	}
+
+	class ConstExprChecker : public Visitor {
+	public:
+		ConstExprChecker() : isConstExpr( true ) {}
+
+		virtual void visit( ApplicationExpr *applicationExpr ) { isConstExpr = false; }
+		virtual void visit( UntypedExpr *untypedExpr ) { isConstExpr = false; }
+		virtual void visit( NameExpr *nameExpr ) { isConstExpr = false; }
+		virtual void visit( CastExpr *castExpr ) { isConstExpr = false; }
+		virtual void visit( LabelAddressExpr *labAddressExpr ) { isConstExpr = false; }
+		virtual void visit( UntypedMemberExpr *memberExpr ) { isConstExpr = false; }
+		virtual void visit( MemberExpr *memberExpr ) { isConstExpr = false; }
+		virtual void visit( VariableExpr *variableExpr ) { isConstExpr = false; }
+		virtual void visit( ConstantExpr *constantExpr ) { /* bottom out */ }
+		// these might be okay?
+		// virtual void visit( SizeofExpr *sizeofExpr );
+		// virtual void visit( AlignofExpr *alignofExpr );
+		// virtual void visit( UntypedOffsetofExpr *offsetofExpr );
+		// virtual void visit( OffsetofExpr *offsetofExpr );
+		// virtual void visit( OffsetPackExpr *offsetPackExpr );
+		// virtual void visit( AttrExpr *attrExpr );
+		// virtual void visit( CommaExpr *commaExpr );
+		// 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; }
+
+		bool isConstExpr;
+	};
+
+	bool isConstExpr( Expression * expr ) {
+		if ( expr ) {
+			ConstExprChecker checker;
+			expr->accept( checker );
+			return checker.isConstExpr;
+		}
+		return true;
+	}
+
+	bool isConstExpr( Initializer * init ) {
+		if ( init ) {
+			ConstExprChecker checker;
+			init->accept( checker );
+			return checker.isConstExpr;
+		} // if
+		// for all intents and purposes, no initializer means const expr
+		return true;
+	}
+
 }
Index: src/InitTweak/InitTweak.h
===================================================================
--- src/InitTweak/InitTweak.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/InitTweak/InitTweak.h	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -26,32 +26,70 @@
 // helper functions for initialization
 namespace InitTweak {
-  /// transform Initializer into an argument list that can be passed to a call expression
-  std::list< Expression * > makeInitList( Initializer * init );
+	/// transform Initializer into an argument list that can be passed to a call expression
+	std::list< Expression * > makeInitList( Initializer * init );
 
-  /// True if the resolver should try to construct objDecl
-  bool tryConstruct( ObjectDecl * objDecl );
+	/// True if the resolver should try to construct objDecl
+	bool tryConstruct( ObjectDecl * objDecl );
 
-  /// True if the Initializer contains designations
-  bool isDesignated( Initializer * init );
+	/// True if the Initializer contains designations
+	bool isDesignated( Initializer * init );
 
-  /// True if stmt is a call statement where the function called is intrinsic and takes one parameter.
-  /// Intended to be used for default ctor/dtor calls, but might have use elsewhere.
-  /// Currently has assertions that make it less than fully general.
-  bool isInstrinsicSingleArgCallStmt( Statement * expr );
+  /// Non-Null if expr is a call expression whose target function is intrinsic
+  ApplicationExpr * isIntrinsicCallExpr( Expression * expr );
 
-  /// get the Ctor/Dtor call expression from a Statement that looks like a generated ctor/dtor call
-  Expression * getCtorDtorCall( Statement * stmt );
+	/// True if stmt is a call statement where the function called is intrinsic and takes one parameter.
+	/// Intended to be used for default ctor/dtor calls, but might have use elsewhere.
+	/// Currently has assertions that make it less than fully general.
+	bool isIntrinsicSingleArgCallStmt( Statement * expr );
 
-  /// returns the name of the function being called
-  std::string getFunctionName( Expression * expr );
+	/// get all Ctor/Dtor call expressions from a Statement
+	void collectCtorDtorCalls( Statement * stmt, std::list< Expression * > & matches );
 
-  /// returns the argument to a call expression in position N indexed from 0
-  Expression *& getCallArg( Expression * callExpr, unsigned int pos );
+	/// get the Ctor/Dtor call expression from a Statement that looks like a generated ctor/dtor call
+	Expression * getCtorDtorCall( Statement * stmt );
 
-  /// returns the base type of a PointerType or ArrayType, else returns NULL
-  Type * getPointerBase( Type * );
+	/// returns the name of the function being called
+	std::string getFunctionName( Expression * expr );
 
-  /// returns the argument if it is a PointerType or ArrayType, else returns NULL
-  Type * isPointerType( Type * );
+	/// returns the argument to a call expression in position N indexed from 0
+	Expression *& getCallArg( Expression * callExpr, unsigned int pos );
+
+	/// returns the base type of a PointerType or ArrayType, else returns NULL
+	Type * getPointerBase( Type * );
+
+	/// returns the argument if it is a PointerType or ArrayType, else returns NULL
+	Type * isPointerType( Type * );
+
+	/// returns true if expr is trivially a compile-time constant
+	bool isConstExpr( Expression * expr );
+	bool isConstExpr( Initializer * init );
+
+	class InitExpander {
+	public:
+		// expand by stepping through init to get each list of arguments
+		InitExpander( Initializer * init );
+
+		// always expand to expr
+		InitExpander( Expression * expr );
+
+		// iterator-like interface
+		std::list< Expression * > operator*();
+		InitExpander & operator++();
+
+		// builds statement which has the same semantics as a C-style list initializer
+		// (for array initializers) using callExpr as the base expression to perform initialization
+		Statement * buildListInit( UntypedExpr * callExpr );
+		void addArrayIndex( Expression * index, Expression * dimension );
+		void clearArrayIndices();
+
+		class ExpanderImpl;
+	private:
+		std::shared_ptr< ExpanderImpl > expander;
+		std::list< Expression * > cur;
+
+		// invariant: list of size 2N (elements come in pairs [index, dimension])
+		typedef std::list< Expression * > IndexList;
+		IndexList indices;
+	};
 } // namespace
 
Index: src/Makefile.in
===================================================================
--- src/Makefile.in	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/Makefile.in	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -108,5 +108,4 @@
 	ControlStruct/driver_cfa_cpp-LabelFixer.$(OBJEXT) \
 	ControlStruct/driver_cfa_cpp-MLEMutator.$(OBJEXT) \
-	ControlStruct/driver_cfa_cpp-CaseRangeMutator.$(OBJEXT) \
 	ControlStruct/driver_cfa_cpp-Mutate.$(OBJEXT) \
 	ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT) \
@@ -373,6 +372,6 @@
 	Common/SemanticError.cc Common/UniqueName.cc \
 	ControlStruct/LabelGenerator.cc ControlStruct/LabelFixer.cc \
-	ControlStruct/MLEMutator.cc ControlStruct/CaseRangeMutator.cc \
-	ControlStruct/Mutate.cc ControlStruct/ForExprMutator.cc \
+	ControlStruct/MLEMutator.cc ControlStruct/Mutate.cc \
+	ControlStruct/ForExprMutator.cc \
 	ControlStruct/LabelTypeChecker.cc Designators/Processor.cc \
 	GenPoly/Box.cc GenPoly/GenPoly.cc GenPoly/PolyMutator.cc \
@@ -543,7 +542,4 @@
 	ControlStruct/$(DEPDIR)/$(am__dirstamp)
 ControlStruct/driver_cfa_cpp-MLEMutator.$(OBJEXT):  \
-	ControlStruct/$(am__dirstamp) \
-	ControlStruct/$(DEPDIR)/$(am__dirstamp)
-ControlStruct/driver_cfa_cpp-CaseRangeMutator.$(OBJEXT):  \
 	ControlStruct/$(am__dirstamp) \
 	ControlStruct/$(DEPDIR)/$(am__dirstamp)
@@ -823,5 +819,4 @@
 	-rm -f Common/driver_cfa_cpp-SemanticError.$(OBJEXT)
 	-rm -f Common/driver_cfa_cpp-UniqueName.$(OBJEXT)
-	-rm -f ControlStruct/driver_cfa_cpp-CaseRangeMutator.$(OBJEXT)
 	-rm -f ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT)
 	-rm -f ControlStruct/driver_cfa_cpp-LabelFixer.$(OBJEXT)
@@ -934,5 +929,4 @@
 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-SemanticError.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-UniqueName.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-CaseRangeMutator.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-ForExprMutator.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Po@am__quote@
@@ -1217,18 +1211,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-MLEMutator.obj `if test -f 'ControlStruct/MLEMutator.cc'; then $(CYGPATH_W) 'ControlStruct/MLEMutator.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/MLEMutator.cc'; fi`
 
-ControlStruct/driver_cfa_cpp-CaseRangeMutator.o: ControlStruct/CaseRangeMutator.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-CaseRangeMutator.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-CaseRangeMutator.Tpo -c -o ControlStruct/driver_cfa_cpp-CaseRangeMutator.o `test -f 'ControlStruct/CaseRangeMutator.cc' || echo '$(srcdir)/'`ControlStruct/CaseRangeMutator.cc
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-CaseRangeMutator.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-CaseRangeMutator.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='ControlStruct/CaseRangeMutator.cc' object='ControlStruct/driver_cfa_cpp-CaseRangeMutator.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-CaseRangeMutator.o `test -f 'ControlStruct/CaseRangeMutator.cc' || echo '$(srcdir)/'`ControlStruct/CaseRangeMutator.cc
-
-ControlStruct/driver_cfa_cpp-CaseRangeMutator.obj: ControlStruct/CaseRangeMutator.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-CaseRangeMutator.obj -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-CaseRangeMutator.Tpo -c -o ControlStruct/driver_cfa_cpp-CaseRangeMutator.obj `if test -f 'ControlStruct/CaseRangeMutator.cc'; then $(CYGPATH_W) 'ControlStruct/CaseRangeMutator.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/CaseRangeMutator.cc'; fi`
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-CaseRangeMutator.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-CaseRangeMutator.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='ControlStruct/CaseRangeMutator.cc' object='ControlStruct/driver_cfa_cpp-CaseRangeMutator.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-CaseRangeMutator.obj `if test -f 'ControlStruct/CaseRangeMutator.cc'; then $(CYGPATH_W) 'ControlStruct/CaseRangeMutator.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/CaseRangeMutator.cc'; fi`
-
 ControlStruct/driver_cfa_cpp-Mutate.o: ControlStruct/Mutate.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-Mutate.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Tpo -c -o ControlStruct/driver_cfa_cpp-Mutate.o `test -f 'ControlStruct/Mutate.cc' || echo '$(srcdir)/'`ControlStruct/Mutate.cc
Index: src/Parser/ExpressionNode.cc
===================================================================
--- src/Parser/ExpressionNode.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/Parser/ExpressionNode.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 13:17:07 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul  5 13:41:55 2016
-// Update Count     : 320
+// Last Modified On : Fri Aug  5 07:56:23 2016
+// Update Count     : 375
 //
 
@@ -83,7 +83,7 @@
 }
 
-CommaExprNode *ExpressionNode::add_to_list( ExpressionNode *exp ) {
-	return new CommaExprNode( this, exp );
-}
+// CommaExprNode *ExpressionNode::add_to_list( ExpressionNode *exp ) {
+// 	return new CommaExprNode( this, exp );
+// }
 
 //##############################################################################
@@ -246,5 +246,5 @@
 	"?|?", "?&?", "?^?", "Cast", "?<<?", "?>>?", "?<?", "?>?", "?<=?", "?>=?", "?==?", "?!=?",
 	"?=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?", "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?",
-	"?[?]", "FieldSel", "PFieldSel", "Range",
+	"?[?]", "FieldSel", "PFieldSel", "...",
 	// monadic
 	"+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&"
@@ -258,5 +258,5 @@
 OperatorNode::~OperatorNode() {}
 
-OperatorNode::Type OperatorNode::get_type( void ) const{
+OperatorNode::Type OperatorNode::get_type( void ) const {
 	return type;
 }
@@ -311,5 +311,88 @@
 }
 
-#include "Common/utility.h"
+
+Expression *build_cast( TypeValueNode * arg, ExpressionNode *expr_node ) {
+	DeclarationNode *decl_node = arg->get_decl();
+
+	Type *targetType = decl_node->buildType();
+	if ( dynamic_cast< VoidType* >( targetType ) ) {
+		delete targetType;
+		return new CastExpr( maybeBuild<Expression>(expr_node) );
+	} else {
+		return new CastExpr( maybeBuild<Expression>(expr_node), targetType );
+	} // if
+}
+
+Expression *build_fieldSel( ExpressionNode *expr_node, VarRefNode *member ) {
+	NameExpr* memberExpr = dynamic_cast<NameExpr*> ( maybeBuild<Expression>( member) );
+	assert( memberExpr );
+	UntypedMemberExpr *ret = new UntypedMemberExpr( memberExpr->get_name(), maybeBuild<Expression>(expr_node) );
+	delete member;
+	return ret;
+}
+
+Expression *build_pfieldSel( ExpressionNode *expr_node, VarRefNode *member ) {
+	NameExpr* memberExpr = dynamic_cast<NameExpr*> ( maybeBuild<Expression>( member) );
+	assert( memberExpr );
+	UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
+	deref->get_args().push_back( maybeBuild<Expression>(expr_node) );
+	UntypedMemberExpr *ret = new UntypedMemberExpr( memberExpr->get_name(), deref );
+	delete member;
+	return ret;
+}
+
+Expression *build_addressOf( ExpressionNode *expr_node ) {
+		return new AddressExpr( maybeBuild<Expression>(expr_node) );
+}
+Expression *build_sizeOf( ExpressionNode *expr_node ) {
+	if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( expr_node ) ) {
+		return new SizeofExpr( arg->get_decl()->buildType() );
+	} else {
+		return new SizeofExpr( maybeBuild<Expression>(expr_node) );
+	} // if
+}
+Expression *build_alignOf( ExpressionNode *expr_node ) {
+	if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( expr_node ) ) {
+		return new AlignofExpr( arg->get_decl()->buildType() );
+	} else {
+		return new AlignofExpr( maybeBuild<Expression>(expr_node) );
+	} // if
+}
+Expression *build_offsetOf( TypeValueNode * arg, VarRefNode *member ) {
+	NameExpr *memberExpr = dynamic_cast<NameExpr *>( maybeBuild<Expression>( member ) );
+	assert( memberExpr );
+	return new UntypedOffsetofExpr( arg->get_decl()->buildType(), memberExpr->get_name() );
+}
+
+Expression *build_and_or( ExpressionNode *expr_node1, ExpressionNode *expr_node2, bool kind ) {
+	return new LogicalExpr( notZeroExpr( maybeBuild<Expression>(expr_node1) ), notZeroExpr( maybeBuild<Expression>(expr_node2) ), kind );
+}
+
+Expression *build_opr1( OperatorNode::Type op, ExpressionNode *expr_node ) {
+	std::list<Expression *> args;
+	args.push_back( new AddressExpr( maybeBuild<Expression>(expr_node) ) );
+	return new UntypedExpr( new NameExpr( opName[ op ] ), args );
+}
+Expression *build_opr2( OperatorNode::Type op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
+	std::list<Expression *> args;
+	args.push_back( maybeBuild<Expression>(expr_node1) );
+	args.push_back( maybeBuild<Expression>(expr_node2) );
+	return new UntypedExpr( new NameExpr( opName[ op ] ), args );
+}
+
+Expression *build_cond( ExpressionNode *expr_node1, ExpressionNode *expr_node2, ExpressionNode *expr_node3 ) {
+	return new ConditionalExpr( notZeroExpr( maybeBuild<Expression>(expr_node1) ), maybeBuild<Expression>(expr_node2), maybeBuild<Expression>(expr_node3) );
+}
+
+Expression *build_comma( ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
+	return new CommaExpr( maybeBuild<Expression>(expr_node1), maybeBuild<Expression>(expr_node2) );
+}
+
+CompositeExprNode2::CompositeExprNode2( Expression *expr ) : expr( expr ) {}
+CompositeExprNode2::CompositeExprNode2( const CompositeExprNode2 &other ) : expr( other.expr->clone() ) {}
+CompositeExprNode2::~CompositeExprNode2() { delete expr; }
+void CompositeExprNode2::print( std::ostream &, int indent ) const { assert( false ); }
+void CompositeExprNode2::printOneLine( std::ostream &, int indent ) const { assert( false ); }
+
 
 Expression *CompositeExprNode::build() const {
@@ -323,9 +406,5 @@
 	} // if
 
-	switch ( op->get_type()) {
-	  case OperatorNode::Incr:
-	  case OperatorNode::Decr:
-	  case OperatorNode::IncrPost:
-	  case OperatorNode::DecrPost:
+	switch ( op->get_type() ) {
 	  case OperatorNode::Assign:
 	  case OperatorNode::MulAssn:
@@ -339,46 +418,6 @@
 	  case OperatorNode::ERAssn:
 	  case OperatorNode::OrAssn:
-		// the rewrite rules for these expressions specify that the first argument has its address taken
 		assert( ! args.empty() );
 		args.front() = new AddressExpr( args.front() );
-		break;
-	  default:		// do nothing
-		;
-	} // switch
-
-	switch ( op->get_type() ) {
-	  case OperatorNode::Incr:
-	  case OperatorNode::Decr:
-	  case OperatorNode::IncrPost:
-	  case OperatorNode::DecrPost:
-	  case OperatorNode::Assign:
-	  case OperatorNode::MulAssn:
-	  case OperatorNode::DivAssn:
-	  case OperatorNode::ModAssn:
-	  case OperatorNode::PlusAssn:
-	  case OperatorNode::MinusAssn:
-	  case OperatorNode::LSAssn:
-	  case OperatorNode::RSAssn:
-	  case OperatorNode::AndAssn:
-	  case OperatorNode::ERAssn:
-	  case OperatorNode::OrAssn:
-	  case OperatorNode::Plus:
-	  case OperatorNode::Minus:
-	  case OperatorNode::Mul:
-	  case OperatorNode::Div:
-	  case OperatorNode::Mod:
-	  case OperatorNode::BitOr:
-	  case OperatorNode::BitAnd:
-	  case OperatorNode::Xor:
-	  case OperatorNode::LShift:
-	  case OperatorNode::RShift:
-	  case OperatorNode::LThan:
-	  case OperatorNode::GThan:
-	  case OperatorNode::LEThan:
-	  case OperatorNode::GEThan:
-	  case OperatorNode::Eq:
-	  case OperatorNode::Neq:
-	  case OperatorNode::Index:
-	  case OperatorNode::Range:
 	  case OperatorNode::UnPlus:
 	  case OperatorNode::UnMinus:
@@ -388,102 +427,17 @@
 	  case OperatorNode::LabelAddress:
 		return new UntypedExpr( new NameExpr( opName[ op->get_type() ] ), args );
-	  case OperatorNode::AddressOf:
-		assert( args.size() == 1 );
-		assert( args.front() );
-
-		return new AddressExpr( args.front() );
-	  case OperatorNode::Cast:
-		{
-			TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args());
-			assert( arg );
-
-			DeclarationNode *decl_node = arg->get_decl();
-			ExpressionNode *expr_node = dynamic_cast<ExpressionNode *>( arg->get_link());
-
-			Type *targetType = decl_node->buildType();
-			if ( dynamic_cast< VoidType* >( targetType ) ) {
-				delete targetType;
-				return new CastExpr( maybeBuild<Expression>(expr_node), maybeBuild< Expression >( get_argName() ) );
-			} else {
-				return new CastExpr( maybeBuild<Expression>(expr_node),targetType, maybeBuild< Expression >( get_argName() ) );
-			} // if
-		}
-	  case OperatorNode::FieldSel:
-		{
-			assert( args.size() == 2 );
-
-			NameExpr *member = dynamic_cast<NameExpr *>( args.back());
-			// TupleExpr *memberTup = dynamic_cast<TupleExpr *>( args.back());
-
-			if ( member != 0 ) {
-				UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), args.front());
-				delete member;
-				return ret;
-				/* else if ( memberTup != 0 )
-				   {
-				   UntypedMemberExpr *ret = new UntypedMemberExpr( memberTup->get_name(), args.front());
-				   delete member;
-				   return ret;
-				   } */
-			} else
-				assert( false );
-		}
-	  case OperatorNode::PFieldSel:
-		{
-			assert( args.size() == 2 );
-
-			NameExpr *member = dynamic_cast<NameExpr *>( args.back());  // modify for Tuples   xxx
-			assert( member != 0 );
-
-			UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
-			deref->get_args().push_back( args.front() );
-
-			UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), deref );
-			delete member;
-			return ret;
-		}
-	  case OperatorNode::SizeOf:
-		{
-			if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
-				return new SizeofExpr( arg->get_decl()->buildType());
-			} else {
-				return new SizeofExpr( args.front());
-			} // if
-		}
-	  case OperatorNode::AlignOf:
-		{
-			if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
-				return new AlignofExpr( arg->get_decl()->buildType());
-			} else {
-				return new AlignofExpr( args.front());
-			} // if
-		}
-	  case OperatorNode::OffsetOf:
-		{
-			assert( args.size() == 2 );
-
-			if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args() ) ) {
-				NameExpr *member = dynamic_cast<NameExpr *>( args.back() );
-				assert( member != 0 );
-
-				return new UntypedOffsetofExpr( arg->get_decl()->buildType(), member->get_name() );
-			} else assert( false );
-		}
+
 	  case OperatorNode::Attr:
 		{
-			VarRefNode *var = dynamic_cast<VarRefNode *>( get_args());
+			VarRefNode *var = dynamic_cast<VarRefNode *>( get_args() );
 			assert( var );
 			if ( ! get_args()->get_link() ) {
 				return new AttrExpr( maybeBuild<Expression>(var), ( Expression*)0);
-			} else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link()) ) {
-				return new AttrExpr( maybeBuild<Expression>(var), arg->get_decl()->buildType());
+			} else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link() ) ) {
+				return new AttrExpr( maybeBuild<Expression>(var), arg->get_decl()->buildType() );
 			} else {
-				return new AttrExpr( maybeBuild<Expression>(var), args.back());
+				return new AttrExpr( maybeBuild<Expression>(var), args.back() );
 			} // if
 		}
-	  case OperatorNode::Or:
-	  case OperatorNode::And:
-		assert( args.size() == 2);
-		return new LogicalExpr( notZeroExpr( args.front() ), notZeroExpr( args.back() ), ( op->get_type() == OperatorNode::And ) );
 	  case OperatorNode::Cond:
 		{
@@ -497,14 +451,4 @@
 	  case OperatorNode::NCond:
 		throw UnimplementedError( "GNU 2-argument conditional expression" );
-	  case OperatorNode::Comma:
-		{
-			assert( args.size() == 2);
-			std::list< Expression * >::const_iterator i = args.begin();
-			Expression *ret = *i++;
-			while ( i != args.end() ) {
-				ret = new CommaExpr( ret, *i++ );
-			}
-			return ret;
-		}
 		// Tuples
 	  case OperatorNode::TupleC:
@@ -515,6 +459,5 @@
 		}
 	  default:
-		// shouldn't happen
-		assert( false );
+		assert( ((void)"CompositeExprNode::build", false) );
 		return 0;
 	} // switch
@@ -605,23 +548,4 @@
 
 void LabelNode::printOneLine( std::ostream &os, int indent ) const {}
-
-//##############################################################################
-
-CommaExprNode::CommaExprNode(): CompositeExprNode( new OperatorNode( OperatorNode::Comma )) {}
-
-CommaExprNode::CommaExprNode( ExpressionNode *exp ) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp ) {
-}
-
-CommaExprNode::CommaExprNode( ExpressionNode *exp1, ExpressionNode *exp2) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp1, exp2) {
-}
-
-CommaExprNode *CommaExprNode::add_to_list( ExpressionNode *exp ) {
-	add_arg( exp );
-
-	return this;
-}
-
-CommaExprNode::CommaExprNode( const CommaExprNode &other ) : CompositeExprNode( other ) {
-}
 
 //##############################################################################
@@ -774,5 +698,4 @@
 }
 
-
 ExpressionNode *flattenCommas( ExpressionNode *list ) {
 	if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) {
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/Parser/ParseNode.h	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 13:28:16 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sun Jul 24 02:17:00 2016
-// Update Count     : 269
+// Last Modified On : Fri Aug  5 07:49:32 2016
+// Update Count     : 288
 //
 
@@ -77,5 +77,5 @@
 	virtual ExpressionNode *clone() const = 0;
 
-	virtual CommaExprNode *add_to_list( ExpressionNode * );
+	// virtual CommaExprNode *add_to_list( ExpressionNode * );
 
 	ExpressionNode *get_argName() const { return argName; }
@@ -225,4 +225,33 @@
 };
 
+Expression *build_cast( TypeValueNode * arg, ExpressionNode *expr_node );
+Expression *build_fieldSel( ExpressionNode *expr_node, VarRefNode *member );
+Expression *build_pfieldSel( ExpressionNode *expr_node, VarRefNode *member );
+Expression *build_addressOf( ExpressionNode *expr_node );
+Expression *build_sizeOf( ExpressionNode *expr_node );
+Expression *build_alignOf( ExpressionNode *expr_node );
+Expression *build_offsetOf( TypeValueNode * arg, VarRefNode *member );
+Expression *build_and( ExpressionNode *expr_node1, ExpressionNode *expr_node2 );
+Expression *build_and_or( ExpressionNode *expr_node1, ExpressionNode *expr_node2, bool kind );
+Expression *build_opr1( OperatorNode::Type op, ExpressionNode *expr_node );
+Expression *build_opr2( OperatorNode::Type op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 );
+Expression *build_cond( ExpressionNode *expr_node1, ExpressionNode *expr_node2, ExpressionNode *expr_node3 );
+Expression *build_comma( ExpressionNode *expr_node1, ExpressionNode *expr_node2 );
+
+class CompositeExprNode2 : public ExpressionNode {
+  public:
+	CompositeExprNode2( Expression *expr );
+	CompositeExprNode2( const CompositeExprNode2 &other );
+	virtual ~CompositeExprNode2();
+
+	virtual CompositeExprNode2 *clone() const { return new CompositeExprNode2( *this ); }
+	virtual Expression *build() const { return expr->clone(); }
+
+	virtual void print( std::ostream &, int indent = 0) const;
+	virtual void printOneLine( std::ostream &, int indent = 0) const;
+  private:
+	Expression *expr;
+};
+
 class CompositeExprNode : public ExpressionNode {
   public:
@@ -290,15 +319,4 @@
   private:
 	std::list< Label > labels;
-};
-
-class CommaExprNode : public CompositeExprNode {
-  public:
-	CommaExprNode();
-	CommaExprNode( ExpressionNode * );
-	CommaExprNode( ExpressionNode *, ExpressionNode * );
-	CommaExprNode( const CommaExprNode &other );
-
-	virtual CommaExprNode *add_to_list( ExpressionNode * );
-	virtual CommaExprNode *clone() const { return new CommaExprNode( *this ); }
 };
 
@@ -485,5 +503,5 @@
 	std::string get_target() const;
 
-	StatementNode *add_controlexp( ExpressionNode * );
+	// StatementNode *add_controlexp( ExpressionNode * );
 	StatementNode *append_block( StatementNode * );
 	StatementNode *append_last_case( StatementNode * );
@@ -531,10 +549,4 @@
 	ConstantNode *clobber;
 	std::list< Label > gotolabels;
-};
-
-class NullStmtNode : public CompoundStmtNode {
-  public:
-	Statement *build() const;
-	void print( std::ostream &, int indent = 0 ) const;
 };
 
Index: src/Parser/StatementNode.cc
===================================================================
--- src/Parser/StatementNode.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/Parser/StatementNode.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -107,9 +107,9 @@
 }
 
-StatementNode *StatementNode::add_controlexp( ExpressionNode *e ) {
-	if ( control && e )
-		control->add_to_list( e ); // xxx - check this
-	return this;
-}
+// StatementNode *StatementNode::add_controlexp( ExpressionNode *e ) {
+// 	if ( control && e )
+// 		control->add_to_list( e ); // xxx - check this
+// 	return this;
+// }
 
 StatementNode *StatementNode::append_block( StatementNode *stmt ) {
@@ -417,13 +417,4 @@
 }
 
-
-void NullStmtNode::print( ostream &os, int indent ) const {
-	os << string( indent, ' ' ) << "Null Statement:" << endl;
-}
-
-Statement *NullStmtNode::build() const {
-	return new NullStmt;
-}
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/Parser/TypeData.cc
===================================================================
--- src/Parser/TypeData.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/Parser/TypeData.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -510,5 +510,5 @@
 		return buildVariable();
 	} else {
-		return new ObjectDecl( name, sc, linkage, bitfieldWidth, build(), init, isInline, isNoreturn );
+		return new ObjectDecl( name, sc, linkage, bitfieldWidth, build(), init, std::list< Attribute * >(),  isInline, isNoreturn );
 	} // if
 	return 0;
Index: src/Parser/parser.cc
===================================================================
--- src/Parser/parser.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/Parser/parser.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -354,4 +354,5 @@
 	LabelNode *label;
 	InitializerNode *in;
+	OperatorNode::Type op;
 	bool flag;
 
@@ -359,5 +360,5 @@
 
 /* Line 293 of yacc.c  */
-#line 362 "Parser/parser.cc"
+#line 363 "Parser/parser.cc"
 } YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
@@ -371,5 +372,5 @@
 
 /* Line 343 of yacc.c  */
-#line 374 "Parser/parser.cc"
+#line 375 "Parser/parser.cc"
 
 #ifdef short
@@ -1016,80 +1017,80 @@
 static const yytype_uint16 yyrline[] =
 {
-       0,   290,   290,   296,   305,   306,   307,   311,   312,   313,
-     317,   318,   322,   323,   327,   328,   332,   333,   339,   341,
-     343,   345,   350,   351,   357,   361,   363,   364,   366,   367,
-     369,   371,   373,   381,   382,   388,   389,   390,   395,   397,
-     402,   403,   407,   411,   413,   415,   417,   422,   425,   427,
-     429,   431,   436,   438,   440,   442,   444,   446,   448,   450,
-     452,   454,   456,   463,   464,   466,   470,   471,   472,   473,
-     477,   478,   480,   485,   486,   488,   490,   495,   496,   498,
-     503,   504,   506,   511,   512,   514,   516,   518,   523,   524,
-     526,   531,   532,   537,   538,   543,   544,   549,   550,   555,
-     556,   561,   562,   564,   566,   571,   576,   577,   579,   581,
-     587,   588,   594,   596,   598,   600,   605,   606,   611,   612,
-     613,   614,   615,   616,   617,   618,   619,   620,   624,   625,
-     631,   632,   638,   639,   640,   641,   642,   643,   644,   645,
-     646,   656,   663,   665,   675,   676,   681,   683,   689,   691,
-     695,   696,   701,   706,   709,   711,   713,   722,   724,   735,
-     736,   738,   742,   743,   748,   749,   754,   755,   759,   764,
-     765,   769,   771,   777,   778,   782,   784,   786,   788,   794,
-     795,   799,   801,   806,   808,   810,   815,   817,   822,   824,
-     828,   831,   835,   838,   842,   844,   848,   850,   857,   859,
-     861,   870,   872,   874,   876,   878,   883,   885,   887,   889,
-     894,   907,   908,   913,   915,   920,   924,   926,   928,   930,
-     932,   938,   939,   945,   946,   950,   951,   956,   958,   964,
-     965,   967,   972,   974,   981,   983,   987,   988,   993,   995,
-     999,  1000,  1004,  1006,  1010,  1011,  1015,  1016,  1020,  1021,
-    1036,  1037,  1038,  1039,  1040,  1044,  1049,  1056,  1066,  1071,
-    1076,  1084,  1089,  1094,  1099,  1104,  1112,  1134,  1139,  1146,
-    1148,  1155,  1160,  1165,  1176,  1181,  1186,  1191,  1196,  1205,
-    1210,  1218,  1219,  1220,  1221,  1227,  1232,  1240,  1241,  1242,
-    1243,  1247,  1248,  1249,  1250,  1255,  1256,  1265,  1266,  1271,
-    1272,  1277,  1279,  1281,  1283,  1285,  1288,  1287,  1299,  1300,
-    1302,  1312,  1313,  1318,  1322,  1324,  1326,  1328,  1330,  1332,
-    1334,  1336,  1341,  1343,  1345,  1347,  1349,  1351,  1353,  1355,
-    1357,  1359,  1361,  1363,  1365,  1371,  1372,  1374,  1376,  1378,
-    1383,  1384,  1390,  1391,  1393,  1395,  1400,  1402,  1404,  1406,
-    1411,  1412,  1414,  1416,  1421,  1422,  1424,  1429,  1430,  1432,
-    1434,  1439,  1441,  1443,  1448,  1449,  1453,  1455,  1461,  1460,
-    1464,  1466,  1471,  1473,  1479,  1480,  1485,  1486,  1488,  1489,
-    1498,  1499,  1501,  1503,  1508,  1510,  1516,  1517,  1519,  1522,
-    1525,  1530,  1531,  1536,  1541,  1545,  1547,  1553,  1552,  1559,
-    1561,  1567,  1568,  1576,  1577,  1581,  1582,  1583,  1585,  1587,
-    1594,  1595,  1597,  1599,  1604,  1605,  1611,  1612,  1616,  1617,
-    1622,  1623,  1624,  1626,  1634,  1635,  1637,  1640,  1642,  1646,
-    1647,  1648,  1650,  1652,  1656,  1661,  1669,  1670,  1679,  1681,
-    1686,  1687,  1688,  1692,  1693,  1694,  1698,  1699,  1700,  1704,
-    1705,  1706,  1711,  1712,  1713,  1714,  1720,  1721,  1723,  1728,
-    1729,  1734,  1735,  1736,  1737,  1738,  1753,  1754,  1759,  1760,
-    1768,  1770,  1772,  1775,  1777,  1779,  1802,  1803,  1805,  1807,
-    1812,  1813,  1815,  1820,  1825,  1826,  1832,  1831,  1835,  1839,
-    1841,  1843,  1849,  1850,  1855,  1860,  1862,  1867,  1869,  1870,
-    1872,  1877,  1879,  1881,  1886,  1888,  1893,  1898,  1906,  1912,
-    1911,  1925,  1926,  1931,  1932,  1936,  1941,  1946,  1954,  1959,
-    1970,  1971,  1982,  1983,  1989,  1990,  1994,  1995,  1996,  1999,
-    1998,  2009,  2018,  2024,  2030,  2039,  2045,  2051,  2057,  2063,
-    2071,  2077,  2085,  2091,  2100,  2101,  2102,  2106,  2110,  2112,
-    2117,  2118,  2122,  2123,  2128,  2134,  2135,  2138,  2140,  2141,
-    2145,  2146,  2147,  2148,  2182,  2184,  2185,  2187,  2192,  2197,
-    2202,  2204,  2206,  2211,  2213,  2215,  2217,  2222,  2224,  2233,
-    2235,  2236,  2241,  2243,  2245,  2250,  2252,  2254,  2259,  2261,
-    2263,  2272,  2273,  2274,  2278,  2280,  2282,  2287,  2289,  2291,
-    2296,  2298,  2300,  2315,  2317,  2318,  2320,  2325,  2326,  2331,
-    2333,  2335,  2340,  2342,  2344,  2346,  2351,  2353,  2355,  2365,
-    2367,  2368,  2370,  2375,  2377,  2379,  2384,  2386,  2388,  2390,
-    2395,  2397,  2399,  2430,  2432,  2433,  2435,  2440,  2445,  2453,
-    2455,  2457,  2462,  2464,  2469,  2471,  2485,  2486,  2488,  2493,
-    2495,  2497,  2499,  2501,  2506,  2507,  2509,  2511,  2516,  2518,
-    2520,  2526,  2528,  2530,  2534,  2536,  2538,  2540,  2554,  2555,
-    2557,  2562,  2564,  2566,  2568,  2570,  2575,  2576,  2578,  2580,
-    2585,  2587,  2589,  2595,  2596,  2598,  2607,  2610,  2612,  2615,
-    2617,  2619,  2632,  2633,  2635,  2640,  2642,  2644,  2646,  2648,
-    2653,  2654,  2656,  2658,  2663,  2665,  2673,  2674,  2675,  2680,
-    2681,  2685,  2687,  2689,  2691,  2693,  2695,  2702,  2704,  2706,
-    2708,  2710,  2712,  2714,  2716,  2718,  2720,  2725,  2727,  2729,
-    2734,  2760,  2761,  2763,  2767,  2768,  2772,  2774,  2776,  2778,
-    2780,  2782,  2789,  2791,  2793,  2795,  2797,  2799,  2804,  2809,
-    2811,  2813,  2831,  2833,  2838,  2839
+       0,   292,   292,   298,   307,   308,   309,   313,   314,   315,
+     319,   320,   324,   325,   329,   330,   334,   335,   341,   343,
+     345,   347,   352,   353,   359,   363,   365,   366,   368,   369,
+     371,   373,   375,   383,   384,   390,   391,   392,   397,   399,
+     404,   405,   409,   413,   415,   417,   419,   424,   427,   429,
+     431,   436,   439,   441,   443,   445,   447,   449,   451,   453,
+     455,   457,   459,   466,   467,   469,   473,   474,   475,   476,
+     480,   481,   483,   488,   489,   491,   493,   498,   499,   501,
+     506,   507,   509,   514,   515,   517,   519,   521,   526,   527,
+     529,   534,   535,   540,   541,   546,   547,   552,   553,   558,
+     559,   564,   565,   568,   570,   575,   580,   581,   583,   585,
+     591,   592,   598,   600,   602,   604,   609,   610,   615,   616,
+     617,   618,   619,   620,   621,   622,   623,   624,   628,   629,
+     636,   637,   643,   644,   645,   646,   647,   648,   649,   650,
+     651,   661,   668,   670,   680,   681,   686,   688,   694,   696,
+     700,   701,   706,   711,   714,   716,   718,   728,   730,   741,
+     742,   744,   748,   750,   754,   755,   760,   761,   765,   770,
+     771,   775,   777,   783,   784,   788,   790,   792,   794,   800,
+     801,   805,   807,   812,   814,   816,   821,   823,   828,   830,
+     834,   837,   841,   844,   848,   850,   854,   856,   863,   865,
+     867,   876,   878,   880,   882,   884,   889,   891,   893,   895,
+     900,   913,   914,   919,   921,   926,   930,   932,   934,   936,
+     938,   944,   945,   951,   952,   956,   957,   962,   964,   970,
+     971,   973,   978,   980,   987,   989,   993,   994,   999,  1001,
+    1005,  1006,  1010,  1012,  1016,  1017,  1021,  1022,  1026,  1027,
+    1042,  1043,  1044,  1045,  1046,  1050,  1055,  1062,  1072,  1077,
+    1082,  1090,  1095,  1100,  1105,  1110,  1118,  1140,  1145,  1152,
+    1154,  1161,  1166,  1171,  1182,  1187,  1192,  1197,  1202,  1211,
+    1216,  1224,  1225,  1226,  1227,  1233,  1238,  1246,  1247,  1248,
+    1249,  1253,  1254,  1255,  1256,  1261,  1262,  1271,  1272,  1277,
+    1278,  1283,  1285,  1287,  1289,  1291,  1294,  1293,  1305,  1306,
+    1308,  1318,  1319,  1324,  1328,  1330,  1332,  1334,  1336,  1338,
+    1340,  1342,  1347,  1349,  1351,  1353,  1355,  1357,  1359,  1361,
+    1363,  1365,  1367,  1369,  1371,  1377,  1378,  1380,  1382,  1384,
+    1389,  1390,  1396,  1397,  1399,  1401,  1406,  1408,  1410,  1412,
+    1417,  1418,  1420,  1422,  1427,  1428,  1430,  1435,  1436,  1438,
+    1440,  1445,  1447,  1449,  1454,  1455,  1459,  1461,  1467,  1466,
+    1470,  1472,  1477,  1479,  1485,  1486,  1491,  1492,  1494,  1495,
+    1504,  1505,  1507,  1509,  1514,  1516,  1522,  1523,  1525,  1528,
+    1531,  1536,  1537,  1542,  1547,  1551,  1553,  1559,  1558,  1565,
+    1567,  1573,  1574,  1582,  1583,  1587,  1588,  1589,  1591,  1593,
+    1600,  1601,  1603,  1605,  1610,  1611,  1617,  1618,  1622,  1623,
+    1628,  1629,  1630,  1632,  1640,  1641,  1643,  1646,  1648,  1652,
+    1653,  1654,  1656,  1658,  1662,  1667,  1675,  1676,  1685,  1687,
+    1692,  1693,  1694,  1698,  1699,  1700,  1704,  1705,  1706,  1710,
+    1711,  1712,  1717,  1718,  1719,  1720,  1726,  1727,  1729,  1734,
+    1735,  1740,  1741,  1742,  1743,  1744,  1759,  1760,  1765,  1766,
+    1774,  1776,  1778,  1781,  1783,  1785,  1808,  1809,  1811,  1813,
+    1818,  1819,  1821,  1826,  1831,  1832,  1838,  1837,  1841,  1845,
+    1847,  1849,  1855,  1856,  1861,  1866,  1868,  1873,  1875,  1876,
+    1878,  1883,  1885,  1887,  1892,  1894,  1899,  1904,  1912,  1918,
+    1917,  1931,  1932,  1937,  1938,  1942,  1947,  1952,  1960,  1965,
+    1976,  1977,  1988,  1989,  1995,  1996,  2000,  2001,  2002,  2005,
+    2004,  2015,  2024,  2030,  2036,  2045,  2051,  2057,  2063,  2069,
+    2077,  2083,  2091,  2097,  2106,  2107,  2108,  2112,  2116,  2118,
+    2123,  2124,  2128,  2129,  2134,  2140,  2141,  2144,  2146,  2147,
+    2151,  2152,  2153,  2154,  2188,  2190,  2191,  2193,  2198,  2203,
+    2208,  2210,  2212,  2217,  2219,  2221,  2223,  2228,  2230,  2239,
+    2241,  2242,  2247,  2249,  2251,  2256,  2258,  2260,  2265,  2267,
+    2269,  2278,  2279,  2280,  2284,  2286,  2288,  2293,  2295,  2297,
+    2302,  2304,  2306,  2321,  2323,  2324,  2326,  2331,  2332,  2337,
+    2339,  2341,  2346,  2348,  2350,  2352,  2357,  2359,  2361,  2371,
+    2373,  2374,  2376,  2381,  2383,  2385,  2390,  2392,  2394,  2396,
+    2401,  2403,  2405,  2436,  2438,  2439,  2441,  2446,  2451,  2459,
+    2461,  2463,  2468,  2470,  2475,  2477,  2491,  2492,  2494,  2499,
+    2501,  2503,  2505,  2507,  2512,  2513,  2515,  2517,  2522,  2524,
+    2526,  2532,  2534,  2536,  2540,  2542,  2544,  2546,  2560,  2561,
+    2563,  2568,  2570,  2572,  2574,  2576,  2581,  2582,  2584,  2586,
+    2591,  2593,  2595,  2601,  2602,  2604,  2613,  2616,  2618,  2621,
+    2623,  2625,  2638,  2639,  2641,  2646,  2648,  2650,  2652,  2654,
+    2659,  2660,  2662,  2664,  2669,  2671,  2679,  2680,  2681,  2686,
+    2687,  2691,  2693,  2695,  2697,  2699,  2701,  2708,  2710,  2712,
+    2714,  2716,  2718,  2720,  2722,  2724,  2726,  2731,  2733,  2735,
+    2740,  2766,  2767,  2769,  2773,  2774,  2778,  2780,  2782,  2784,
+    2786,  2788,  2795,  2797,  2799,  2801,  2803,  2805,  2810,  2815,
+    2817,  2819,  2837,  2839,  2844,  2845
 };
 #endif
@@ -5216,5 +5217,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 290 "parser.yy"
+#line 292 "parser.yy"
     {
 			typedefTable.enterScope();
@@ -5225,5 +5226,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 296 "parser.yy"
+#line 298 "parser.yy"
     {
 			typedefTable.leaveScope();
@@ -5234,5 +5235,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 305 "parser.yy"
+#line 307 "parser.yy"
     { (yyval.constant) = makeConstantInteger( *(yyvsp[(1) - (1)].tok) ); }
     break;
@@ -5241,5 +5242,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 306 "parser.yy"
+#line 308 "parser.yy"
     { (yyval.constant) = makeConstantFloat( *(yyvsp[(1) - (1)].tok) ); }
     break;
@@ -5248,5 +5249,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 307 "parser.yy"
+#line 309 "parser.yy"
     { (yyval.constant) = makeConstantChar( *(yyvsp[(1) - (1)].tok) ); }
     break;
@@ -5255,5 +5256,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 332 "parser.yy"
+#line 334 "parser.yy"
     { (yyval.constant) = makeConstantStr( *(yyvsp[(1) - (1)].tok) ); }
     break;
@@ -5262,16 +5263,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 333 "parser.yy"
+#line 335 "parser.yy"
     { (yyval.constant) = (yyvsp[(1) - (2)].constant)->appendstr( (yyvsp[(2) - (2)].tok) ); }
     break;
 
   case 18:
-
-/* Line 1806 of yacc.c  */
-#line 340 "parser.yy"
-    { (yyval.en) = new VarRefNode( (yyvsp[(1) - (1)].tok) ); }
-    break;
-
-  case 19:
 
 /* Line 1806 of yacc.c  */
@@ -5280,8 +5274,15 @@
     break;
 
+  case 19:
+
+/* Line 1806 of yacc.c  */
+#line 344 "parser.yy"
+    { (yyval.en) = new VarRefNode( (yyvsp[(1) - (1)].tok) ); }
+    break;
+
   case 20:
 
 /* Line 1806 of yacc.c  */
-#line 344 "parser.yy"
+#line 346 "parser.yy"
     { (yyval.en) = (yyvsp[(2) - (3)].en); }
     break;
@@ -5290,5 +5291,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 346 "parser.yy"
+#line 348 "parser.yy"
     { (yyval.en) = new ValofExprNode( (yyvsp[(2) - (3)].sn) ); }
     break;
@@ -5297,6 +5298,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 356 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Index ), (yyvsp[(1) - (6)].en), (yyvsp[(4) - (6)].en) ); }
+#line 358 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr2( OperatorNode::Index, (yyvsp[(1) - (6)].en), (yyvsp[(4) - (6)].en) ) ); }
     break;
 
@@ -5304,5 +5305,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 358 "parser.yy"
+#line 360 "parser.yy"
     { (yyval.en) = new CompositeExprNode( (yyvsp[(1) - (4)].en), (yyvsp[(3) - (4)].en) ); }
     break;
@@ -5311,6 +5312,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 362 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::FieldSel ), (yyvsp[(1) - (3)].en), new VarRefNode( (yyvsp[(3) - (3)].tok) )); }
+#line 364 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_fieldSel( (yyvsp[(1) - (3)].en), new VarRefNode( (yyvsp[(3) - (3)].tok) ) ) ); }
     break;
 
@@ -5318,6 +5319,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 365 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::PFieldSel ), (yyvsp[(1) - (3)].en), new VarRefNode( (yyvsp[(3) - (3)].tok) )); }
+#line 367 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_pfieldSel( (yyvsp[(1) - (3)].en), new VarRefNode( (yyvsp[(3) - (3)].tok) ) ) ); }
     break;
 
@@ -5325,6 +5326,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 368 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::IncrPost ), (yyvsp[(1) - (2)].en) ); }
+#line 370 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr1( OperatorNode::IncrPost, (yyvsp[(1) - (2)].en) ) ); }
     break;
 
@@ -5332,6 +5333,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 370 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::DecrPost ), (yyvsp[(1) - (2)].en) ); }
+#line 372 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr1( OperatorNode::DecrPost, (yyvsp[(1) - (2)].en) ) ); }
     break;
 
@@ -5339,5 +5340,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 372 "parser.yy"
+#line 374 "parser.yy"
     { (yyval.en) = new CompoundLiteralNode( (yyvsp[(2) - (7)].decl), new InitializerNode( (yyvsp[(5) - (7)].in), true ) ); }
     break;
@@ -5346,5 +5347,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 374 "parser.yy"
+#line 376 "parser.yy"
     {
 			Token fn; fn.str = new std::string( "?{}" ); // location undefined
@@ -5356,5 +5357,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 383 "parser.yy"
+#line 385 "parser.yy"
     { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (3)].en)->set_link( (yyvsp[(3) - (3)].en) )); }
     break;
@@ -5363,5 +5364,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 388 "parser.yy"
+#line 390 "parser.yy"
     { (yyval.en) = 0; }
     break;
@@ -5370,5 +5371,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 391 "parser.yy"
+#line 393 "parser.yy"
     { (yyval.en) = (yyvsp[(3) - (3)].en)->set_argName( (yyvsp[(1) - (3)].tok) ); }
     break;
@@ -5377,5 +5378,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 396 "parser.yy"
+#line 398 "parser.yy"
     { (yyval.en) = (yyvsp[(7) - (7)].en)->set_argName( (yyvsp[(3) - (7)].en) ); }
     break;
@@ -5384,5 +5385,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 398 "parser.yy"
+#line 400 "parser.yy"
     { (yyval.en) = (yyvsp[(9) - (9)].en)->set_argName( new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)(yyvsp[(3) - (9)].en)->set_link( flattenCommas( (yyvsp[(5) - (9)].en) )))); }
     break;
@@ -5391,5 +5392,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 403 "parser.yy"
+#line 405 "parser.yy"
     { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_link( (yyvsp[(3) - (3)].en) ); }
     break;
@@ -5398,5 +5399,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 408 "parser.yy"
+#line 410 "parser.yy"
     { (yyval.en) = new VarRefNode( (yyvsp[(1) - (1)].tok) ); }
     break;
@@ -5405,6 +5406,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 412 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::FieldSel ), new VarRefNode( (yyvsp[(1) - (3)].tok) ), (yyvsp[(3) - (3)].en) ); }
+#line 414 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_fieldSel( (yyvsp[(3) - (3)].en), new VarRefNode( (yyvsp[(1) - (3)].tok) ) ) ); }
     break;
 
@@ -5412,6 +5413,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 414 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::FieldSel ), new VarRefNode( (yyvsp[(1) - (7)].tok) ), (yyvsp[(5) - (7)].en) ); }
+#line 416 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_fieldSel( (yyvsp[(5) - (7)].en), new VarRefNode( (yyvsp[(1) - (7)].tok) ) ) ); }
     break;
 
@@ -5419,6 +5420,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 416 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::PFieldSel ), new VarRefNode( (yyvsp[(1) - (3)].tok) ), (yyvsp[(3) - (3)].en) ); }
+#line 418 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_pfieldSel( (yyvsp[(3) - (3)].en), new VarRefNode( (yyvsp[(1) - (3)].tok) ) ) ); }
     break;
 
@@ -5426,16 +5427,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 418 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::PFieldSel ), new VarRefNode( (yyvsp[(1) - (7)].tok) ), (yyvsp[(5) - (7)].en) ); }
+#line 420 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_pfieldSel( (yyvsp[(5) - (7)].en), new VarRefNode( (yyvsp[(1) - (7)].tok) ) ) ); }
     break;
 
   case 48:
-
-/* Line 1806 of yacc.c  */
-#line 426 "parser.yy"
-    { (yyval.en) = (yyvsp[(1) - (1)].constant); }
-    break;
-
-  case 49:
 
 /* Line 1806 of yacc.c  */
@@ -5444,8 +5438,15 @@
     break;
 
+  case 49:
+
+/* Line 1806 of yacc.c  */
+#line 430 "parser.yy"
+    { (yyval.en) = (yyvsp[(1) - (1)].constant); }
+    break;
+
   case 50:
 
 /* Line 1806 of yacc.c  */
-#line 430 "parser.yy"
+#line 432 "parser.yy"
     { (yyval.en) = (yyvsp[(2) - (2)].en)->set_extension( true ); }
     break;
@@ -5454,20 +5455,21 @@
 
 /* Line 1806 of yacc.c  */
-#line 432 "parser.yy"
+#line 437 "parser.yy"
+    { (yyval.en) = (yyvsp[(1) - (2)].op) == OperatorNode::AddressOf ? (ExpressionNode*) new CompositeExprNode2( build_addressOf( (yyvsp[(2) - (2)].en) ) )
+											: (ExpressionNode*)new CompositeExprNode( new OperatorNode ( (yyvsp[(1) - (2)].op) ), (yyvsp[(2) - (2)].en) ); }
+    break;
+
+  case 52:
+
+/* Line 1806 of yacc.c  */
+#line 440 "parser.yy"
     { (yyval.en) = new CompositeExprNode( (yyvsp[(1) - (2)].en), (yyvsp[(2) - (2)].en) ); }
     break;
 
-  case 52:
-
-/* Line 1806 of yacc.c  */
-#line 437 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( (yyvsp[(1) - (2)].en), (yyvsp[(2) - (2)].en) ); }
-    break;
-
   case 53:
 
 /* Line 1806 of yacc.c  */
-#line 439 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Incr ), (yyvsp[(2) - (2)].en) ); }
+#line 442 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr1( OperatorNode::Incr, (yyvsp[(2) - (2)].en) ) ); }
     break;
 
@@ -5475,6 +5477,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 441 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Decr ), (yyvsp[(2) - (2)].en) ); }
+#line 444 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr1( OperatorNode::Decr, (yyvsp[(2) - (2)].en) ) ); }
     break;
 
@@ -5482,6 +5484,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 443 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::SizeOf ), (yyvsp[(2) - (2)].en) ); }
+#line 446 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_sizeOf( (yyvsp[(2) - (2)].en) ) ); }
     break;
 
@@ -5489,6 +5491,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 445 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::SizeOf ), new TypeValueNode( (yyvsp[(3) - (4)].decl) )); }
+#line 448 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_sizeOf( new TypeValueNode( (yyvsp[(3) - (4)].decl) ) ) ); }
     break;
 
@@ -5496,6 +5498,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 447 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::OffsetOf ), new TypeValueNode( (yyvsp[(3) - (6)].decl) ), new VarRefNode( (yyvsp[(5) - (6)].tok) )); }
+#line 450 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_offsetOf( new TypeValueNode( (yyvsp[(3) - (6)].decl) ), new VarRefNode( (yyvsp[(5) - (6)].tok) ) ) ); }
     break;
 
@@ -5503,6 +5505,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 449 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Attr ), new VarRefNode( (yyvsp[(1) - (1)].tok) )); }
+#line 452 "parser.yy"
+    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Attr ), new VarRefNode( (yyvsp[(1) - (1)].tok) ) ); }
     break;
 
@@ -5510,6 +5512,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 451 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Attr ), new VarRefNode( (yyvsp[(1) - (4)].tok) ), new TypeValueNode( (yyvsp[(3) - (4)].decl) )); }
+#line 454 "parser.yy"
+    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Attr ), new VarRefNode( (yyvsp[(1) - (4)].tok) ), new TypeValueNode( (yyvsp[(3) - (4)].decl) ) ); }
     break;
 
@@ -5517,5 +5519,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 453 "parser.yy"
+#line 456 "parser.yy"
     { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Attr ), new VarRefNode( (yyvsp[(1) - (4)].tok) ), (yyvsp[(3) - (4)].en) ); }
     break;
@@ -5524,6 +5526,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 455 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::AlignOf ), (yyvsp[(2) - (2)].en) ); }
+#line 458 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_alignOf( (yyvsp[(2) - (2)].en) ) ); }
     break;
 
@@ -5531,6 +5533,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 457 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::AlignOf ), new TypeValueNode( (yyvsp[(3) - (4)].decl) ) ); }
+#line 460 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_alignOf( new TypeValueNode( (yyvsp[(3) - (4)].decl) ) ) ); }
     break;
 
@@ -5538,6 +5540,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 463 "parser.yy"
-    { (yyval.en) = new OperatorNode( OperatorNode::PointTo ); }
+#line 466 "parser.yy"
+    { (yyval.op) = OperatorNode::PointTo; }
     break;
 
@@ -5545,6 +5547,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 464 "parser.yy"
-    { (yyval.en) = new OperatorNode( OperatorNode::AddressOf ); }
+#line 467 "parser.yy"
+    { (yyval.op) = OperatorNode::AddressOf; }
     break;
 
@@ -5552,6 +5554,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 466 "parser.yy"
-    { (yyval.en) = new OperatorNode( OperatorNode::And ); }
+#line 469 "parser.yy"
+    { (yyval.op) = OperatorNode::And; }
     break;
 
@@ -5559,5 +5561,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 470 "parser.yy"
+#line 473 "parser.yy"
     { (yyval.en) = new OperatorNode( OperatorNode::UnPlus ); }
     break;
@@ -5566,5 +5568,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 471 "parser.yy"
+#line 474 "parser.yy"
     { (yyval.en) = new OperatorNode( OperatorNode::UnMinus ); }
     break;
@@ -5573,5 +5575,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 472 "parser.yy"
+#line 475 "parser.yy"
     { (yyval.en) = new OperatorNode( OperatorNode::Neg ); }
     break;
@@ -5580,5 +5582,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 473 "parser.yy"
+#line 476 "parser.yy"
     { (yyval.en) = new OperatorNode( OperatorNode::BitNeg ); }
     break;
@@ -5587,6 +5589,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 479 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Cast ), new TypeValueNode( (yyvsp[(2) - (4)].decl) ), (yyvsp[(4) - (4)].en) ); }
+#line 482 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_cast( new TypeValueNode( (yyvsp[(2) - (4)].decl) ), (yyvsp[(4) - (4)].en) ) ); }
     break;
 
@@ -5594,6 +5596,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 481 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Cast ), new TypeValueNode( (yyvsp[(2) - (4)].decl) ), (yyvsp[(4) - (4)].en) ); }
+#line 484 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_cast( new TypeValueNode( (yyvsp[(2) - (4)].decl) ), (yyvsp[(4) - (4)].en) ) ); }
     break;
 
@@ -5601,6 +5603,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 487 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Mul ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 490 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr2( OperatorNode::Mul, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
 
@@ -5608,6 +5610,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 489 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Div ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 492 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr2( OperatorNode::Div, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
 
@@ -5615,6 +5617,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 491 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Mod ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 494 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr2( OperatorNode::Mod, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
 
@@ -5622,6 +5624,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 497 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Plus ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 500 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr2( OperatorNode::Plus, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
 
@@ -5629,6 +5631,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 499 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Minus ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 502 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr2( OperatorNode::Minus, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
 
@@ -5636,6 +5638,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 505 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::LShift ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 508 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr2( OperatorNode::LShift, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
 
@@ -5643,6 +5645,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 507 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::RShift ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 510 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr2( OperatorNode::RShift, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
 
@@ -5650,6 +5652,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 513 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::LThan ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 516 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr2( OperatorNode::LThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
 
@@ -5657,6 +5659,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 515 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::GThan ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 518 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr2( OperatorNode::GThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
 
@@ -5664,6 +5666,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 517 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::LEThan ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 520 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr2( OperatorNode::LEThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
 
@@ -5671,6 +5673,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 519 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::GEThan ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 522 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr2( OperatorNode::GEThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
 
@@ -5678,6 +5680,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 525 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Eq ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 528 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr2( OperatorNode::Eq, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
 
@@ -5685,6 +5687,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 527 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Neq ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 530 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr2( OperatorNode::Neq, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
 
@@ -5692,6 +5694,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 533 "parser.yy"
-    { (yyval.en) =new CompositeExprNode( new OperatorNode( OperatorNode::BitAnd ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 536 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr2( OperatorNode::BitAnd, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
 
@@ -5699,6 +5701,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 539 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Xor ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 542 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr2( OperatorNode::Xor, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
 
@@ -5706,6 +5708,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 545 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::BitOr ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 548 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr2( OperatorNode::BitOr, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
 
@@ -5713,6 +5715,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 551 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::And ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 554 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_and_or( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en), true ) ); }
     break;
 
@@ -5720,6 +5722,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 557 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Or ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 560 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_and_or( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en), false ) ); }
     break;
 
@@ -5727,6 +5729,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 563 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Cond ), (ExpressionNode *)mkList( (*(yyvsp[(1) - (5)].en), *(yyvsp[(3) - (5)].en), *(yyvsp[(5) - (5)].en) ) ) ); }
+#line 567 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_cond( (yyvsp[(1) - (5)].en), (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].en) ) ); }
     break;
 
@@ -5734,6 +5736,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 565 "parser.yy"
-    { (yyval.en)=new CompositeExprNode( new OperatorNode( OperatorNode::NCond ), (yyvsp[(1) - (4)].en), (yyvsp[(4) - (4)].en) ); }
+#line 569 "parser.yy"
+    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::NCond ), (yyvsp[(1) - (4)].en), (yyvsp[(4) - (4)].en) ); }
     break;
 
@@ -5741,6 +5743,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 567 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Cond ), (ExpressionNode *)mkList( (*(yyvsp[(1) - (5)].en), *(yyvsp[(3) - (5)].en), *(yyvsp[(5) - (5)].en) ) ) ); }
+#line 571 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_cond( (yyvsp[(1) - (5)].en), (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].en) ) ); }
     break;
 
@@ -5748,6 +5750,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 578 "parser.yy"
-    { (yyval.en) =new CompositeExprNode( new OperatorNode( OperatorNode::Assign ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 582 "parser.yy"
+    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Assign ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
     break;
 
@@ -5755,6 +5757,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 580 "parser.yy"
-    { (yyval.en) =new CompositeExprNode( (yyvsp[(2) - (3)].en), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 584 "parser.yy"
+    { (yyval.en) = new CompositeExprNode( (yyvsp[(2) - (3)].en), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
     break;
 
@@ -5762,5 +5764,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 582 "parser.yy"
+#line 586 "parser.yy"
     { (yyval.en) = ( (yyvsp[(2) - (2)].en) == 0 ) ? (yyvsp[(1) - (2)].en) : new CompositeExprNode( new OperatorNode( OperatorNode::Assign ), (yyvsp[(1) - (2)].en), (yyvsp[(2) - (2)].en) ); }
     break;
@@ -5769,5 +5771,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 587 "parser.yy"
+#line 591 "parser.yy"
     { (yyval.en) = new NullExprNode; }
     break;
@@ -5776,5 +5778,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 595 "parser.yy"
+#line 599 "parser.yy"
     { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ) ); }
     break;
@@ -5783,5 +5785,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 597 "parser.yy"
+#line 601 "parser.yy"
     { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (yyvsp[(3) - (5)].en) ); }
     break;
@@ -5790,5 +5792,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 599 "parser.yy"
+#line 603 "parser.yy"
     { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)(new NullExprNode)->set_link( (yyvsp[(4) - (6)].en) ) ); }
     break;
@@ -5797,5 +5799,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 601 "parser.yy"
+#line 605 "parser.yy"
     { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)(yyvsp[(3) - (7)].en)->set_link( flattenCommas( (yyvsp[(5) - (7)].en) ) ) ); }
     break;
@@ -5804,5 +5806,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 607 "parser.yy"
+#line 611 "parser.yy"
     { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_link( (yyvsp[(3) - (3)].en) ); }
     break;
@@ -5811,5 +5813,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 611 "parser.yy"
+#line 615 "parser.yy"
     { (yyval.en) = new OperatorNode( OperatorNode::MulAssn ); }
     break;
@@ -5818,5 +5820,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 612 "parser.yy"
+#line 616 "parser.yy"
     { (yyval.en) = new OperatorNode( OperatorNode::DivAssn ); }
     break;
@@ -5825,5 +5827,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 613 "parser.yy"
+#line 617 "parser.yy"
     { (yyval.en) = new OperatorNode( OperatorNode::ModAssn ); }
     break;
@@ -5832,5 +5834,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 614 "parser.yy"
+#line 618 "parser.yy"
     { (yyval.en) = new OperatorNode( OperatorNode::PlusAssn ); }
     break;
@@ -5839,5 +5841,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 615 "parser.yy"
+#line 619 "parser.yy"
     { (yyval.en) = new OperatorNode( OperatorNode::MinusAssn ); }
     break;
@@ -5846,5 +5848,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 616 "parser.yy"
+#line 620 "parser.yy"
     { (yyval.en) = new OperatorNode( OperatorNode::LSAssn ); }
     break;
@@ -5853,5 +5855,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 617 "parser.yy"
+#line 621 "parser.yy"
     { (yyval.en) = new OperatorNode( OperatorNode::RSAssn ); }
     break;
@@ -5860,5 +5862,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 618 "parser.yy"
+#line 622 "parser.yy"
     { (yyval.en) = new OperatorNode( OperatorNode::AndAssn ); }
     break;
@@ -5867,5 +5869,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 619 "parser.yy"
+#line 623 "parser.yy"
     { (yyval.en) = new OperatorNode( OperatorNode::ERAssn ); }
     break;
@@ -5874,5 +5876,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 620 "parser.yy"
+#line 624 "parser.yy"
     { (yyval.en) = new OperatorNode( OperatorNode::OrAssn ); }
     break;
@@ -5881,6 +5883,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 626 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Comma ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 631 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_comma( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
 
@@ -5888,5 +5890,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 631 "parser.yy"
+#line 636 "parser.yy"
     { (yyval.en) = 0; }
     break;
@@ -5895,5 +5897,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 640 "parser.yy"
+#line 645 "parser.yy"
     { (yyval.sn) = (yyvsp[(1) - (1)].sn); }
     break;
@@ -5902,5 +5904,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 647 "parser.yy"
+#line 652 "parser.yy"
     {
 			Token fn; fn.str = new std::string( "^?{}" ); // location undefined
@@ -5913,5 +5915,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 657 "parser.yy"
+#line 662 "parser.yy"
     {
 			(yyval.sn) = (yyvsp[(4) - (4)].sn)->add_label( (yyvsp[(1) - (4)].tok) );
@@ -5922,5 +5924,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 664 "parser.yy"
+#line 669 "parser.yy"
     { (yyval.sn) = new CompoundStmtNode( (StatementNode *)0 ); }
     break;
@@ -5929,5 +5931,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 671 "parser.yy"
+#line 676 "parser.yy"
     { (yyval.sn) = new CompoundStmtNode( (yyvsp[(5) - (7)].sn) ); }
     break;
@@ -5936,5 +5938,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 677 "parser.yy"
+#line 682 "parser.yy"
     { if ( (yyvsp[(1) - (3)].sn) != 0 ) { (yyvsp[(1) - (3)].sn)->set_link( (yyvsp[(3) - (3)].sn) ); (yyval.sn) = (yyvsp[(1) - (3)].sn); } }
     break;
@@ -5943,5 +5945,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 682 "parser.yy"
+#line 687 "parser.yy"
     { (yyval.sn) = new StatementNode( (yyvsp[(1) - (1)].decl) ); }
     break;
@@ -5950,5 +5952,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 684 "parser.yy"
+#line 689 "parser.yy"
     {	// mark all fields in list
 			for ( DeclarationNode *iter = (yyvsp[(2) - (2)].decl); iter != NULL; iter = (DeclarationNode *)iter->get_link() )
@@ -5961,5 +5963,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 690 "parser.yy"
+#line 695 "parser.yy"
     { (yyval.sn) = new StatementNode( (yyvsp[(1) - (1)].decl) ); }
     break;
@@ -5968,5 +5970,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 697 "parser.yy"
+#line 702 "parser.yy"
     { if ( (yyvsp[(1) - (2)].sn) != 0 ) { (yyvsp[(1) - (2)].sn)->set_link( (yyvsp[(2) - (2)].sn) ); (yyval.sn) = (yyvsp[(1) - (2)].sn); } }
     break;
@@ -5975,5 +5977,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 702 "parser.yy"
+#line 707 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::Exp, (yyvsp[(1) - (2)].en), 0 ); }
     break;
@@ -5982,5 +5984,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 708 "parser.yy"
+#line 713 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::If, (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ); }
     break;
@@ -5989,5 +5991,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 710 "parser.yy"
+#line 715 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::If, (yyvsp[(3) - (7)].en), (StatementNode *)mkList((*(yyvsp[(5) - (7)].sn), *(yyvsp[(7) - (7)].sn) )) ); }
     break;
@@ -5996,5 +5998,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 712 "parser.yy"
+#line 717 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::Switch, (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ); }
     break;
@@ -6003,5 +6005,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 714 "parser.yy"
+#line 719 "parser.yy"
     {
 			StatementNode *sw = new StatementNode( StatementNode::Switch, (yyvsp[(3) - (9)].en), (yyvsp[(8) - (9)].sn) );
@@ -6009,5 +6011,6 @@
 			// *before* the transfer to the appropriate case clause by hoisting the declarations into a compound
 			// statement around the switch.  Statements after the initial declaration list can never be executed, and
-			// therefore, are removed from the grammar even though C allows it. Change also applies to choose statement.
+			// therefore, are removed from the grammar even though C allows it. The change also applies to choose
+			// statement.
 			(yyval.sn) = (yyvsp[(7) - (9)].decl) != 0 ? new CompoundStmtNode( (StatementNode *)((new StatementNode( (yyvsp[(7) - (9)].decl) ))->set_link( sw )) ) : sw;
 		}
@@ -6017,5 +6020,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 723 "parser.yy"
+#line 729 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::Switch, (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ); }
     break;
@@ -6024,5 +6027,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 725 "parser.yy"
+#line 731 "parser.yy"
     {
 			StatementNode *sw = new StatementNode( StatementNode::Switch, (yyvsp[(3) - (9)].en), (yyvsp[(8) - (9)].sn) );
@@ -6034,5 +6037,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 735 "parser.yy"
+#line 741 "parser.yy"
     { (yyval.en) = (yyvsp[(1) - (1)].en); }
     break;
@@ -6041,6 +6044,13 @@
 
 /* Line 1806 of yacc.c  */
-#line 737 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Range ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 743 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr2( OperatorNode::Range, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
+    break;
+
+  case 162:
+
+/* Line 1806 of yacc.c  */
+#line 748 "parser.yy"
+    { (yyval.sn) = new StatementNode( StatementNode::Case, (yyvsp[(1) - (1)].en), 0 ); }
     break;
 
@@ -6048,6 +6058,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 744 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)(tupleContents( (yyvsp[(1) - (3)].en) ))->set_link( (yyvsp[(3) - (3)].en) ) ); }
+#line 750 "parser.yy"
+    { (yyval.sn) = (StatementNode *)((yyvsp[(1) - (3)].sn)->set_link( new StatementNode( StatementNode::Case, (yyvsp[(3) - (3)].en), 0 ) ) ); }
     break;
 
@@ -6055,6 +6065,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 748 "parser.yy"
-    { (yyval.sn) = new StatementNode( StatementNode::Case, (yyvsp[(2) - (3)].en), 0 ); }
+#line 754 "parser.yy"
+    { (yyval.sn) = (yyvsp[(2) - (3)].sn); }
     break;
 
@@ -6062,5 +6072,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 749 "parser.yy"
+#line 755 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::Default ); }
     break;
@@ -6069,5 +6079,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 755 "parser.yy"
+#line 761 "parser.yy"
     { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (2)].sn)->set_link( (yyvsp[(2) - (2)].sn) )); }
     break;
@@ -6076,5 +6086,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 759 "parser.yy"
+#line 765 "parser.yy"
     { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new CompoundStmtNode( (yyvsp[(2) - (2)].sn) ) ); }
     break;
@@ -6083,5 +6093,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 764 "parser.yy"
+#line 770 "parser.yy"
     { (yyval.sn) = 0; }
     break;
@@ -6090,5 +6100,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 770 "parser.yy"
+#line 776 "parser.yy"
     { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new CompoundStmtNode( (yyvsp[(2) - (2)].sn) ) ); }
     break;
@@ -6097,5 +6107,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 772 "parser.yy"
+#line 778 "parser.yy"
     { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_link( (yyvsp[(2) - (3)].sn)->append_last_case( new CompoundStmtNode( (yyvsp[(3) - (3)].sn) ) ) ) ); }
     break;
@@ -6104,5 +6114,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 777 "parser.yy"
+#line 783 "parser.yy"
     { (yyval.sn) = 0; }
     break;
@@ -6111,5 +6121,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 783 "parser.yy"
+#line 789 "parser.yy"
     { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( (yyvsp[(2) - (2)].sn) ); }
     break;
@@ -6118,5 +6128,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 785 "parser.yy"
+#line 791 "parser.yy"
     { (yyval.sn) = (yyvsp[(1) - (3)].sn)->append_last_case( new CompoundStmtNode( (StatementNode *)mkList( (*(yyvsp[(2) - (3)].sn), *(yyvsp[(3) - (3)].sn) ) ) ) ); }
     break;
@@ -6125,5 +6135,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 787 "parser.yy"
+#line 793 "parser.yy"
     { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_link( (yyvsp[(2) - (3)].sn)->append_last_case( (yyvsp[(3) - (3)].sn) ))); }
     break;
@@ -6132,5 +6142,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 789 "parser.yy"
+#line 795 "parser.yy"
     { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (4)].sn)->set_link( (yyvsp[(2) - (4)].sn)->append_last_case( new CompoundStmtNode( (StatementNode *)mkList( (*(yyvsp[(3) - (4)].sn), *(yyvsp[(4) - (4)].sn) ) ) ) ) ) ); }
     break;
@@ -6139,5 +6149,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 794 "parser.yy"
+#line 800 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::Break ); }
     break;
@@ -6146,5 +6156,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 800 "parser.yy"
+#line 806 "parser.yy"
     { (yyval.sn) = 0; }
     break;
@@ -6153,5 +6163,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 802 "parser.yy"
+#line 808 "parser.yy"
     { (yyval.sn) = 0; }
     break;
@@ -6160,5 +6170,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 807 "parser.yy"
+#line 813 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::While, (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ); }
     break;
@@ -6167,5 +6177,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 809 "parser.yy"
+#line 815 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::Do, (yyvsp[(5) - (7)].en), (yyvsp[(2) - (7)].sn) ); }
     break;
@@ -6174,5 +6184,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 811 "parser.yy"
+#line 817 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::For, (yyvsp[(4) - (6)].en), (yyvsp[(6) - (6)].sn) ); }
     break;
@@ -6181,5 +6191,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 816 "parser.yy"
+#line 822 "parser.yy"
     { (yyval.en) = new ForCtlExprNode( (yyvsp[(1) - (6)].en), (yyvsp[(4) - (6)].en), (yyvsp[(6) - (6)].en) ); }
     break;
@@ -6188,5 +6198,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 818 "parser.yy"
+#line 824 "parser.yy"
     { (yyval.en) = new ForCtlExprNode( (yyvsp[(1) - (4)].decl), (yyvsp[(2) - (4)].en), (yyvsp[(4) - (4)].en) ); }
     break;
@@ -6195,5 +6205,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 823 "parser.yy"
+#line 829 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::Goto, (yyvsp[(2) - (3)].tok) ); }
     break;
@@ -6202,5 +6212,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 827 "parser.yy"
+#line 833 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::Goto, (yyvsp[(3) - (4)].en) ); }
     break;
@@ -6209,5 +6219,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 830 "parser.yy"
+#line 836 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::Continue ); }
     break;
@@ -6216,5 +6226,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 834 "parser.yy"
+#line 840 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::Continue, (yyvsp[(2) - (3)].tok) ); }
     break;
@@ -6223,5 +6233,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 837 "parser.yy"
+#line 843 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::Break ); }
     break;
@@ -6230,5 +6240,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 841 "parser.yy"
+#line 847 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::Break, (yyvsp[(2) - (3)].tok) ); }
     break;
@@ -6237,5 +6247,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 843 "parser.yy"
+#line 849 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::Return, (yyvsp[(2) - (3)].en), 0 ); }
     break;
@@ -6244,5 +6254,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 845 "parser.yy"
+#line 851 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::Throw, (yyvsp[(2) - (3)].en), 0 ); }
     break;
@@ -6251,5 +6261,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 849 "parser.yy"
+#line 855 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::Throw, (yyvsp[(2) - (3)].en), 0 ); }
     break;
@@ -6258,5 +6268,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 851 "parser.yy"
+#line 857 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::Throw, (yyvsp[(2) - (5)].en), 0 ); }
     break;
@@ -6265,5 +6275,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 858 "parser.yy"
+#line 864 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::Try, 0,(StatementNode *)(mkList((*(yyvsp[(2) - (3)].sn),*(yyvsp[(3) - (3)].pn) )))); }
     break;
@@ -6272,5 +6282,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 860 "parser.yy"
+#line 866 "parser.yy"
     { (yyval.sn) = new StatementNode( StatementNode::Try, 0,(StatementNode *)(mkList((*(yyvsp[(2) - (3)].sn),*(yyvsp[(3) - (3)].pn) )))); }
     break;
@@ -6279,5 +6289,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 862 "parser.yy"
+#line 868 "parser.yy"
     {
 			(yyvsp[(3) - (4)].pn)->set_link( (yyvsp[(4) - (4)].pn) );
@@ -6289,5 +6299,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 873 "parser.yy"
+#line 879 "parser.yy"
     { (yyval.pn) = StatementNode::newCatchStmt( 0, (yyvsp[(5) - (5)].sn), true ); }
     break;
@@ -6296,5 +6306,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 875 "parser.yy"
+#line 881 "parser.yy"
     { (yyval.pn) = (yyvsp[(1) - (6)].pn)->set_link( StatementNode::newCatchStmt( 0, (yyvsp[(6) - (6)].sn), true ) ); }
     break;
@@ -6303,5 +6313,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 877 "parser.yy"
+#line 883 "parser.yy"
     { (yyval.pn) = StatementNode::newCatchStmt( 0, (yyvsp[(5) - (5)].sn), true ); }
     break;
@@ -6310,5 +6320,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 879 "parser.yy"
+#line 885 "parser.yy"
     { (yyval.pn) = (yyvsp[(1) - (6)].pn)->set_link( StatementNode::newCatchStmt( 0, (yyvsp[(6) - (6)].sn), true ) ); }
     break;
@@ -6317,5 +6327,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 884 "parser.yy"
+#line 890 "parser.yy"
     { (yyval.pn) = StatementNode::newCatchStmt( (yyvsp[(5) - (9)].decl), (yyvsp[(8) - (9)].sn) ); }
     break;
@@ -6324,5 +6334,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 886 "parser.yy"
+#line 892 "parser.yy"
     { (yyval.pn) = (yyvsp[(1) - (10)].pn)->set_link( StatementNode::newCatchStmt( (yyvsp[(6) - (10)].decl), (yyvsp[(9) - (10)].sn) ) ); }
     break;
@@ -6331,5 +6341,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 888 "parser.yy"
+#line 894 "parser.yy"
     { (yyval.pn) = StatementNode::newCatchStmt( (yyvsp[(5) - (9)].decl), (yyvsp[(8) - (9)].sn) ); }
     break;
@@ -6338,5 +6348,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 890 "parser.yy"
+#line 896 "parser.yy"
     { (yyval.pn) = (yyvsp[(1) - (10)].pn)->set_link( StatementNode::newCatchStmt( (yyvsp[(6) - (10)].decl), (yyvsp[(9) - (10)].sn) ) ); }
     break;
@@ -6345,5 +6355,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 895 "parser.yy"
+#line 901 "parser.yy"
     {
 			(yyval.pn) = new StatementNode( StatementNode::Finally, 0, (yyvsp[(2) - (2)].sn) );
@@ -6355,5 +6365,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 909 "parser.yy"
+#line 915 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6365,5 +6375,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 914 "parser.yy"
+#line 920 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -6372,5 +6382,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 916 "parser.yy"
+#line 922 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6382,5 +6392,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 925 "parser.yy"
+#line 931 "parser.yy"
     { (yyval.sn) = new AsmStmtNode( StatementNode::Asm, (yyvsp[(2) - (6)].flag), (yyvsp[(4) - (6)].constant), 0 ); }
     break;
@@ -6389,5 +6399,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 927 "parser.yy"
+#line 933 "parser.yy"
     { (yyval.sn) = new AsmStmtNode( StatementNode::Asm, (yyvsp[(2) - (8)].flag), (yyvsp[(4) - (8)].constant), (yyvsp[(6) - (8)].en) ); }
     break;
@@ -6396,5 +6406,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 929 "parser.yy"
+#line 935 "parser.yy"
     { (yyval.sn) = new AsmStmtNode( StatementNode::Asm, (yyvsp[(2) - (10)].flag), (yyvsp[(4) - (10)].constant), (yyvsp[(6) - (10)].en), (yyvsp[(8) - (10)].en) ); }
     break;
@@ -6403,5 +6413,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 931 "parser.yy"
+#line 937 "parser.yy"
     { (yyval.sn) = new AsmStmtNode( StatementNode::Asm, (yyvsp[(2) - (12)].flag), (yyvsp[(4) - (12)].constant), (yyvsp[(6) - (12)].en), (yyvsp[(8) - (12)].en), (yyvsp[(10) - (12)].constant) ); }
     break;
@@ -6410,5 +6420,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 933 "parser.yy"
+#line 939 "parser.yy"
     { (yyval.sn) = new AsmStmtNode( StatementNode::Asm, (yyvsp[(2) - (14)].flag), (yyvsp[(5) - (14)].constant), 0, (yyvsp[(8) - (14)].en), (yyvsp[(10) - (14)].constant), (yyvsp[(12) - (14)].label) ); }
     break;
@@ -6417,5 +6427,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 938 "parser.yy"
+#line 944 "parser.yy"
     { (yyval.flag) = false; }
     break;
@@ -6424,5 +6434,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 940 "parser.yy"
+#line 946 "parser.yy"
     { (yyval.flag) = true; }
     break;
@@ -6431,5 +6441,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 945 "parser.yy"
+#line 951 "parser.yy"
     { (yyval.en) = 0; }
     break;
@@ -6438,5 +6448,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 952 "parser.yy"
+#line 958 "parser.yy"
     { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_link( (yyvsp[(3) - (3)].en) ); }
     break;
@@ -6445,5 +6455,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 957 "parser.yy"
+#line 963 "parser.yy"
     { (yyval.en) = new AsmExprNode( 0, (yyvsp[(1) - (4)].constant), (yyvsp[(3) - (4)].en) ); }
     break;
@@ -6452,5 +6462,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 959 "parser.yy"
+#line 965 "parser.yy"
     { (yyval.en) = new AsmExprNode( (yyvsp[(2) - (7)].en), (yyvsp[(4) - (7)].constant), (yyvsp[(6) - (7)].en) ); }
     break;
@@ -6459,5 +6469,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 964 "parser.yy"
+#line 970 "parser.yy"
     { (yyval.constant) = 0; }
     break;
@@ -6466,5 +6476,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 966 "parser.yy"
+#line 972 "parser.yy"
     { (yyval.constant) = (yyvsp[(1) - (1)].constant); }
     break;
@@ -6473,5 +6483,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 968 "parser.yy"
+#line 974 "parser.yy"
     { (yyval.constant) = (ConstantNode *)(yyvsp[(1) - (3)].constant)->set_link( (yyvsp[(3) - (3)].constant) ); }
     break;
@@ -6480,5 +6490,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 973 "parser.yy"
+#line 979 "parser.yy"
     { (yyval.label) = new LabelNode(); (yyval.label)->append_label( (yyvsp[(1) - (1)].tok) ); }
     break;
@@ -6487,5 +6497,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 975 "parser.yy"
+#line 981 "parser.yy"
     { (yyval.label) = (yyvsp[(1) - (3)].label); (yyvsp[(1) - (3)].label)->append_label( (yyvsp[(3) - (3)].tok) ); }
     break;
@@ -6494,5 +6504,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 982 "parser.yy"
+#line 988 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -6501,5 +6511,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 989 "parser.yy"
+#line 995 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -6508,5 +6518,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 994 "parser.yy"
+#line 1000 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -6515,5 +6525,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1001 "parser.yy"
+#line 1007 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -6522,5 +6532,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1015 "parser.yy"
+#line 1021 "parser.yy"
     {}
     break;
@@ -6529,5 +6539,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1016 "parser.yy"
+#line 1022 "parser.yy"
     {}
     break;
@@ -6536,5 +6546,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1045 "parser.yy"
+#line 1051 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6546,5 +6556,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1052 "parser.yy"
+#line 1058 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6556,5 +6566,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1057 "parser.yy"
+#line 1063 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(5) - (6)].tok), TypedefTable::ID );
@@ -6566,5 +6576,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1067 "parser.yy"
+#line 1073 "parser.yy"
     {
 			typedefTable.setNextIdentifier( *(yyvsp[(2) - (3)].tok) );
@@ -6576,5 +6586,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1072 "parser.yy"
+#line 1078 "parser.yy"
     {
 			typedefTable.setNextIdentifier( *(yyvsp[(2) - (3)].tok) );
@@ -6586,5 +6596,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1077 "parser.yy"
+#line 1083 "parser.yy"
     {
 			typedefTable.setNextIdentifier( *(yyvsp[(3) - (4)].tok) );
@@ -6596,5 +6606,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1085 "parser.yy"
+#line 1091 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6606,5 +6616,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1090 "parser.yy"
+#line 1096 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6616,5 +6626,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1095 "parser.yy"
+#line 1101 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6626,5 +6636,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1100 "parser.yy"
+#line 1106 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6636,5 +6646,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1105 "parser.yy"
+#line 1111 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(5) - (5)].tok), TypedefTable::ID );
@@ -6646,5 +6656,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1113 "parser.yy"
+#line 1119 "parser.yy"
     {
 			(yyval.decl) = DeclarationNode::newFunction( (yyvsp[(3) - (8)].tok), DeclarationNode::newTuple( 0 ), (yyvsp[(6) - (8)].decl), 0, true );
@@ -6655,5 +6665,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1136 "parser.yy"
+#line 1142 "parser.yy"
     {
 			(yyval.decl) = DeclarationNode::newFunction( (yyvsp[(2) - (7)].tok), (yyvsp[(1) - (7)].decl), (yyvsp[(5) - (7)].decl), 0, true );
@@ -6664,5 +6674,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1140 "parser.yy"
+#line 1146 "parser.yy"
     {
 			(yyval.decl) = DeclarationNode::newFunction( (yyvsp[(2) - (7)].tok), (yyvsp[(1) - (7)].decl), (yyvsp[(5) - (7)].decl), 0, true );
@@ -6673,5 +6683,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1147 "parser.yy"
+#line 1153 "parser.yy"
     { (yyval.decl) = DeclarationNode::newTuple( (yyvsp[(3) - (5)].decl) ); }
     break;
@@ -6680,5 +6690,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1151 "parser.yy"
+#line 1157 "parser.yy"
     { (yyval.decl) = DeclarationNode::newTuple( (yyvsp[(3) - (9)].decl)->appendList( (yyvsp[(7) - (9)].decl) ) ); }
     break;
@@ -6687,5 +6697,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1156 "parser.yy"
+#line 1162 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::TD );
@@ -6697,5 +6707,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1161 "parser.yy"
+#line 1167 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::TD );
@@ -6707,5 +6717,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1166 "parser.yy"
+#line 1172 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(5) - (5)].tok), TypedefTable::TD );
@@ -6717,5 +6727,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1177 "parser.yy"
+#line 1183 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::TD );
@@ -6727,5 +6737,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1182 "parser.yy"
+#line 1188 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::TD );
@@ -6737,5 +6747,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1187 "parser.yy"
+#line 1193 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::TD );
@@ -6747,5 +6757,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1192 "parser.yy"
+#line 1198 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::TD );
@@ -6757,5 +6767,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1197 "parser.yy"
+#line 1203 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::TD );
@@ -6767,5 +6777,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1206 "parser.yy"
+#line 1212 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(2) - (4)].tok), TypedefTable::TD );
@@ -6777,5 +6787,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1211 "parser.yy"
+#line 1217 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(5) - (7)].tok), TypedefTable::TD );
@@ -6787,5 +6797,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1228 "parser.yy"
+#line 1234 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6797,5 +6807,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1233 "parser.yy"
+#line 1239 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6807,5 +6817,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1255 "parser.yy"
+#line 1261 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -6814,5 +6824,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1267 "parser.yy"
+#line 1273 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6821,5 +6831,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1278 "parser.yy"
+#line 1284 "parser.yy"
     { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Const ); }
     break;
@@ -6828,5 +6838,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1280 "parser.yy"
+#line 1286 "parser.yy"
     { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Restrict ); }
     break;
@@ -6835,5 +6845,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1282 "parser.yy"
+#line 1288 "parser.yy"
     { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Volatile ); }
     break;
@@ -6842,5 +6852,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1284 "parser.yy"
+#line 1290 "parser.yy"
     { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Lvalue ); }
     break;
@@ -6849,5 +6859,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1286 "parser.yy"
+#line 1292 "parser.yy"
     { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Atomic ); }
     break;
@@ -6856,5 +6866,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1288 "parser.yy"
+#line 1294 "parser.yy"
     {
 			typedefTable.enterScope();
@@ -6865,5 +6875,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1292 "parser.yy"
+#line 1298 "parser.yy"
     {
 			typedefTable.leaveScope();
@@ -6875,5 +6885,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1301 "parser.yy"
+#line 1307 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6882,5 +6892,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1303 "parser.yy"
+#line 1309 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -6889,5 +6899,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1314 "parser.yy"
+#line 1320 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6896,5 +6906,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1323 "parser.yy"
+#line 1329 "parser.yy"
     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Extern ); }
     break;
@@ -6903,5 +6913,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1325 "parser.yy"
+#line 1331 "parser.yy"
     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Static ); }
     break;
@@ -6910,5 +6920,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1327 "parser.yy"
+#line 1333 "parser.yy"
     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Auto ); }
     break;
@@ -6917,5 +6927,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1329 "parser.yy"
+#line 1335 "parser.yy"
     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Register ); }
     break;
@@ -6924,5 +6934,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1331 "parser.yy"
+#line 1337 "parser.yy"
     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Inline ); }
     break;
@@ -6931,5 +6941,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1333 "parser.yy"
+#line 1339 "parser.yy"
     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Fortran ); }
     break;
@@ -6938,5 +6948,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1335 "parser.yy"
+#line 1341 "parser.yy"
     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Noreturn ); }
     break;
@@ -6945,5 +6955,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1337 "parser.yy"
+#line 1343 "parser.yy"
     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Threadlocal ); }
     break;
@@ -6952,5 +6962,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1342 "parser.yy"
+#line 1348 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Char ); }
     break;
@@ -6959,5 +6969,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1344 "parser.yy"
+#line 1350 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Double ); }
     break;
@@ -6966,5 +6976,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1346 "parser.yy"
+#line 1352 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Float ); }
     break;
@@ -6973,5 +6983,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1348 "parser.yy"
+#line 1354 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Int ); }
     break;
@@ -6980,5 +6990,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1350 "parser.yy"
+#line 1356 "parser.yy"
     { (yyval.decl) = DeclarationNode::newModifier( DeclarationNode::Long ); }
     break;
@@ -6987,5 +6997,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1352 "parser.yy"
+#line 1358 "parser.yy"
     { (yyval.decl) = DeclarationNode::newModifier( DeclarationNode::Short ); }
     break;
@@ -6994,5 +7004,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1354 "parser.yy"
+#line 1360 "parser.yy"
     { (yyval.decl) = DeclarationNode::newModifier( DeclarationNode::Signed ); }
     break;
@@ -7001,5 +7011,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1356 "parser.yy"
+#line 1362 "parser.yy"
     { (yyval.decl) = DeclarationNode::newModifier( DeclarationNode::Unsigned ); }
     break;
@@ -7008,5 +7018,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1358 "parser.yy"
+#line 1364 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Void ); }
     break;
@@ -7015,5 +7025,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1360 "parser.yy"
+#line 1366 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Bool ); }
     break;
@@ -7022,5 +7032,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1362 "parser.yy"
+#line 1368 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Complex ); }
     break;
@@ -7029,5 +7039,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1364 "parser.yy"
+#line 1370 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Imaginary ); }
     break;
@@ -7036,5 +7046,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1366 "parser.yy"
+#line 1372 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBuiltinType( DeclarationNode::Valist ); }
     break;
@@ -7043,5 +7053,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1373 "parser.yy"
+#line 1379 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7050,5 +7060,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1375 "parser.yy"
+#line 1381 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -7057,5 +7067,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1377 "parser.yy"
+#line 1383 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -7064,5 +7074,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1379 "parser.yy"
+#line 1385 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addType( (yyvsp[(1) - (3)].decl) ); }
     break;
@@ -7071,5 +7081,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1385 "parser.yy"
+#line 1391 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl)->addQualifiers( (yyvsp[(1) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -7078,5 +7088,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1392 "parser.yy"
+#line 1398 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7085,5 +7095,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1394 "parser.yy"
+#line 1400 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -7092,5 +7102,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1396 "parser.yy"
+#line 1402 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addType( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -7099,5 +7109,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1401 "parser.yy"
+#line 1407 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (4)].decl); }
     break;
@@ -7106,5 +7116,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1403 "parser.yy"
+#line 1409 "parser.yy"
     { (yyval.decl) = DeclarationNode::newTypeof( (yyvsp[(3) - (4)].en) ); }
     break;
@@ -7113,5 +7123,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1405 "parser.yy"
+#line 1411 "parser.yy"
     { (yyval.decl) = DeclarationNode::newAttr( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].decl) ); }
     break;
@@ -7120,5 +7130,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1407 "parser.yy"
+#line 1413 "parser.yy"
     { (yyval.decl) = DeclarationNode::newAttr( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].en) ); }
     break;
@@ -7127,5 +7137,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1413 "parser.yy"
+#line 1419 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7134,5 +7144,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1415 "parser.yy"
+#line 1421 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -7141,5 +7151,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1417 "parser.yy"
+#line 1423 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -7148,5 +7158,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1423 "parser.yy"
+#line 1429 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7155,5 +7165,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1425 "parser.yy"
+#line 1431 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -7162,5 +7172,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1431 "parser.yy"
+#line 1437 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7169,5 +7179,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1433 "parser.yy"
+#line 1439 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -7176,5 +7186,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1435 "parser.yy"
+#line 1441 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -7183,5 +7193,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1440 "parser.yy"
+#line 1446 "parser.yy"
     { (yyval.decl) = DeclarationNode::newFromTypedef( (yyvsp[(1) - (1)].tok) ); }
     break;
@@ -7190,5 +7200,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1442 "parser.yy"
+#line 1448 "parser.yy"
     { (yyval.decl) = DeclarationNode::newFromTypedef( (yyvsp[(2) - (2)].tok) )->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7197,5 +7207,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1444 "parser.yy"
+#line 1450 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -7204,5 +7214,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1454 "parser.yy"
+#line 1460 "parser.yy"
     { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (4)].aggKey), 0, 0, (yyvsp[(3) - (4)].decl), true ); }
     break;
@@ -7211,5 +7221,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1456 "parser.yy"
+#line 1462 "parser.yy"
     {
 			typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) );
@@ -7221,5 +7231,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1461 "parser.yy"
+#line 1467 "parser.yy"
     { typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) ); }
     break;
@@ -7228,5 +7238,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1463 "parser.yy"
+#line 1469 "parser.yy"
     { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (6)].aggKey), (yyvsp[(2) - (6)].tok), 0, (yyvsp[(5) - (6)].decl), true ); }
     break;
@@ -7235,5 +7245,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1465 "parser.yy"
+#line 1471 "parser.yy"
     { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (7)].aggKey), 0, (yyvsp[(3) - (7)].en), (yyvsp[(6) - (7)].decl), false ); }
     break;
@@ -7242,5 +7252,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1467 "parser.yy"
+#line 1473 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl); }
     break;
@@ -7249,5 +7259,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1472 "parser.yy"
+#line 1478 "parser.yy"
     { (yyval.aggKey) = DeclarationNode::Struct; }
     break;
@@ -7256,5 +7266,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1474 "parser.yy"
+#line 1480 "parser.yy"
     { (yyval.aggKey) = DeclarationNode::Union; }
     break;
@@ -7263,5 +7273,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1479 "parser.yy"
+#line 1485 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -7270,5 +7280,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1481 "parser.yy"
+#line 1487 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl) != 0 ? (yyvsp[(1) - (2)].decl)->appendList( (yyvsp[(2) - (2)].decl) ) : (yyvsp[(2) - (2)].decl); }
     break;
@@ -7277,5 +7287,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1487 "parser.yy"
+#line 1493 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl)->set_extension( true ); }
     break;
@@ -7284,5 +7294,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1490 "parser.yy"
+#line 1496 "parser.yy"
     {	// mark all fields in list
 			for ( DeclarationNode *iter = (yyvsp[(2) - (3)].decl); iter != NULL; iter = (DeclarationNode *)iter->get_link() )
@@ -7295,5 +7305,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1500 "parser.yy"
+#line 1506 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addName( (yyvsp[(2) - (2)].tok) ); }
     break;
@@ -7302,5 +7312,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1502 "parser.yy"
+#line 1508 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(1) - (3)].decl)->cloneType( (yyvsp[(3) - (3)].tok) ) ); }
     break;
@@ -7309,5 +7319,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1504 "parser.yy"
+#line 1510 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->appendList( (yyvsp[(1) - (2)].decl)->cloneType( 0 ) ); }
     break;
@@ -7316,5 +7326,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1509 "parser.yy"
+#line 1515 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7323,5 +7333,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1511 "parser.yy"
+#line 1517 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (4)].decl)->appendList( (yyvsp[(1) - (4)].decl)->cloneBaseType( (yyvsp[(4) - (4)].decl) ) ); }
     break;
@@ -7330,5 +7340,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1516 "parser.yy"
+#line 1522 "parser.yy"
     { (yyval.decl) = DeclarationNode::newName( 0 ); /* XXX */ }
     break;
@@ -7337,5 +7347,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1518 "parser.yy"
+#line 1524 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBitfield( (yyvsp[(1) - (1)].en) ); }
     break;
@@ -7344,5 +7354,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1521 "parser.yy"
+#line 1527 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addBitfield( (yyvsp[(2) - (2)].en) ); }
     break;
@@ -7351,5 +7361,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1524 "parser.yy"
+#line 1530 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addBitfield( (yyvsp[(2) - (2)].en) ); }
     break;
@@ -7358,5 +7368,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1530 "parser.yy"
+#line 1536 "parser.yy"
     { (yyval.en) = 0; }
     break;
@@ -7365,5 +7375,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1532 "parser.yy"
+#line 1538 "parser.yy"
     { (yyval.en) = (yyvsp[(1) - (1)].en); }
     break;
@@ -7372,5 +7382,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1537 "parser.yy"
+#line 1543 "parser.yy"
     { (yyval.en) = (yyvsp[(2) - (2)].en); }
     break;
@@ -7379,5 +7389,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1546 "parser.yy"
+#line 1552 "parser.yy"
     { (yyval.decl) = DeclarationNode::newEnum( 0, (yyvsp[(3) - (5)].decl) ); }
     break;
@@ -7386,5 +7396,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1548 "parser.yy"
+#line 1554 "parser.yy"
     {
 			typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) );
@@ -7396,5 +7406,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1553 "parser.yy"
+#line 1559 "parser.yy"
     { typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) ); }
     break;
@@ -7403,5 +7413,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1555 "parser.yy"
+#line 1561 "parser.yy"
     { (yyval.decl) = DeclarationNode::newEnum( (yyvsp[(2) - (7)].tok), (yyvsp[(5) - (7)].decl) ); }
     break;
@@ -7410,5 +7420,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1560 "parser.yy"
+#line 1566 "parser.yy"
     { (yyval.decl) = DeclarationNode::newEnumConstant( (yyvsp[(1) - (2)].tok), (yyvsp[(2) - (2)].en) ); }
     break;
@@ -7417,5 +7427,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1562 "parser.yy"
+#line 1568 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (4)].decl)->appendList( DeclarationNode::newEnumConstant( (yyvsp[(3) - (4)].tok), (yyvsp[(4) - (4)].en) ) ); }
     break;
@@ -7424,5 +7434,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1567 "parser.yy"
+#line 1573 "parser.yy"
     { (yyval.en) = 0; }
     break;
@@ -7431,5 +7441,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1569 "parser.yy"
+#line 1575 "parser.yy"
     { (yyval.en) = (yyvsp[(2) - (2)].en); }
     break;
@@ -7438,5 +7448,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1576 "parser.yy"
+#line 1582 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -7445,5 +7455,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1584 "parser.yy"
+#line 1590 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
     break;
@@ -7452,5 +7462,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1586 "parser.yy"
+#line 1592 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (5)].decl)->addVarArgs(); }
     break;
@@ -7459,5 +7469,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1588 "parser.yy"
+#line 1594 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (5)].decl)->addVarArgs(); }
     break;
@@ -7466,5 +7476,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1596 "parser.yy"
+#line 1602 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
     break;
@@ -7473,5 +7483,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1598 "parser.yy"
+#line 1604 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
     break;
@@ -7480,5 +7490,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1600 "parser.yy"
+#line 1606 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (9)].decl)->appendList( (yyvsp[(5) - (9)].decl) )->appendList( (yyvsp[(9) - (9)].decl) ); }
     break;
@@ -7487,5 +7497,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1606 "parser.yy"
+#line 1612 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
     break;
@@ -7494,5 +7504,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1611 "parser.yy"
+#line 1617 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -7501,5 +7511,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1618 "parser.yy"
+#line 1624 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (5)].decl)->addVarArgs(); }
     break;
@@ -7508,5 +7518,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1625 "parser.yy"
+#line 1631 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
     break;
@@ -7515,5 +7525,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1627 "parser.yy"
+#line 1633 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
     break;
@@ -7522,5 +7532,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1636 "parser.yy"
+#line 1642 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addName( (yyvsp[(2) - (3)].tok) ); }
     break;
@@ -7529,5 +7539,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1639 "parser.yy"
+#line 1645 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addName( (yyvsp[(2) - (3)].tok) ); }
     break;
@@ -7536,5 +7546,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1641 "parser.yy"
+#line 1647 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addName( (yyvsp[(3) - (4)].tok) )->addQualifiers( (yyvsp[(1) - (4)].decl) ); }
     break;
@@ -7543,5 +7553,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1651 "parser.yy"
+#line 1657 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7550,5 +7560,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1657 "parser.yy"
+#line 1663 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7560,5 +7570,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1662 "parser.yy"
+#line 1668 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7570,5 +7580,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1671 "parser.yy"
+#line 1677 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7577,5 +7587,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1680 "parser.yy"
+#line 1686 "parser.yy"
     { (yyval.decl) = DeclarationNode::newName( (yyvsp[(1) - (1)].tok) ); }
     break;
@@ -7584,5 +7594,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1682 "parser.yy"
+#line 1688 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( DeclarationNode::newName( (yyvsp[(3) - (3)].tok) ) ); }
     break;
@@ -7591,5 +7601,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1707 "parser.yy"
+#line 1713 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7598,5 +7608,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1715 "parser.yy"
+#line 1721 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7605,5 +7615,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1720 "parser.yy"
+#line 1726 "parser.yy"
     { (yyval.in) = 0; }
     break;
@@ -7612,5 +7622,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1722 "parser.yy"
+#line 1728 "parser.yy"
     { (yyval.in) = (yyvsp[(2) - (2)].in); }
     break;
@@ -7619,5 +7629,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1724 "parser.yy"
+#line 1730 "parser.yy"
     { (yyval.in) = (yyvsp[(2) - (2)].in)->set_maybeConstructed( false ); }
     break;
@@ -7626,5 +7636,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1728 "parser.yy"
+#line 1734 "parser.yy"
     { (yyval.in) = new InitializerNode( (yyvsp[(1) - (1)].en) ); }
     break;
@@ -7633,5 +7643,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1729 "parser.yy"
+#line 1735 "parser.yy"
     { (yyval.in) = new InitializerNode( (yyvsp[(2) - (4)].in), true ); }
     break;
@@ -7640,5 +7650,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1734 "parser.yy"
+#line 1740 "parser.yy"
     { (yyval.in) = 0; }
     break;
@@ -7647,5 +7657,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1736 "parser.yy"
+#line 1742 "parser.yy"
     { (yyval.in) = (yyvsp[(2) - (2)].in)->set_designators( (yyvsp[(1) - (2)].en) ); }
     break;
@@ -7654,5 +7664,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1737 "parser.yy"
+#line 1743 "parser.yy"
     { (yyval.in) = (InitializerNode *)( (yyvsp[(1) - (3)].in)->set_link( (yyvsp[(3) - (3)].in) ) ); }
     break;
@@ -7661,5 +7671,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1739 "parser.yy"
+#line 1745 "parser.yy"
     { (yyval.in) = (InitializerNode *)( (yyvsp[(1) - (4)].in)->set_link( (yyvsp[(4) - (4)].in)->set_designators( (yyvsp[(3) - (4)].en) ) ) ); }
     break;
@@ -7668,5 +7678,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1755 "parser.yy"
+#line 1761 "parser.yy"
     { (yyval.en) = new VarRefNode( (yyvsp[(1) - (2)].tok) ); }
     break;
@@ -7675,5 +7685,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1761 "parser.yy"
+#line 1767 "parser.yy"
     { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (2)].en)->set_link( (yyvsp[(2) - (2)].en) )); }
     break;
@@ -7682,5 +7692,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1769 "parser.yy"
+#line 1775 "parser.yy"
     { (yyval.en) = new DesignatorNode( new VarRefNode( (yyvsp[(1) - (1)].tok) ) ); }
     break;
@@ -7689,5 +7699,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1771 "parser.yy"
+#line 1777 "parser.yy"
     { (yyval.en) = new DesignatorNode( new VarRefNode( (yyvsp[(2) - (2)].tok) ) ); }
     break;
@@ -7696,5 +7706,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1774 "parser.yy"
+#line 1780 "parser.yy"
     { (yyval.en) = new DesignatorNode( (yyvsp[(3) - (5)].en), true ); }
     break;
@@ -7703,5 +7713,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1776 "parser.yy"
+#line 1782 "parser.yy"
     { (yyval.en) = new DesignatorNode( (yyvsp[(3) - (5)].en), true ); }
     break;
@@ -7710,6 +7720,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 1778 "parser.yy"
-    { (yyval.en) = new DesignatorNode( new CompositeExprNode( new OperatorNode( OperatorNode::Range ), (yyvsp[(3) - (7)].en), (yyvsp[(5) - (7)].en) ), true ); }
+#line 1784 "parser.yy"
+    { (yyval.en) = new DesignatorNode( new CompositeExprNode2( build_opr2( OperatorNode::Range, (yyvsp[(3) - (7)].en), (yyvsp[(5) - (7)].en) ) ), true ); }
     break;
 
@@ -7717,5 +7727,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1780 "parser.yy"
+#line 1786 "parser.yy"
     { (yyval.en) = new DesignatorNode( (yyvsp[(4) - (6)].en) ); }
     break;
@@ -7724,5 +7734,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1804 "parser.yy"
+#line 1810 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7731,5 +7741,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1806 "parser.yy"
+#line 1812 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -7738,5 +7748,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1808 "parser.yy"
+#line 1814 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -7745,5 +7755,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1814 "parser.yy"
+#line 1820 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7752,5 +7762,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1816 "parser.yy"
+#line 1822 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -7759,5 +7769,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1821 "parser.yy"
+#line 1827 "parser.yy"
     { (yyval.decl) = DeclarationNode::newFromTypeGen( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].en) ); }
     break;
@@ -7766,5 +7776,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1827 "parser.yy"
+#line 1833 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (4)].decl)->appendList( (yyvsp[(3) - (4)].decl) ); }
     break;
@@ -7773,5 +7783,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1832 "parser.yy"
+#line 1838 "parser.yy"
     { typedefTable.addToEnclosingScope( *(yyvsp[(2) - (2)].tok), TypedefTable::TD ); }
     break;
@@ -7780,5 +7790,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1834 "parser.yy"
+#line 1840 "parser.yy"
     { (yyval.decl) = DeclarationNode::newTypeParam( (yyvsp[(1) - (4)].tclass), (yyvsp[(2) - (4)].tok) )->addAssertions( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -7787,5 +7797,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1840 "parser.yy"
+#line 1846 "parser.yy"
     { (yyval.tclass) = DeclarationNode::Type; }
     break;
@@ -7794,5 +7804,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1842 "parser.yy"
+#line 1848 "parser.yy"
     { (yyval.tclass) = DeclarationNode::Ftype; }
     break;
@@ -7801,5 +7811,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1844 "parser.yy"
+#line 1850 "parser.yy"
     { (yyval.tclass) = DeclarationNode::Dtype; }
     break;
@@ -7808,5 +7818,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1849 "parser.yy"
+#line 1855 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -7815,5 +7825,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1851 "parser.yy"
+#line 1857 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl) != 0 ? (yyvsp[(1) - (2)].decl)->appendList( (yyvsp[(2) - (2)].decl) ) : (yyvsp[(2) - (2)].decl); }
     break;
@@ -7822,5 +7832,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1856 "parser.yy"
+#line 1862 "parser.yy"
     {
 			typedefTable.openTrait( *(yyvsp[(2) - (5)].tok) );
@@ -7832,5 +7842,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1861 "parser.yy"
+#line 1867 "parser.yy"
     { (yyval.decl) = (yyvsp[(4) - (5)].decl); }
     break;
@@ -7839,5 +7849,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1863 "parser.yy"
+#line 1869 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -7846,5 +7856,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1868 "parser.yy"
+#line 1874 "parser.yy"
     { (yyval.en) = new TypeValueNode( (yyvsp[(1) - (1)].decl) ); }
     break;
@@ -7853,5 +7863,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1871 "parser.yy"
+#line 1877 "parser.yy"
     { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (3)].en)->set_link( new TypeValueNode( (yyvsp[(3) - (3)].decl) ))); }
     break;
@@ -7860,5 +7870,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1873 "parser.yy"
+#line 1879 "parser.yy"
     { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (3)].en)->set_link( (yyvsp[(3) - (3)].en) )); }
     break;
@@ -7867,5 +7877,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1878 "parser.yy"
+#line 1884 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl); }
     break;
@@ -7874,5 +7884,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1880 "parser.yy"
+#line 1886 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addQualifiers( (yyvsp[(1) - (3)].decl) ); }
     break;
@@ -7881,5 +7891,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1882 "parser.yy"
+#line 1888 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl)->copyStorageClasses( (yyvsp[(1) - (3)].decl) ) ); }
     break;
@@ -7888,5 +7898,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1887 "parser.yy"
+#line 1893 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addAssertions( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -7895,5 +7905,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1889 "parser.yy"
+#line 1895 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (4)].decl)->addAssertions( (yyvsp[(2) - (4)].decl) )->addType( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -7902,5 +7912,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1894 "parser.yy"
+#line 1900 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(1) - (1)].tok), TypedefTable::TD );
@@ -7912,5 +7922,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1899 "parser.yy"
+#line 1905 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(1) - (6)].tok), TypedefTable::TG );
@@ -7922,5 +7932,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1907 "parser.yy"
+#line 1913 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(2) - (9)].tok), TypedefTable::ID );
@@ -7932,5 +7942,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1912 "parser.yy"
+#line 1918 "parser.yy"
     {
 			typedefTable.enterTrait( *(yyvsp[(2) - (8)].tok) );
@@ -7942,5 +7952,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1917 "parser.yy"
+#line 1923 "parser.yy"
     {
 			typedefTable.leaveTrait();
@@ -7953,5 +7963,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1927 "parser.yy"
+#line 1933 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -7960,5 +7970,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1937 "parser.yy"
+#line 1943 "parser.yy"
     {
 			typedefTable.addToEnclosingScope2( TypedefTable::ID );
@@ -7970,5 +7980,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1942 "parser.yy"
+#line 1948 "parser.yy"
     {
 			typedefTable.addToEnclosingScope2( TypedefTable::ID );
@@ -7980,5 +7990,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1947 "parser.yy"
+#line 1953 "parser.yy"
     {
 			typedefTable.addToEnclosingScope2( *(yyvsp[(5) - (5)].tok), TypedefTable::ID );
@@ -7990,5 +8000,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1955 "parser.yy"
+#line 1961 "parser.yy"
     {
 			typedefTable.addToEnclosingScope2( TypedefTable::ID );
@@ -8000,5 +8010,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1960 "parser.yy"
+#line 1966 "parser.yy"
     {
 			typedefTable.addToEnclosingScope2( TypedefTable::ID );
@@ -8010,5 +8020,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1970 "parser.yy"
+#line 1976 "parser.yy"
     {}
     break;
@@ -8017,5 +8027,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1972 "parser.yy"
+#line 1978 "parser.yy"
     {
 			if ( theTree ) {
@@ -8030,5 +8040,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1984 "parser.yy"
+#line 1990 "parser.yy"
     { (yyval.decl) = ( (yyvsp[(1) - (3)].decl) != NULL ) ? (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ) : (yyvsp[(3) - (3)].decl); }
     break;
@@ -8037,5 +8047,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1989 "parser.yy"
+#line 1995 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -8044,5 +8054,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1997 "parser.yy"
+#line 2003 "parser.yy"
     {}
     break;
@@ -8051,5 +8061,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1999 "parser.yy"
+#line 2005 "parser.yy"
     {
 			linkageStack.push( linkage );
@@ -8061,5 +8071,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2004 "parser.yy"
+#line 2010 "parser.yy"
     {
 			linkage = linkageStack.top();
@@ -8072,5 +8082,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2010 "parser.yy"
+#line 2016 "parser.yy"
     {	// mark all fields in list
 			for ( DeclarationNode *iter = (yyvsp[(2) - (2)].decl); iter != NULL; iter = (DeclarationNode *)iter->get_link() )
@@ -8083,5 +8093,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2025 "parser.yy"
+#line 2031 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -8094,5 +8104,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2031 "parser.yy"
+#line 2037 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -8105,5 +8115,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2040 "parser.yy"
+#line 2046 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -8116,5 +8126,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2046 "parser.yy"
+#line 2052 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -8125,15 +8135,4 @@
 
   case 537:
-
-/* Line 1806 of yacc.c  */
-#line 2052 "parser.yy"
-    {
-			typedefTable.addToEnclosingScope( TypedefTable::ID );
-			typedefTable.leaveScope();
-			(yyval.decl) = (yyvsp[(2) - (3)].decl)->addFunctionBody( (yyvsp[(3) - (3)].sn) )->addQualifiers( (yyvsp[(1) - (3)].decl) );
-		}
-    break;
-
-  case 538:
 
 /* Line 1806 of yacc.c  */
@@ -8146,8 +8145,19 @@
     break;
 
+  case 538:
+
+/* Line 1806 of yacc.c  */
+#line 2064 "parser.yy"
+    {
+			typedefTable.addToEnclosingScope( TypedefTable::ID );
+			typedefTable.leaveScope();
+			(yyval.decl) = (yyvsp[(2) - (3)].decl)->addFunctionBody( (yyvsp[(3) - (3)].sn) )->addQualifiers( (yyvsp[(1) - (3)].decl) );
+		}
+    break;
+
   case 539:
 
 /* Line 1806 of yacc.c  */
-#line 2064 "parser.yy"
+#line 2070 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -8160,5 +8170,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2072 "parser.yy"
+#line 2078 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -8171,5 +8181,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2078 "parser.yy"
+#line 2084 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -8182,5 +8192,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2086 "parser.yy"
+#line 2092 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -8193,5 +8203,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2092 "parser.yy"
+#line 2098 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -8204,6 +8214,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 2107 "parser.yy"
-    { (yyval.en) = new CompositeExprNode( new OperatorNode( OperatorNode::Range ), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ); }
+#line 2113 "parser.yy"
+    { (yyval.en) = new CompositeExprNode2( build_opr2( OperatorNode::Range, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
 
@@ -8211,5 +8221,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2117 "parser.yy"
+#line 2123 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -8218,5 +8228,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2124 "parser.yy"
+#line 2130 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -8225,5 +8235,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2130 "parser.yy"
+#line 2136 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -8232,5 +8242,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2145 "parser.yy"
+#line 2151 "parser.yy"
     {}
     break;
@@ -8239,5 +8249,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2146 "parser.yy"
+#line 2152 "parser.yy"
     {}
     break;
@@ -8246,5 +8256,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2147 "parser.yy"
+#line 2153 "parser.yy"
     {}
     break;
@@ -8253,5 +8263,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2148 "parser.yy"
+#line 2154 "parser.yy"
     {}
     break;
@@ -8260,5 +8270,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2183 "parser.yy"
+#line 2189 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8267,5 +8277,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2186 "parser.yy"
+#line 2192 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8274,5 +8284,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2188 "parser.yy"
+#line 2194 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8281,5 +8291,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2193 "parser.yy"
+#line 2199 "parser.yy"
     {
 			typedefTable.setNextIdentifier( *(yyvsp[(1) - (1)].tok) );
@@ -8291,5 +8301,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2198 "parser.yy"
+#line 2204 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8298,5 +8308,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2203 "parser.yy"
+#line 2209 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8305,5 +8315,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2205 "parser.yy"
+#line 2211 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8312,5 +8322,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2207 "parser.yy"
+#line 2213 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8319,5 +8329,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2212 "parser.yy"
+#line 2218 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8326,5 +8336,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2214 "parser.yy"
+#line 2220 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -8333,5 +8343,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2216 "parser.yy"
+#line 2222 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -8340,5 +8350,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2218 "parser.yy"
+#line 2224 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8347,5 +8357,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2223 "parser.yy"
+#line 2229 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -8354,5 +8364,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2225 "parser.yy"
+#line 2231 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8361,5 +8371,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2234 "parser.yy"
+#line 2240 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8368,5 +8378,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2237 "parser.yy"
+#line 2243 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8375,5 +8385,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2242 "parser.yy"
+#line 2248 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); }
     break;
@@ -8382,5 +8392,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2244 "parser.yy"
+#line 2250 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -8389,5 +8399,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2246 "parser.yy"
+#line 2252 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8396,5 +8406,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2251 "parser.yy"
+#line 2257 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8403,5 +8413,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2253 "parser.yy"
+#line 2259 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8410,5 +8420,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2255 "parser.yy"
+#line 2261 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8417,5 +8427,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2260 "parser.yy"
+#line 2266 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -8424,5 +8434,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2262 "parser.yy"
+#line 2268 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -8431,5 +8441,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2264 "parser.yy"
+#line 2270 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8438,5 +8448,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2279 "parser.yy"
+#line 2285 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (4)].decl)->addIdList( (yyvsp[(3) - (4)].decl) ); }
     break;
@@ -8445,5 +8455,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2281 "parser.yy"
+#line 2287 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (6)].decl)->addIdList( (yyvsp[(5) - (6)].decl) ); }
     break;
@@ -8452,5 +8462,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2283 "parser.yy"
+#line 2289 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8459,5 +8469,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2288 "parser.yy"
+#line 2294 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8466,5 +8476,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2290 "parser.yy"
+#line 2296 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8473,5 +8483,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2292 "parser.yy"
+#line 2298 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8480,5 +8490,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2297 "parser.yy"
+#line 2303 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -8487,5 +8497,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2299 "parser.yy"
+#line 2305 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -8494,5 +8504,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2301 "parser.yy"
+#line 2307 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8501,5 +8511,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2316 "parser.yy"
+#line 2322 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8508,5 +8518,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2319 "parser.yy"
+#line 2325 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8515,5 +8525,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2321 "parser.yy"
+#line 2327 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8522,5 +8532,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2327 "parser.yy"
+#line 2333 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8529,5 +8539,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2332 "parser.yy"
+#line 2338 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8536,5 +8546,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2334 "parser.yy"
+#line 2340 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8543,5 +8553,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2336 "parser.yy"
+#line 2342 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8550,5 +8560,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2341 "parser.yy"
+#line 2347 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8557,5 +8567,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2343 "parser.yy"
+#line 2349 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -8564,5 +8574,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2345 "parser.yy"
+#line 2351 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -8571,5 +8581,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2347 "parser.yy"
+#line 2353 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8578,5 +8588,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2352 "parser.yy"
+#line 2358 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); }
     break;
@@ -8585,5 +8595,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2354 "parser.yy"
+#line 2360 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -8592,5 +8602,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2356 "parser.yy"
+#line 2362 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8599,5 +8609,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2366 "parser.yy"
+#line 2372 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8606,5 +8616,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2369 "parser.yy"
+#line 2375 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8613,5 +8623,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2371 "parser.yy"
+#line 2377 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8620,5 +8630,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2376 "parser.yy"
+#line 2382 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8627,5 +8637,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2378 "parser.yy"
+#line 2384 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8634,5 +8644,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2380 "parser.yy"
+#line 2386 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8641,5 +8651,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2385 "parser.yy"
+#line 2391 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8648,5 +8658,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2387 "parser.yy"
+#line 2393 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -8655,5 +8665,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2389 "parser.yy"
+#line 2395 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -8662,5 +8672,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2391 "parser.yy"
+#line 2397 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8669,5 +8679,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2396 "parser.yy"
+#line 2402 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); }
     break;
@@ -8676,5 +8686,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2398 "parser.yy"
+#line 2404 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -8683,5 +8693,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2400 "parser.yy"
+#line 2406 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8690,5 +8700,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2431 "parser.yy"
+#line 2437 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8697,5 +8707,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2434 "parser.yy"
+#line 2440 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8704,5 +8714,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2436 "parser.yy"
+#line 2442 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8711,5 +8721,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2441 "parser.yy"
+#line 2447 "parser.yy"
     {
 			typedefTable.setNextIdentifier( *(yyvsp[(1) - (1)].tok) );
@@ -8721,5 +8731,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2446 "parser.yy"
+#line 2452 "parser.yy"
     {
 			typedefTable.setNextIdentifier( *(yyvsp[(1) - (1)].tok) );
@@ -8731,5 +8741,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2454 "parser.yy"
+#line 2460 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8738,5 +8748,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2456 "parser.yy"
+#line 2462 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8745,5 +8755,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2458 "parser.yy"
+#line 2464 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8752,5 +8762,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2463 "parser.yy"
+#line 2469 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8759,5 +8769,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2465 "parser.yy"
+#line 2471 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -8766,5 +8776,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2470 "parser.yy"
+#line 2476 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); }
     break;
@@ -8773,5 +8783,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2472 "parser.yy"
+#line 2478 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -8780,5 +8790,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2487 "parser.yy"
+#line 2493 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8787,5 +8797,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2489 "parser.yy"
+#line 2495 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8794,5 +8804,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2494 "parser.yy"
+#line 2500 "parser.yy"
     { (yyval.decl) = DeclarationNode::newPointer( 0 ); }
     break;
@@ -8801,5 +8811,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2496 "parser.yy"
+#line 2502 "parser.yy"
     { (yyval.decl) = DeclarationNode::newPointer( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8808,5 +8818,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2498 "parser.yy"
+#line 2504 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8815,5 +8825,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2500 "parser.yy"
+#line 2506 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8822,5 +8832,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2502 "parser.yy"
+#line 2508 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8829,5 +8839,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2508 "parser.yy"
+#line 2514 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -8836,5 +8846,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2510 "parser.yy"
+#line 2516 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -8843,5 +8853,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2512 "parser.yy"
+#line 2518 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8850,5 +8860,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2517 "parser.yy"
+#line 2523 "parser.yy"
     { (yyval.decl) = DeclarationNode::newFunction( 0, 0, (yyvsp[(3) - (5)].decl), 0 ); }
     break;
@@ -8857,5 +8867,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2519 "parser.yy"
+#line 2525 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -8864,5 +8874,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2521 "parser.yy"
+#line 2527 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8871,5 +8881,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2527 "parser.yy"
+#line 2533 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( 0, 0, false ); }
     break;
@@ -8878,5 +8888,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2529 "parser.yy"
+#line 2535 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( 0, 0, false )->addArray( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -8885,5 +8895,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2535 "parser.yy"
+#line 2541 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(3) - (5)].en), 0, false ); }
     break;
@@ -8892,5 +8902,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2537 "parser.yy"
+#line 2543 "parser.yy"
     { (yyval.decl) = DeclarationNode::newVarArray( 0 ); }
     break;
@@ -8899,5 +8909,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2539 "parser.yy"
+#line 2545 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addArray( DeclarationNode::newArray( (yyvsp[(4) - (6)].en), 0, false ) ); }
     break;
@@ -8906,5 +8916,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2541 "parser.yy"
+#line 2547 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addArray( DeclarationNode::newVarArray( 0 ) ); }
     break;
@@ -8913,5 +8923,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2556 "parser.yy"
+#line 2562 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8920,5 +8930,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2558 "parser.yy"
+#line 2564 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8927,5 +8937,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2563 "parser.yy"
+#line 2569 "parser.yy"
     { (yyval.decl) = DeclarationNode::newPointer( 0 ); }
     break;
@@ -8934,5 +8944,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2565 "parser.yy"
+#line 2571 "parser.yy"
     { (yyval.decl) = DeclarationNode::newPointer( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8941,5 +8951,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2567 "parser.yy"
+#line 2573 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8948,5 +8958,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2569 "parser.yy"
+#line 2575 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8955,5 +8965,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2571 "parser.yy"
+#line 2577 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8962,5 +8972,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2577 "parser.yy"
+#line 2583 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -8969,5 +8979,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2579 "parser.yy"
+#line 2585 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -8976,5 +8986,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2581 "parser.yy"
+#line 2587 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8983,5 +8993,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2586 "parser.yy"
+#line 2592 "parser.yy"
     { (yyval.decl) = DeclarationNode::newFunction( 0, 0, (yyvsp[(3) - (5)].decl), 0 ); }
     break;
@@ -8990,5 +9000,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2588 "parser.yy"
+#line 2594 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -8997,5 +9007,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2590 "parser.yy"
+#line 2596 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -9004,5 +9014,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2597 "parser.yy"
+#line 2603 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -9011,5 +9021,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2608 "parser.yy"
+#line 2614 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( 0, 0, false ); }
     break;
@@ -9018,5 +9028,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2611 "parser.yy"
+#line 2617 "parser.yy"
     { (yyval.decl) = DeclarationNode::newVarArray( (yyvsp[(3) - (6)].decl) ); }
     break;
@@ -9025,5 +9035,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2613 "parser.yy"
+#line 2619 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( 0, (yyvsp[(3) - (5)].decl), false ); }
     break;
@@ -9032,5 +9042,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2616 "parser.yy"
+#line 2622 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), false ); }
     break;
@@ -9039,5 +9049,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2618 "parser.yy"
+#line 2624 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(4) - (7)].decl), true ); }
     break;
@@ -9046,5 +9056,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2620 "parser.yy"
+#line 2626 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(3) - (7)].decl), true ); }
     break;
@@ -9053,5 +9063,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2634 "parser.yy"
+#line 2640 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -9060,5 +9070,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2636 "parser.yy"
+#line 2642 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -9067,5 +9077,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2641 "parser.yy"
+#line 2647 "parser.yy"
     { (yyval.decl) = DeclarationNode::newPointer( 0 ); }
     break;
@@ -9074,5 +9084,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2643 "parser.yy"
+#line 2649 "parser.yy"
     { (yyval.decl) = DeclarationNode::newPointer( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -9081,5 +9091,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2645 "parser.yy"
+#line 2651 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -9088,5 +9098,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2647 "parser.yy"
+#line 2653 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -9095,5 +9105,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2649 "parser.yy"
+#line 2655 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -9102,5 +9112,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2655 "parser.yy"
+#line 2661 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -9109,5 +9119,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2657 "parser.yy"
+#line 2663 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -9116,5 +9126,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2659 "parser.yy"
+#line 2665 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -9123,5 +9133,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2664 "parser.yy"
+#line 2670 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -9130,5 +9140,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2666 "parser.yy"
+#line 2672 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -9137,5 +9147,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2676 "parser.yy"
+#line 2682 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -9144,5 +9154,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2686 "parser.yy"
+#line 2692 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -9151,5 +9161,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2688 "parser.yy"
+#line 2694 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     break;
@@ -9158,5 +9168,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2690 "parser.yy"
+#line 2696 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -9165,5 +9175,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2692 "parser.yy"
+#line 2698 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     break;
@@ -9172,5 +9182,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2694 "parser.yy"
+#line 2700 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -9179,5 +9189,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2696 "parser.yy"
+#line 2702 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     break;
@@ -9186,30 +9196,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2703 "parser.yy"
+#line 2709 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     break;
 
   case 718:
-
-/* Line 1806 of yacc.c  */
-#line 2705 "parser.yy"
-    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
-    break;
-
-  case 719:
-
-/* Line 1806 of yacc.c  */
-#line 2707 "parser.yy"
-    { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
-    break;
-
-  case 720:
-
-/* Line 1806 of yacc.c  */
-#line 2709 "parser.yy"
-    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( (yyvsp[(2) - (3)].decl) )->addNewArray( (yyvsp[(1) - (3)].decl) ); }
-    break;
-
-  case 721:
 
 /* Line 1806 of yacc.c  */
@@ -9218,33 +9207,33 @@
     break;
 
+  case 719:
+
+/* Line 1806 of yacc.c  */
+#line 2713 "parser.yy"
+    { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
+    break;
+
+  case 720:
+
+/* Line 1806 of yacc.c  */
+#line 2715 "parser.yy"
+    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( (yyvsp[(2) - (3)].decl) )->addNewArray( (yyvsp[(1) - (3)].decl) ); }
+    break;
+
+  case 721:
+
+/* Line 1806 of yacc.c  */
+#line 2717 "parser.yy"
+    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
+    break;
+
   case 722:
 
 /* Line 1806 of yacc.c  */
-#line 2713 "parser.yy"
+#line 2719 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     break;
 
   case 723:
-
-/* Line 1806 of yacc.c  */
-#line 2715 "parser.yy"
-    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
-    break;
-
-  case 724:
-
-/* Line 1806 of yacc.c  */
-#line 2717 "parser.yy"
-    { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
-    break;
-
-  case 725:
-
-/* Line 1806 of yacc.c  */
-#line 2719 "parser.yy"
-    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( (yyvsp[(2) - (3)].decl) )->addNewArray( (yyvsp[(1) - (3)].decl) ); }
-    break;
-
-  case 726:
 
 /* Line 1806 of yacc.c  */
@@ -9253,8 +9242,29 @@
     break;
 
+  case 724:
+
+/* Line 1806 of yacc.c  */
+#line 2723 "parser.yy"
+    { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
+    break;
+
+  case 725:
+
+/* Line 1806 of yacc.c  */
+#line 2725 "parser.yy"
+    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( (yyvsp[(2) - (3)].decl) )->addNewArray( (yyvsp[(1) - (3)].decl) ); }
+    break;
+
+  case 726:
+
+/* Line 1806 of yacc.c  */
+#line 2727 "parser.yy"
+    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
+    break;
+
   case 727:
 
 /* Line 1806 of yacc.c  */
-#line 2726 "parser.yy"
+#line 2732 "parser.yy"
     { (yyval.decl) = DeclarationNode::newVarArray( (yyvsp[(3) - (6)].decl) ); }
     break;
@@ -9263,5 +9273,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2728 "parser.yy"
+#line 2734 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), false ); }
     break;
@@ -9270,5 +9280,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2733 "parser.yy"
+#line 2739 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), true ); }
     break;
@@ -9277,5 +9287,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2735 "parser.yy"
+#line 2741 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(4) - (7)].decl)->addQualifiers( (yyvsp[(3) - (7)].decl) ), true ); }
     break;
@@ -9284,5 +9294,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2762 "parser.yy"
+#line 2768 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -9291,5 +9301,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2773 "parser.yy"
+#line 2779 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -9298,5 +9308,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2775 "parser.yy"
+#line 2781 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     break;
@@ -9305,5 +9315,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2777 "parser.yy"
+#line 2783 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -9312,5 +9322,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2779 "parser.yy"
+#line 2785 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     break;
@@ -9319,5 +9329,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2781 "parser.yy"
+#line 2787 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -9326,30 +9336,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2783 "parser.yy"
+#line 2789 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     break;
 
   case 742:
-
-/* Line 1806 of yacc.c  */
-#line 2790 "parser.yy"
-    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
-    break;
-
-  case 743:
-
-/* Line 1806 of yacc.c  */
-#line 2792 "parser.yy"
-    { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
-    break;
-
-  case 744:
-
-/* Line 1806 of yacc.c  */
-#line 2794 "parser.yy"
-    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
-    break;
-
-  case 745:
 
 /* Line 1806 of yacc.c  */
@@ -9358,5 +9347,5 @@
     break;
 
-  case 746:
+  case 743:
 
 /* Line 1806 of yacc.c  */
@@ -9365,5 +9354,5 @@
     break;
 
-  case 747:
+  case 744:
 
 /* Line 1806 of yacc.c  */
@@ -9372,8 +9361,29 @@
     break;
 
+  case 745:
+
+/* Line 1806 of yacc.c  */
+#line 2802 "parser.yy"
+    { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
+    break;
+
+  case 746:
+
+/* Line 1806 of yacc.c  */
+#line 2804 "parser.yy"
+    { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
+    break;
+
+  case 747:
+
+/* Line 1806 of yacc.c  */
+#line 2806 "parser.yy"
+    { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
+    break;
+
   case 748:
 
 /* Line 1806 of yacc.c  */
-#line 2805 "parser.yy"
+#line 2811 "parser.yy"
     { (yyval.decl) = DeclarationNode::newTuple( (yyvsp[(3) - (5)].decl) ); }
     break;
@@ -9382,5 +9392,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2810 "parser.yy"
+#line 2816 "parser.yy"
     { (yyval.decl) = DeclarationNode::newFunction( 0, DeclarationNode::newTuple( 0 ), (yyvsp[(4) - (5)].decl), 0 ); }
     break;
@@ -9389,5 +9399,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2812 "parser.yy"
+#line 2818 "parser.yy"
     { (yyval.decl) = DeclarationNode::newFunction( 0, (yyvsp[(1) - (6)].decl), (yyvsp[(4) - (6)].decl), 0 ); }
     break;
@@ -9396,5 +9406,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2814 "parser.yy"
+#line 2820 "parser.yy"
     { (yyval.decl) = DeclarationNode::newFunction( 0, (yyvsp[(1) - (6)].decl), (yyvsp[(4) - (6)].decl), 0 ); }
     break;
@@ -9403,5 +9413,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2838 "parser.yy"
+#line 2844 "parser.yy"
     { (yyval.en) = 0; }
     break;
@@ -9410,5 +9420,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2840 "parser.yy"
+#line 2846 "parser.yy"
     { (yyval.en) = (yyvsp[(2) - (2)].en); }
     break;
@@ -9417,5 +9427,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 9420 "Parser/parser.cc"
+#line 9430 "Parser/parser.cc"
       default: break;
     }
@@ -9648,5 +9658,5 @@
 
 /* Line 2067 of yacc.c  */
-#line 2843 "parser.yy"
+#line 2849 "parser.yy"
 
 // ----end of grammar----
Index: src/Parser/parser.h
===================================================================
--- src/Parser/parser.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/Parser/parser.h	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -274,4 +274,5 @@
 	LabelNode *label;
 	InitializerNode *in;
+	OperatorNode::Type op;
 	bool flag;
 
@@ -279,5 +280,5 @@
 
 /* Line 2068 of yacc.c  */
-#line 282 "Parser/parser.h"
+#line 283 "Parser/parser.h"
 } YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/Parser/parser.yy	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 23 17:01:30 2016
-// Update Count     : 1668
+// Last Modified On : Fri Aug  5 08:15:57 2016
+// Update Count     : 1721
 //
 
@@ -119,4 +119,5 @@
 	LabelNode *label;
 	InitializerNode *in;
+	OperatorNode::Type op;
 	bool flag;
 }
@@ -129,5 +130,6 @@
 %type<constant> constant
 %type<en> tuple							tuple_expression_list
-%type<en> ptrref_operator				unary_operator				assignment_operator
+%type<op> ptrref_operator
+%type<en> unary_operator				assignment_operator
 %type<en> primary_expression			postfix_expression			unary_expression
 %type<en> cast_expression				multiplicative_expression	additive_expression			shift_expression
@@ -150,6 +152,6 @@
 %type<sn> block_item_list				block_item
 %type<sn> case_clause
-%type<en> case_value					case_value_list
-%type<sn> case_label					case_label_list
+%type<en> case_value
+%type<sn> case_value_list				case_label					case_label_list
 %type<sn> switch_clause_list_opt		switch_clause_list			choose_clause_list_opt		choose_clause_list
 %type<pn> handler_list					handler_clause				finally_clause
@@ -354,5 +356,5 @@
 		// little advantage to this feature and many disadvantages. It is possible to write x[(i,j)] in CFA, which is
 		// equivalent to the old x[i,j].
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Index ), $1, $4 ); }
+		{ $$ = new CompositeExprNode2( build_opr2( OperatorNode::Index, $1, $4 ) ); }
 	| postfix_expression '(' argument_expression_list ')'
 		{ $$ = new CompositeExprNode( $1, $3 ); }
@@ -360,13 +362,13 @@
 		//   struct S { int 0, 1; } s; s. 0 = 0; s. 1 = 1;
 	| postfix_expression '.' no_attr_identifier
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::FieldSel ), $1, new VarRefNode( $3 )); }
+		{ $$ = new CompositeExprNode2( build_fieldSel( $1, new VarRefNode( $3 ) ) ); }
 	| postfix_expression '.' '[' push field_list pop ']' // CFA, tuple field selector
 	| postfix_expression ARROW no_attr_identifier
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::PFieldSel ), $1, new VarRefNode( $3 )); }
+		{ $$ = new CompositeExprNode2( build_pfieldSel( $1, new VarRefNode( $3 ) ) ); }
 	| postfix_expression ARROW '[' push field_list pop ']' // CFA, tuple field selector
 	| postfix_expression ICR
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::IncrPost ), $1 ); }
+	  	{ $$ = new CompositeExprNode2( build_opr1( OperatorNode::IncrPost, $1 ) ); }
 	| postfix_expression DECR
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::DecrPost ), $1 ); }
+	  	{ $$ = new CompositeExprNode2( build_opr1( OperatorNode::DecrPost, $1 ) ); }
 	| '(' type_name_no_function ')' '{' initializer_list comma_opt '}' // C99
 		{ $$ = new CompoundLiteralNode( $2, new InitializerNode( $5, true ) ); }
@@ -410,11 +412,11 @@
 		//   struct S { int 0, 1; } s; s. 0 = 0; s. 1 = 1;
 	| no_attr_identifier '.' field
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::FieldSel ), new VarRefNode( $1 ), $3 ); }
+		{ $$ = new CompositeExprNode2( build_fieldSel( $3, new VarRefNode( $1 ) ) ); }
 	| no_attr_identifier '.' '[' push field_list pop ']'
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::FieldSel ), new VarRefNode( $1 ), $5 ); }
+		{ $$ = new CompositeExprNode2( build_fieldSel( $5, new VarRefNode( $1 ) ) ); }
 	| no_attr_identifier ARROW field
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::PFieldSel ), new VarRefNode( $1 ), $3 ); }
+		{ $$ = new CompositeExprNode2( build_pfieldSel( $3, new VarRefNode( $1 ) ) ); }
 	| no_attr_identifier ARROW '[' push field_list pop ']'
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::PFieldSel ), new VarRefNode( $1 ), $5 ); }
+		{ $$ = new CompositeExprNode2( build_pfieldSel( $5, new VarRefNode( $1 ) ) ); }
 	;
 
@@ -429,31 +431,32 @@
 	| EXTENSION cast_expression							// GCC
 		{ $$ = $2->set_extension( true ); }
-	| ptrref_operator cast_expression					// CFA
-		{ $$ = new CompositeExprNode( $1, $2 ); }
 		// '*' ('&') is separated from unary_operator because of shift/reduce conflict in:
 		//		{ * X; }	 // dereference X
 		//		{ * int X; } // CFA declaration of pointer to int
+	| ptrref_operator cast_expression					// CFA
+		{ $$ = $1 == OperatorNode::AddressOf ? (ExpressionNode*) new CompositeExprNode2( build_addressOf( $2 ) )
+											: (ExpressionNode*)new CompositeExprNode( new OperatorNode ( $1 ), $2 ); }
 	| unary_operator cast_expression
 		{ $$ = new CompositeExprNode( $1, $2 ); }
 	| ICR unary_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Incr ), $2 ); }
+	  	{ $$ = new CompositeExprNode2( build_opr1( OperatorNode::Incr, $2 ) ); }
 	| DECR unary_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Decr ), $2 ); }
+	  	{ $$ = new CompositeExprNode2( build_opr1( OperatorNode::Decr, $2 ) ); }
 	| SIZEOF unary_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::SizeOf ), $2 ); }
+		{ $$ = new CompositeExprNode2( build_sizeOf( $2 ) ); }
 	| SIZEOF '(' type_name_no_function ')'
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::SizeOf ), new TypeValueNode( $3 )); }
+		{ $$ = new CompositeExprNode2( build_sizeOf( new TypeValueNode( $3 ) ) ); }
 	| OFFSETOF '(' type_name_no_function ',' no_attr_identifier ')'
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::OffsetOf ), new TypeValueNode( $3 ), new VarRefNode( $5 )); }
+		{ $$ = new CompositeExprNode2( build_offsetOf( new TypeValueNode( $3 ), new VarRefNode( $5 ) ) ); }
 	| ATTR_IDENTIFIER
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Attr ), new VarRefNode( $1 )); }
+		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Attr ), new VarRefNode( $1 ) ); }
 	| ATTR_IDENTIFIER '(' type_name ')'
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Attr ), new VarRefNode( $1 ), new TypeValueNode( $3 )); }
+		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Attr ), new VarRefNode( $1 ), new TypeValueNode( $3 ) ); }
 	| ATTR_IDENTIFIER '(' argument_expression ')'
 		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Attr ), new VarRefNode( $1 ), $3 ); }
 	| ALIGNOF unary_expression							// GCC, variable alignment
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::AlignOf ), $2 ); }
+		{ $$ = new CompositeExprNode2( build_alignOf( $2 ) ); }
 	| ALIGNOF '(' type_name_no_function ')'				// GCC, type alignment
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::AlignOf ), new TypeValueNode( $3 ) ); }
+		{ $$ = new CompositeExprNode2( build_alignOf( new TypeValueNode( $3 ) ) ); }
 //	| ANDAND IDENTIFIER									// GCC, address of label
 //		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::LabelAddress ), new VarRefNode( $2, true ) ); }
@@ -461,8 +464,8 @@
 
 ptrref_operator:
-	'*'											{ $$ = new OperatorNode( OperatorNode::PointTo ); }
-	| '&'										{ $$ = new OperatorNode( OperatorNode::AddressOf ); }
+	'*'											{ $$ = OperatorNode::PointTo; }
+	| '&'										{ $$ = OperatorNode::AddressOf; }
 		// GCC, address of label must be handled by semantic check for ref,ref,label
-	| ANDAND									{ $$ = new OperatorNode( OperatorNode::And ); }
+	| ANDAND									{ $$ = OperatorNode::And; }
 	;
 
@@ -477,7 +480,7 @@
 	unary_expression
 	| '(' type_name_no_function ')' cast_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Cast ), new TypeValueNode( $2 ), $4 ); }
+		{ $$ = new CompositeExprNode2( build_cast( new TypeValueNode( $2 ), $4 ) ); }
 	| '(' type_name_no_function ')' tuple
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Cast ), new TypeValueNode( $2 ), $4 ); }
+		{ $$ = new CompositeExprNode2( build_cast( new TypeValueNode( $2 ), $4 ) ); }
 	;
 
@@ -485,9 +488,9 @@
 	cast_expression
 	| multiplicative_expression '*' cast_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Mul ), $1, $3 ); }
+		{ $$ = new CompositeExprNode2( build_opr2( OperatorNode::Mul, $1, $3 ) ); }
 	| multiplicative_expression '/' cast_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Div ), $1, $3 ); }
+		{ $$ = new CompositeExprNode2( build_opr2( OperatorNode::Div, $1, $3 ) ); }
 	| multiplicative_expression '%' cast_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Mod ), $1, $3 ); }
+		{ $$ = new CompositeExprNode2( build_opr2( OperatorNode::Mod, $1, $3 ) ); }
 	;
 
@@ -495,7 +498,7 @@
 	multiplicative_expression
 	| additive_expression '+' multiplicative_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Plus ), $1, $3 ); }
+		{ $$ = new CompositeExprNode2( build_opr2( OperatorNode::Plus, $1, $3 ) ); }
 	| additive_expression '-' multiplicative_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Minus ), $1, $3 ); }
+		{ $$ = new CompositeExprNode2( build_opr2( OperatorNode::Minus, $1, $3 ) ); }
 	;
 
@@ -503,7 +506,7 @@
 	additive_expression
 	| shift_expression LS additive_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::LShift ), $1, $3 ); }
+		{ $$ = new CompositeExprNode2( build_opr2( OperatorNode::LShift, $1, $3 ) ); }
 	| shift_expression RS additive_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::RShift ), $1, $3 ); }
+		{ $$ = new CompositeExprNode2( build_opr2( OperatorNode::RShift, $1, $3 ) ); }
 	;
 
@@ -511,11 +514,11 @@
 	shift_expression
 	| relational_expression '<' shift_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::LThan ), $1, $3 ); }
+		{ $$ = new CompositeExprNode2( build_opr2( OperatorNode::LThan, $1, $3 ) ); }
 	| relational_expression '>' shift_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::GThan ), $1, $3 ); }
+		{ $$ = new CompositeExprNode2( build_opr2( OperatorNode::GThan, $1, $3 ) ); }
 	| relational_expression LE shift_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::LEThan ), $1, $3 ); }
+		{ $$ = new CompositeExprNode2( build_opr2( OperatorNode::LEThan, $1, $3 ) ); }
 	| relational_expression GE shift_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::GEThan ), $1, $3 ); }
+		{ $$ = new CompositeExprNode2( build_opr2( OperatorNode::GEThan, $1, $3 ) ); }
 	;
 
@@ -523,7 +526,7 @@
 	relational_expression
 	| equality_expression EQ relational_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Eq ), $1, $3 ); }
+		{ $$ = new CompositeExprNode2( build_opr2( OperatorNode::Eq, $1, $3 ) ); }
 	| equality_expression NE relational_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Neq ), $1, $3 ); }
+		{ $$ = new CompositeExprNode2( build_opr2( OperatorNode::Neq, $1, $3 ) ); }
 	;
 
@@ -531,5 +534,5 @@
 	equality_expression
 	| AND_expression '&' equality_expression
-		{ $$ =new CompositeExprNode( new OperatorNode( OperatorNode::BitAnd ), $1, $3 ); }
+		{ $$ = new CompositeExprNode2( build_opr2( OperatorNode::BitAnd, $1, $3 ) ); }
 	;
 
@@ -537,5 +540,5 @@
 	AND_expression
 	| exclusive_OR_expression '^' AND_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Xor ), $1, $3 ); }
+		{ $$ = new CompositeExprNode2( build_opr2( OperatorNode::Xor, $1, $3 ) ); }
 	;
 
@@ -543,5 +546,5 @@
 	exclusive_OR_expression
 	| inclusive_OR_expression '|' exclusive_OR_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::BitOr ), $1, $3 ); }
+		{ $$ = new CompositeExprNode2( build_opr2( OperatorNode::BitOr, $1, $3 ) ); }
 	;
 
@@ -549,5 +552,5 @@
 	inclusive_OR_expression
 	| logical_AND_expression ANDAND inclusive_OR_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::And ), $1, $3 ); }
+		{ $$ = new CompositeExprNode2( build_and_or( $1, $3, true ) ); }
 	;
 
@@ -555,5 +558,5 @@
 	logical_AND_expression
 	| logical_OR_expression OROR logical_AND_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Or ), $1, $3 ); }
+		{ $$ = new CompositeExprNode2( build_and_or( $1, $3, false ) ); }
 	;
 
@@ -561,9 +564,9 @@
 	logical_OR_expression
 	| logical_OR_expression '?' comma_expression ':' conditional_expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Cond ), (ExpressionNode *)mkList( (*$1, *$3, *$5 ) ) ); }
+		{ $$ = new CompositeExprNode2( build_cond( $1, $3, $5 ) ); }
 	| logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand
-		{ $$=new CompositeExprNode( new OperatorNode( OperatorNode::NCond ), $1, $4 ); }
+		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::NCond ), $1, $4 ); }
 	| logical_OR_expression '?' comma_expression ':' tuple // CFA, tuple expression
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Cond ), (ExpressionNode *)mkList( (*$1, *$3, *$5 ) ) ); }
+		{ $$ = new CompositeExprNode2( build_cond( $1, $3, $5 ) ); }
 	;
 
@@ -576,7 +579,7 @@
 	conditional_expression
 	| unary_expression '=' assignment_expression
-		{ $$ =new CompositeExprNode( new OperatorNode( OperatorNode::Assign ), $1, $3 ); }
+		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Assign ), $1, $3 ); }
 	| unary_expression assignment_operator assignment_expression
-		{ $$ =new CompositeExprNode( $2, $1, $3 ); }
+		{ $$ = new CompositeExprNode( $2, $1, $3 ); }
 	| tuple assignment_opt								// CFA, tuple expression
 		{ $$ = ( $2 == 0 ) ? $1 : new CompositeExprNode( new OperatorNode( OperatorNode::Assign ), $1, $2 ); }
@@ -624,5 +627,6 @@
 	assignment_expression
 	| comma_expression ',' assignment_expression	// { $$ = (ExpressionNode *)$1->add_to_list( $3 ); }
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Comma ), $1, $3 ); }
+	//{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Comma ), $1, $3 ); }
+		{ $$ = new CompositeExprNode2( build_comma( $1, $3 ) ); }
 	;
 
@@ -717,5 +721,6 @@
 			// *before* the transfer to the appropriate case clause by hoisting the declarations into a compound
 			// statement around the switch.  Statements after the initial declaration list can never be executed, and
-			// therefore, are removed from the grammar even though C allows it. Change also applies to choose statement.
+			// therefore, are removed from the grammar even though C allows it. The change also applies to choose
+			// statement.
 			$$ = $7 != 0 ? new CompoundStmtNode( (StatementNode *)((new StatementNode( $7 ))->set_link( sw )) ) : sw;
 		}
@@ -735,16 +740,16 @@
 	constant_expression							{ $$ = $1; }
 	| constant_expression ELLIPSIS constant_expression	// GCC, subrange
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Range ), $1, $3 ); }
+		{ $$ = new CompositeExprNode2( build_opr2( OperatorNode::Range, $1, $3 ) ); }
 	| subrange											// CFA, subrange
 	;
 
 case_value_list:										// CFA
-	case_value
-	| case_value_list ',' case_value
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)(tupleContents( $1 ))->set_link( $3 ) ); }
+	case_value									{ $$ = new StatementNode( StatementNode::Case, $1, 0 ); }
+		// convert case list, e.g., "case 1, 3, 5:" into "case 1: case 3: case 5"
+	| case_value_list ',' case_value			{ $$ = (StatementNode *)($1->set_link( new StatementNode( StatementNode::Case, $3, 0 ) ) ); }
 	;
 
 case_label:												// CFA
-	CASE case_value_list ':'					{ $$ = new StatementNode( StatementNode::Case, $2, 0 ); }
+	CASE case_value_list ':'					{ $$ = $2; }
 	| DEFAULT ':'								{ $$ = new StatementNode( StatementNode::Default ); }
 		// A semantic check is required to ensure only one default clause per switch/choose statement.
@@ -1776,5 +1781,5 @@
 		{ $$ = new DesignatorNode( $3, true ); }
 	| '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements
-		{ $$ = new DesignatorNode( new CompositeExprNode( new OperatorNode( OperatorNode::Range ), $3, $5 ), true ); }
+		{ $$ = new DesignatorNode( new CompositeExprNode2( build_opr2( OperatorNode::Range, $3, $5 ) ), true ); }
 	| '.' '[' push field_list pop ']'					// CFA, tuple field selector
 		{ $$ = new DesignatorNode( $4 ); }
@@ -2105,5 +2110,5 @@
 subrange:
 	constant_expression '~' constant_expression			// CFA, integer subrange
-		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Range ), $1, $3 ); }
+		{ $$ = new CompositeExprNode2( build_opr2( OperatorNode::Range, $1, $3 ) ); }
 	;
 
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/ResolvExpr/Resolver.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -24,4 +24,5 @@
 #include "SynTree/Initializer.h"
 #include "SymTab/Indexer.h"
+#include "SymTab/Autogen.h"
 #include "Common/utility.h"
 #include "InitTweak/InitTweak.h"
@@ -41,4 +42,5 @@
 
 		virtual void visit( ArrayType * at );
+		virtual void visit( PointerType * at );
 
 		virtual void visit( ExprStmt *exprStmt );
@@ -52,5 +54,4 @@
 		virtual void visit( BranchStmt *branchStmt );
 		virtual void visit( ReturnStmt *returnStmt );
-		virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt );
 
 		virtual void visit( SingleInit *singleInit );
@@ -59,4 +60,7 @@
 	  private:
   	typedef std::list< Initializer * >::iterator InitIterator;
+
+		template< typename PtrType >
+		void handlePtrType( PtrType * type );
 
 	  void resolveAggrInit( AggregateDecl *, InitIterator &, InitIterator & );
@@ -192,13 +196,22 @@
 	}
 
+	template< typename PtrType >
+	void Resolver::handlePtrType( PtrType * type ) {
+		if ( type->get_dimension() ) {
+			CastExpr *castExpr = new CastExpr( type->get_dimension(), SymTab::SizeType->clone() );
+			Expression *newExpr = findSingleExpression( castExpr, *this );
+			delete type->get_dimension();
+			type->set_dimension( newExpr );
+		}
+	}
+
 	void Resolver::visit( ArrayType * at ) {
-		if ( at->get_dimension() ) {
-			BasicType arrayLenType = BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
-			CastExpr *castExpr = new CastExpr( at->get_dimension(), arrayLenType.clone() );
-			Expression *newExpr = findSingleExpression( castExpr, *this );
-			delete at->get_dimension();
-			at->set_dimension( newExpr );
-		}
+		handlePtrType( at );
 		Visitor::visit( at );
+	}
+
+	void Resolver::visit( PointerType * pt ) {
+		handlePtrType( pt );
+		Visitor::visit( pt );
 	}
 
@@ -422,6 +435,6 @@
 
 	void Resolver::visit( ListInit * listInit ) {
-		InitIterator iter = listInit->begin_initializers();
-		InitIterator end = listInit->end_initializers();
+		InitIterator iter = listInit->begin();
+		InitIterator end = listInit->end();
 
 		if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) {
@@ -521,54 +534,19 @@
 		// implicitly generated, there's no way for it to have side effects, so get rid of it
 		// to clean up generated code.
-		if ( InitTweak::isInstrinsicSingleArgCallStmt( ctorInit->get_ctor() ) ) {
+		if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->get_ctor() ) ) {
 			delete ctorInit->get_ctor();
 			ctorInit->set_ctor( NULL );
 		}
-		if ( InitTweak::isInstrinsicSingleArgCallStmt( ctorInit->get_ctor() ) ) {
+
+		// xxx - todo
+		// if ( InitTweak::isIntrinsicCallStmt( ctorInit->get_ctor() ) ) {
+		// 	// can reduce the constructor down to a SingleInit using the
+		// 	// second argument from the ctor call
+		// }
+
+		if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->get_dtor() ) ) {
 			delete ctorInit->get_dtor();
 			ctorInit->set_dtor( NULL );
 		}
-	}
-
-	void Resolver::visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) {
-		// before resolving ctor/dtor, need to remove type qualifiers from the first argument (the object being constructed).
-		// Do this through a cast expression to greatly simplify the code.
-		Expression * callExpr = InitTweak::getCtorDtorCall( impCtorDtorStmt );
-		assert( callExpr );
-		Expression *& constructee = InitTweak::getCallArg( callExpr, 0 );
-		Type * type = 0;
-
-		// need to find the type of the first argument, which is unfortunately not uniform since array construction
-		// includes an untyped '+' expression.
-		if ( UntypedExpr * plusExpr = dynamic_cast< UntypedExpr * >( constructee ) ) {
-			// constructee is <array>+<index>
-			// get Variable <array>, then get the base type of the VariableExpr - this is the type that needs to be fixed
-			Expression * arr = InitTweak::getCallArg( plusExpr, 0 );
-			assert( dynamic_cast< VariableExpr * >( arr ) || dynamic_cast< MemberExpr *>( arr ) );
-			assert( arr && arr->get_results().size() == 1 );
-			type = arr->get_results().front()->clone();
-		} else {
-			// otherwise, constructing a plain object, which means the object's address is being taken.
-			// Need to get the type of the VariableExpr object, because the AddressExpr is rebuilt and uses the
-			// type of the VariableExpr to do so.
-			assert( constructee->get_results().size() == 1 );
-			AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee );
-			assert( addrExpr && addrExpr->get_results().size() == 1 );
-			type = addrExpr->get_results().front()->clone();
-		}
-		// cast to T* with qualifiers removed.
-		// unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
-		// must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
-		// remove lvalue as a qualifier, this can change to
-		//   type->get_qualifiers() = Type::Qualifiers();
-		Type * base = InitTweak::getPointerBase( type );
-		assert( base );
-		base->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true);
-		// if pointer has lvalue qualifier, cast won't appear in output
-		type->set_isLvalue( false );
-		constructee = new CastExpr( constructee, type );
-
-		// finally, resolve the ctor/dtor
-		impCtorDtorStmt->get_callStmt()->accept( *this );
 	}
 } // namespace ResolvExpr
Index: src/SymTab/AddVisit.h
===================================================================
--- src/SymTab/AddVisit.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SymTab/AddVisit.h	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,6 +10,6 @@
 // Created On       : Sun May 17 16:14:32 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul 12 17:46:33 2016
-// Update Count     : 6
+// Last Modified On : Thu Aug  4 11:22:01 2016
+// Update Count     : 9
 //
 
@@ -33,5 +33,5 @@
 	template< typename Visitor >
 	inline void addVisit(SwitchStmt *switchStmt, Visitor &visitor) {
-		addVisitStatementList( switchStmt->get_branches(), visitor );
+		addVisitStatementList( switchStmt->get_statements(), visitor );
 		maybeAccept( switchStmt->get_condition(), visitor );
 	}
Index: src/SymTab/Autogen.cc
===================================================================
--- src/SymTab/Autogen.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SymTab/Autogen.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -26,4 +26,6 @@
 
 namespace SymTab {
+	Type * SizeType = 0;
+
 	class AutogenerateRoutines : public Visitor {
 		public:
@@ -59,36 +61,4 @@
 	bool isUnnamedBitfield( ObjectDecl * obj ) {
 		return obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL;
-	}
-
-	template< typename OutputIterator >
-	void makeScalarFunction( Expression *src, ObjectDecl *dstParam, DeclarationWithType *member, std::string fname, OutputIterator out ) {
-		ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member );
-		// unnamed bit fields are not copied as they cannot be accessed
-		if ( isUnnamedBitfield( obj ) ) return;
-
-		// want to be able to generate assignment, ctor, and dtor generically,
-		// so fname is either ?=?, ?{}, or ^?{}
-		UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
-
-		UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
-		derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
-
-		// do something special for unnamed members
-		Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );
-		fExpr->get_args().push_back( dstselect );
-
-		if ( src ) {
-			fExpr->get_args().push_back( src );
-		}
-
-		Statement * callStmt = new ExprStmt( noLabels, fExpr );
-		if ( (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) ) ) {
-			// implicitly generated ctor/dtor calls should be wrapped
-			// so that later passes are aware they were generated.
-			// xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,
-			// because this causes the address to be taken at codegen, which is illegal in C.
-			callStmt = new ImplicitCtorDtorStmt( callStmt );
-		}
-		*out++ = callStmt;
 	}
 
@@ -219,21 +189,17 @@
 		}
 
+		InitTweak::InitExpander srcParam( src );
+
 		// assign to destination (and return value if generic)
-		if ( ArrayType *array = dynamic_cast< ArrayType * >( field->get_type() ) ) {
-			UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
-			derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
-			Expression *dstselect = new MemberExpr( field, derefExpr );
-
-			makeArrayFunction( src, dstselect, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ), forward );
-			if ( isDynamicLayout && returnVal ) {
-				UntypedExpr *derefRet = new UntypedExpr( new NameExpr( "*?" ) );
-				derefRet->get_args().push_back( new VariableExpr( returnVal ) );
-				Expression *retselect = new MemberExpr( field, derefRet );
-
-				makeArrayFunction( src, retselect, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ), forward );
-			}
-		} else {
-			makeScalarFunction( src, dstParam, field, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
-			if ( isDynamicLayout && returnVal ) makeScalarFunction( src, returnVal, field, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
+		UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
+		derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
+		Expression *dstselect = new MemberExpr( field, derefExpr );
+		genImplicitCall( srcParam, dstselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
+
+		if ( isDynamicLayout && returnVal ) {
+			UntypedExpr *derefRet = new UntypedExpr( new NameExpr( "*?" ) );
+			derefRet->get_args().push_back( new VariableExpr( returnVal ) );
+			Expression *retselect = new MemberExpr( field, derefRet );
+			genImplicitCall( srcParam, retselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
 		} // if
 	}
Index: src/SymTab/Autogen.h
===================================================================
--- src/SymTab/Autogen.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SymTab/Autogen.h	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -22,82 +22,160 @@
 #include "SynTree/Declaration.h"
 #include "SynTree/Initializer.h"
+#include "InitTweak/InitTweak.h"
 
 namespace SymTab {
-  /// Generates assignment operators, constructors, and destructor for aggregate types as required
-  void autogenerateRoutines( std::list< Declaration * > &translationUnit );
+	/// Generates assignment operators, constructors, and destructor for aggregate types as required
+	void autogenerateRoutines( std::list< Declaration * > &translationUnit );
 
-  // originally makeArrayAssignment - changed to Function because it is now used for ctors and dtors as well
-  // admittedly not a great name change. This used to live in Validate.cc, but has been moved so it can be reused elsewhere
+	/// returns true if obj's name is the empty string and it has a bitfield width
+	bool isUnnamedBitfield( ObjectDecl * obj );
 
-  /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.
-  /// If forward is true, loop goes from 0 to N-1, else N-1 to 0
-  template< typename OutputIterator >
-  void makeArrayFunction( Expression *srcParam, Expression *dstParam, ArrayType *array, std::string fname, OutputIterator out, bool forward = true ) {
-    static UniqueName indexName( "_index" );
+	/// size_t type - set when size_t typedef is seen. Useful in a few places,
+	/// such as in determining array dimension type
+	extern Type * SizeType;
 
-    // for a flexible array member nothing is done -- user must define own assignment
-    if ( ! array->get_dimension() ) return;
+	/// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls.
+	template< typename OutputIterator >
+	Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false, bool forward = true );
 
-    Expression * begin, * end, * update, * cmp;
-    if ( forward ) {
-      // generate: for ( int i = 0; i < 0; ++i )
-      begin = new NameExpr( "0" );
-      end = array->get_dimension()->clone();
-      cmp = new NameExpr( "?<?" );
-      update = new NameExpr( "++?" );
-    } else {
-      // generate: for ( int i = N-1; i >= 0; --i )
-      begin = new UntypedExpr( new NameExpr( "?-?" ) );
-      ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() );
-      ((UntypedExpr*)begin)->get_args().push_back( new NameExpr( "1" ) );
-      end = new NameExpr( "0" );
-      cmp = new NameExpr( "?>=?" );
-      update = new NameExpr( "--?" );
-    }
+	/// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types.
+	/// optionally returns a statement which must be inserted prior to the containing loop, if there is one
+	template< typename OutputIterator >
+	Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false ) {
+		// want to be able to generate assignment, ctor, and dtor generically,
+		// so fname is either ?=?, ?{}, or ^?{}
+		UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
 
-    ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), NULL );
+		// do something special for unnamed members
+		dstParam = new AddressExpr( dstParam );
+		if ( addCast ) {
+			// cast to T* with qualifiers removed, so that qualified objects can be constructed
+			// and destructed with the same functions as non-qualified objects.
+			// unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
+			// must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
+			// remove lvalue as a qualifier, this can change to
+			//   type->get_qualifiers() = Type::Qualifiers();
+			assert( type );
+			Type * castType = type->clone();
+			castType->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true);
+			castType->set_isLvalue( true ); // xxx - might not need this
+			dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) );
+		}
+		fExpr->get_args().push_back( dstParam );
 
-    UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
-    init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
-    init->get_args().push_back( begin );
-    index->set_init( new SingleInit( init, std::list<Expression*>() ) );
+		Statement * listInit = srcParam.buildListInit( fExpr );
 
-    UntypedExpr *cond = new UntypedExpr( cmp );
-    cond->get_args().push_back( new VariableExpr( index ) );
-    cond->get_args().push_back( end );
+		std::list< Expression * > args = *++srcParam;
+		fExpr->get_args().splice( fExpr->get_args().end(), args );
 
-    UntypedExpr *inc = new UntypedExpr( update );
-    inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
+		*out++ = new ExprStmt( noLabels, fExpr );
 
-    // want to be able to generate assignment, ctor, and dtor generically,
-    // so fname is either ?=?, ?{}, or ^?{}
-    UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
+		srcParam.clearArrayIndices();
 
-    UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) );
-    dstIndex->get_args().push_back( dstParam );
-    dstIndex->get_args().push_back( new VariableExpr( index ) );
-    fExpr->get_args().push_back( dstIndex );
+		return listInit;
+	}
 
-    // srcParam is NULL for default ctor/dtor
-    if ( srcParam ) {
-      UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
-      srcIndex->get_args().push_back( srcParam );
-      srcIndex->get_args().push_back( new VariableExpr( index ) );
-      fExpr->get_args().push_back( srcIndex );
-    }
+	/// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.
+	/// If forward is true, loop goes from 0 to N-1, else N-1 to 0
+	template< typename OutputIterator >
+	void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) {
+		static UniqueName indexName( "_index" );
 
-    std::list<Statement *> initList;
-    CompoundStmt * block = new CompoundStmt( noLabels );
-    block->get_kids().push_back( new DeclStmt( noLabels, index ) );
-    block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, new ExprStmt( noLabels, fExpr ) ) );
+		// for a flexible array member nothing is done -- user must define own assignment
+		if ( ! array->get_dimension() ) return ;
 
-    Statement * stmt = block;
-    if ( fname == "?{}" || fname == "^?{}" ) {
-      // implicitly generated ctor/dtor calls should be wrapped
-      // so that later passes are aware they were generated
-      stmt = new ImplicitCtorDtorStmt( stmt );
-    }
-    *out++ = stmt;
-  }
+		Expression * begin, * end, * update, * cmp;
+		if ( forward ) {
+			// generate: for ( int i = 0; i < 0; ++i )
+			begin = new NameExpr( "0" );
+			end = array->get_dimension()->clone();
+			cmp = new NameExpr( "?<?" );
+			update = new NameExpr( "++?" );
+		} else {
+			// generate: for ( int i = N-1; i >= 0; --i )
+			begin = new UntypedExpr( new NameExpr( "?-?" ) );
+			((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() );
+			((UntypedExpr*)begin)->get_args().push_back( new NameExpr( "1" ) );
+			end = new NameExpr( "0" );
+			cmp = new NameExpr( "?>=?" );
+			update = new NameExpr( "--?" );
+		}
+
+		ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), NULL );
+
+		UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
+		init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
+		init->get_args().push_back( begin );
+		index->set_init( new SingleInit( init, std::list<Expression*>() ) );
+
+		UntypedExpr *cond = new UntypedExpr( cmp );
+		cond->get_args().push_back( new VariableExpr( index ) );
+		cond->get_args().push_back( end );
+
+		UntypedExpr *inc = new UntypedExpr( update );
+		inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
+
+		UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
+		dstIndex->get_args().push_back( dstParam );
+		dstIndex->get_args().push_back( new VariableExpr( index ) );
+		dstParam = dstIndex;
+
+		// srcParam must keep track of the array indices to build the
+		// source parameter and/or array list initializer
+		srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone() );
+
+		// for stmt's body, eventually containing call
+		CompoundStmt * body = new CompoundStmt( noLabels );
+		Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward );
+
+		// block containing for stmt and index variable
+		std::list<Statement *> initList;
+		CompoundStmt * block = new CompoundStmt( noLabels );
+		block->get_kids().push_back( new DeclStmt( noLabels, index ) );
+		if ( listInit ) block->get_kids().push_back( listInit );
+		block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) );
+
+		*out++ = block;
+	}
+
+	template< typename OutputIterator >
+	Statement * genCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) {
+		if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
+			genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward );
+			return 0;
+		} else {
+			return genScalarCall( srcParam, dstParam, fname, out, type, addCast );
+		}
+	}
+
+	/// inserts into out a generated call expression to function fname with arguments dstParam
+	/// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the
+	/// object being constructed. The function wraps constructor and destructor calls in an
+	/// ImplicitCtorDtorStmt node.
+	template< typename OutputIterator >
+	void genImplicitCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
+		ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );
+		assert( obj );
+		// unnamed bit fields are not copied as they cannot be accessed
+		if ( isUnnamedBitfield( obj ) ) return;
+
+		bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) );
+		std::list< Statement * > stmts;
+		genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward );
+
+		// currently genCall should produce at most one element, but if that changes then the next line needs to be updated to grab the statement which contains the call
+		assert( stmts.size() <= 1 );
+		if ( stmts.size() == 1 ) {
+			Statement * callStmt = stmts.front();
+			if ( addCast ) {
+				// implicitly generated ctor/dtor calls should be wrapped
+				// so that later passes are aware they were generated.
+				// xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,
+				// because this causes the address to be taken at codegen, which is illegal in C.
+				callStmt = new ImplicitCtorDtorStmt( callStmt );
+			}
+			*out++ = callStmt;
+		}
+	}
 } // namespace SymTab
 #endif // AUTOGEN_H
Index: src/SymTab/FixFunction.cc
===================================================================
--- src/SymTab/FixFunction.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SymTab/FixFunction.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// FixFunction.cc -- 
+// FixFunction.cc --
 //
 // Author           : Richard C. Bilson
@@ -44,5 +44,6 @@
 
 	Type * FixFunction::mutate(ArrayType *arrayType) {
-		PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), maybeClone( arrayType->get_base()->clone() ), maybeClone( arrayType->get_dimension() ), arrayType->get_isVarLen(), arrayType->get_isStatic() );
+		// need to recursively mutate the base type in order for multi-dimensional arrays to work.
+		PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->get_base()->clone()->acceptMutator( *this ), maybeClone( arrayType->get_dimension() ), arrayType->get_isVarLen(), arrayType->get_isStatic() );
 		delete arrayType;
 		return pointerType;
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SymTab/Validate.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -174,5 +174,5 @@
 
 		virtual void visit( FunctionDecl *funcDecl );
-};
+	};
 
 	class CompoundLiteral : public GenPoly::DeclMutator {
@@ -191,9 +191,9 @@
 		EliminateTypedef::eliminateTypedef( translationUnit );
 		HoistStruct::hoistStruct( translationUnit );
+		autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs Pass1
 		acceptAll( translationUnit, pass1 );
 		acceptAll( translationUnit, pass2 );
 		ReturnChecker::checkFunctionReturns( translationUnit );
-		mutateAll( translationUnit, compoundliteral );
-		autogenerateRoutines( translationUnit );
+		compoundliteral.mutateDeclarationList( translationUnit );
 		acceptAll( translationUnit, pass3 );
 		VerifyCtorDtor::verify( translationUnit );
@@ -490,5 +490,14 @@
 		EliminateTypedef eliminator;
 		mutateAll( translationUnit, eliminator );
+		if ( eliminator.typedefNames.count( "size_t" ) ) {
+			// grab and remember declaration of size_t
+			SizeType = eliminator.typedefNames["size_t"].first->get_base()->clone();
+		} else {
+			// xxx - missing global typedef for size_t - default to long unsigned int, even though that may be wrong
+			// eventually should have a warning for this case.
+			SizeType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
+		}
 		filter( translationUnit, isTypedef, true );
+
 	}
 
@@ -518,4 +527,5 @@
 	Declaration *EliminateTypedef::mutate( TypedefDecl * tyDecl ) {
 		Declaration *ret = Mutator::mutate( tyDecl );
+
 		if ( typedefNames.count( tyDecl->get_name() ) == 1 && typedefNames[ tyDecl->get_name() ].second == scopeLevel ) {
 			// typedef to the same name from the same scope
Index: src/SynTree/AddStmtVisitor.cc
===================================================================
--- src/SynTree/AddStmtVisitor.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SynTree/AddStmtVisitor.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,6 +10,6 @@
 // Created On       : Wed Jun 22 12:11:17 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul 12 17:49:59 2016
-// Update Count     : 12
+// Last Modified On : Thu Aug  4 11:23:47 2016
+// Update Count     : 16
 //
 
@@ -71,5 +71,5 @@
 
 void AddStmtVisitor::visit(SwitchStmt *switchStmt) {
-	visitStatementList( switchStmt->get_branches() );
+	visitStatementList( switchStmt->get_statements() );
 	maybeAccept( switchStmt->get_condition(), *this );
 }
Index: src/SynTree/Declaration.cc
===================================================================
--- src/SynTree/Declaration.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SynTree/Declaration.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// Declaration.cc -- 
+// Declaration.cc --
 //
 // Author           : Richard C. Bilson
@@ -20,4 +20,5 @@
 #include "Initializer.h"
 #include "Type.h"
+#include "Attribute.h"
 #include "Common/utility.h"
 
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SynTree/Declaration.h	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -64,5 +64,5 @@
 class DeclarationWithType : public Declaration {
   public:
-	DeclarationWithType( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage );
+	DeclarationWithType( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, const std::list< Attribute * > & attributes );
 	DeclarationWithType( const DeclarationWithType &other );
 	virtual ~DeclarationWithType();
@@ -75,4 +75,7 @@
 	int get_scopeLevel() const { return scopeLevel; }
 	void set_scopeLevel( int newValue ) { scopeLevel = newValue; }
+
+	std::list< Attribute * >& get_attributes() { return attributes; }
+	const std::list< Attribute * >& get_attributes() const { return attributes; }
 
 	virtual DeclarationWithType *clone() const = 0;
@@ -87,4 +90,6 @@
 	// shadowed identifiers can be accessed
 	int scopeLevel = 0;
+
+	std::list< Attribute * > attributes;
 };
 
@@ -92,5 +97,5 @@
 	typedef DeclarationWithType Parent;
   public:
-	ObjectDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, Expression *bitfieldWidth, Type *type, Initializer *init, bool isInline = false, bool isNoreturn = false );
+	ObjectDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, Expression *bitfieldWidth, Type *type, Initializer *init, const std::list< Attribute * > attributes = std::list< Attribute * >(), bool isInline = false, bool isNoreturn = false );
 	ObjectDecl( const ObjectDecl &other );
 	virtual ~ObjectDecl();
@@ -131,5 +136,4 @@
 	std::list< std::string >& get_oldIdents() { return oldIdents; }
 	std::list< Declaration* >& get_oldDecls() { return oldDecls; }
-	std::list< Attribute * >& get_attributes() { return attributes; }
 
 	virtual FunctionDecl *clone() const { return new FunctionDecl( *this ); }
@@ -143,5 +147,4 @@
 	std::list< std::string > oldIdents;
 	std::list< Declaration* > oldDecls;
-	std::list< Attribute * > attributes;
 };
 
Index: src/SynTree/DeclarationWithType.cc
===================================================================
--- src/SynTree/DeclarationWithType.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SynTree/DeclarationWithType.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -16,15 +16,18 @@
 #include "Declaration.h"
 #include "Type.h"
+#include "Attribute.h"
 #include "Common/utility.h"
 
-DeclarationWithType::DeclarationWithType( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage )
-		: Declaration( name, sc, linkage ) {
+DeclarationWithType::DeclarationWithType( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, const std::list< Attribute * > & attributes )
+		: Declaration( name, sc, linkage ), attributes( attributes ) {
 }
 
 DeclarationWithType::DeclarationWithType( const DeclarationWithType &other )
 		: Declaration( other ), mangleName( other.mangleName ), scopeLevel( other.scopeLevel ) {
+	cloneAll( other.attributes, attributes );
 }
 
 DeclarationWithType::~DeclarationWithType() {
+	deleteAll( attributes );
 }
 
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SynTree/Expression.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Jun 13 16:03:39 2016
-// Update Count     : 42
+// Last Modified On : Wed Aug  3 17:06:51 2016
+// Update Count     : 45
 //
 
@@ -344,10 +344,11 @@
 }
 
+//// is this right? It's cloning the member, but the member is a declaration so probably shouldn't be cloned...
 MemberExpr::MemberExpr( const MemberExpr &other ) :
-		Expression( other ), member( maybeClone( other.member ) ), aggregate( maybeClone( other.aggregate ) ) {
+		Expression( other ), member( other.member ), aggregate( maybeClone( other.aggregate ) ) {
 }
 
 MemberExpr::~MemberExpr() {
-	delete member;
+	// delete member;
 	delete aggregate;
 }
@@ -528,4 +529,12 @@
 }
 
+RangeExpr::RangeExpr( ConstantExpr *low, ConstantExpr *high ) : low( low ), high( high ) {}
+RangeExpr::RangeExpr( const RangeExpr &other ) : low( other.low->clone() ), high( other.high->clone() ) {}
+void RangeExpr::print( std::ostream &os, int indent ) const {
+	os << std::string( indent, ' ' ) << "Range Expression: ";
+	low->print( os, indent );
+	os << " ... ";
+	high->print( os, indent );
+}
 
 std::ostream & operator<<( std::ostream & out, Expression * expr ) {
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SynTree/Expression.h	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Jul  4 14:45:32 2016
-// Update Count     : 23
+// Last Modified On : Wed Aug  3 17:08:44 2016
+// Update Count     : 27
 //
 
@@ -18,4 +18,5 @@
 
 #include <map>
+#include <memory>
 #include "SynTree.h"
 #include "Visitor.h"
@@ -634,4 +635,22 @@
 };
 
+class RangeExpr : public Expression {
+  public:
+	RangeExpr( ConstantExpr *low, ConstantExpr *high );
+	RangeExpr( const RangeExpr &other );
+
+	ConstantExpr * get_low() const { return low.get(); }
+	ConstantExpr * get_high() const { return high.get(); }
+	RangeExpr * set_low( ConstantExpr *low ) { RangeExpr::low.reset( low ); return this; }
+	RangeExpr * set_high( ConstantExpr *high ) { RangeExpr::high.reset( high ); return this; }
+
+	virtual RangeExpr *clone() const { return new RangeExpr( *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::unique_ptr<ConstantExpr> low, high;
+};
+
 std::ostream & operator<<( std::ostream & out, Expression * expr );
 
Index: src/SynTree/FunctionDecl.cc
===================================================================
--- src/SynTree/FunctionDecl.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SynTree/FunctionDecl.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -23,5 +23,5 @@
 
 FunctionDecl::FunctionDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline, bool isNoreturn, std::list< Attribute * > attributes )
-		: Parent( name, sc, linkage ), type( type ), statements( statements ), attributes( attributes ) {
+		: Parent( name, sc, linkage, attributes ), type( type ), statements( statements ) {
 	set_isInline( isInline );
 	set_isNoreturn( isNoreturn );
@@ -34,5 +34,4 @@
 FunctionDecl::FunctionDecl( const FunctionDecl &other )
 	: Parent( other ), type( maybeClone( other.type ) ), statements( maybeClone( other.statements ) ) {
-		cloneAll( other.attributes, attributes );
 }
 
@@ -40,5 +39,4 @@
 	delete type;
 	delete statements;
-	deleteAll( attributes );
 }
 
@@ -69,5 +67,5 @@
 	} // if
 
-	printAll( attributes, os, indent );
+	printAll( get_attributes(), os, indent );
 
 	if ( get_storageClass() != DeclarationNode::NoStorageClass ) {
Index: src/SynTree/Initializer.h
===================================================================
--- src/SynTree/Initializer.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SynTree/Initializer.h	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -93,6 +93,7 @@
 	std::list<Initializer*> &get_initializers() { return initializers; }
 
-	std::list<Initializer*>::iterator begin_initializers() { return initializers.begin(); }
-	std::list<Initializer*>::iterator end_initializers() { return initializers.end(); }
+	typedef std::list<Initializer*>::iterator iterator;
+	iterator begin() { return initializers.begin(); }
+	iterator end() { return initializers.end(); }
 
 	virtual ListInit *clone() const { return new ListInit( *this ); }
Index: src/SynTree/Label.h
===================================================================
--- src/SynTree/Label.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SynTree/Label.h	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -24,5 +24,5 @@
 class Label {
   public:
-	Label( const std::string & name = "", Statement * labelled = 0 ) : name( name ), labelled( labelled ) {}
+	Label( const std::string & name = "", Statement * labelled = 0, const std::list< Attribute * > & attributes = std::list< Attribute * >() ) : name( name ), labelled( labelled ), attributes( attributes ) {}
 	Label( const char * name, Statement * labelled = 0 ) : name( name ), labelled( labelled ) {}
 
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SynTree/Mutator.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul 12 17:51:19 2016
-// Update Count     : 17
+// Last Modified On : Thu Aug  4 11:23:21 2016
+// Update Count     : 19
 //
 
@@ -126,5 +126,5 @@
 Statement *Mutator::mutate( SwitchStmt *switchStmt ) {
 	switchStmt->set_condition( maybeMutate( switchStmt->get_condition(), *this ) );
-	mutateAll( switchStmt->get_branches(), *this );
+	mutateAll( switchStmt->get_statements(), *this );
 	return switchStmt;
 }
@@ -349,4 +349,10 @@
 	compLitExpr->set_initializer( maybeMutate( compLitExpr->get_initializer(), *this ) );
 	return compLitExpr;
+}
+
+Expression *Mutator::mutate( RangeExpr *rangeExpr ) {
+	rangeExpr->set_low( maybeMutate( rangeExpr->get_low(), *this ) );
+	rangeExpr->set_high( maybeMutate( rangeExpr->get_high(), *this ) );
+	return rangeExpr;
 }
 
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SynTree/Mutator.h	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul 12 17:51:43 2016
-// Update Count     : 11
+// Last Modified On : Wed Aug  3 16:59:45 2016
+// Update Count     : 12
 //
 #include <cassert>
@@ -78,4 +78,5 @@
 	virtual Expression* mutate( UntypedValofExpr *valofExpr );
 	virtual Expression* mutate( CompoundLiteralExpr *compLitExpr );
+	virtual Expression* mutate( RangeExpr *rangeExpr );
 
 	virtual Type* mutate( VoidType *basicType );
Index: src/SynTree/ObjectDecl.cc
===================================================================
--- src/SynTree/ObjectDecl.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SynTree/ObjectDecl.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -18,9 +18,10 @@
 #include "Initializer.h"
 #include "Expression.h"
+#include "Attribute.h"
 #include "Common/utility.h"
 #include "Statement.h"
 
-ObjectDecl::ObjectDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, Expression *bitfieldWidth, Type *type, Initializer *init, bool isInline, bool isNoreturn )
-	: Parent( name, sc, linkage ), type( type ), init( init ), bitfieldWidth( bitfieldWidth ) {
+ObjectDecl::ObjectDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, Expression *bitfieldWidth, Type *type, Initializer *init, const std::list< Attribute * > attributes, bool isInline, bool isNoreturn )
+	: Parent( name, sc, linkage, attributes ), type( type ), init( init ), bitfieldWidth( bitfieldWidth ) {
 	set_isInline( isInline );
 	set_isNoreturn( isNoreturn );
@@ -45,4 +46,6 @@
 		os << LinkageSpec::toString( get_linkage() ) << " ";
 	} // if
+
+	printAll( get_attributes(), os, indent );
 
 	if ( get_storageClass() != DeclarationNode::NoStorageClass ) {
@@ -80,4 +83,6 @@
 	} // if
 
+	// xxx - should printShort print attributes?
+
 	if ( get_storageClass() != DeclarationNode::NoStorageClass ) {
 		os << DeclarationNode::storageName[ get_storageClass() ] << ' ';
Index: src/SynTree/Statement.cc
===================================================================
--- src/SynTree/Statement.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SynTree/Statement.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul 12 17:52:32 2016
-// Update Count     : 55
+// Last Modified On : Thu Aug  4 11:25:20 2016
+// Update Count     : 61
 //
 
@@ -143,19 +143,17 @@
 }
 
-SwitchStmt::SwitchStmt( std::list<Label> _labels, Expression * _condition, std::list<Statement *> &_branches ):
-	Statement( _labels ), condition( _condition ), branches( _branches ) {
+SwitchStmt::SwitchStmt( std::list<Label> _labels, Expression * _condition, std::list<Statement *> &_statements ):
+	Statement( _labels ), condition( _condition ), statements( _statements ) {
 }
 
 SwitchStmt::SwitchStmt( const SwitchStmt & other ):
 	Statement( other ), condition( maybeClone( other.condition ) ) {
-	cloneAll( other.branches, branches );
+	cloneAll( other.statements, statements );
 }
 
 SwitchStmt::~SwitchStmt() {
 	delete condition;
-	// destroy branches
-}
-
-void SwitchStmt::add_case( CaseStmt *c ) {}
+	// destroy statements
+}
 
 void SwitchStmt::print( std::ostream &os, int indent ) const {
@@ -164,10 +162,10 @@
 	os << endl;
 
-	// branches
+	// statements
 	std::list<Statement *>::const_iterator i;
-	for ( i = branches.begin(); i != branches.end(); i++)
+	for ( i = statements.begin(); i != statements.end(); i++)
 		(*i)->print( os, indent + 4 );
 
-	//for_each( branches.begin(), branches.end(), mem_fun( bind1st(&Statement::print ), os ));
+	//for_each( statements.begin(), statements.end(), mem_fun( bind1st(&Statement::print ), os ));
 }
 
@@ -187,6 +185,6 @@
 }
 
-CaseStmt * CaseStmt::makeDefault( std::list<Label> labels, std::list<Statement *> branches ) {
-	return new CaseStmt( labels, 0, branches, true );
+CaseStmt * CaseStmt::makeDefault( std::list<Label> labels, std::list<Statement *> stmts ) {
+	return new CaseStmt( labels, 0, stmts, true );
 }
 
Index: src/SynTree/Statement.h
===================================================================
--- src/SynTree/Statement.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SynTree/Statement.h	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul 12 17:53:29 2016
-// Update Count     : 47
+// Last Modified On : Thu Aug  4 11:26:02 2016
+// Update Count     : 64
 //
 
@@ -129,5 +129,5 @@
 class SwitchStmt : public Statement {
   public:
-	SwitchStmt( std::list<Label> labels, Expression *condition, std::list<Statement *> &branches );
+	SwitchStmt( std::list<Label> labels, Expression *condition, std::list<Statement *> &statements );
 	SwitchStmt( const SwitchStmt &other );
 	virtual ~SwitchStmt();
@@ -136,6 +136,5 @@
 	void set_condition( Expression *newValue ) { condition = newValue; }
 
-	std::list<Statement *> & get_branches() { return branches; }
-	void add_case( CaseStmt * );
+	std::list<Statement *> & get_statements() { return statements; }
 
 	virtual void accept( Visitor &v ) { v.visit( this ); }
@@ -146,16 +145,14 @@
   private:
 	Expression * condition;
-	std::list<Statement *> branches; // should be list of CaseStmt
+	std::list<Statement *> statements;
 };
 
 class CaseStmt : public Statement {
   public:
-	CaseStmt( std::list<Label> labels, Expression *conditions,
-	      std::list<Statement *> &stmts, bool isdef = false ) throw(SemanticError);
+	CaseStmt( std::list<Label> labels, Expression *conditions, std::list<Statement *> &stmts, bool isdef = false ) throw(SemanticError);
 	CaseStmt( const CaseStmt &other );
 	virtual ~CaseStmt();
 
-	static CaseStmt * makeDefault( std::list<Label> labels = std::list<Label>(),
-		std::list<Statement *> stmts = std::list<Statement *>() );
+	static CaseStmt * makeDefault( std::list<Label> labels = std::list<Label>(), std::list<Statement *> stmts = std::list<Statement *>() );
 
 	bool isDefault() const { return _isDefault; }
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SynTree/SynTree.h	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul 12 17:54:02 2016
-// Update Count     : 6
+// Last Modified On : Wed Aug  3 17:02:34 2016
+// Update Count     : 7
 //
 
@@ -83,4 +83,5 @@
 class UntypedValofExpr;
 class CompoundLiteralExpr;
+class RangeExpr;
 
 class Type;
Index: src/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SynTree/Visitor.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul 12 17:54:39 2016
-// Update Count     : 19
+// Last Modified On : Thu Aug  4 11:24:25 2016
+// Update Count     : 21
 //
 
@@ -109,5 +109,5 @@
 void Visitor::visit( SwitchStmt *switchStmt ) {
 	maybeAccept( switchStmt->get_condition(), *this );
-	acceptAll( switchStmt->get_branches(), *this );
+	acceptAll( switchStmt->get_statements(), *this );
 }
 
@@ -296,4 +296,9 @@
 	maybeAccept( compLitExpr->get_type(), *this );
 	maybeAccept( compLitExpr->get_initializer(), *this );
+}
+
+void Visitor::visit( RangeExpr *rangeExpr ) {
+	maybeAccept( rangeExpr->get_low(), *this );
+	maybeAccept( rangeExpr->get_high(), *this );
 }
 
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/SynTree/Visitor.h	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul 12 17:55:09 2016
-// Update Count     : 8
+// Last Modified On : Wed Aug  3 17:01:50 2016
+// Update Count     : 9
 //
 
@@ -78,4 +78,5 @@
 	virtual void visit( UntypedValofExpr *valofExpr );
 	virtual void visit( CompoundLiteralExpr *compLitExpr );
+	virtual void visit( RangeExpr *rangeExpr );
 
 	virtual void visit( VoidType *basicType );
Index: src/examples/gc_no_raii/bug-repro/return_template.c
===================================================================
--- src/examples/gc_no_raii/bug-repro/return_template.c	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/examples/gc_no_raii/bug-repro/return_template.c	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -5,6 +5,11 @@
 };
 
+forall(otype T) void ?{}(wrap(T)* this);
+forall(otype T) void ?{}(wrap(T)* this, wrap(T)* rhs);
+forall(otype T) void ^?{}(wrap(T)* this);
+forall(otype T) void ?=?(wrap(T)* this, wrap(T)* rhs);
+
 forall(otype T)
-static inline wrap(T) test()
+wrap(T) test()
 {
 	wrap(T) tester;
Index: src/examples/gc_no_raii/src/gc.h
===================================================================
--- src/examples/gc_no_raii/src/gc.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/examples/gc_no_raii/src/gc.h	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -7,7 +7,9 @@
 static inline gcpointer(T) gcmalloc()
 {
-    gcpointer(T) test;
-    // ctor(&test, gc_allocate(sizeof(T)));
-    // gc_conditional_collect();
-    return test;
+    gcpointer(T) ptr;
+    void* address = gc_allocate(sizeof(T));
+    (&ptr){ address };
+    ctor(&ptr, address);
+    gc_conditional_collect();
+    return ptr;
 }
Index: src/examples/gc_no_raii/src/gcpointers.c
===================================================================
--- src/examples/gc_no_raii/src/gcpointers.c	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/examples/gc_no_raii/src/gcpointers.c	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -1,5 +1,5 @@
 #include "gcpointers.h"
 
-#include "gc.h"
+// #include "gc.h"
 #include "internal/collector.h"
 #include "internal/object_header.h"
Index: src/examples/gc_no_raii/src/gcpointers.h
===================================================================
--- src/examples/gc_no_raii/src/gcpointers.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/examples/gc_no_raii/src/gcpointers.h	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,9 +10,9 @@
 };
 
-void gcpointer_ctor(gcpointer_t* this);
-void gcpointer_ctor(gcpointer_t* this, void* address);
-void gcpointer_ctor(gcpointer_t* this, gcpointer_t* other);
-void gcpointer_dtor(gcpointer_t* this);
-gcpointer_t* gcpointer_assign(gcpointer_t* this, gcpointer_t* rhs);
+void ?{}(gcpointer_t* this);
+void ?{}(gcpointer_t* this, void* address);
+void ?{}(gcpointer_t* this, gcpointer_t other);
+void ^?{}(gcpointer_t* this);
+gcpointer_t* ?=?(gcpointer_t this, gcpointer_t rhs);
 
 //Logical operators
@@ -27,60 +27,16 @@
 };
 
-forall(otype T)
-static inline void ctor(gcpointer(T)* this)
-{
-	gcpointer_ctor(&this->internal);
-}
+//
+forall(otype T) void ?{}(gcpointer(T)* this);
+forall(otype T) void ?{}(gcpointer(T)* this, void* address);
+forall(otype T) void ctor(gcpointer(T)* this, void* address);
+forall(otype T) void ?{}(gcpointer(T)* this, gcpointer(T)* other);
+forall(otype T) void ^?{}(gcpointer(T)* this);
+forall(otype T) gcpointer(T) ?=?(gcpointer(T) this, gcpointer(T) rhs);
 
-// forall(otype T)
-// static inline void ctor(gcpointer(T)* this, int null)
-// {
-// 	gcpointer_ctor(&this->internal, NULL);
-// }
 
-forall(otype T)
-static inline void ctor(gcpointer(T)* this, void* address)
-{
-	gcpointer_ctor(&this->internal, address);
-}
-
-forall(otype T)
-static inline void ctor(gcpointer(T)* this, gcpointer(T)* other)
-{
-	gcpointer_ctor(&this->internal, other);
-}
-
-forall(otype T)
-static inline void dtor(gcpointer(T)* this)
-{
-	gcpointer_dtor(&this->internal);
-}
-
-forall(otype T)
-static inline gcpointer(T)* ?=?(gcpointer(T)* this, gcpointer(T)* rhs)
-{
-	gcpointer_assign(&this->internal, &rhs->internal);
-	return this;
-}
-
-forall(otype T)
-static inline T *?(gcpointer(T) this)
-{
-	return *(T*)this.internal.ptr;
-}
+forall(otype T) T *?(gcpointer(T) this);
 
 //Logical operators
-forall(otype T)
-static inline int ?!=?(gcpointer(T) this, gcpointer(T) rhs)
-{
-	return this.internal.ptr != rhs.internal.ptr;
-}
-
-forall(otype T)
-static inline int ?==?(gcpointer(T) this, gcpointer(T) rhs)
-{
-	return !(this == rhs);
-}
-
-forall(otype T)
-extern struct gcpointer(T) 0;
+forall(otype T) int ?!=?(gcpointer(T) this, gcpointer(T) rhs);
+forall(otype T) int ?==?(gcpointer(T) this, gcpointer(T) rhs);
Index: src/examples/gc_no_raii/src/internal/memory_pool.h
===================================================================
--- src/examples/gc_no_raii/src/internal/memory_pool.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/examples/gc_no_raii/src/internal/memory_pool.h	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -3,4 +3,5 @@
 extern "C" {
 #include <stdbool.h>
+#include <stddef.h>
 #include <stdint.h>
 }
Index: src/examples/gc_no_raii/src/internal/state.h
===================================================================
--- src/examples/gc_no_raii/src/internal/state.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/examples/gc_no_raii/src/internal/state.h	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -1,9 +1,15 @@
 #pragma once
 
+#ifdef __cforall
+extern "C" {
+#endif
 #include <stddef.h>
 #include <stdint.h>
+#ifdef __cforall
+}
+#endif
+#include <vector>
 
 #include "tools.h"
-#include "vector.h"
 
 typedef vector(struct gc_memory_pool*, heap_allocator(struct gc_memory_pool*)) pools_table_t;
Index: src/examples/gc_no_raii/src/tools/worklist.h
===================================================================
--- src/examples/gc_no_raii/src/tools/worklist.h	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/examples/gc_no_raii/src/tools/worklist.h	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,5 +10,5 @@
 #endif
 
-#include "vector.h"
+#include <vector>
 
 typedef vector(intptr_t*, heap_allocator(intptr_t*)) worklist_t;
Index: src/examples/gc_no_raii/test/badlll.c
===================================================================
--- src/examples/gc_no_raii/test/badlll.c	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/examples/gc_no_raii/test/badlll.c	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -7,46 +7,50 @@
 };
 
+void ?{}(List_t* this);
+List_t* ?=?(List_t* this, List_t* rhs);
+
 typedef gcpointer(List_t) LLL;
 
 #define MAX (1024 * 1024)
 
-LLL buildLLL(int sz)
+// LLL buildLLL(int sz)
+void bla()
 {
 	int i;
-	LLL ll0, lll, llc;
-
-	ll0 = gcmalloc();
-	ll0->val = 0;
-	lll = ll0;
-
-	for (i = 1; i < sz; i++)
-	{
-		llc = gcmalloc();
-		llc->val = i;
-		lll->next = llc;
-		lll = llc;
-	}
-
-	return ll0;
+	// LLL ll0;//, lll, llc;
+//
+// 	ll0 = gcmalloc();
+// 	ll0->val = 0;
+// 	lll = ll0;
+//
+// 	for (i = 1; i < sz; i++)
+// 	{
+// 		llc = gcmalloc();
+// 		llc->val = i;
+// 		lll->next = llc;
+// 		lll = llc;
+// 	}
+//
+	// return ll0;
 }
-
-void testLLL(LLL lll)
-{
-	unsigned char *counted;
-
-	counted = (unsigned char *) calloc(MAX, sizeof(unsigned char));
-	while (lll)
-	{
-		counted[lll->val]++;
-		if (counted[lll->val] > 1)
-		{
-			fprintf(stderr, "ERROR! Encountered %d twice!\n", lll->val);
-			exit(1);
-		}
-		lll = lll->next;
-	}
-
-	return;
-}
+//
+// void testLLL(LLL lll)
+// {
+// 	unsigned char *counted;
+//
+// 	counted = (unsigned char *) calloc(MAX, sizeof(unsigned char));
+// 	while (lll)
+// 	{
+// 		counted[lll->val]++;
+// 		if (counted[lll->val] > 1)
+// 		{
+// 			fprintf(stderr, "ERROR! Encountered %d twice!\n", lll->val);
+// 			exit(1);
+// 		}
+// 		lll = lll->next;
+// 	}
+//
+// 	return;
+// }
 
 int main(void)
@@ -54,7 +58,7 @@
 	LLL mylll;
 
-	mylll = buildLLL(MAX);
-
-	testLLL(mylll);
+	// mylll = buildLLL(MAX);
+	//
+	// testLLL(mylll);
 
 	return 0;
Index: src/examples/gc_no_raii/test/gctest.c
===================================================================
--- src/examples/gc_no_raii/test/gctest.c	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/examples/gc_no_raii/test/gctest.c	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -7,3 +7,5 @@
 int main() {
 	sout | "Bonjour au monde!\n";
+
+	gcpointer(int) anInt = gcmalloc();
 }
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/main.cc	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -43,5 +43,4 @@
 #include "InitTweak/GenInit.h"
 #include "InitTweak/FixInit.h"
-#include "InitTweak/FixGlobalInit.h"
 //#include "Explain/GenProlog.h"
 //#include "Try/Visit.h"
@@ -283,6 +282,4 @@
 		OPTPRINT( "fixNames" )
 		CodeGen::fixNames( translationUnit );
-		OPTPRINT( "fixGlobalInit" );
-		InitTweak::fixGlobalInit( translationUnit, filename, libcfap || treep );
 		OPTPRINT( "tweakInit" )
 		InitTweak::genInit( translationUnit );
@@ -305,7 +302,7 @@
 		}
 
+		// fix ObjectDecl - replaces ConstructorInit nodes
 		OPTPRINT( "fixInit" )
-		// fix ObjectDecl - replaces ConstructorInit nodes
-		InitTweak::fix( translationUnit );
+		InitTweak::fix( translationUnit, filename, libcfap || treep );
 		if ( ctorinitp ) {
 			dump ( translationUnit );
Index: src/tests/.expect/64/extension.txt
===================================================================
--- src/tests/.expect/64/extension.txt	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/tests/.expect/64/extension.txt	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -100,15 +100,2 @@
     ((void)((__extension__ __a__i_2 , __extension__ __b__i_2) , __extension__ __c__i_2));
 }
-__attribute__ ((constructor(),)) static void _init_extension(void){
-    int _global_init0;
-    ((void)((*((int *)(&__a__i_1)))=_global_init0) /* ?{} */);
-    int _global_init1;
-    ((void)((*((int *)(&__b__i_1)))=_global_init1) /* ?{} */);
-    int _global_init2;
-    ((void)((*((int *)(&__c__i_1)))=_global_init2) /* ?{} */);
-}
-__attribute__ ((destructor(),)) static void _destroy_extension(void){
-    ((void)((*((int *)(&__c__i_1)))) /* ^?{} */);
-    ((void)((*((int *)(&__b__i_1)))) /* ^?{} */);
-    ((void)((*((int *)(&__a__i_1)))) /* ^?{} */);
-}
Index: src/tests/.expect/multiDimension.txt
===================================================================
--- src/tests/.expect/multiDimension.txt	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
+++ src/tests/.expect/multiDimension.txt	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -0,0 +1,304 @@
+constructing with 1
+constructing with 2
+constructing with 3
+constructing with 4
+constructing with 5
+constructing with 6
+constructing with 7
+constructing with 8
+constructing with 9
+constructing with 10
+constructing with 1
+constructing with 2
+constructing with 3
+constructing with 4
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+constructing with 1234567
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+constructing with 1
+constructing with 2
+constructing with 3
+constructing with 4
+constructing with 5
+constructing with 6
+constructing with 7
+constructing with 8
+constructing with 9
+constructing with 0
+constructing with 0
+constructing with 0
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+default constructing
+constructing with 999
+constructing with 1111
+default constructing
+default constructing
+constructing with 1
+constructing with 2
+constructing with 3
+constructing with 4
+default constructing
+default constructing
+default constructing
+default constructing
+constructing with 0
+default constructing
+default constructing
+default constructing
+constructing with 11
+constructing with 22
+constructing with 33
+constructing with 55
+constructing with 66
+default constructing
+constructing with 77
+default constructing
+default constructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
+destructing
Index: src/tests/init_once.c
===================================================================
--- src/tests/init_once.c	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/tests/init_once.c	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -92,4 +92,8 @@
 init_once y = x;
 
+void static_variable() {
+	static init_once x;
+}
+
 int main() {
 	// local variables
@@ -179,4 +183,9 @@
 		}
 	}
+
+	// function-scoped static variable
+	for (int i = 0; i < 10; i++) {
+		static_variable();
+	}
 }
 
Index: src/tests/multiDimension.c
===================================================================
--- src/tests/multiDimension.c	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
+++ src/tests/multiDimension.c	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -0,0 +1,72 @@
+struct X {
+  int a;
+  int * ptr;
+};
+
+void ?{}(X * this) {
+  printf("default constructing\n");
+  (&this->a){ 123 };
+  this->ptr = malloc(sizeof(int));
+}
+
+void ?{}(X * this, X other) {
+  printf("copy constructing\n");
+  (&this->a){ other.a };
+  this->ptr = malloc(sizeof(int));
+}
+
+void ?{}(X * this, int a) {
+  printf("constructing with %d\n", a);
+  (&this->a){ a };
+  this->ptr = malloc(sizeof(int));
+}
+
+void ^?{}(X * this) {
+  printf("destructing\n");
+  free(this->ptr);
+}
+
+X ?=?(X * this, X other) {
+  this->a = other.a;
+  return *this;
+}
+
+X global[10][10] = {
+  { 1, { 2 }, { 3 }, { 4 }, 5, 6, 7, 8, 9, 10, 11, 12 },
+  { 1, 2, 3, 4 },
+  { { 1234567 } }
+};
+
+X global2[3][3][3] = {
+  {
+    { 1, 2, 3 },
+    { 4, 5, 6 },
+    { 7, 8, 9 },
+    { 10, 11, 12 }
+  },
+  {
+    { 0, 0, 0 }
+  }
+};
+
+int foo() {
+  static X abc[3][3] = {
+    { 11, 22, 33, 44 },
+    { 55, 66 },
+    { 77 },
+    { 88, 99, 1010 }
+  };
+}
+
+int main() {
+  X abc[4][4] = {
+    { 999, 1111 },
+    { 1, 2, 3, 4, 5 },
+    {},
+    { 0 },
+    { 88 }
+  };
+
+  foo();
+  foo();
+}
Index: src/tests/switch.c
===================================================================
--- src/tests/switch.c	(revision 5070fe4b9ad7bec2681f51b6b650a12237ceefc1)
+++ src/tests/switch.c	(revision c3314061a7f72e82701eb3e9bdf37c2cd6d45268)
@@ -10,6 +10,6 @@
 // Created On       : Tue Jul 12 06:50:22 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 30 14:41:32 2016
-// Update Count     : 30
+// Last Modified On : Thu Aug  4 11:44:29 2016
+// Update Count     : 31
 // 
 
@@ -39,4 +39,12 @@
 	  case 4:
 		j = 0;
+	}
+
+	switch ( i ) {
+	  case 1, 2, 3:
+		switch ( i ) {
+		  case 2, 3, 4:
+			7;
+		}
 	}
 
