Index: translator/Abstype.c
===================================================================
--- translator/Abstype.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Abstype.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,28 @@
+// "cfa-cpp -nx Abstype.c"
+
+type T | { T x( T ); };
+
+T y( T t )
+{
+	T t_instance;
+	return x( t );
+}
+
+forall(type T) lvalue T			*?(                T* );
+int		?++( int *);
+int ?=?( int*, int );
+forall(dtype DT) DT* 		   	?=?(                DT *          *,          DT* );
+
+type U = int*;
+
+U x( U u )
+{
+	U u_instance = u;
+	(*u)++;
+	return u;
+}
+
+int *break_abstraction( U u )
+{
+	return u;
+}
Index: translator/ArgTweak/FunctionFixer.cc
===================================================================
--- translator/ArgTweak/FunctionFixer.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ArgTweak/FunctionFixer.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,117 @@
+#include <list>
+#include <vector>
+#include <cassert>
+#include <algorithm>
+
+#include "FunctionFixer.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+
+namespace ArgTweak {
+
+
+  FunctionFixer::FunctionFixer( SymTab::Indexer *ind ) : index( ind )
+  {
+    if ( index == 0 ) index = new SymTab::Indexer();
+  }
+
+  FunctionFixer::~FunctionFixer()
+  {
+    delete index;
+  }
+
+  DeclarationWithType *FunctionFixer::mutate( FunctionDecl *functionDecl )
+  {
+    index->visit( functionDecl );
+    /* check for duplicate named parameters here?  It might not be an
+    error if they're never used, on the other hand, it might be to
+    costly to check for duplicates every time we try a match */
+    return Parent::mutate( functionDecl );
+  }
+
+  Expression *FunctionFixer::mutate( UntypedExpr *untypedExpr )
+    throw ( SemanticError )
+  {
+    assert( untypedExpr != 0 );
+    NameExpr *function;
+
+    if ( ( function = dynamic_cast< NameExpr *>(untypedExpr->get_function()) ) != 0 )
+      {
+	std::list < DeclarationWithType * > options;
+	index->lookupId ( function->get_name(), options );
+ 	for ( std::list < DeclarationWithType * >::iterator i = options.begin(); i != options.end(); i++ )
+ 	  {
+ 	    FunctionType *f;
+ 	    if ( ( f = dynamic_cast< FunctionType * > ( (*i)->get_type() ) ) != 0 )
+ 	      {
+ 		std::list < DeclarationWithType * > &pars = f->get_parameters();
+
+ 		bool candidateExists ;
+ 		for( std::list < DeclarationWithType * >::iterator p = pars.begin(); p != pars.end(); p++ )
+ 		  if ( ( candidateExists = align( f->get_parameters(), untypedExpr->get_args(), Matcher() ) ) ) break;
+
+ 		if ( !candidateExists ) throw SemanticError("Error in function call");
+ 	      }
+ 	  }
+      }
+    return untypedExpr;
+  }
+
+  template < class L1, class L2, class Helper >
+  bool align( L1 &pattern, L2 &possible_permutation, Helper help )
+  {
+    std::map < typename Helper::key, int > positions;
+    int p = 0;
+
+    for ( typename L1::iterator i = pattern.begin(); i != pattern.end(); i++, p++ )
+      if ( help.extract_key( *i ) != Helper::null_key )
+	positions[ help.extract_key( *i ) ] = p;
+
+    L2 copy_pp( possible_permutation );
+
+    std::vector< typename L2::value_type > temp(copy_pp.size(), Helper::null_value );
+    for ( typename L2::iterator i = copy_pp.begin(); i != copy_pp.end(); i++ )
+      if ( positions.find( help.extract_key( *i ) ) != positions.end() ) {
+	temp [ positions [ help.extract_key( *i ) ] ] = *i;
+	*i = Helper::null_value;
+      }
+
+    // rest of the arguments
+    int a = 0;
+    bool goAhead = true;  // go ahead and change the list
+    for ( typename L2::iterator i = copy_pp.begin(); i != copy_pp.end(); i++, a++ ) {
+      if (  *i != Helper::null_value )
+	if ( temp[a] == Helper::null_value )
+	  temp[a] = *i;
+	else
+	  { goAhead = false; /* there's something there already */; break; }
+      else
+	if ( temp[a] == Helper::null_value )
+	  { goAhead = false; /* can't leave empty spaces */ break; }
+	else
+	  ; // all good, this was filled during the first pass
+      assert ( temp[a] != Helper::null_value );
+    }
+
+    // Change the original list
+    if ( goAhead ) std::copy( temp.begin(), temp.end(), possible_permutation.begin() );
+
+    return goAhead;
+  }
+
+  std::string FunctionFixer::Matcher::null_key("");
+  Expression *FunctionFixer::Matcher::null_value = 0;
+
+  std::string FunctionFixer::Matcher::extract_key ( DeclarationWithType *decl ) {
+    return decl->get_name();
+  }
+
+  std::string FunctionFixer::Matcher::extract_key ( Expression *expression ) {
+    if ( expression->get_argName() == 0 )
+      return std::string("");
+    else
+      return *(expression->get_argName());
+  }
+
+} // namespace ArgTweak
Index: translator/ArgTweak/FunctionFixer.h
===================================================================
--- translator/ArgTweak/FunctionFixer.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ArgTweak/FunctionFixer.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,50 @@
+#ifndef _DEFS_FUNCTION_FIXER_H_
+#define _DEFS_FUNCTION_FIXER_H_
+
+#include "SynTree/Mutator.h"
+#include "SymTab/Indexer.h"
+
+#include "SynTree/Expression.h"
+
+namespace ArgTweak {
+  class FunctionFixer : public Mutator
+  {
+    typedef Mutator Parent;
+
+  public:
+    FunctionFixer(SymTab::Indexer *ind = 0);
+    ~FunctionFixer();
+
+    virtual DeclarationWithType *mutate( FunctionDecl *functionDecl );
+    virtual Expression *mutate( UntypedExpr *untypedExpr ) throw ( SemanticError );
+
+  private:
+    class Matcher {
+      typedef std::string key;
+      typedef DeclarationWithType * pattern_type;
+      typedef Expression * permutation_type;
+    public:
+      static key null_key;
+      static permutation_type null_value;
+
+      std::string extract_key( DeclarationWithType * );
+      std::string extract_key( Expression * );
+
+      bool operator()( DeclarationWithType *, Expression * ) { return true; }
+    };
+
+    SymTab::Indexer *index;
+  };
+
+  template < class L1, class L2, class Predicate > bool align( L1 &pattern, L2 &possible_permutation, Predicate pred ); 
+
+} // namespace ArgTweak
+
+
+#endif // #ifndef _DEFS_FUNCTION_FIXER_H_
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/ArgTweak/Mutate.cc
===================================================================
--- translator/ArgTweak/Mutate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ArgTweak/Mutate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,17 @@
+#include "SynTree/Mutator.h"
+
+#include "Mutate.h"
+#include "FunctionFixer.h"
+
+namespace ArgTweak {
+
+  void mutate( std::list< Declaration * > translationUnit )
+  {
+    FunctionFixer ff;
+
+    mutateAll( translationUnit, ff );
+  }
+
+} // namespace ArgTweak
+
+
Index: translator/ArgTweak/Mutate.h
===================================================================
--- translator/ArgTweak/Mutate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ArgTweak/Mutate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,21 @@
+#ifndef ARGTWEAK_MUTATE_H
+#define ARGTWEAK_MUTATE_H
+
+#include <list>
+#include <iostream>
+
+#include "SynTree/Declaration.h"
+
+namespace ArgTweak {
+
+  void mutate( std::list< Declaration* > translationUnit );
+
+} // namespace ArgTweak
+
+#endif // #ifndef ARGTWEAK_MUTATE_H
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/ArgTweak/module.mk
===================================================================
--- translator/ArgTweak/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ArgTweak/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,4 @@
+SRC +=  ArgTweak/Rewriter.cc \
+#	ArgTweak/Mutate.cc \
+	$(NULL)
+
Index: translator/CodeGen/CodeGenerator2.cc
===================================================================
--- translator/CodeGen/CodeGenerator2.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/CodeGenerator2.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,715 @@
+#include <algorithm>
+#include <iostream>
+#include <cassert>
+#include <list>
+
+#include "SynTree/Type.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Initializer.h"
+
+#include "utility.h"
+#include "UnimplementedError.h"
+
+#include "CodeGenerator2.h"
+#include "OperatorTable.h"
+#include "GenType.h"
+
+using namespace std;
+
+namespace CodeGen {
+
+  int CodeGenerator2::tabsize = 4;
+
+  CodeGenerator2::CodeGenerator2( std::ostream &os ) : cur_indent( 0 ), insideFunction( false ), before(os), after() { }
+
+  CodeGenerator2::CodeGenerator2(std::ostream &os, std::string init, int indent, bool infunp )
+    : cur_indent( indent ), insideFunction( infunp ), before(os), after()
+  {
+    //before << std::string( init );
+  }
+
+  CodeGenerator2::CodeGenerator2(std::ostream &os, char *init, int indent, bool infunp )
+    : cur_indent( indent ), insideFunction( infunp ), before(os), after()
+  {
+    //before << std::string( init );
+  }
+
+  CodeGenerator2::~CodeGenerator2() {
+    after.freeze( false );
+  }
+
+  string
+  mangleName( DeclarationWithType *decl ) {
+    if( decl->get_mangleName() != "" ) {
+      return decl->get_mangleName();
+    } else {
+      return decl->get_name();
+    }
+  }
+  
+  //*** Declarations
+  void CodeGenerator2::visit(FunctionDecl *functionDecl){
+  
+    handleStorageClass( functionDecl );
+    before << genType( functionDecl->get_functionType(), mangleName( functionDecl ) );
+
+    // how to get this to the Functype?
+    std::list< Declaration * > olds = functionDecl->get_oldDecls();
+    if( ! olds.empty() ) {
+      before << " /* function has old declaration */";
+    }
+
+    // acceptAll( functionDecl->get_oldDecls(), *this );
+    if( functionDecl->get_statements() ) {
+      functionDecl->get_statements()->accept(*this);
+    }
+  }
+
+  void CodeGenerator2::visit(ObjectDecl *objectDecl){
+
+    handleStorageClass( objectDecl );
+    before << genType( objectDecl->get_type(), mangleName( objectDecl ) );
+    
+    if( objectDecl->get_init() ) {
+      before << " = ";
+      objectDecl->get_init()->accept( *this );
+    }
+    if( objectDecl->get_bitfieldWidth() ) {
+      before << ":";
+      objectDecl->get_bitfieldWidth()->accept( *this );
+    }
+  }
+
+  void
+  CodeGenerator2::handleAggregate( AggregateDecl *aggDecl )
+  {
+    if ( aggDecl->get_name() != "" )
+      before << aggDecl->get_name();
+    
+    std::list< Declaration * > &memb = aggDecl->get_members();
+
+    if( ! memb.empty() ){
+      before << endl << string(cur_indent, ' ') << "{" << endl;
+
+      cur_indent += CodeGenerator2::tabsize; 
+      for(std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++){
+	before << string(cur_indent, ' '); 
+	(*i)->accept(*this);
+	before << ";" << endl;
+      }
+
+      cur_indent -= CodeGenerator2::tabsize; 
+
+      before << string(cur_indent, ' ') << "}";
+    }
+  }
+
+  void CodeGenerator2::visit( StructDecl *structDecl ){
+    before << "struct ";
+    handleAggregate( structDecl );
+  }
+
+  void 
+  CodeGenerator2::visit(UnionDecl *aggregateDecl)
+  {
+    before << "union ";
+    handleAggregate( aggregateDecl );
+  }
+  
+  void 
+  CodeGenerator2::visit(EnumDecl *aggDecl)
+  {
+    before << "enum ";
+
+    if ( aggDecl->get_name() != "" )
+      before << aggDecl->get_name();
+    
+    std::list< Declaration* > &memb = aggDecl->get_members();
+
+    if( ! memb.empty() ){
+      before << endl << "{" << endl;
+
+      cur_indent += CodeGenerator2::tabsize; 
+      for(std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++){
+        ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
+        assert( obj );
+	before << string(cur_indent, ' ') << mangleName( obj ); 
+	if( obj->get_init() ) {
+	  before << " = ";
+	  obj->get_init()->accept(*this);
+	}
+	before << "," << endl;
+      }
+
+      cur_indent -= CodeGenerator2::tabsize; 
+
+      before << "}" << endl;
+    }
+  }
+  
+  void 
+  CodeGenerator2::visit(ContextDecl *aggregateDecl)
+  {
+  }
+  
+  void 
+  CodeGenerator2::visit(TypedefDecl *typeDecl)
+  {
+    before << "typedef ";
+    before << genType( typeDecl->get_base(), typeDecl->get_name() );
+  }
+  
+  void 
+  CodeGenerator2::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
+    before << "extern unsigned long " << typeDecl->get_name();
+    if( typeDecl->get_base() ) {
+      before << " = sizeof( " << genType( typeDecl->get_base(), "" ) << " )";
+    }
+  }
+
+  //*** Initializer
+  void
+  CodeGenerator2::visit(SingleInit *init)
+  {
+    init->get_value()->accept( *this );
+  }
+
+  void
+  CodeGenerator2::visit(ListInit *init)
+  {
+    before << "{ ";
+    genCommaList( init->begin_initializers(), init->end_initializers() );
+    before << " }";
+  }
+
+  //*** Constant
+  void CodeGenerator2::visit(Constant *constant) { 
+    before << constant->get_value() ;
+  }
+
+  //*** Expressions
+  void 
+  CodeGenerator2::visit(ApplicationExpr *applicationExpr)
+  {
+    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 ) ) {
+        std::list< Expression* >::iterator arg = applicationExpr->get_args().begin();
+        switch( opInfo.type ) {
+        case OT_PREFIXASSIGN:
+        case OT_POSTFIXASSIGN:
+        case OT_INFIXASSIGN:
+        {
+          assert( arg != applicationExpr->get_args().end() );
+          if( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
+            
+            *arg = addrExpr->get_arg();
+          } else {
+            UntypedExpr *newExpr = new UntypedExpr( new NameExpr( "*?" ) );
+            newExpr->get_args().push_back( *arg );
+            *arg = newExpr;
+          }
+          break;
+        }
+          
+        default:
+          // do nothing
+          ;
+        }
+        
+        switch( opInfo.type ) {
+        case OT_INDEX:
+          assert( applicationExpr->get_args().size() == 2 );
+          (*arg++)->accept( *this );
+          before << "[";
+          (*arg)->accept( *this );
+          before << "]";
+          break;
+          
+        case OT_CALL:
+          // there are no intrinsic definitions of the function call operator
+          assert( false );
+          break;
+          
+        case OT_PREFIX:
+        case OT_PREFIXASSIGN:
+          assert( applicationExpr->get_args().size() == 1 );
+          before << "(";
+          before << opInfo.symbol;
+          (*arg)->accept( *this );
+          before << ")";
+          break;
+          
+        case OT_POSTFIX:
+        case OT_POSTFIXASSIGN:
+          assert( applicationExpr->get_args().size() == 1 );
+          (*arg)->accept( *this );
+          before << opInfo.symbol;
+          break;
+
+        case OT_INFIX:
+        case OT_INFIXASSIGN:
+          assert( applicationExpr->get_args().size() == 2 );
+          before << "(";
+          (*arg++)->accept( *this );
+          before << opInfo.symbol;
+          (*arg)->accept( *this );
+          before << ")";
+          break;
+          
+        case OT_CONSTANT:
+          // there are no intrinsic definitions of 0 or 1 as functions
+          assert( false );
+        }
+      } else {
+        varExpr->accept( *this );
+        before << "(";
+        genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
+        before << ")";
+      }
+    } else {
+      applicationExpr->get_function()->accept( *this );
+      before << "(";
+      genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
+      before << ")";
+    }
+  }
+  
+  void 
+  CodeGenerator2::visit(UntypedExpr *untypedExpr)
+  {
+    if( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
+      OperatorInfo opInfo;
+      if( operatorLookup( nameExpr->get_name(), opInfo ) ) {
+        std::list< Expression* >::iterator arg = untypedExpr->get_args().begin();
+        switch( opInfo.type ) {
+        case OT_INDEX:
+          assert( untypedExpr->get_args().size() == 2 );
+          (*arg++)->accept( *this );
+          before << "[";
+          (*arg)->accept( *this );
+          before << "]";
+          break;
+          
+        case OT_CALL:
+          assert( false );
+          break;
+          
+        case OT_PREFIX:
+        case OT_PREFIXASSIGN:
+          assert( untypedExpr->get_args().size() == 1 );
+          before << "(";
+          before << opInfo.symbol;
+          (*arg)->accept( *this );
+          before << ")";
+          break;
+          
+        case OT_POSTFIX:
+        case OT_POSTFIXASSIGN:
+          assert( untypedExpr->get_args().size() == 1 );
+          (*arg)->accept( *this );
+          before << opInfo.symbol;
+          break;
+  
+        case OT_INFIX:
+        case OT_INFIXASSIGN:
+          assert( untypedExpr->get_args().size() == 2 );
+          before << "(";
+          (*arg++)->accept( *this );
+          before << opInfo.symbol;
+          (*arg)->accept( *this );
+          before << ")";
+          break;
+          
+        case OT_CONSTANT:
+          // there are no intrinsic definitions of 0 or 1 as functions
+          assert( false );
+        }
+      } else {
+        nameExpr->accept( *this );
+        before << "(";
+        genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
+        before << ")";
+      }
+    } else {
+      untypedExpr->get_function()->accept( *this );
+      before << "(";
+      genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
+      before << ")";
+    }
+  }
+  
+  void 
+  CodeGenerator2::visit(NameExpr *nameExpr)
+  {
+    OperatorInfo opInfo;
+    if( operatorLookup( nameExpr->get_name(), opInfo ) ) {
+      assert( opInfo.type == OT_CONSTANT );
+      before << opInfo.symbol;
+    } else {
+      before << nameExpr->get_name();
+    }
+  }
+  
+  void 
+  CodeGenerator2::visit(AddressExpr *addressExpr)
+  {
+    before << "(&";
+    // 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() ) ) {
+      before << mangleName( variableExpr->get_var() );
+    } else {
+      addressExpr->get_arg()->accept( *this );
+    }
+    before << ")";
+  }
+
+  void 
+  CodeGenerator2::visit(CastExpr *castExpr)
+  {
+    before << "((";
+    if( castExpr->get_results().empty() ) {
+      before << "void" ;
+    } else {
+      before << genType( castExpr->get_results().front(), "" );
+    }
+    before << ")";
+    castExpr->get_arg()->accept( *this );
+    before << ")";
+  }
+  
+  void 
+  CodeGenerator2::visit(UntypedMemberExpr *memberExpr)
+  {
+    assert( false );
+  }
+  
+  void 
+  CodeGenerator2::visit(MemberExpr *memberExpr)
+  {
+    memberExpr->get_aggregate()->accept( *this );
+    before << "." << mangleName( memberExpr->get_member() );
+  }
+  
+  void 
+  CodeGenerator2::visit(VariableExpr *variableExpr)
+  {
+    OperatorInfo opInfo;
+    if( variableExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( variableExpr->get_var()->get_name(), opInfo ) && opInfo.type == OT_CONSTANT ) {
+      before << opInfo.symbol;
+    } else {
+      before << mangleName( variableExpr->get_var() );
+    }
+  }
+  
+  void 
+  CodeGenerator2::visit(ConstantExpr *constantExpr)
+  {
+    assert( constantExpr->get_constant() );
+    constantExpr->get_constant()->accept( *this );
+  }
+  
+  void 
+  CodeGenerator2::visit(SizeofExpr *sizeofExpr)
+  {
+    before << "sizeof(";
+    if( sizeofExpr->get_isType() ) {
+      before << genType( sizeofExpr->get_type(), "" );
+    } else {
+      sizeofExpr->get_expr()->accept( *this );
+    }
+    before << ")";
+ }
+  
+  void 
+  CodeGenerator2::visit(LogicalExpr *logicalExpr)
+  {
+    before << "(";
+    logicalExpr->get_arg1()->accept( *this );
+    if( logicalExpr->get_isAnd() ) {
+      before << " && ";
+    } else {
+      before << " || ";
+    }
+    logicalExpr->get_arg2()->accept( *this );
+    before << ")";
+  }
+  
+  void 
+  CodeGenerator2::visit(ConditionalExpr *conditionalExpr)
+  {
+    before << "(";
+    conditionalExpr->get_arg1()->accept( *this );
+    before << " ? ";
+    conditionalExpr->get_arg2()->accept( *this );
+    before << " : ";
+    conditionalExpr->get_arg3()->accept( *this );
+    before << ")";
+  }
+  
+  void 
+  CodeGenerator2::visit(CommaExpr *commaExpr)
+  {
+    before << "(";
+    commaExpr->get_arg1()->accept( *this );
+    before << " , ";
+    commaExpr->get_arg2()->accept( *this );
+    before << ")";
+  }
+  
+  void 
+  CodeGenerator2::visit(TupleExpr *tupleExpr)
+  {
+  }
+  
+  void 
+  CodeGenerator2::visit(TypeExpr *typeExpr)
+  {
+  }
+  
+  
+  //*** Statements
+  void CodeGenerator2::visit(CompoundStmt *compoundStmt){
+    std::list<Statement*> ks = compoundStmt->get_kids();
+
+    before << endl << string(cur_indent,' ') << "{" << endl;
+
+    cur_indent += CodeGenerator2::tabsize; 
+
+    for(std::list<Statement *>::iterator i = ks.begin(); i != ks.end();  i++){
+      before << string(cur_indent, ' ') << printLabels( (*i)->get_labels() )  ;
+      (*i)->accept(*this);
+      shift_left();
+      before << endl;
+    }
+    cur_indent -= CodeGenerator2::tabsize; 
+
+    before << string(cur_indent,' ') << "}" << endl;
+  }
+
+  void CodeGenerator2::visit(ExprStmt *exprStmt){
+    if(exprStmt != 0){
+      exprStmt->get_expr()->accept( *this );
+      shift_left();
+      before << ";" ;
+    }
+  }
+
+  void CodeGenerator2::visit(IfStmt *ifStmt){
+    before << "if (";
+    ifStmt->get_condition()->accept(*this);
+    after << ")" << endl ;
+    shift_left(); 
+
+    cur_indent += CodeGenerator2::tabsize;
+    before << string(cur_indent, ' ');
+    ifStmt->get_thenPart()->accept(*this);
+    cur_indent -= CodeGenerator2::tabsize; 
+    shift_left(); before << endl;
+
+    if(ifStmt->get_elsePart() != 0){
+      before << string(cur_indent, ' ') << " else " << endl ;
+
+      cur_indent += CodeGenerator2::tabsize; 
+      ifStmt->get_elsePart()->accept(*this);
+      cur_indent -= CodeGenerator2::tabsize; 
+    }
+  }
+
+  void CodeGenerator2::visit(SwitchStmt *switchStmt){
+    //before << /* "\r" << */ string(cur_indent, ' ') << CodeGenerator2::printLabels( switchStmt->get_labels() ) 
+    before << "switch (" ;
+    switchStmt->get_condition()->accept(*this);
+    after << ")" << std::endl ;
+    shift_left();
+
+    before << string(cur_indent, ' ') << "{" << std::endl;
+    cur_indent += CodeGenerator2::tabsize;
+
+    std::list< Statement * > stmts = switchStmt->get_branches();
+    bool lastBreak = false; 
+
+    // horrible, horrible hack
+    if( dynamic_cast<BranchStmt *>(stmts.back()) != 0 ) {
+      lastBreak = true;
+      stmts.pop_back();
+    }
+    acceptAll(stmts, *this );
+    if ( lastBreak ) {
+      Statement *st = switchStmt->get_branches().back();
+      before << CodeGenerator2::printLabels(st->get_labels());
+      st->accept(*this);
+    }
+      
+    cur_indent -= CodeGenerator2::tabsize; 
+
+    before << /* "\r" << */ string(cur_indent, ' ') << "}" << endl ;
+  }
+
+  void CodeGenerator2::visit(CaseStmt *caseStmt){
+    before << string(cur_indent, ' ');
+    if (caseStmt->isDefault()) 
+      before << "default "  ;
+    else {
+      before << "case "  ;
+      caseStmt->get_condition()->accept(*this);
+    }
+    after << ":" << std::endl ;
+    shift_left();
+
+    std::list<Statement *> sts = caseStmt->get_statements();
+
+    cur_indent += CodeGenerator2::tabsize;
+    for(std::list<Statement *>::iterator i = sts.begin(); i != sts.end();  i++){
+      before << /* "\r" << */ string(cur_indent, ' ') << printLabels( (*i)->get_labels() )  ;
+      (*i)->accept(*this);
+      shift_left();
+      before << ";" << endl;
+    }
+    cur_indent -= CodeGenerator2::tabsize;
+  }
+
+  void CodeGenerator2::visit(BranchStmt *branchStmt){
+    switch(branchStmt->get_type()){
+    case BranchStmt::Goto:
+      if( ! branchStmt->get_target().empty() )
+	before << "goto " << branchStmt->get_target();
+      else { 
+	if ( branchStmt->get_computedTarget() != 0 ) {
+	  before << "goto *";
+	  branchStmt->get_computedTarget()->accept(*this);
+	}
+      }
+      break;
+    case BranchStmt::Break:
+      before << "break";
+      break;
+    case BranchStmt::Continue:
+      before << "continue";
+      break;
+    }
+    before << ";";
+  }
+
+
+  void CodeGenerator2::visit(ReturnStmt *returnStmt){
+    before << "return ";
+
+    // xxx -- check for null expression;
+    if ( returnStmt->get_expr() ){
+      returnStmt->get_expr()->accept( *this );
+    }
+    after << ";";
+  }
+
+  void CodeGenerator2::visit(WhileStmt *whileStmt){
+    if( whileStmt->get_isDoWhile() )
+      before << "do" ;
+    else {
+      before << "while(" ;
+      whileStmt->get_condition()->accept(*this);
+      after << ")";
+    }
+    after << "{" << endl  ;
+    shift_left();
+
+    whileStmt->get_body()->accept( *this );
+
+    before << /* "\r" << */ string(cur_indent, ' ') << "}" ;
+
+    if( whileStmt->get_isDoWhile() ){
+      before << " while(" ;
+      whileStmt->get_condition()->accept(*this);
+      after << ");";
+    }
+
+    after << endl;
+  }
+
+  void CodeGenerator2::visit(ForStmt *forStmt){
+    before << "for (";
+
+    if( forStmt->get_initialization() != 0 )
+      forStmt->get_initialization()->accept( *this );
+    else
+      before << ";";
+    shift_left();
+
+    if( forStmt->get_condition() != 0 )
+      forStmt->get_condition()->accept( *this );
+    shift_left(); before << ";";
+
+    if( forStmt->get_increment() != 0 )
+      forStmt->get_increment()->accept( *this );
+    shift_left(); before << ")" << endl;
+
+    if( forStmt->get_body() != 0 ){
+      cur_indent += CodeGenerator2::tabsize; 
+      before << string(cur_indent, ' ') << CodeGenerator2::printLabels( forStmt->get_body()->get_labels() );
+      forStmt->get_body()->accept( *this );
+      cur_indent -= CodeGenerator2::tabsize; 
+    }
+  }
+
+  void CodeGenerator2::visit(NullStmt *nullStmt){
+    //before << /* "\r" << */ string(cur_indent, ' ') << CodeGenerator2::printLabels( nullStmt->get_labels() );
+    before << "/* null statement */ ;";
+  }
+
+  void CodeGenerator2::visit(DeclStmt *declStmt){
+    declStmt->get_decl()->accept( *this );
+    
+    if( doSemicolon( declStmt->get_decl() ) ) {
+      after << ";";
+    }
+    shift_left();
+  }
+
+  std::string CodeGenerator2::printLabels ( std::list< Label > &l ) {
+    std::string str("");
+    l.unique();
+
+    for( std::list< Label >::iterator i = l.begin(); i != l.end(); i++)
+      str += *i + ": ";
+
+    return str;
+  }
+
+  void CodeGenerator2::shift_left(){
+    before << string(after.str(), after.pcount());
+
+    after.freeze( false );
+    after.seekp(0);
+  }
+
+  void 
+  CodeGenerator2::handleStorageClass( Declaration *decl )
+  {
+    switch( decl->get_storageClass() ) {
+    case Declaration::NoStorageClass:
+      break;
+    case Declaration::Auto:
+      break;
+    case Declaration::Static:
+      before << "static ";
+      break;
+    case Declaration::Extern:
+      before << "extern ";
+      break;
+    case Declaration::Register:
+      before << "register ";
+      break;
+    case Declaration::Fortran:
+      before << "fortran ";
+      break;
+    }
+  }
+
+} // namespace CodeGen
+
+
Index: translator/CodeGen/CodeGenerator2.h
===================================================================
--- translator/CodeGen/CodeGenerator2.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/CodeGenerator2.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,123 @@
+#ifndef CODEGENV_H
+#define CODEGENV_H
+
+#include <strstream>
+#include <list>
+
+#include "SynTree/SynTree.h"
+#include "SynTree/Visitor.h"
+#include "SymTab/Indexer.h"
+
+namespace CodeGen {
+
+  class CodeGenerator2 : public Visitor
+    {
+    public:
+      static int tabsize;
+
+      CodeGenerator2( std::ostream &os );
+      CodeGenerator2(std::ostream &os, std::string, int indent = 0, bool infun = false );
+      CodeGenerator2(std::ostream &os, char *, int indent = 0, bool infun = false );
+
+      CodeGenerator2( CodeGenerator2 & );
+
+      virtual ~CodeGenerator2();
+
+      //*** Declaration
+      virtual void visit(StructDecl *);
+      virtual void visit(FunctionDecl *);
+      virtual void visit(ObjectDecl *);
+      virtual void visit(UnionDecl *aggregateDecl);
+      virtual void visit(EnumDecl *aggregateDecl);
+      virtual void visit(ContextDecl *aggregateDecl);
+      virtual void visit(TypedefDecl *typeDecl);
+      virtual void visit(TypeDecl *typeDecl);
+
+      //*** Initializer
+      virtual void visit(SingleInit *);
+      virtual void visit(ListInit *);
+
+      //*** Constant
+      virtual void visit(Constant *);
+
+      //*** Expression
+      virtual void visit(ApplicationExpr *applicationExpr);
+      virtual void visit(UntypedExpr *untypedExpr);
+      virtual void visit(NameExpr *nameExpr);
+      virtual void visit(AddressExpr *addressExpr);
+      virtual void visit(CastExpr *castExpr);
+      virtual void visit(UntypedMemberExpr *memberExpr);
+      virtual void visit(MemberExpr *memberExpr);
+      virtual void visit(VariableExpr *variableExpr);
+      virtual void visit(ConstantExpr *constantExpr); 
+      virtual void visit(SizeofExpr *sizeofExpr);
+      virtual void visit(LogicalExpr *logicalExpr);
+      virtual void visit(ConditionalExpr *conditionalExpr);
+      virtual void visit(CommaExpr *commaExpr);
+      virtual void visit(TupleExpr *tupleExpr);
+      virtual void visit(TypeExpr *typeExpr);
+
+      //*** Statements
+      virtual void visit(CompoundStmt *);
+      virtual void visit(ExprStmt *);
+      virtual void visit(IfStmt *);
+      virtual void visit(SwitchStmt *);
+      virtual void visit(CaseStmt *);
+      virtual void visit(BranchStmt *);
+      virtual void visit(ReturnStmt *);
+      virtual void visit(WhileStmt *);
+      virtual void visit(ForStmt *);
+      virtual void visit(NullStmt *);
+      virtual void visit(DeclStmt *); 
+
+      std::string get_string(void);
+      void add_string_left(std::string s) { before << s; }
+      void shift_left();
+      template< class Iterator > void genCommaList( Iterator begin, Iterator end );
+
+    private:
+      int cur_indent;
+      bool insideFunction;
+      std::ostream &before;
+      std::ostrstream after;
+
+      static std::string printLabels ( std::list < Label > & );
+      void handleStorageClass( Declaration *decl );
+      void handleAggregate( AggregateDecl *aggDecl );
+      void handleTypedef( NamedTypeDecl *namedType );
+
+    };
+    
+  template< class Iterator >
+  void
+  CodeGenerator2::genCommaList( Iterator begin, Iterator end )
+  {
+    if( begin == end ) return;
+    
+    for( ;; ) {
+      (*begin++)->accept( *this );
+      
+      if( begin == end ) return;
+      
+      before << ", ";
+    }
+  }
+  
+  inline bool
+  doSemicolon( Declaration* decl )
+  {
+    if( FunctionDecl* func = dynamic_cast< FunctionDecl* >( decl ) ) {
+      return !func->get_statements();
+    }
+    return true;
+  }
+  
+} // namespace CodeGen
+
+#endif /* #ifndef CODEGENV_H */
+
+/*
+  Local Variables:
+  mode: "c++"
+  End:
+*/
Index: translator/CodeGen/FixNames.cc
===================================================================
--- translator/CodeGen/FixNames.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/FixNames.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: FixNames.cc,v 1.8 2005/08/29 20:14:12 rcbilson Exp $
+ *
+ */
+
+#include "FixNames.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Visitor.h"
+#include "SymTab/Mangler.h"
+#include "OperatorTable.h"
+
+namespace CodeGen {
+
+class FixNames : public Visitor
+{
+public:
+  virtual void visit( ObjectDecl *objectDecl );
+  virtual void visit( FunctionDecl *functionDecl );
+};
+
+void
+fixNames( std::list< Declaration* > translationUnit )
+{
+  FixNames fixer;
+  acceptAll( translationUnit, fixer );
+}
+
+void
+fixDWT( DeclarationWithType *dwt )
+{
+  if( dwt->get_name() != "" ) {
+    if( LinkageSpec::isDecoratable( dwt->get_linkage() ) ) {
+      dwt->set_mangleName( SymTab::Mangler::mangle( dwt ) );
+    }
+  }
+}
+
+void 
+FixNames::visit( ObjectDecl *objectDecl )
+{
+  Visitor::visit( objectDecl );
+  fixDWT( objectDecl );
+}
+
+void 
+FixNames::visit( FunctionDecl *functionDecl )
+{
+  Visitor::visit( functionDecl );
+  fixDWT( functionDecl );
+}
+
+} // namespace CodeGen
Index: translator/CodeGen/FixNames.h
===================================================================
--- translator/CodeGen/FixNames.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/FixNames.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,19 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: FixNames.h,v 1.2 2005/08/29 20:14:12 rcbilson Exp $
+ *
+ */
+
+#ifndef FIXNAMES_H
+#define FIXNAMES_H
+
+#include "SynTree/SynTree.h"
+
+namespace CodeGen {
+
+void fixNames( std::list< Declaration* > translationUnit );
+
+} // namespace CodeGen
+
+#endif /* #ifndef FIXNAMES_H */
Index: translator/CodeGen/GenType.cc
===================================================================
--- translator/CodeGen/GenType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/GenType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,273 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: GenType.cc,v 1.6 2005/08/29 20:14:12 rcbilson Exp $
+ *
+ */
+
+#include <strstream>
+#include <cassert>
+
+#include "GenType.h"
+#include "CodeGenerator2.h"
+#include "SynTree/Visitor.h"
+#include "SynTree/Type.h"
+#include "SynTree/Expression.h"
+
+namespace CodeGen {
+
+class GenType : public Visitor
+{
+public:
+  GenType( const std::string &typeString );
+  std::string get_typeString() const { return typeString; }
+  void set_typeString( const std::string &newValue ) { typeString = newValue; }
+  
+  virtual void visit( FunctionType *funcType );
+  virtual void visit( VoidType *voidType );
+  virtual void visit( BasicType *basicType );
+  virtual void visit( PointerType *pointerType );
+  virtual void visit( ArrayType *arrayType );
+  virtual void visit( StructInstType *structInst );
+  virtual void visit( UnionInstType *unionInst );
+  virtual void visit( EnumInstType *enumInst );
+  virtual void visit( TypeInstType *typeInst );
+  
+private:
+  void handleQualifiers( Type *type );
+  void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic );
+  
+  std::string typeString;
+};
+
+std::string
+genType( Type *type, const std::string &baseString )
+{
+  GenType gt( baseString );
+  type->accept( gt );
+  return gt.get_typeString();
+}
+
+GenType::GenType( const std::string &typeString )
+  : typeString( typeString )
+{
+}
+
+void GenType::visit(VoidType *voidType){
+  typeString = "void " + typeString;
+  handleQualifiers( voidType );
+}
+
+void GenType::visit(BasicType *basicType)
+{
+  std::string typeWords;
+  switch(basicType->get_kind()){
+  case BasicType::Bool:
+    typeWords = "bool";
+    break;
+  case BasicType::Char:
+  case BasicType::SignedChar:
+    typeWords = "char";
+    break;
+  case BasicType::UnsignedChar:
+    typeWords = "unsigned char";
+    break;
+  case BasicType::ShortSignedInt:
+    typeWords = "short";
+    break;
+  case BasicType::ShortUnsignedInt:
+    typeWords = "short unsigned";
+    break;
+  case BasicType::SignedInt:
+    typeWords = "int";
+    break;
+  case BasicType::UnsignedInt:
+    typeWords = "unsigned int";
+    break;
+  case BasicType::LongSignedInt:
+    typeWords = "long int";
+    break;
+  case BasicType::LongUnsignedInt:
+    typeWords = "long unsigned int";
+    break;
+  case BasicType::LongLongSignedInt:
+    typeWords = "long long int";
+    break;
+  case BasicType::LongLongUnsignedInt:
+    typeWords = "long long unsigned int";
+    break;
+  case BasicType::Float:
+    typeWords = "float";
+    break;
+  case BasicType::Double:
+    typeWords = "double";
+    break;
+  case BasicType::LongDouble:
+    typeWords = "long double";
+    break;
+  case BasicType::FloatComplex:
+    typeWords = "float _Complex";
+    break;
+  case BasicType::DoubleComplex:
+    typeWords = "double _Complex";
+    break;
+  case BasicType::LongDoubleComplex:
+    typeWords = "long double _Complex";
+    break;
+  case BasicType::FloatImaginary:
+    typeWords = "float _Imaginary";
+    break;
+  case BasicType::DoubleImaginary:
+    typeWords = "double _Imaginary";
+    break;
+  case BasicType::LongDoubleImaginary:
+    typeWords = "long double _Imaginary";
+    break;
+  default:
+    assert( false );
+  }
+  typeString = typeWords + " " + typeString;
+  handleQualifiers( basicType );
+}
+
+void
+GenType::genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic )
+{
+  std::ostrstream os;
+  if( typeString != "" ) {
+    if( typeString[ 0 ] == '*' ) {
+      os << "(" << typeString << ")";
+    } else {
+      os << typeString;
+    }
+  }
+  os << "[";
+  if( isStatic ) {
+    os << "static ";
+  }
+  if( qualifiers.isConst ) {
+    os << "const ";
+  }
+  if( qualifiers.isVolatile ) {
+    os << "volatile ";
+  }
+  if( isVarLen ) {
+    os << "*";
+  }
+  if( dimension != 0 ) {
+    CodeGenerator2 cg( os );
+    dimension->accept( cg );
+  }
+  os << "]";
+  
+  typeString = std::string( os.str(), os.pcount() );
+  
+  base->accept ( *this );
+}
+
+void GenType::visit(PointerType *pointerType) {
+  assert(pointerType->get_base() != 0);
+  if( pointerType->get_isStatic() || pointerType->get_isVarLen() || pointerType->get_dimension() ) {
+    genArray( pointerType->get_qualifiers(), pointerType->get_base(), pointerType->get_dimension(), pointerType->get_isVarLen(), pointerType->get_isStatic() );
+  } else {
+    handleQualifiers( pointerType );
+    if( typeString[ 0 ] == '?' ) {
+      typeString = "* " + typeString;
+    } else {
+      typeString = "*" + typeString;
+    }
+    pointerType->get_base()->accept ( *this );
+  }
+}
+
+void GenType::visit(ArrayType *arrayType){
+  genArray( arrayType->get_qualifiers(), arrayType->get_base(), arrayType->get_dimension(), arrayType->get_isVarLen(), arrayType->get_isStatic() );
+}
+
+void GenType::visit(FunctionType *funcType) {
+  std::ostrstream os;
+
+  if( typeString != "" ) {
+    if( typeString[ 0 ] == '*' ) {
+      os << "(" << typeString << ")";
+    } else {
+      os << typeString;
+    }
+  }
+  
+  /************* parameters ***************/
+
+  const std::list<DeclarationWithType*> &pars = funcType->get_parameters();
+
+  if( pars.empty() ) {
+    if( funcType->get_isVarArgs() ) {
+      os << "()";
+    } else {
+      os << "(void)";
+    }
+  } else {
+    CodeGenerator2 cg( os );
+    os << "(" ;
+
+    cg.genCommaList( pars.begin(), pars.end() );
+    
+    if( funcType->get_isVarArgs() ){
+      os << ", ...";
+    }
+    os << ")";
+  }
+  
+  typeString = std::string( os.str(), os.pcount() );
+
+  if( funcType->get_returnVals().size() == 0 ) {
+    typeString = "void " + typeString;
+  } else {
+
+    funcType->get_returnVals().front()->get_type()->accept( *this );
+
+  }
+  
+}
+
+void GenType::visit( StructInstType *structInst ) 
+{
+  typeString = "struct " + structInst->get_name() + " " + typeString;
+  handleQualifiers( structInst );
+}
+
+void 
+GenType::visit( UnionInstType *unionInst )
+{
+  typeString = "union " + unionInst->get_name() + " " + typeString;
+  handleQualifiers( unionInst );
+}
+
+void 
+GenType::visit( EnumInstType *enumInst )
+{
+  typeString = "enum " + enumInst->get_name() + " " + typeString;
+  handleQualifiers( enumInst );
+}
+
+void 
+GenType::visit( TypeInstType *typeInst )
+{
+  typeString = typeInst->get_name() + " " + typeString;
+  handleQualifiers( typeInst );
+}
+
+void 
+GenType::handleQualifiers( Type *type )
+{
+  if( type->get_isConst() ) {
+    typeString = "const " + typeString;
+  }
+  if( type->get_isVolatile() ) {
+    typeString = "volatile " + typeString;
+  }
+  if( type->get_isRestrict() ) {
+    typeString = "__restrict " + typeString;
+  }
+}
+
+} // namespace CodeGen
Index: translator/CodeGen/GenType.h
===================================================================
--- translator/CodeGen/GenType.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/GenType.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,20 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: GenType.h,v 1.2 2005/08/29 20:14:12 rcbilson Exp $
+ *
+ */
+
+#ifndef CODEGEN_GENTYPE_H
+#define CODEGEN_GENTYPE_H
+
+#include <string>
+#include "SynTree/SynTree.h"
+
+namespace CodeGen {
+
+std::string genType( Type *type, const std::string &baseString );
+
+} // namespace CodeGen
+
+#endif /* #ifndef CODEGEN_GENTYPE_H */
Index: translator/CodeGen/Generate.cc
===================================================================
--- translator/CodeGen/Generate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/Generate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,35 @@
+#include <algorithm>
+#include <iostream>
+#include <cassert>
+#include <list>
+
+#include "Generate.h"
+#include "SynTree/Declaration.h"
+
+#include "CodeGenerator2.h"
+
+using namespace std;
+
+namespace CodeGen {
+
+  void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics ) {
+
+    CodeGen::CodeGenerator2 cgv( os );
+
+    for(std::list<Declaration *>::iterator i = translationUnit.begin(); i != translationUnit.end();  i++)
+      {
+        if( LinkageSpec::isGeneratable( (*i)->get_linkage() ) && (doIntrinsics || !LinkageSpec::isBuiltin( (*i)->get_linkage() ) ) ) {
+    	  (*i)->accept(cgv);
+    	  cgv.shift_left();
+    	  if( doSemicolon( *i ) ) {
+      	    os << ";";
+      	  }
+      	  os << std::endl;
+    	}
+      }
+
+  }
+
+} // namespace CodeGen
+
+
Index: translator/CodeGen/Generate.h
===================================================================
--- translator/CodeGen/Generate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/Generate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,15 @@
+#ifndef GENERATE_H
+#define GENERATE_H
+
+#include <list>
+#include <iostream>
+
+#include "SynTree/SynTree.h"
+
+namespace CodeGen {
+
+  void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics );
+
+} // namespace CodeGen
+
+#endif /* #ifndef GENERATE_H */
Index: translator/CodeGen/OperatorTable.cc
===================================================================
--- translator/CodeGen/OperatorTable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/OperatorTable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,89 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: OperatorTable.cc,v 1.6 2003/01/19 04:19:31 rcbilson Exp $
+ *
+ */
+
+#include <map>
+
+#include "OperatorTable.h"
+
+namespace CodeGen {
+
+namespace {
+
+const OperatorInfo tableValues[] = {
+{	"?[?]",		"",		"_operator_index",		OT_INDEX		},
+{	"?()",		"",		"_operator_call",		OT_CALL			},
+{	"?++",		"++",		"_operator_postincr",		OT_POSTFIXASSIGN	},
+{	"?--",		"--",		"_operator_postdecr",		OT_POSTFIXASSIGN	},
+{	"*?",		"*",		"_operator_deref",		OT_PREFIX		},
+{	"+?",		"+",		"_operator_unaryplus",		OT_PREFIX		},
+{	"-?",		"-",		"_operator_unaryminus",		OT_PREFIX		},
+{	"~?",		"~",		"_operator_bitnot",		OT_PREFIX		},
+{	"!?",		"!",		"_operator_lognot",		OT_PREFIX		},
+{	"++?",		"++",		"_operator_preincr",		OT_PREFIXASSIGN		},
+{	"--?",		"--",		"_operator_predecr",		OT_PREFIXASSIGN		},
+{	"?*?",		"*",		"_operator_multiply",		OT_INFIX		},
+{	"?/?",		"/",		"_operator_divide",		OT_INFIX		},
+{	"?%?",		"%",		"_operator_modulus",		OT_INFIX		},
+{	"?+?",		"+",		"_operator_add",		OT_INFIX		},
+{	"?-?",		"-",		"_operator_subtract",		OT_INFIX		},
+{	"?<<?",		"<<",		"_operator_shiftleft",		OT_INFIX		},
+{	"?>>?",		">>",		"_operator_shiftright",		OT_INFIX		},
+{	"?<?",		"<",		"_operator_less",		OT_INFIX		},
+{	"?>?",		">",		"_operator_greater",		OT_INFIX		},
+{	"?<=?",		"<=",		"_operator_lessequal",		OT_INFIX		},
+{	"?>=?",		">=",		"_operator_greaterequal",	OT_INFIX		},
+{	"?==?",		"==",		"_operator_equal",		OT_INFIX		},
+{	"?!=?",		"!=",		"_operator_notequal",		OT_INFIX		},
+{	"?&?",		"&",		"_operator_bitand",		OT_INFIX		},
+{	"?^?",		"^",		"_operator_bitxor",		OT_INFIX		},
+{	"?|?",		"|",		"_operator_bitor",		OT_INFIX		},
+{	"?=?",		"=",		"_operator_assign",		OT_INFIXASSIGN		},
+{	"?*=?",		"*=",		"_operator_multassign",		OT_INFIXASSIGN		},
+{	"?/=?",		"/=",		"_operator_divassign",		OT_INFIXASSIGN		},
+{	"?%=?",		"%=",		"_operator_modassign",		OT_INFIXASSIGN		},
+{	"?+=?",		"+=",		"_operator_addassign",		OT_INFIXASSIGN		},
+{	"?-=?",		"-=",		"_operator_subassign",		OT_INFIXASSIGN		},
+{	"?<<=?",	"<<=",		"_operator_shiftleftassign",	OT_INFIXASSIGN		},
+{	"?>>=?",	">>=",		"_operator_shiftrightassign",	OT_INFIXASSIGN		},
+{	"?&=?",		"&=",		"_operator_bitandassign",	OT_INFIXASSIGN		},
+{	"?^=?",		"^=",		"_operator_bitxorassign",	OT_INFIXASSIGN		},
+{	"?|=?",		"|=",		"_operator_bitorassign",	OT_INFIXASSIGN		},
+{	"0",		"0",		"_constant_zero",		OT_CONSTANT		},
+{	"1",		"1",		"_constant_one",			OT_CONSTANT		}
+};
+
+const int numOps = sizeof( tableValues ) / sizeof( OperatorInfo );
+
+std::map< std::string, OperatorInfo > table;
+
+void
+initialize()
+{
+  for( int i = 0; i < numOps; ++i ) {
+    table[ tableValues[i].inputName ] = tableValues[i];
+  }
+}
+
+} // namespace
+
+bool
+operatorLookup( std::string funcName, OperatorInfo &info )
+{
+  static bool init = false;
+  if( !init ) {
+    initialize();
+  }
+  std::map< std::string, OperatorInfo >::const_iterator i = table.find( funcName );
+  if( i == table.end() ) {
+    return false;
+  } else {
+    info = i->second;
+    return true;
+  }
+}
+
+} // namespace CodeGen
Index: translator/CodeGen/OperatorTable.h
===================================================================
--- translator/CodeGen/OperatorTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/OperatorTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: OperatorTable.h,v 1.4 2003/01/19 04:19:31 rcbilson Exp $
+ *
+ */
+
+#ifndef CODEGEN_OPERATORTABLE_H
+#define CODEGEN_OPERATORTABLE_H
+
+#include <string>
+
+namespace CodeGen {
+
+enum OperatorType
+{
+  OT_INDEX,
+  OT_CALL,
+  OT_PREFIX,
+  OT_POSTFIX,
+  OT_INFIX,
+  OT_PREFIXASSIGN,
+  OT_POSTFIXASSIGN,
+  OT_INFIXASSIGN,
+  OT_CONSTANT
+};
+
+struct OperatorInfo
+{
+  std::string inputName;
+  std::string symbol;
+  std::string outputName;
+  OperatorType type;
+};
+
+bool operatorLookup( std::string funcName, OperatorInfo &info );
+
+} // namespace CodeGen
+
+#endif /* #ifndef CODEGEN_OPERATORTABLE_H */
Index: translator/CodeGen/module.mk
===================================================================
--- translator/CodeGen/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/CodeGen/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,6 @@
+SRC +=  CodeGen/Generate.cc \
+	CodeGen/CodeGenerator2.cc \
+	CodeGen/GenType.cc \
+	CodeGen/FixNames.cc \
+	CodeGen/OperatorTable.cc \
+	$(NULL)
Index: translator/Common/CompilerError.h
===================================================================
--- translator/Common/CompilerError.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Common/CompilerError.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,27 @@
+#ifndef COMPILER_ERROR_H
+#define COMPILER_ERROR_H
+
+#include <string>
+//#include "../config.h"
+
+class CompilerError : public std::exception
+{
+public:
+  CompilerError();
+  CompilerError( std::string what ) : what( what ) {}
+  ~CompilerError() throw () {}
+
+  std::string get_what() const { return what; }
+  void set_what( std::string newValue ) { what = newValue; }
+
+private:
+  std::string what;
+};
+
+#endif /* COMPILER_ERROR_H */
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/Common/SemanticError.cc
===================================================================
--- translator/Common/SemanticError.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Common/SemanticError.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,41 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: SemanticError.cc,v 1.1 2002/04/27 19:57:10 rcbilson Exp $
+ *
+ */
+
+#include <iostream>
+#include <list>
+#include <string>
+#include <algorithm>
+#include <iterator>
+
+#include "SemanticError.h"
+
+SemanticError::SemanticError()
+{
+}
+
+SemanticError::SemanticError( std::string error )
+{
+  errors.push_back( std::string( "Error: " ) + error );
+}
+
+void
+SemanticError::append( SemanticError &other )
+{
+  errors.splice( errors.end(), other.errors );
+}
+
+bool
+SemanticError::isEmpty() const
+{
+  return errors.empty();
+}
+
+void
+SemanticError::print( std::ostream &os )
+{
+  std::copy( errors.begin(), errors.end(), std::ostream_iterator< std::string >( os, "\n" ) );
+}
Index: translator/Common/SemanticError.h
===================================================================
--- translator/Common/SemanticError.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Common/SemanticError.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: SemanticError.h,v 1.1 2002/04/27 19:57:10 rcbilson Exp $
+ *
+ */
+
+#ifndef SEMANTICERROR_H
+#define SEMANTICERROR_H
+
+#include <exception>
+#include <string>
+#include <strstream>
+#include <list>
+#include <iostream>
+
+class SemanticError : public std::exception
+{
+public:
+  SemanticError();
+  SemanticError( std::string error );
+  template< typename T > SemanticError( const std::string &error, const T *obj );
+  ~SemanticError() throw() {}
+
+  void append( SemanticError &other );
+  bool isEmpty() const;
+  void print( std::ostream &os );
+
+  // constructs an exception using the given message and the printed
+  // representation of the obj (T must have a print method)
+
+private:
+  std::list< std::string > errors;
+};
+
+template< typename T >
+SemanticError::SemanticError( const std::string &error, const T *obj )
+{
+  std::ostrstream os;
+  os << "Error: " << error;
+  obj->print( os );
+  errors.push_back( std::string( os.str(), os.pcount() ) );
+}
+
+#endif /* SEMANTICERROR_H */
Index: translator/Common/UnimplementedError.h
===================================================================
--- translator/Common/UnimplementedError.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Common/UnimplementedError.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: UnimplementedError.h,v 1.1 2002/09/02 20:31:53 rcbilson Exp $
+ *
+ */
+
+#ifndef COMMON_UNIMPLEMENTEDERROR_H
+#define COMMON_UNIMPLEMENTEDERROR_H
+
+#include <string>
+
+class UnimplementedError : public std::exception
+{
+public:
+  UnimplementedError();
+  UnimplementedError( std::string what ) : what( what ) {}
+  ~UnimplementedError() throw () {}
+  
+  std::string get_what() const { return what; }
+  void set_what( std::string newValue ) { what = newValue; }
+  
+private:
+  std::string what;
+};
+
+#endif /* #ifndef COMMON_UNIMPLEMENTEDERROR_H */
Index: translator/Common/UniqueName.cc
===================================================================
--- translator/Common/UniqueName.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Common/UniqueName.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,25 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: UniqueName.cc,v 1.1 2002/04/30 03:30:14 rcbilson Exp $
+ *
+ */
+
+#include <string>
+#include <strstream>
+
+#include "UniqueName.h"
+
+UniqueName::UniqueName( const std::string &base )
+  : base( base ), count( 0 )
+{
+}
+
+std::string 
+UniqueName::newName( const std::string &additional )
+{
+  std::ostrstream os;
+  os << base << additional << count++;
+  return std::string( os.str(), os.pcount() );
+}
+
Index: translator/Common/UniqueName.h
===================================================================
--- translator/Common/UniqueName.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Common/UniqueName.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,25 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: UniqueName.h,v 1.1 2002/04/30 03:30:14 rcbilson Exp $
+ *
+ */
+
+#ifndef UNIQUENAME_H
+#define UNIQUENAME_H
+
+#include <string>
+
+class UniqueName
+{
+public:
+  UniqueName( const std::string &base = "" );
+
+  std::string newName( const std::string &additional = "" );
+
+private:
+  std::string base;
+  int count;
+};
+
+#endif /* #ifndef UNIQUENAME_H */
Index: translator/Common/module.mk
===================================================================
--- translator/Common/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Common/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,2 @@
+SRC += Common/SemanticError.cc \
+       Common/UniqueName.cc
Index: translator/Common/utility.h
===================================================================
--- translator/Common/utility.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Common/utility.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,218 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * Some useful template utility functions
+ *
+ * $Id: utility.h,v 1.17 2003/11/26 18:05:21 rgesteve Exp $
+ *
+ */
+
+#ifndef COMMON_UTILITY_H
+#define COMMON_UTILITY_H
+
+#include <iostream>
+#include <strstream>
+#include <iterator>
+#include <string>
+#include <cctype>
+#include <list>
+
+template< typename T >
+static inline T*
+maybeClone( const T *orig )
+{
+  if( orig ) {
+    return orig->clone();
+  } else {
+    return 0;
+  }
+}
+
+template< typename T, typename U >
+static inline T*
+maybeBuild( const U *orig )
+{
+  if( orig ) {
+    return orig->build();
+  } else {
+    return 0;
+  }
+}
+
+template< typename Input_iterator >
+void
+printEnums( Input_iterator begin, Input_iterator end, const char * const *name_array, std::ostream &os )
+{
+  for( Input_iterator i = begin; i != end; ++i ) {
+    os << name_array[ *i ] << ' ';
+  }
+}
+
+template< typename Container >
+void
+deleteAll( Container &container )
+{
+  for( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
+    delete *i;
+  }
+}
+
+template< typename Container >
+void
+printAll( const Container &container, std::ostream &os, int indent = 0 )
+{
+  for( typename Container::const_iterator i = container.begin(); i != container.end(); ++i ) {
+    if( *i ) {
+      os << std::string(indent,  ' ');
+      (*i)->print( os, indent + 2 );
+      os << std::endl;
+    }
+  }
+}
+
+template< typename SrcContainer, typename DestContainer >
+void
+cloneAll( const SrcContainer &src, DestContainer &dest )
+{
+  typename SrcContainer::const_iterator in = src.begin();
+  std::back_insert_iterator< DestContainer > out( dest );
+  while( in != src.end() ) {
+    *out++ = (*in++)->clone();
+  }
+}
+
+template< typename Container >
+void
+assertAll( const Container &container )
+{
+  int count = 0;
+  for( typename Container::const_iterator i = container.begin(); i != container.end(); ++i ) {
+    if( !(*i) ) {
+      std::cerr << count << " is null" << std::endl;
+    }
+  }
+}
+
+static inline std::string
+assign_strptr( std::string *str )
+{
+  if( str == 0 ) {
+    return "";
+  } else {
+    std::string tmp;
+    tmp = *str;
+    delete str;
+    return tmp;
+  }
+}
+
+template< class T, typename ResultType, ResultType (T::* memfunc)() >
+ResultType dispatch(T *pT){
+  return (pT->*memfunc)();
+}
+
+template < typename T >
+std::list<T> tail( std::list<T> l )
+{
+  if(! l.empty()){
+    std::list<T> ret(++(l.begin()), l.end());
+    return ret;
+  }
+}
+
+template < typename T >
+std::list<T> flatten( std::list < std::list<T> > l) {
+  typedef std::list <T> Ts;
+
+  Ts ret;
+
+  switch( l.size() ){
+  case 0:
+    return ret;
+  case 1:
+    return l.front();
+  default:
+    ret = flatten(tail(l));
+    ret.insert(ret.begin(), l.front().begin(), l.front().end());
+    return ret;
+  }
+}
+
+template < typename T > 
+std::string toString ( T value ) {
+  std::ostrstream os;
+  
+  os << value; // << std::ends;
+  os.freeze( false );
+
+  return std::string(os.str(), os.pcount());
+}
+
+template< class Constructed, typename Arg >
+Constructed *ctor( Arg arg ) {
+  Constructed *c = new Constructed( arg );
+  return c;
+}
+
+template< class Constructed, typename Arg >
+Constructed ctor_noptr( Arg arg ) {
+  return Constructed( arg );
+}
+
+template< typename T >
+void replace( std::list< T > &org, typename std::list< T >::iterator pos, std::list< T > &with ) {
+  // TIter should secretly be a typename std::list< T >::iterator
+  //   ( g++ 3.2 issues a 'is implicitly a typename' warning if I make this explicit )
+   typename std::list< T >::iterator next = pos; advance( next, 1 );
+
+   //if ( next != org.end() ) {
+    org.erase( pos );
+    org.splice( next, with );
+    //}
+
+  return;
+}
+
+template< typename T1, typename T2 >
+T2 *cast_ptr( T1 *from ) {
+  return dynamic_cast< T2 * >( from );
+}
+
+template< class Exception, typename Arg >
+void inline assert_throw( bool pred, Arg arg ) {
+  if (pred) throw Exception( arg );
+}
+
+template< typename T >
+struct is_null_pointer {
+  bool operator()( const T *ptr ){ return ( ptr == 0 ); }
+};
+
+template< class InputIterator, class OutputIterator, class Predicate >
+void filter(InputIterator begin, InputIterator end, OutputIterator out, Predicate pred)
+{
+  while ( begin++ != end )
+    if( pred(*begin) ) *out++ = *begin;
+
+  return;
+}
+
+template< class InputIterator1, class InputIterator2, class OutputIterator >
+void zip( InputIterator1 b1, InputIterator1 e1, InputIterator2 b2, InputIterator2 e2, OutputIterator out ) {
+  while( b1 != e1 && b2 != e2 )
+    *out++ = std::pair<typename InputIterator1::value_type, typename InputIterator2::value_type>(*b1++, *b2++);
+}
+
+template< class InputIterator1, class InputIterator2, class OutputIterator, class BinFunction >
+void zipWith( InputIterator1 b1, InputIterator1 e1, InputIterator2 b2, InputIterator2 e2, OutputIterator out, BinFunction func ) {
+  while( b1 != e1 && b2 != e2 )
+    *out++ = func(*b1++, *b2++);
+}
+
+#endif /* #ifndef COMMON_UTILITY_H */
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/ControlStruct/CaseRangeMutator.cc
===================================================================
--- translator/ControlStruct/CaseRangeMutator.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ControlStruct/CaseRangeMutator.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,190 @@
+#include <list>
+#include <cassert>
+#include <cstdlib>
+#include <iterator>
+
+#include "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(ChooseStmt   *chooseStmt)
+  {
+    /* There shouldn't be any `choose' statements by now, throw an exception or something. */
+    throw( 0 ) ; /* FIXME */
+  }
+
+  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::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 ) );
+	}
+
+	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() );
+	  }
+	std::list< Statement * >::iterator j = i; advance( j, 1 );
+	replace ( cases, i, newCases );
+	i = j;
+	newCaseLabels.clear();
+      } else
+	i++;
+    }
+
+    return switchStmt;
+  }
+
+  Statement* CaseRangeMutator::mutate(FallthruStmt *fallthruStmt)
+  {
+    //delete fallthruStmt;
+    return new NullStmt();
+  }
+
+  Statement* CaseRangeMutator::mutate(CaseStmt *caseStmt)
+  {
+    UntypedExpr *cond;
+    if ( (cond = dynamic_cast< UntypedExpr * >( caseStmt->get_condition() )) != 0 ) {
+      NameExpr *nmfunc;
+      if ( (nmfunc = dynamic_cast< NameExpr *>( cond->get_function() )) != 0 ) {
+	if ( nmfunc->get_name() == std::string("Range") ) {
+	  assert( cond->get_args().size() == 2 );
+	  std::list<Expression *>::iterator i = cond->get_args().begin();
+	  Expression *lo = *i, *hi = *(++i); // "unnecessary" temporaries
+	  fillRange( lo, hi);
+	}
+      }
+    } else if ( TupleExpr *tcond = dynamic_cast< TupleExpr * >( caseStmt->get_condition() ) ) {
+      // case list
+      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?
+    }
+
+    std::list< Statement * > &stmts = caseStmt->get_statements();
+    mutateAll ( stmts, *this );
+
+    return caseStmt;
+  }
+
+  void CaseRangeMutator::fillRange(Expression *lo, Expression *hi) {
+    // generate the actual range (and check for consistency)
+    Constant *c_lo, *c_hi;
+    ConstantExpr *ce_lo, *ce_hi;
+    ce_lo = dynamic_cast< ConstantExpr * >( lo );
+    ce_hi = dynamic_cast< ConstantExpr * >( hi );
+
+    if ( ce_lo && ce_hi ) {
+      c_lo = ce_lo->get_constant(); c_hi = ce_hi->get_constant();
+    } /* else {
+      if ( !ce_lo ) ;
+      if ( !ce_hi ) ;
+      } */
+    BasicType *ty_lo = dynamic_cast< BasicType * >( c_lo->get_type() ),
+                       *ty_hi = dynamic_cast< BasicType * >( c_hi->get_type() );
+    
+    if( !ty_lo || !ty_hi )
+      return; // one of them is not a constant
+
+
+    switch( ty_lo->get_kind() ) {
+    case BasicType::Char:
+    case BasicType::UnsignedChar:
+      switch( ty_hi->get_kind() ) 
+	{
+	case BasicType::Char:
+	case BasicType::UnsignedChar:
+	  // first case, they are both printable ASCII characters represented as 'x'
+	  if ( c_lo->get_value().size() == 3 && c_hi->get_value().size() == 3 ) {
+	    char ch_lo = (c_lo->get_value())[1], ch_hi = (c_hi->get_value())[1];
+
+	    if ( ch_lo > ch_hi ) { char t=ch_lo; ch_lo=ch_hi; ch_hi=t; }
+
+	    for( char c = ch_lo; c <=  ch_hi; c++ ){
+	      Type::Qualifiers q;
+	      Constant cnst( new BasicType(q, BasicType::Char),
+				      std::string("'") + c + std::string("'") );
+	      newCaseLabels.push_back( new ConstantExpr( cnst ) );
+	    }
+
+	    return;
+	  }
+	  break;
+	default:
+	  // error: incompatible constants
+	  break;
+	}
+      break;
+    case BasicType::ShortSignedInt:
+    case BasicType::ShortUnsignedInt:
+    case BasicType::SignedInt:
+    case BasicType::UnsignedInt:
+    case BasicType::LongSignedInt:
+    case BasicType::LongUnsignedInt:
+    case BasicType::LongLongSignedInt:
+    case BasicType::LongLongUnsignedInt:
+      switch( ty_hi->get_kind() ) 
+	{
+	case BasicType::ShortSignedInt:
+	case BasicType::ShortUnsignedInt:
+	case BasicType::SignedInt:
+	case BasicType::UnsignedInt:
+	case BasicType::LongSignedInt:
+	case BasicType::LongUnsignedInt:
+	case BasicType::LongLongSignedInt:
+	case BasicType::LongLongUnsignedInt: {
+	  int i_lo = atoi(c_lo->get_value().c_str()),
+	      i_hi = atoi(c_hi->get_value().c_str());
+
+	  if ( i_lo > i_hi ) { int t=i_lo; i_lo=i_hi; i_hi=t; }
+
+	  for( int c = i_lo; c <=  i_hi; c++ ){
+	    Type::Qualifiers q;
+	    Constant cnst( new BasicType(q, ty_hi->get_kind()), // figure can't hurt (used to think in positives)
+				    toString< int >( c ) );
+	    newCaseLabels.push_back( new ConstantExpr( cnst ) );
+	  }
+
+	  return;
+	}
+	default:
+	  // error: incompatible constants
+	  break;
+	}
+      break;
+    default:
+      break;
+    }
+
+/* End: */{ 
+      // invalid range, signal a warning (it still generates the two case labels)
+      newCaseLabels.push_back( lo );
+      newCaseLabels.push_back( hi );
+      return;
+    }
+  }
+
+} // namespace ControlStruct
Index: translator/ControlStruct/CaseRangeMutator.h
===================================================================
--- translator/ControlStruct/CaseRangeMutator.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ControlStruct/CaseRangeMutator.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,35 @@
+#ifndef CASERNG_MUTATOR_H
+#define CASERNG_MUTATOR_H
+
+#include <list>
+
+#include "SynTree/Mutator.h"
+
+namespace ControlStruct {
+
+  class CaseRangeMutator : public Mutator
+  {
+  public:
+    CaseRangeMutator() {}
+
+    virtual Statement* mutate(ChooseStmt   *);
+    virtual Statement* mutate(SwitchStmt   *);
+    virtual Statement* mutate(FallthruStmt *);
+    virtual Statement* mutate(CaseStmt     *);
+
+  private:
+    void fillRange(Expression *lo, Expression *hi);
+
+    Expression *currentCondition;
+    std::list< Expression * > newCaseLabels;
+  };
+
+} // namespace ControlStruct
+
+#endif // #ifndef CASERNG_MUTATOR_H
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/ControlStruct/ChooseMutator.cc
===================================================================
--- translator/ControlStruct/ChooseMutator.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ControlStruct/ChooseMutator.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,55 @@
+#include <list>
+
+#include "SynTree/Statement.h"
+#include "ChooseMutator.h"
+
+namespace ControlStruct {
+
+  Statement* ChooseMutator::mutate(ChooseStmt   *chooseStmt)
+  {
+    bool enclosingChoose = insideChoose;
+    insideChoose = true;
+    mutateAll( chooseStmt->get_branches(), *this );
+    insideChoose = enclosingChoose;
+
+    return new SwitchStmt( chooseStmt->get_labels(),  chooseStmt->get_condition(), chooseStmt->get_branches() );
+  }
+
+  Statement* ChooseMutator::mutate(SwitchStmt   *switchStmt)
+  {
+    bool enclosingChoose = insideChoose;
+    insideChoose = false;
+    mutateAll( switchStmt->get_branches(), *this );
+    insideChoose = enclosingChoose;
+
+    return switchStmt;
+  }
+
+  Statement* ChooseMutator::mutate(FallthruStmt *fallthruStmt)
+  {
+    delete fallthruStmt;
+    return new NullStmt();
+  }
+
+  Statement* ChooseMutator::mutate(CaseStmt *caseStmt)
+  {
+
+    std::list< Statement * > &stmts = caseStmt->get_statements();
+
+    if ( insideChoose ) {
+      BranchStmt *posBrk;
+      if ( (( posBrk = dynamic_cast< BranchStmt * > ( stmts.back() ) ) && 
+	    ( posBrk->get_type() == BranchStmt::Break ))  // last statement in the list is a (superfluous) 'break' 
+	   || dynamic_cast< FallthruStmt * > ( stmts.back() ) )
+	; 
+      else {
+	stmts.push_back( new BranchStmt( std::list< Label >(), "", BranchStmt::Break ) );
+      }
+    }
+
+    mutateAll ( stmts, *this );
+
+    return caseStmt;
+  }
+
+} // namespace ControlStruct
Index: translator/ControlStruct/ChooseMutator.h
===================================================================
--- translator/ControlStruct/ChooseMutator.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ControlStruct/ChooseMutator.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,31 @@
+#ifndef CHOOSE_MUTATOR_H
+#define CHOOSE_MUTATOR_H
+
+#include "SynTree/Mutator.h"
+
+#include "utility.h"
+
+namespace ControlStruct {
+
+  class ChooseMutator : public Mutator
+  {
+  public:
+    ChooseMutator() : insideChoose( false ) {}
+
+    virtual Statement* mutate(ChooseStmt   *);
+    virtual Statement* mutate(SwitchStmt   *);
+    virtual Statement* mutate(FallthruStmt *);
+    virtual Statement* mutate(CaseStmt     *);
+  private:
+    bool insideChoose;
+  };
+
+} // namespace ControlStruct
+
+#endif // #ifndef CHOOSE_MUTATOR_H
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/ControlStruct/ForExprMutator.cc
===================================================================
--- translator/ControlStruct/ForExprMutator.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ControlStruct/ForExprMutator.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,26 @@
+#include "SynTree/Mutator.h"
+#include "SynTree/Statement.h"
+#include "ForExprMutator.h"
+
+namespace ControlStruct {
+  Statement* ForExprMutator::mutate(ForStmt *forStmt)
+  {
+    DeclStmt *decl;
+    if (( decl = dynamic_cast< DeclStmt * > ( forStmt->get_initialization() )) != 0 )
+      {
+	// create compound statement, move declaration outside, leave _for_ as-is
+	CompoundStmt *block = new CompoundStmt( std::list< Label >() );
+	std::list<Statement *> &stmts = block->get_kids();
+
+	stmts.push_back( decl );
+	forStmt->set_initialization( 0 );
+	stmts.push_back( forStmt );
+
+	return block;
+      }
+    // ForStmt still needs to be fixed
+    else
+      return forStmt;
+  }
+
+} // namespace ControlStruct
Index: translator/ControlStruct/ForExprMutator.h
===================================================================
--- translator/ControlStruct/ForExprMutator.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ControlStruct/ForExprMutator.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,24 @@
+#ifndef FOR_MUTATOR_H
+#define FOR_MUTATOR_H
+
+#include "SynTree/Mutator.h"
+
+#include "utility.h"
+
+namespace ControlStruct {
+
+  class ForExprMutator : public Mutator
+  {
+  public:
+    virtual Statement* mutate(ForStmt   *);
+  };
+
+} // namespace ControlStruct
+
+#endif // #ifndef CHOOSE_MUTATOR_H
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/ControlStruct/LabelFixer.cc
===================================================================
--- translator/ControlStruct/LabelFixer.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ControlStruct/LabelFixer.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,140 @@
+#include <list>
+#include <cassert>
+
+#include "LabelFixer.h"
+#include "MLEMutator.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Declaration.h"
+#include "utility.h"
+
+namespace ControlStruct {
+  LabelFixer::Entry::Entry( Statement *to, Statement *from ) :
+    definition ( to )
+  {
+    if ( from != 0 )
+    usage.push_back( from );
+  }
+
+  bool LabelFixer::Entry::insideLoop()
+  {
+    return ( dynamic_cast< ForStmt * > ( definition ) ||
+	     dynamic_cast< WhileStmt * > ( definition )  );
+  }
+
+  LabelFixer::LabelFixer( LabelGenerator *gen ) : generator ( gen )
+  {
+    if ( generator == 0 )
+      generator = LabelGenerator::getGenerator();
+  }
+
+  void LabelFixer::visit(FunctionDecl *functionDecl)
+  {
+    if ( functionDecl->get_statements() != 0 )
+      functionDecl->get_statements()->accept( *this );
+
+    MLEMutator mlemut( resolveJumps(), generator );
+    functionDecl->acceptMutator( mlemut );
+  }
+
+  void LabelFixer::visit(Statement *stmt )
+  {
+    std::list< Label > &labels = stmt->get_labels();
+
+    if ( ! labels.empty() ) {
+      Label current = setLabelsDef( labels, stmt );
+      labels.clear();
+      labels.push_front( current );
+    }
+  }
+
+  void LabelFixer::visit(BranchStmt *branchStmt)
+  {
+    visit ( ( Statement * )branchStmt );  // the labels this statement might have
+
+    Label target;
+    if ( (target = branchStmt->get_target()) != "" ) {
+      setLabelsUsg( target, branchStmt );
+    } //else       /* computed goto or normal exit-loop statements */
+  }
+
+
+  Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition )
+  {
+    assert( definition != 0 );
+    Entry *entry = new Entry( definition );
+    bool used = false;
+
+    for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ )
+      if ( labelTable.find( *i ) == labelTable.end() )
+	{ used = true; labelTable[ *i ] = entry; } // undefined and unused
+      else
+	if( labelTable[ *i ]->defined() )
+	  throw SemanticError("Duplicate definition of label: " + *i );
+	else
+	  labelTable[ *i ]->set_definition( definition );
+
+    if (! used ) delete entry;
+
+    return labelTable[ llabel.front() ]->get_label();  // this *must* exist
+  }
+
+  Label LabelFixer::setLabelsUsg( Label orgValue, Statement *use )
+  {
+    assert( use != 0 );
+
+    if ( labelTable.find( orgValue ) != labelTable.end() )
+      labelTable[ orgValue ]->add_use( use );         // the label has been defined or used before
+    else
+      labelTable[ orgValue ] = new Entry( 0, use );
+
+    return labelTable[ orgValue ]->get_label();
+  }
+
+  std::map < Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError )
+  {
+    std::map < Statement *, Entry * > def_us;
+
+    for( std::map < Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); i++ ) {
+      Entry *e = i->second;
+
+      if ( def_us.find ( e->get_definition() ) == def_us.end() )
+	  def_us[ e->get_definition() ] = e;
+      else
+	if(e->used())
+	  def_us[ e->get_definition() ]->add_uses( e->get_uses() );
+    }
+
+    // get rid of labelTable
+    for( std::map < Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) {
+      Statement *to = (*i).first;
+      std::list < Statement *> &from = (*i).second->get_uses();
+      Label finalLabel = generator->newLabel();
+      (*i).second->set_label( finalLabel );
+
+      if ( to == 0 ) {
+	BranchStmt *first_use = dynamic_cast<BranchStmt *>(from.back());
+	Label undef("");
+	if ( first_use != 0 )
+	  undef = first_use->get_target();
+	throw SemanticError ( "'" + undef + "' label not defined");
+      }
+
+      to->get_labels().clear();
+      to->get_labels().push_back( finalLabel );
+
+      for ( std::list< Statement *>::iterator j = from.begin(); j != from.end(); j++ ) {
+	BranchStmt *jumpTo = dynamic_cast < BranchStmt * > ( *j );
+	assert( jumpTo != 0 );
+	jumpTo->set_target( finalLabel );
+      }
+    }
+
+    // reverse table
+    std::map < Label, Statement * > *ret = new std::map < Label, Statement * >();
+    for(std::map < Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) 
+      (*ret)[ (*i).second->get_label() ] = (*i).first;
+
+    return ret;
+  }
+
+}  // namespace ControlStruct
Index: translator/ControlStruct/LabelFixer.h
===================================================================
--- translator/ControlStruct/LabelFixer.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ControlStruct/LabelFixer.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,85 @@
+#ifndef LABEL_FIXER_H
+#define LABEL_FIXER_H
+
+#include "utility.h"
+
+#include "SynTree/SynTree.h"
+#include "SynTree/Visitor.h"
+
+#include "LabelGenerator.h"
+
+#include <map>
+
+namespace ControlStruct {
+
+  class LabelFixer : public Visitor 
+    {
+      typedef Visitor Parent;
+
+    public:
+      LabelFixer( LabelGenerator *gen = 0 );
+
+      std::map < Label, Statement * > *resolveJumps() throw ( SemanticError );
+
+      // Declarations
+      virtual void visit(FunctionDecl *functionDecl);
+
+      // Statements
+      void visit(Statement *stmt);
+
+      virtual void visit(CompoundStmt *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
+      virtual void visit(NullStmt     *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
+      virtual void visit(ExprStmt     *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
+      virtual void visit(IfStmt       *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
+      virtual void visit(WhileStmt    *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
+      virtual void visit(ForStmt      *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
+      virtual void visit(SwitchStmt   *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
+      virtual void visit(ChooseStmt   *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
+      virtual void visit(FallthruStmt *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
+      virtual void visit(CaseStmt     *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
+      virtual void visit(ReturnStmt   *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
+      virtual void visit(TryStmt      *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
+      virtual void visit(CatchStmt    *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
+      virtual void visit(DeclStmt     *stmt) {  visit( (Statement *)stmt ); return Parent::visit(stmt); }
+      virtual void visit(BranchStmt   *branchStmt);
+
+      Label setLabelsDef( std::list< Label > &, Statement *definition );
+      Label setLabelsUsg( Label, Statement *usage = 0 );
+
+    private:
+      class Entry
+      {
+      public:
+	Entry( Statement *to = 0, Statement *from = 0 );
+	bool used() { return ( usage.empty() ); }
+	bool defined() { return ( definition != 0 ); }
+	bool insideLoop();
+
+	Label get_label() const { return label; }
+	Statement *get_definition() const { return definition; }
+	std::list< Statement *> &get_uses() { return usage; }
+
+	void add_use ( Statement *use ) { usage.push_back(use); }
+	void add_uses ( std::list<Statement *> uses ) { usage.insert( usage.end(), uses.begin(), uses.end() ); }
+	void set_definition( Statement *def ) { definition = def; }
+
+	void set_label( Label lab ) { label = lab; }
+	Label gset_label() const { return label; }
+      private:
+	Label label;  
+	Statement *definition;
+	std::list<Statement *> usage;
+      };
+              
+      std::map < Label, Entry *> labelTable;
+      LabelGenerator *generator;
+    };
+} // namespace ControlStruct
+
+#endif // #ifndef LABEL_FIXER_H
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/ControlStruct/LabelGenerator.cc
===================================================================
--- translator/ControlStruct/LabelGenerator.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ControlStruct/LabelGenerator.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,25 @@
+#include <iostream>
+#include <strstream>
+
+#include "LabelGenerator.h"
+
+namespace ControlStruct {
+
+  LabelGenerator *LabelGenerator::labelGenerator = 0;
+
+  LabelGenerator *LabelGenerator::getGenerator() {
+    if ( LabelGenerator::labelGenerator == 0 )
+      LabelGenerator::labelGenerator = new LabelGenerator();
+
+    return labelGenerator;
+  }
+
+  Label LabelGenerator::newLabel() {
+    std::ostrstream os;
+    os << "__L" << current++ << "__";// << std::ends;
+    os.freeze( false );
+    std::string ret = std::string (os.str(), os.pcount());
+    return Label( ret );
+  }
+
+} // namespace ControlStruct
Index: translator/ControlStruct/LabelGenerator.h
===================================================================
--- translator/ControlStruct/LabelGenerator.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ControlStruct/LabelGenerator.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,32 @@
+#ifndef LABEL_GENERATOR_H
+#define LABEL_GENERATOR_H
+
+#include "SynTree/SynTree.h"
+
+namespace ControlStruct {
+
+  class LabelGenerator
+  {
+  public:
+    static LabelGenerator *getGenerator();
+    Label newLabel();
+    void reset() { current = 0; }
+    void rewind() { current--; }
+
+  protected:
+    LabelGenerator(): current(0) {}
+
+  private:
+    int current;
+    static LabelGenerator *labelGenerator;
+  };
+
+} // namespace ControlStruct
+
+#endif // #ifndef LABEL_GENERATOR_H
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/ControlStruct/LabelTypeChecker.cc
===================================================================
--- translator/ControlStruct/LabelTypeChecker.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ControlStruct/LabelTypeChecker.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,72 @@
+#include <list>
+#include <cassert>
+
+#include "SynTree/Type.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Declaration.h"
+
+#include "LabelTypeChecker.h"
+
+
+namespace ControlStruct {
+
+  void LabelTypeChecker::visit(UntypedExpr *untypedExpr){
+    assert( untypedExpr != 0 );
+    NameExpr *fname;
+    if( ((fname = dynamic_cast<NameExpr *>(untypedExpr->get_function())) != 0) 
+	&& fname->get_name() == std::string("LabAddress") )
+      std::cerr << "Taking the label of an address." << std::endl;
+    else {
+      acceptAll( untypedExpr->get_results(), *this );
+      acceptAll( untypedExpr->get_args(), *this );
+    }
+    return;
+  }
+
+  void LabelTypeChecker::visit(CompoundStmt *compoundStmt) {
+    index.enterScope();
+    acceptAll( compoundStmt->get_kids(), *this );
+    index.leaveScope();
+  }
+
+  void LabelTypeChecker::visit(DeclStmt *declStmt){
+    declStmt->accept( index );
+
+    //ObjectDecl *odecl = 0;
+    // if( ( odecl = dynamic_cast<ObjectDecl *>(declStmt->get_decl()) ) != 0 ){
+    return;
+  }
+
+  void LabelTypeChecker::visit(BranchStmt *branchStmt) {
+    if( branchStmt->get_type() != BranchStmt::Goto ) return;
+    Expression *target;
+    if( (target = branchStmt->get_computedTarget()) == 0 ) return;
+
+    NameExpr *name;
+    if( ((name = dynamic_cast<NameExpr *>(target)) == 0) )
+      return; // Not a name expression
+    
+    std::list< DeclarationWithType * > interps;
+    index.lookupId(name->get_name(), interps);
+    if ( interps.size() != 1)
+      // in case of multiple declarations
+      throw SemanticError("Illegal label expression: " + name->get_name() );
+
+    PointerType *ptr;
+    if ( (ptr = dynamic_cast<PointerType *>(interps.front()->get_type())) != 0 )
+      if ( dynamic_cast<VoidType *>(ptr->get_base()) != 0 )
+	return;
+      else
+	throw SemanticError("Wrong type of parameter for computed goto");
+    else
+	throw SemanticError("Wrong type of parameter for computed goto");
+
+    return;
+  }
+} // namespace ControlStruct
+
+
+
+
+
Index: translator/ControlStruct/LabelTypeChecker.h
===================================================================
--- translator/ControlStruct/LabelTypeChecker.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ControlStruct/LabelTypeChecker.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,36 @@
+#ifndef LABEL_TYPE_H
+#define LABEL_TYPE_H
+
+#include "SynTree/Visitor.h"
+#include "SymTab/Indexer.h"
+#include "SynTree/Statement.h"
+
+#include "utility.h"
+
+namespace ControlStruct {
+
+  class LabelTypeChecker : public Visitor
+  {
+  public:
+    //LabelTypeChecker() {
+
+    virtual void visit(CompoundStmt *compoundStmt);
+    virtual void visit(DeclStmt *declStmt);
+    virtual void visit(BranchStmt *branchStmt);
+    virtual void visit(UntypedExpr *untypedExpr);
+  private:
+    SymTab::Indexer index;
+  };
+
+} // namespace ControlStruct
+
+#endif // #ifndef LABEL_TYPE_H
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
+
+
+
Index: translator/ControlStruct/MLEMutator.cc
===================================================================
--- translator/ControlStruct/MLEMutator.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ControlStruct/MLEMutator.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,203 @@
+#include <cassert>
+#include <algorithm>
+
+#include "MLEMutator.h"
+#include "SynTree/Statement.h"
+
+
+namespace ControlStruct {
+  MLEMutator::~MLEMutator()
+  {
+    delete targetTable;
+    targetTable = 0;
+  }
+
+  CompoundStmt* MLEMutator::mutate(CompoundStmt *cmpndStmt)
+  {
+    bool labeledBlock = false;
+    if (!((cmpndStmt->get_labels()).empty())) {
+      labeledBlock = true;
+      enclosingBlocks.push_back( Entry( cmpndStmt ) );
+    }
+
+    std::list< Statement * > &kids = cmpndStmt->get_kids();
+    for( std::list< Statement * >::iterator k = kids.begin(); k != kids.end(); k++ ) {
+      *k = (*k)->acceptMutator(*this);
+
+      if (!get_breakLabel().empty()) {
+	std::list< Statement * >::iterator next = k; next++;
+	if( next == kids.end() ) {
+	  std::list<Label> ls; ls.push_back( get_breakLabel() );
+	  kids.push_back( new NullStmt(ls) );
+	} else
+	  (*next)->get_labels().push_back( get_breakLabel() );
+
+	set_breakLabel("");
+      }
+    }
+
+    if ( labeledBlock ) {
+      assert( ! enclosingBlocks.empty() );
+      if( ! enclosingBlocks.back().get_breakExit().empty() )
+	set_breakLabel( enclosingBlocks.back().get_breakExit() );
+      enclosingBlocks.pop_back();
+    }
+
+    //mutateAll( cmpndStmt->get_kids(), *this );
+    return cmpndStmt;
+  }
+
+  Statement *MLEMutator::mutate( WhileStmt *whileStmt )
+  {
+    enclosingLoops.push_back( Entry( whileStmt ) );
+    whileStmt->set_body ( whileStmt->get_body()->acceptMutator( *this ) );
+
+    Entry &e = enclosingLoops.back();
+    assert ( e == whileStmt );
+    whileStmt->set_body( mutateLoop( whileStmt->get_body(), e ) );
+    enclosingLoops.pop_back();
+
+    return whileStmt;
+  }
+
+  Statement *MLEMutator::mutate( ForStmt *forStmt )
+  {
+    enclosingLoops.push_back( Entry( forStmt ) );
+    maybeMutate( forStmt->get_body(), *this );
+
+    Entry &e = enclosingLoops.back();
+    assert ( e == forStmt );
+    forStmt->set_body( mutateLoop( forStmt->get_body(), e ) );
+    enclosingLoops.pop_back();
+
+    return forStmt;
+  }
+
+  Statement *MLEMutator::mutate( BranchStmt *branchStmt )
+    throw ( SemanticError )
+  {
+    if ( branchStmt->get_type() == BranchStmt::Goto )
+      return branchStmt;
+
+    if ( branchStmt->get_type() == BranchStmt::Continue && enclosingLoops.empty() )
+      throw SemanticError( "'continue' outside a loop" );
+
+  if ( branchStmt->get_type() == BranchStmt::Break && (enclosingLoops.empty() && enclosingSwitches.empty() && enclosingBlocks.empty() ) )
+      throw SemanticError( "'break' outside a loop or switch" );
+
+    if ( branchStmt->get_target() == "" ) return branchStmt;
+
+    if ( targetTable->find( branchStmt->get_target() ) == targetTable->end() )
+      throw SemanticError("The label defined in the exit loop statement does not exist." );  // shouldn't happen (since that's already checked)
+
+    std::list< Entry >::iterator check;
+    if ( ( check = std::find( enclosingLoops.begin(), enclosingLoops.end(), (*targetTable)[branchStmt->get_target()] ) ) == enclosingLoops.end() )
+      // not in loop, checking if in switch/choose
+      if ( (check = std::find( enclosingBlocks.begin(), enclosingBlocks.end(), (*targetTable)[branchStmt->get_target()] )) == enclosingBlocks.end() )
+	// neither in loop nor in block, checking if in switch/choose
+	if ( (check = std::find( enclosingSwitches.begin(), enclosingSwitches.end(), (*targetTable)[branchStmt->get_target()] )) == enclosingSwitches.end() )
+	  throw SemanticError("The target specified in the exit loop statement does not correspond to an enclosing loop.");
+
+    if ( enclosingLoops.back() == (*check) )
+      return branchStmt;                      // exit the innermost loop (labels not necessary)
+
+    Label newLabel;
+    switch( branchStmt->get_type() ) {
+    case BranchStmt::Break:
+      if ( check->get_breakExit() != "" )
+	newLabel = check->get_breakExit();
+      else
+	{ newLabel = generator->newLabel(); check->set_breakExit( newLabel ); }
+      break;
+    case BranchStmt::Continue:
+      if ( check->get_contExit() != "" )
+	newLabel = check->get_contExit();
+      else
+	{ newLabel = generator->newLabel(); check->set_contExit( newLabel ); }
+      break;
+
+    default:
+      // shouldn't be here
+      return 0;
+    }
+
+    return new BranchStmt(std::list<Label>(), newLabel, BranchStmt::Goto );
+  }
+
+
+  Statement *MLEMutator::mutate(SwitchStmt *switchStmt)
+  {
+    Label brkLabel = generator->newLabel();
+    enclosingSwitches.push_back( Entry(switchStmt, "", brkLabel) );
+    mutateAll( switchStmt->get_branches(), *this );
+    {
+      // check if this is necessary (if there is a break to this point, otherwise do not generate
+      std::list<Label> temp; temp.push_back( brkLabel );
+      switchStmt->get_branches().push_back( new BranchStmt( temp, Label(""), BranchStmt::Break ) );
+    }
+    assert ( enclosingSwitches.back() == switchStmt );
+    enclosingSwitches.pop_back();
+    return switchStmt;
+  }
+
+  Statement *MLEMutator::mutate(ChooseStmt *switchStmt)
+  {
+    Label brkLabel = generator->newLabel();
+    enclosingSwitches.push_back( Entry(switchStmt,"", brkLabel) );
+    mutateAll( switchStmt->get_branches(), *this );
+    {
+      // check if this is necessary (if there is a break to this point, otherwise do not generate
+      std::list<Label> temp; temp.push_back( brkLabel );
+      switchStmt->get_branches().push_back( new BranchStmt( temp, Label(""), BranchStmt::Break ) );
+    }
+    assert ( enclosingSwitches.back() == switchStmt );
+    enclosingSwitches.pop_back();
+    return switchStmt;
+  }
+
+  Statement *MLEMutator::mutateLoop( Statement *bodyLoop, Entry &e ) {
+    CompoundStmt *newBody;
+    if ( ! (newBody = dynamic_cast<CompoundStmt *>( bodyLoop )) ) {
+      newBody = new CompoundStmt( std::list< Label >() );
+      newBody->get_kids().push_back( bodyLoop );
+    }
+
+    Label endLabel = e.get_contExit();
+
+    if ( e.get_breakExit() != "" ) {
+      if ( endLabel == "" ) endLabel = generator->newLabel();
+      // check for whether this label is used or not, so as to not generate extraneous gotos
+      if (e.breakExitUsed)
+	newBody->get_kids().push_back( new BranchStmt( std::list< Label >(), endLabel, BranchStmt::Goto ) );
+      // xxx
+      //std::list< Label > ls; ls.push_back( e.get_breakExit() );
+      set_breakLabel( e.get_breakExit() );
+      //newBody->get_kids().push_back( new BranchStmt( ls, "", BranchStmt::Break ) );
+    }
+
+    if ( e.get_breakExit() != "" || e.get_contExit() != "" ){
+      if(dynamic_cast< NullStmt *>( newBody->get_kids().back() ))
+	newBody->get_kids().back()->get_labels().push_back( endLabel );
+      else {
+	std::list < Label > ls; ls.push_back( endLabel );
+	newBody->get_kids().push_back( new NullStmt( ls ) );
+      }
+    }
+
+    return newBody;
+  }
+
+  //*** Entry's methods
+  void MLEMutator::Entry::set_contExit( Label l )
+  {
+    assert ( contExit == "" || contExit == l );
+    contExit = l;
+  }
+
+  void MLEMutator::Entry::set_breakExit( Label l )
+  {
+    assert ( breakExit == "" || breakExit == l );
+    breakExit = l;
+  }
+
+} // namespace ControlStruct
Index: translator/ControlStruct/MLEMutator.h
===================================================================
--- translator/ControlStruct/MLEMutator.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ControlStruct/MLEMutator.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,75 @@
+#ifndef MLE_MUTATOR_H
+#define MLE_MUTATOR_H
+
+#include <map>
+#include <list>
+
+#include "utility.h"
+#include "SynTree/SynTree.h"
+#include "SynTree/Mutator.h"
+
+#include "LabelGenerator.h"
+
+namespace ControlStruct {
+
+  class MLEMutator : public Mutator {
+    class Entry;
+
+  public:
+    MLEMutator( std::map <Label, Statement *> *t, LabelGenerator *gen = 0 ) : targetTable( t ), breakLabel(std::string("")), generator( gen ) {}
+    ~MLEMutator();
+
+    CompoundStmt *mutate( CompoundStmt *cmpndStmt );
+    Statement *mutate( WhileStmt *whileStmt );
+    Statement *mutate( ForStmt *forStmt );
+    Statement *mutate( BranchStmt *branchStmt ) throw ( SemanticError );
+
+    Statement *mutate( SwitchStmt *switchStmt );
+    Statement *mutate( ChooseStmt *switchStmt );
+
+    Statement *mutateLoop( Statement *bodyLoop, Entry &e );
+
+    Label &get_breakLabel() { return breakLabel; }
+    void set_breakLabel( Label newValue ) { breakLabel = newValue; }
+
+  private:
+    class Entry {
+    public:
+      explicit Entry( Statement *_loop = 0, Label _contExit = Label(""), Label _breakExit = Label("") ) :
+	loop( _loop ), contExit( _contExit ), breakExit( _breakExit ), contExitUsed( false ), breakExitUsed( false ) {}
+
+      bool operator==( const Statement *stmt ) { return ( loop == stmt ) ; }
+      bool operator!=( const Statement *stmt ) { return ( loop != stmt ) ; }
+
+      bool operator==( const Entry &other ) { return ( loop == other.get_loop() ) ; }
+
+      Statement *get_loop() const { return loop; }
+
+      Label get_contExit() const { return contExit; }
+      void set_contExit( Label );
+
+      Label get_breakExit() const { return breakExit; }
+      void set_breakExit( Label );
+
+    private:
+      Statement *loop;
+      Label contExit, breakExit;
+    public: // hack, provide proper [sg]etters
+      bool contExitUsed, breakExitUsed;
+    };
+
+    std::map <Label, Statement *> *targetTable;
+    std::list < Entry > enclosingBlocks,enclosingLoops,enclosingSwitches;
+    Label breakLabel;
+    LabelGenerator *generator;
+  };
+
+} // namespace ControlStruct
+
+#endif
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/ControlStruct/Mutate.cc
===================================================================
--- translator/ControlStruct/Mutate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ControlStruct/Mutate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,42 @@
+#include <algorithm>
+#include <iostream>
+#include <cassert>
+#include <list>
+
+#include "Mutate.h"
+#include "ChooseMutator.h"
+#include "LabelFixer.h"
+#include "MLEMutator.h"
+#include "CaseRangeMutator.h"
+#include "ForExprMutator.h"
+#include "LabelTypeChecker.h"
+//#include "ExceptMutator.h"
+
+#include "utility.h"
+
+#include "SynTree/Visitor.h"
+
+using namespace std;
+
+namespace ControlStruct {
+
+  void mutate( std::list< Declaration * > translationUnit )
+  {
+    ChooseMutator chmut;
+    ForExprMutator formut;
+    CaseRangeMutator ranges;  // has to run after ChooseMutator
+    LabelFixer lfix;
+    //ExceptMutator exc;
+    LabelTypeChecker lbl;
+
+    mutateAll( translationUnit , formut );
+    acceptAll( translationUnit , lfix );
+    mutateAll( translationUnit , chmut );
+    mutateAll( translationUnit , ranges );
+    //mutateAll( translationUnit , exc );
+    //acceptAll( translationUnit , lbl );
+  }
+
+} // namespace CodeGen
+
+
Index: translator/ControlStruct/Mutate.h
===================================================================
--- translator/ControlStruct/Mutate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ControlStruct/Mutate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,21 @@
+#ifndef CTRLS_MUTATE_H
+#define CTRLS_MUTATE_H
+
+#include <list>
+#include <iostream>
+
+#include "SynTree/Declaration.h"
+
+namespace ControlStruct {
+
+  void mutate( std::list< Declaration* > translationUnit );
+
+} // namespace ControlStruct
+
+#endif // #ifndef CTRLS_MUTATE_H
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/ControlStruct/module.mk
===================================================================
--- translator/ControlStruct/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ControlStruct/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,10 @@
+SRC +=  ControlStruct/LabelGenerator.cc \
+        ControlStruct/LabelFixer.cc \
+        ControlStruct/MLEMutator.cc \
+	ControlStruct/CaseRangeMutator.cc \
+	ControlStruct/Mutate.cc \
+	ControlStruct/ChooseMutator.cc \
+	ControlStruct/ForExprMutator.cc \
+	ControlStruct/LabelTypeChecker.cc \
+	$(NULL)
+
Index: translator/Designators/Processor.cc
===================================================================
--- translator/Designators/Processor.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Designators/Processor.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,151 @@
+#include <vector>
+#include <algorithm>
+
+#include "Processor.h"
+#include "SynTree/Declaration.h"
+
+namespace Designators {
+
+  Matcher::Matcher( const std::list< DeclarationWithType * > &decls ) {
+    int cnt = 0;
+    for( std::list< DeclarationWithType * >::const_iterator i = decls.begin();
+	 i != decls.end(); i++, cnt++ ) {
+      std::string newName = (*i)->get_name();
+      if( table.find( newName ) == table.end() ) {
+	table.insert( std::pair<std::string, int>(newName, cnt) );
+	order.push_back( newName );
+	declarations.push_back( *i );
+	alternatives.push_back( 0 );
+      }
+    }
+  }
+
+  template< class InputIterator >
+  bool Matcher::add(InputIterator begin, InputIterator end, ResolvExpr::Alternative &alt ) {
+    while( begin != end ) {
+      if ( table.find( *begin ) != table.end() )
+	alternatives[ table[ *begin ] ] = new ResolvExpr::Alternative(alt);
+      else
+	return false;
+      begin++;
+    }
+    return true;
+  }
+
+  template< class InputIterator, class OutputIterator >
+  bool Matcher::slice(InputIterator begin, InputIterator end, OutputIterator out ) {
+    while( begin != end )
+      if ( table.find( *begin ) != table.end() )
+	*out++ = declarations [ table[ *begin++ ] ];
+      else
+	return false; // throw 0;
+    return true;
+  }
+
+  template< class OutputIterator >
+  bool Matcher::get_reorderedCall( OutputIterator out ) {
+    // fill call with defaults, if need be
+    for (Matcher::iterator o = begin(); o != end(); o++ )
+      if ( alternatives[ table[ *o ] ] == 0 )
+	return false;
+      else
+	out++ = *alternatives[table[ *o ]];
+    return true;
+  }
+
+  bool fixDesignations( ResolvExpr::AlternativeFinder &finder, Expression *designation ) {
+    /* Distribute `designation' over alternatives contained in `finder' */
+    if (!designation) return false;
+    else
+      for( ResolvExpr::AlternativeFinder::iterator alt = finder.begin(); alt != finder.end(); alt++ )
+	alt->expr->set_argName( designation );
+    return true;
+  }
+
+  template < class OutputIterator >
+  bool extractNames( Expression *expr, OutputIterator out, Matcher matcher ) {
+    Expression *designator = expr->get_argName();
+    if ( designator == 0 ) return false;
+
+    if( NameExpr *ndes = dynamic_cast<NameExpr *>(designator) )
+	out++ = ndes->get_name();
+    else if ( TupleExpr *tdes = dynamic_cast<TupleExpr *>(designator) ) {
+      std::cerr << "Tuple designation" << std::endl;
+//      ObjectDecl *decl = extractTupleV(matcher, tdes); // xxx
+      // transform?
+      for( std::list< Expression * >::iterator n = tdes->get_exprs().begin();
+	   n != tdes->get_exprs().end(); n++ ) {
+
+	if ( NameExpr *name = dynamic_cast<NameExpr *>(*n) )
+	  out++ = name->get_name();
+	else
+	  // flatten nested Tuples
+	  throw SemanticError( "Invalid tuple designation." );
+      }
+    }
+    return true;
+  }
+
+  std::string extractName( Expression *expr ) /* throw NoNameExtraction */ {
+    if( NameExpr *name = dynamic_cast< NameExpr *>(expr) )
+      return name->get_name();
+    else /* if() */
+      throw 0;
+  }
+
+  DeclarationWithType *gensym( DeclarationWithType *, std::string prefix ) {
+    return 0;
+  }
+
+  ObjectDecl *extractTupleV( Matcher matcher, TupleExpr *nmTuple ) {
+    /* extract a subtuple of the function `fun' argument list, corresponding to the tuple
+       of names requested by `nmTuple'.
+     */
+    std::list< Expression * > &exprs = nmTuple->get_exprs();
+    std::cerr << "In extractTupleV, the tuple has " << exprs.size() << " components." << std::endl;
+    std::list< std::string > names;
+    std::transform( exprs.begin(), exprs.end(), back_inserter(names), extractName );
+    std::list< DeclarationWithType * > decls;
+    matcher.slice( names.begin(), names.end(), back_inserter(decls) );
+    //std::for_each( decls.begin(), decls.end(), gensym );
+    std::cerr << "Returning declaration with " << decls.size() << " components." << std::endl;
+
+    return 0;//new ObjectDecl()
+  }
+
+  void check_alternative( FunctionType *fun, ResolvExpr::AltList &args ) {
+    using namespace ResolvExpr;
+
+    Matcher matcher( fun->get_parameters() );
+    for ( AltList::iterator a = args.begin(); a != args.end(); a++ ) {
+      std::list< std::string > actNames;
+      if ( !extractNames( a->expr, back_inserter(actNames), matcher ) ) {
+	return; // not a designated call, leave alternative alone
+      } else {
+	// see if there's a match
+	matcher.add( actNames.begin(), actNames.end(), *a );
+      }
+    }
+    //AltList newArgs;
+    args.clear();
+    matcher.get_reorderedCall( back_inserter(args) );
+
+    return;
+  }
+
+  /*
+  void pruneAlternatives( Expression *expr, ResolvExpr::AlternativeFinder &finder ) {
+    if ( expr->get_argName() != 0 ) {
+      // Looking at designated expression
+	using namespace ResolvExpr;
+	AltList &alternatives = finder.get_alternatives();
+	std::cerr << "Now printing alternatives: " << std::endl;
+	for( AltList::iterator a = alternatives.begin(); a != alternatives.end(); a++ )
+	  a->expr->print( std::cerr );
+	//std::cerr << "Looking for constructions of length no more than: " << tdes->get_exprs().size() << "." << std::endl;
+      }
+    }
+    return;
+  }
+  */
+} // namespaces Designators
Index: translator/Designators/Processor.h
===================================================================
--- translator/Designators/Processor.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Designators/Processor.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,64 @@
+#include "SynTree/Declaration.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Type.h"
+#include "ResolvExpr/AlternativeFinder.h"
+
+#include <vector>
+#include <string>
+#include <list>
+#include <map>
+
+namespace Designators {
+  class Matcher;
+  class GenSym;
+
+  template < class OutputIterator >  bool extractNames( std::list< DeclarationWithType * > &, OutputIterator );
+  template < class OutputIterator >  bool extractNames( Expression *, OutputIterator, Matcher );
+  void check_alternative( FunctionType *, ResolvExpr::AltList & );
+  ObjectDecl *extractTupleV( Matcher, TupleExpr *names );
+  bool fixDesignations( ResolvExpr::AlternativeFinder &finder, Expression *designation );
+  DeclarationWithType *gensym( GenSym &, DeclarationWithType * );
+
+  class GenSym {
+  public:
+    GenSym( std::string prefix = "" ) : gensym_count(0) {}
+    GenSym( GenSym &other ) { gensym_count = other.gensym_count; }
+
+//    std::string get_symbol() { }
+  private:
+    std::string prefix;
+    int gensym_count;
+  };
+
+  // template< typename Key >
+  class Matcher {
+  public:
+    typedef std::vector< std::string >::iterator iterator;
+
+    Matcher( const std::list< DeclarationWithType * > & );
+    ~Matcher() {}
+
+    template< class OutputIterator > bool get_reorderedCall( OutputIterator );
+    template< class InputIterator >  bool add(InputIterator, InputIterator, ResolvExpr::Alternative &);
+    template< class InputIterator, class OutputIterator >  bool slice(InputIterator begin, InputIterator end, OutputIterator );
+    //std::vector<std::string> &get_order() const { return order; }
+
+    iterator begin() { return order.begin(); }
+    iterator end() { return order.end(); }
+
+    //Expression *operator[]( int idx ) { return table( order[ idx ] ); }
+  private:
+    std::map< std::string, int > table;
+    std::vector<std::string> order;
+    std::vector<DeclarationWithType *> declarations;
+    std::vector<ResolvExpr::Alternative *> alternatives;
+  };
+  //  void pruneAlternatives( Expression *expr, ResolvExpr::AlternativeFinder & );
+
+} // namespace Designators
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/Designators/module.mk
===================================================================
--- translator/Designators/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Designators/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,2 @@
+SRC +=  Designators/Processor.cc \
+	$(NULL)
Index: translator/Docs/Makefile
===================================================================
--- translator/Docs/Makefile	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Docs/Makefile	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,38 @@
+DIA = dia --nosplash
+TEX = latex
+DVIPS = dvips
+DVIPSFLAGS = -t landscape
+JUNK = .aux .log .dvi 
+
+# DocBook macros
+# JADE=openjade 
+# STYLEDIR=$(SGML_SHARE)/dsssl/docbook
+# STYLE=print/docbook.dsl
+# TARGET = tex
+
+DIAGRAMS = uml.dia
+DIAGRAMSOUT = $(DIAGRAMS:.dia=.eps)
+
+# SOURCES = intro.sgml mngmt.sgml pcap.sgml biblo.sgml conc.sgml
+
+.SUFFIXES : .dia .eps
+.dia.eps:
+	$(DIA) $< --export=$@
+
+%.dvi: %.tex
+	$(TEX) $<
+
+%.ps: %.dvi
+	$(DVIPS) $(DVIPSFLAGS) $< -o $@
+
+design.ps:
+
+# project.dvi: project.$(TARGET)
+# 	jadetex $<
+
+# project.$(TARGET):project.sgml $(DIAGRAMSOUT) $(SOURCES)
+# 	$(JADE) -t $(TARGET) -d $(STYLEDIR)/$(STYLE) project.sgml
+
+clean: 
+	rm -f *.dvi *.tex *.ps *~ *.aux *.log
+
Index: translator/Docs/cfa-cpp.1
===================================================================
--- translator/Docs/cfa-cpp.1	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Docs/cfa-cpp.1	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,46 @@
+.TH "cfa-cpp" "1"  "December 2002" "" ""
+.SH NAME
+cfa-cpp \- The CForall preprocessor
+.SH SYNOPSIS
+.B cfa-cpp
+\fBcfa-cpp\fP [ -dtsgmcvenplD ] input_files
+.br
+.SH DESCRIPTION
+\fBcfa-cpp\fP converts (cpp) preprocessed programs to C source files
+for later processing by \fBgcc\fP(1)
+.SH OPTIONS
+.TP
+\fB-d\fP
+bison(1) debugging info
+.TP
+\fB-t\fP
+dump parse tree
+.TP
+\fB-s\fP
+dump Abstract Syntax Tree
+.TP
+\fB-g\fP
+print alternatives for expressions
+.TP
+\fB-m\fP
+print symbol table events
+.TP
+\fB-c\fP
+generate C code
+.TP
+\fB-v\fP
+dump AST after validation of declarations
+.TP
+\fB-e\fP
+dump AST after expression analysis
+.TP
+\fB-n\fP
+don't read preamble (can be combined with any of the preceding)
+.TP
+\fB-p\fP
+generate prototypes for preamble functions
+.TP
+\fB-l\fP
+generate libcfa.c
+.SH "SEE ALSO"
+The Cforall project homepage (http://plg.uwaterloo.ca/~cforall)
Index: translator/Docs/design.tex
===================================================================
--- translator/Docs/design.tex	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Docs/design.tex	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,14 @@
+\documentclass[landscape]{article}
+
+\usepackage{graphicx}
+
+\begin{document}
+
+ \begin{figure}
+ \centering
+ %\includegraphics[totalheight=0.8\textheight,viewport=50 260 400 1000,clip]{erptsqfit}
+ \includegraphics{uml}
+ %\caption[UML Diagram for the CFA translator] %\label{fig:erptsqfit}
+ \end{figure}
+
+\end{document}
Index: translator/GenPoly/Box.cc
===================================================================
--- translator/GenPoly/Box.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/GenPoly/Box.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,1143 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Box.cc,v 1.20 2005/08/29 20:14:13 rcbilson Exp $
+ *
+ */
+
+#include <set>
+#include <string>
+#include <iterator>
+#include <algorithm>
+#include <cassert>
+
+#include "Box.h"
+#include "PolyMutator.h"
+#include "FindFunction.h"
+#include "ScrubTyVars.h"
+
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Initializer.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Mutator.h"
+#include "ResolvExpr/TypeEnvironment.h"
+#include "SymTab/Mangler.h"
+
+#include "SemanticError.h"
+#include "UniqueName.h"
+#include "utility.h"
+
+#include <ext/functional> // temporary
+
+namespace GenPoly {
+
+namespace {
+
+const std::list<Label> noLabels;
+
+class Pass1 : public PolyMutator
+{
+public:
+  Pass1();
+  virtual Expression *mutate( ApplicationExpr *appExpr );
+  virtual Expression *mutate( AddressExpr *addrExpr );
+  virtual Expression *mutate( UntypedExpr *expr );
+  virtual DeclarationWithType* mutate( FunctionDecl *functionDecl );
+  virtual TypeDecl* mutate( TypeDecl *typeDecl );
+  virtual Expression *mutate( CommaExpr *commaExpr );
+  virtual Expression *mutate( ConditionalExpr *condExpr );
+  virtual Statement* mutate(ReturnStmt *catchStmt);
+  virtual Type* mutate( PointerType *pointerType );
+  virtual Type* mutate( FunctionType *pointerType );
+  
+  virtual void doEndScope();
+  
+private:
+  void passTypeVars( ApplicationExpr* appExpr, std::list< Expression* >::iterator &arg, const TyVarMap &exprTyVars );
+  Expression* addRetParam( ApplicationExpr* appExpr, FunctionType *function, Type *retType, std::list< Expression* >::iterator &arg );
+  Expression* addPolyRetParam( ApplicationExpr* appExpr, FunctionType *function, std::string typeName, std::list< Expression* >::iterator &arg );
+  Expression* applyAdapter( ApplicationExpr* appExpr, FunctionType *function, std::list< Expression* >::iterator &arg, const TyVarMap &exprTyVars );
+  void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars );
+  void boxParams( ApplicationExpr* appExpr, FunctionType *function, std::list< Expression* >::iterator &arg, const TyVarMap &exprTyVars );
+  void addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression* >::iterator &arg, const TyVarMap &tyVars );
+  void findAssignOps( const std::list< TypeDecl* > &forall );
+  void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars );
+  FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars );
+  Expression *handleIntrinsics( ApplicationExpr *appExpr );
+  ObjectDecl *makeTemporary( Type *type );
+  
+  std::map< std::string, DeclarationWithType* > assignOps;
+  std::map< std::string, FunctionDecl* > adapters;
+  DeclarationWithType* retval;
+  bool useRetval;
+  UniqueName tempNamer;
+};
+
+class Pass2 : public PolyMutator
+{
+public:
+  Pass2();
+  template< typename DeclClass >
+  DeclClass* handleDecl( DeclClass *decl, Type *type );
+  virtual DeclarationWithType* mutate( FunctionDecl *functionDecl );
+  virtual ObjectDecl* mutate( ObjectDecl *objectDecl );
+  virtual TypeDecl* mutate( TypeDecl *typeDecl );
+  virtual TypedefDecl* mutate( TypedefDecl *typedefDecl );
+  virtual Type* mutate( PointerType *pointerType );
+  virtual Type* mutate( FunctionType *funcType );
+
+private:
+  void addAdapters( FunctionType *functionType );
+  
+  std::map< UniqueId, std::string > adapterName;
+};
+
+class Pass3 : public PolyMutator
+{
+public:
+  template< typename DeclClass >
+  DeclClass* handleDecl( DeclClass *decl, Type *type );
+  virtual DeclarationWithType* mutate( FunctionDecl *functionDecl );
+  virtual ObjectDecl* mutate( ObjectDecl *objectDecl );
+  virtual TypedefDecl* mutate( TypedefDecl *objectDecl );
+  virtual TypeDecl* mutate( TypeDecl *objectDecl );
+  virtual Statement* mutate( DeclStmt *declStmt );
+  virtual Type* mutate( PointerType *pointerType );
+  virtual Type* mutate( FunctionType *funcType );
+
+private:
+};
+
+} // anonymous namespace
+
+void
+printAllNotBuiltin( const std::list< Declaration* >& translationUnit, std::ostream &os )
+{
+  for( std::list< Declaration* >::const_iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
+    if( !LinkageSpec::isBuiltin( (*i)->get_linkage() ) ) {
+      (*i)->print( os );
+      os << std::endl;
+    }
+  }
+}
+
+void
+box( std::list< Declaration* >& translationUnit )
+{
+  Pass1 pass1;
+  Pass2 pass2;
+  Pass3 pass3;
+  mutateAll( translationUnit, pass1 );
+  mutateAll( translationUnit, pass2 );
+  mutateAll( translationUnit, pass3 );
+}
+
+////////////////////////////////////////// Pass1 ////////////////////////////////////////////////////
+
+namespace {
+
+bool
+isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars )
+{
+  bool doTransform = false;
+  if( !function->get_returnVals().empty() ) {
+    if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( function->get_returnVals().front()->get_type() ) ) {
+    
+      // figure out if the return type is specified by a type parameter
+      for( std::list< TypeDecl* >::const_iterator tyVar = function->get_forall().begin(); tyVar != function->get_forall().end(); ++tyVar ) {
+        if( (*tyVar)->get_name() == typeInst->get_name() ) {
+          doTransform = true;
+          name = typeInst->get_name();
+          break;
+        }
+      }
+      if( !doTransform && otherTyVars.find( typeInst->get_name() ) != otherTyVars.end() ) {
+        doTransform = true;
+      }
+    }
+  }
+  return doTransform;
+}
+
+bool
+isPolyRet( FunctionType *function, std::string &name )
+{
+  TyVarMap dummyTyVars;
+  return isPolyRet( function, name, dummyTyVars );
+}
+
+Pass1::Pass1()
+  : useRetval( false ), tempNamer( "_temp" )
+{
+}
+
+bool
+checkAssignment( DeclarationWithType *decl, std::string &name )
+{
+  if( decl->get_name() == "?=?" ) {
+    if( PointerType *ptrType = dynamic_cast< PointerType* >( decl->get_type() ) ) {
+      if( FunctionType *funType = dynamic_cast< FunctionType* >( ptrType->get_base() ) ) {
+        if( funType->get_parameters().size() == 2 ) {
+          if( PointerType *pointer = dynamic_cast< PointerType* >( funType->get_parameters().front()->get_type() ) ) {
+            if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( pointer->get_base() ) ) {
+              name = typeInst->get_name();
+              return true;
+            }
+          }
+        }
+      }
+    }
+  }
+  return false;
+}
+
+void 
+Pass1::findAssignOps( const std::list< TypeDecl* > &forall )
+{
+  assignOps.clear();
+  for( std::list< TypeDecl* >::const_iterator i = forall.begin(); i != forall.end(); ++i ) {
+    for( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
+      std::string typeName;
+      if( checkAssignment( *assert, typeName ) ) {
+        assignOps[ typeName ] = *assert;
+      }
+    }
+  }
+}
+
+DeclarationWithType* 
+Pass1::mutate( FunctionDecl *functionDecl )
+{
+  if( functionDecl->get_statements() ) {
+    TyVarMap oldtyVars = scopeTyVars;
+    DeclarationWithType *oldRetval = retval;
+    bool oldUseRetval = useRetval;
+    
+    retval = 0;
+    std::string typeName;
+    if( isPolyRet( functionDecl->get_functionType(), typeName ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) {
+      retval = functionDecl->get_functionType()->get_returnVals().front();
+  
+      // give names to unnamed return values
+      if( retval->get_name() == "" ) {
+        retval->set_name( "_retparm" );
+        retval->set_linkage( LinkageSpec::C );
+      }
+    }
+    
+    scopeTyVars.clear();
+///     std::cerr << "clear\n";
+    makeTyVarMap( functionDecl->get_functionType(), scopeTyVars );
+    findAssignOps( functionDecl->get_functionType()->get_forall() );
+    functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) );
+  
+    scopeTyVars = oldtyVars;
+///     std::cerr << "end FunctionDecl: ";
+///     for( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
+///       std::cerr << i->first << " ";
+///     }
+///     std::cerr << "\n";
+    retval = oldRetval;
+    useRetval = oldUseRetval;
+    doEndScope();
+  }
+  return functionDecl;
+}
+
+TypeDecl*
+Pass1::mutate( TypeDecl *typeDecl )
+{
+///     std::cerr << "add " << typeDecl->get_name() << "\n";
+  scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
+  return Mutator::mutate( typeDecl );
+}
+
+Expression *
+Pass1::mutate( CommaExpr *commaExpr )
+{
+  bool oldUseRetval = useRetval;
+  useRetval = false;
+  commaExpr->set_arg1( maybeMutate( commaExpr->get_arg1(), *this ) );
+  useRetval = oldUseRetval;
+  commaExpr->set_arg2( maybeMutate( commaExpr->get_arg2(), *this ) );
+  return commaExpr;
+}
+
+Expression *
+Pass1::mutate( ConditionalExpr *condExpr )
+{
+  bool oldUseRetval = useRetval;
+  useRetval = false;
+  condExpr->set_arg1( maybeMutate( condExpr->get_arg1(), *this ) );
+  useRetval = oldUseRetval;
+  condExpr->set_arg2( maybeMutate( condExpr->get_arg2(), *this ) );
+  condExpr->set_arg3( maybeMutate( condExpr->get_arg3(), *this ) );
+  return condExpr;
+
+}
+
+void
+Pass1::passTypeVars( ApplicationExpr* appExpr, std::list< Expression* >::iterator &arg, const TyVarMap &exprTyVars )
+{
+  for( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) {
+    ResolvExpr::EqvClass eqvClass;
+    assert( env );
+    if( tyParm->second == TypeDecl::Any ) {
+      Type *concrete = env->lookup( tyParm->first );
+      if( concrete ) {
+        arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) );
+        arg++;
+      } else {
+        throw SemanticError( "unbound type variable in application ", appExpr );
+      }
+    }
+  }
+}
+
+ObjectDecl*
+Pass1::makeTemporary( Type *type )
+{
+  ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Declaration::NoStorageClass, LinkageSpec::C, 0, type, 0 );
+  stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
+  return newObj;
+}
+
+TypeInstType *
+isPolyType( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars )
+{
+  if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
+    if( env ) {
+      if( Type *newType = env->lookup( typeInst->get_name() ) ) {
+        return isPolyType( newType, env, tyVars );
+      }
+    }
+    if( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
+      return typeInst;
+    } else {
+      return 0;
+    }
+  } else {
+    return 0;
+  }
+}
+
+Expression*
+Pass1::addRetParam( ApplicationExpr* appExpr, FunctionType *function, Type *retType, std::list< Expression* >::iterator &arg )
+{
+  if( useRetval ) {
+    assert( retval );
+    arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) );
+    arg++;
+  } else {
+    ObjectDecl *newObj = makeTemporary( retType->clone() );
+    Expression *paramExpr = new VariableExpr( newObj );
+    if( !isPolyType( newObj->get_type(), env, scopeTyVars ) ) {
+      paramExpr = new AddressExpr( paramExpr );
+    }
+    arg = appExpr->get_args().insert( arg, paramExpr );
+    arg++;
+///     stmtsToAdd.push_back( new ExprStmt( noLabels, appExpr ) );
+    CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) );
+    commaExpr->set_env( appExpr->get_env() );
+    appExpr->set_env( 0 );
+    return commaExpr;
+  }
+  return appExpr;
+}
+
+Expression*
+Pass1::addPolyRetParam( ApplicationExpr* appExpr, FunctionType *function, std::string typeName, std::list< Expression* >::iterator &arg )
+{
+  ResolvExpr::EqvClass eqvClass;
+  assert( env );
+  Type *concrete = env->lookup( typeName );
+  if( concrete == 0 ) {
+    throw SemanticError( "Unbound type variable " + typeName + " in", appExpr );
+  }
+  return addRetParam( appExpr, function, concrete, arg );
+}
+
+Expression*
+Pass1::applyAdapter( ApplicationExpr* appExpr, FunctionType *function, std::list< Expression* >::iterator &arg, const TyVarMap &tyVars )
+{
+  Expression *ret = appExpr;
+  if( !function->get_returnVals().empty() && isPolyVal( function->get_returnVals().front()->get_type(), tyVars ) ) {
+    ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg );
+  }
+  appExpr->get_args().push_front( appExpr->get_function() );
+  appExpr->set_function( new NameExpr( "_adapter" + SymTab::Mangler::mangle( function ) ) );
+  
+  return ret;
+}
+
+void
+Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars )
+{
+  assert( !arg->get_results().empty() );
+///   if( !dynamic_cast< PointerType* >( arg->get_results().front() ) ) {
+    TypeInstType *typeInst = dynamic_cast< TypeInstType* >( param );
+    if( typeInst && exprTyVars.find( typeInst->get_name() ) != exprTyVars.end() ) {
+      if( arg->get_results().front()->get_isLvalue() ) {
+        arg = new AddressExpr( arg );
+      } else {
+        ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Declaration::NoStorageClass, LinkageSpec::C, 0, arg->get_results().front()->clone(), 0 );
+        newObj->get_type()->get_qualifiers() = Type::Qualifiers();
+        stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
+        UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
+        assign->get_args().push_back( new VariableExpr( newObj ) );
+        assign->get_args().push_back( arg );
+        stmtsToAdd.push_back( new ExprStmt( noLabels, assign ) );
+        arg = new AddressExpr( new VariableExpr( newObj ) );
+      }
+    }
+///   }
+}
+
+void
+addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars )
+{
+  Type *newType = formal->clone();
+  std::list< FunctionType* > functions;
+  // instead of functions needing adapters, this really ought to look for
+  // any function mentioning a polymorphic type
+  findAndReplaceFunction( newType, functions, tyVars, needsAdapter );
+  if( !functions.empty() ) {
+    actual = new CastExpr( actual, newType );
+  } else {
+    delete newType;
+  }
+}
+
+void
+Pass1::boxParams( ApplicationExpr* appExpr, FunctionType *function, std::list< Expression* >::iterator &arg, const TyVarMap &exprTyVars )
+{
+///   std::cout << "function is ";
+///   function->print( std::cout );
+  for( std::list< DeclarationWithType* >::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) {
+///     std::cout << "parameter is ";
+///     (*param)->print( std::cout );
+///     std::cout << std::endl << "argument is ";
+///     (*arg)->print( std::cout );
+    assert( arg != appExpr->get_args().end() );
+    addCast( *arg, (*param)->get_type(), exprTyVars );
+    boxParam( (*param)->get_type(), *arg, exprTyVars );
+  }
+}
+
+void
+Pass1::addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression* >::iterator &arg, const TyVarMap &tyVars )
+{
+  std::list< Expression* >::iterator cur = arg;
+  for( std::list< TypeDecl* >::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
+    for( std::list< DeclarationWithType* >::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
+      InferredParams::const_iterator inferParam = appExpr->get_inferParams().find( (*assert)->get_uniqueId() );
+      assert( inferParam != appExpr->get_inferParams().end() );
+      Expression *newExpr = inferParam->second.expr->clone();
+      addCast( newExpr, (*assert)->get_type(), tyVars );
+      boxParam( (*assert)->get_type(), newExpr, tyVars );
+      appExpr->get_args().insert( cur, newExpr );
+    }
+  }
+}
+
+void
+makeRetParm( FunctionType *funcType )
+{
+  DeclarationWithType *retParm = funcType->get_returnVals().front();
+
+  // make a new parameter that is a pointer to the type of the old return value
+  retParm->set_type( new PointerType( Type::Qualifiers(), retParm->get_type() ) );
+  funcType->get_parameters().push_front( retParm );
+
+  // we don't need the return value any more
+  funcType->get_returnVals().clear();
+}
+
+FunctionType *
+makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars )
+{
+  // actually make the adapter type
+  FunctionType *adapter = adaptee->clone();
+  if( !adapter->get_returnVals().empty() && isPolyVal( adapter->get_returnVals().front()->get_type(), tyVars ) ) {
+    makeRetParm( adapter );
+  }
+  adapter->get_parameters().push_front( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 ) );
+  return adapter;
+}
+
+Expression*
+makeAdapterArg( DeclarationWithType *param, DeclarationWithType *arg, DeclarationWithType *realParam, const TyVarMap &tyVars )
+{
+  assert( param );
+  assert( arg );
+///   std::cout << "arg type is ";
+///   arg->get_type()->print( std::cout );
+///   std::cout << "param type is ";
+///   param->get_type()->print( std::cout );
+///   std::cout << " tyVars are: ";
+///   printTyVarMap( std::cout, tyVars );
+  if( isPolyVal( realParam->get_type(), tyVars ) ) {
+///     if( dynamic_cast< PointerType* >( arg->get_type() ) ) {
+///       return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() );
+///     } else {
+      UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
+      deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
+      deref->get_results().push_back( arg->get_type()->clone() );
+      return deref;
+///     }
+  }
+  return new VariableExpr( param );
+}
+
+void
+addAdapterParams( ApplicationExpr *adapteeApp, std::list< DeclarationWithType* >::iterator arg, std::list< DeclarationWithType* >::iterator param, std::list< DeclarationWithType* >::iterator paramEnd, std::list< DeclarationWithType* >::iterator realParam, const TyVarMap &tyVars )
+{
+  UniqueName paramNamer( "_p" );
+  for( ; param != paramEnd; ++param, ++arg, ++realParam ) {
+    if( (*param)->get_name() == "" ) {
+      (*param)->set_name( paramNamer.newName() );
+      (*param)->set_linkage( LinkageSpec::C );
+    }
+    adapteeApp->get_args().push_back( makeAdapterArg( *param, *arg, *realParam, tyVars ) );
+  }
+}
+
+FunctionDecl *
+Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars )
+{
+  FunctionType *adapterType = makeAdapterType( adaptee, tyVars );
+  adapterType = ScrubTyVars::scrub( adapterType, tyVars );
+  DeclarationWithType *adapteeDecl = adapterType->get_parameters().front();
+  adapteeDecl->set_name( "_adaptee" );
+  ApplicationExpr *adapteeApp = new ApplicationExpr( new CastExpr( new VariableExpr( adapteeDecl ), new PointerType( Type::Qualifiers(), realType ) ) );
+  Statement *bodyStmt;
+  
+  std::list< TypeDecl* >::iterator tyArg = realType->get_forall().begin();
+  std::list< TypeDecl* >::iterator tyParam = adapterType->get_forall().begin();
+  std::list< TypeDecl* >::iterator realTyParam = adaptee->get_forall().begin();
+  for( ; tyParam != adapterType->get_forall().end(); ++tyArg, ++tyParam, ++realTyParam ) {
+    assert( tyArg != realType->get_forall().end() );
+    std::list< DeclarationWithType* >::iterator assertArg = (*tyArg)->get_assertions().begin();
+    std::list< DeclarationWithType* >::iterator assertParam = (*tyParam)->get_assertions().begin();
+    std::list< DeclarationWithType* >::iterator realAssertParam = (*realTyParam)->get_assertions().begin();
+    for( ; assertParam != (*tyParam)->get_assertions().end(); ++assertArg, ++assertParam, ++realAssertParam ) {
+      assert( assertArg != (*tyArg)->get_assertions().end() );
+      adapteeApp->get_args().push_back( makeAdapterArg( *assertParam, *assertArg, *realAssertParam, tyVars ) );
+    }
+  }
+  
+  std::list< DeclarationWithType* >::iterator arg = realType->get_parameters().begin();
+  std::list< DeclarationWithType* >::iterator param = adapterType->get_parameters().begin();
+  std::list< DeclarationWithType* >::iterator realParam = adaptee->get_parameters().begin();
+  param++;		// skip adaptee parameter
+  if( realType->get_returnVals().empty() ) {
+    addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
+    bodyStmt = new ExprStmt( noLabels, adapteeApp );
+  } else if( isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
+    if( (*param)->get_name() == "" ) {
+      (*param)->set_name( "_ret" );
+      (*param)->set_linkage( LinkageSpec::C );
+    }
+    UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
+    UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
+    deref->get_args().push_back( new CastExpr( new VariableExpr( *param++ ), new PointerType( Type::Qualifiers(), realType->get_returnVals().front()->get_type()->clone() ) ) );
+    assign->get_args().push_back( deref );
+    addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
+    assign->get_args().push_back( adapteeApp );
+    bodyStmt = new ExprStmt( noLabels, assign );
+  } else {
+    // adapter for a function that returns a monomorphic value
+    addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
+    bodyStmt = new ReturnStmt( noLabels, adapteeApp );
+  }
+  CompoundStmt *adapterBody = new CompoundStmt( noLabels );
+  adapterBody->get_kids().push_back( bodyStmt );
+  return new FunctionDecl( "_adapter" + mangleName, Declaration::NoStorageClass, LinkageSpec::C, adapterType, adapterBody, false );
+}
+
+void
+Pass1::passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars )
+{
+  std::list< DeclarationWithType* > &paramList = functionType->get_parameters();
+  std::list< FunctionType* > functions;
+  for( std::list< TypeDecl* >::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
+    for( std::list< DeclarationWithType* >::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
+      findFunction( (*assert)->get_type(), functions, exprTyVars, needsAdapter );
+    }
+  }
+  for( std::list< DeclarationWithType* >::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
+    findFunction( (*arg)->get_type(), functions, exprTyVars, needsAdapter );
+  }
+  std::set< std::string > adaptersDone;
+  for( std::list< FunctionType* >::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
+    FunctionType *realFunction = (*funType)->clone();
+    assert( env );
+    env->apply( realFunction );
+    std::string mangleName = SymTab::Mangler::mangle( realFunction );
+    if( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
+      std::map< std::string, FunctionDecl* >::iterator adapter = adapters.find( mangleName );
+      if( adapter == adapters.end() ) {
+        FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars );
+        adapter = adapters.insert( adapters.begin(), std::pair< std::string, FunctionDecl* >( mangleName, newAdapter ) );
+        stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) );
+      }
+      assert( adapter != adapters.end() );
+      appExpr->get_args().push_front( new VariableExpr( adapter->second ) );
+      adaptersDone.insert( adaptersDone.begin(), mangleName );
+    }
+  }
+}
+
+TypeInstType*
+isPolyPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars )
+{
+  if( PointerType *ptr = dynamic_cast< PointerType* >( type ) ) {
+    return isPolyType( ptr->get_base(), env, tyVars );
+  } else if( env ) {
+    if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
+      if( Type *newType = env->lookup( typeInst->get_name() ) ) {
+        return isPolyPtr( newType, env, tyVars );
+      }
+    }
+  }
+  return 0;
+}
+
+TypeInstType*
+isPolyPtrPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars )
+{
+  if( PointerType *ptr = dynamic_cast< PointerType* >( type ) ) {
+    return isPolyPtr( ptr->get_base(), env, tyVars );
+  } else if( env ) {
+    if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
+      if( Type *newType = env->lookup( typeInst->get_name() ) ) {
+        return isPolyPtrPtr( newType, env, tyVars );
+      }
+    }
+  }
+  return 0;
+}
+
+Expression *
+makeIncrDecrExpr( ApplicationExpr *appExpr, std::string polyName, bool isIncr )
+{
+  NameExpr *opExpr;
+  if( isIncr ) {
+    opExpr = new NameExpr( "?+=?" );
+  } else {
+    opExpr = new NameExpr( "?-=?" );
+  }
+  UntypedExpr *addAssign = new UntypedExpr( opExpr );
+  if( AddressExpr *address = dynamic_cast< AddressExpr* >( appExpr->get_args().front() ) ) {
+    addAssign->get_args().push_back( address->get_arg() );
+  } else {
+    addAssign->get_args().push_back( appExpr->get_args().front() );
+  }
+  addAssign->get_args().push_back( new NameExpr( polyName ) );
+  addAssign->get_results().front() = appExpr->get_results().front()->clone();
+  if( appExpr->get_env() ) {
+    addAssign->set_env( appExpr->get_env() );
+    appExpr->set_env( 0 );
+  }
+  appExpr->get_args().clear();
+  delete appExpr;
+  return addAssign;
+}
+
+Expression*
+Pass1::handleIntrinsics( ApplicationExpr *appExpr )
+{
+  if( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( appExpr->get_function() ) ) {
+    if( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
+      if( varExpr->get_var()->get_name() == "?[?]" ) {
+        assert( !appExpr->get_results().empty() );
+        assert( appExpr->get_args().size() == 2 );
+        TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars );
+        TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars );
+        assert( !typeInst1 || !typeInst2 );
+        UntypedExpr *ret = 0;
+        if( typeInst1 || typeInst2 ) {
+          ret = new UntypedExpr( new NameExpr( "?+?" ) );
+        }
+        if( typeInst1 ) {
+          UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
+          multiply->get_args().push_back( appExpr->get_args().back() );
+          multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
+          ret->get_args().push_back( appExpr->get_args().front() );
+          ret->get_args().push_back( multiply );
+        } else if( typeInst2 ) {
+          UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
+          multiply->get_args().push_back( appExpr->get_args().front() );
+          multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );
+          ret->get_args().push_back( multiply );
+          ret->get_args().push_back( appExpr->get_args().back() );
+        }
+        if( typeInst1 || typeInst2 ) {
+          ret->get_results().push_front( appExpr->get_results().front()->clone() );
+          if( appExpr->get_env() ) {
+            ret->set_env( appExpr->get_env() );
+            appExpr->set_env( 0 );
+          }
+          appExpr->get_args().clear();
+          delete appExpr;
+          return ret;
+        }
+      } else if( varExpr->get_var()->get_name() == "*?" ) {
+        assert( !appExpr->get_results().empty() );
+        assert( !appExpr->get_args().empty() );
+        if( isPolyType( appExpr->get_results().front(), env, scopeTyVars ) ) {
+          Expression *ret = appExpr->get_args().front();
+          delete ret->get_results().front();
+          ret->get_results().front() = appExpr->get_results().front()->clone();
+          if( appExpr->get_env() ) {
+            ret->set_env( appExpr->get_env() );
+            appExpr->set_env( 0 );
+          }
+          appExpr->get_args().clear();
+          delete appExpr;
+          return ret;
+        }
+      } else if( varExpr->get_var()->get_name() == "?++" || varExpr->get_var()->get_name() == "?--" ) {
+        assert( !appExpr->get_results().empty() );
+        assert( appExpr->get_args().size() == 1 );
+        if( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) {
+          Type *tempType = appExpr->get_results().front()->clone();
+          if( env ) {
+            env->apply( tempType );
+          }
+          ObjectDecl *newObj = makeTemporary( tempType );
+          VariableExpr *tempExpr = new VariableExpr( newObj );
+          UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
+          assignExpr->get_args().push_back( tempExpr->clone() );
+          if( AddressExpr *address = dynamic_cast< AddressExpr* >( appExpr->get_args().front() ) ) {
+            assignExpr->get_args().push_back( address->get_arg()->clone() );
+          } else {
+            assignExpr->get_args().push_back( appExpr->get_args().front()->clone() );
+          }
+          CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "?++" ) );
+          return new CommaExpr( firstComma, tempExpr );
+        }
+      } else if( varExpr->get_var()->get_name() == "++?" || varExpr->get_var()->get_name() == "--?" ) {
+        assert( !appExpr->get_results().empty() );
+        assert( appExpr->get_args().size() == 1 );
+        if( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) {
+           return makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "++?" );
+        }
+      } else if( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) {
+        assert( !appExpr->get_results().empty() );
+        assert( appExpr->get_args().size() == 2 );
+        TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars );
+        TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars );
+        if( typeInst1 && typeInst2 ) {
+          UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) );
+          divide->get_args().push_back( appExpr );
+          divide->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
+          divide->get_results().push_front( appExpr->get_results().front()->clone() );
+          if( appExpr->get_env() ) {
+            divide->set_env( appExpr->get_env() );
+            appExpr->set_env( 0 );
+          }
+          return divide;
+        } else if( typeInst1 ) {
+          UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
+          multiply->get_args().push_back( appExpr->get_args().back() );
+          multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
+          appExpr->get_args().back() = multiply;
+        } else if( typeInst2 ) {
+          UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
+          multiply->get_args().push_back( appExpr->get_args().front() );
+          multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );
+          appExpr->get_args().front() = multiply;
+        }
+      } else if( varExpr->get_var()->get_name() == "?+=?" || varExpr->get_var()->get_name() == "?-=?" ) {
+        assert( !appExpr->get_results().empty() );
+        assert( appExpr->get_args().size() == 2 );
+        TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars );
+        if( typeInst ) {
+          UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
+          multiply->get_args().push_back( appExpr->get_args().back() );
+          multiply->get_args().push_back( new NameExpr( typeInst->get_name() ) );
+          appExpr->get_args().back() = multiply;
+        }
+      }
+      return appExpr;
+    }
+  }
+  return 0;
+}
+
+Expression*
+Pass1::mutate( ApplicationExpr *appExpr )
+{
+///     std::cerr << "mutate appExpr: ";
+///     for( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
+///       std::cerr << i->first << " ";
+///     }
+///     std::cerr << "\n";
+  bool oldUseRetval = useRetval;
+  useRetval = false;
+  appExpr->get_function()->acceptMutator( *this );
+  mutateAll( appExpr->get_args(), *this );
+  useRetval = oldUseRetval;
+  
+  assert( !appExpr->get_function()->get_results().empty() );
+  PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
+  assert( pointer );
+  FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
+  assert( function );
+  
+  if( Expression *newExpr = handleIntrinsics( appExpr ) ) {
+    return newExpr;
+  }
+  
+  Expression *ret = appExpr;
+  
+  std::list< Expression* >::iterator arg = appExpr->get_args().begin();
+  std::list< Expression* >::iterator paramBegin = appExpr->get_args().begin();
+  
+  std::string typeName;
+  if( isPolyRet( function, typeName ) ) {
+    ret = addPolyRetParam( appExpr, function, typeName, arg );
+  } else if( needsAdapter( function, scopeTyVars ) ) {
+///     std::cerr << "needs adapter: ";
+///     for( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
+///       std::cerr << i->first << " ";
+///     }
+///     std::cerr << "\n";
+    // change the application so it calls the adapter rather than the passed function
+    ret = applyAdapter( appExpr, function, arg, scopeTyVars );
+  }
+  arg = appExpr->get_args().begin();
+  
+  TyVarMap exprTyVars;
+  makeTyVarMap( function, exprTyVars );
+  
+  passTypeVars( appExpr, arg, exprTyVars );
+  addInferredParams( appExpr, function, arg, exprTyVars );
+
+  arg = paramBegin;
+  
+  boxParams( appExpr, function, arg, exprTyVars );
+
+  passAdapters( appExpr, function, exprTyVars );
+
+  return ret;
+}
+
+Expression *
+Pass1::mutate( UntypedExpr *expr )
+{
+  if( !expr->get_results().empty() && isPolyType( expr->get_results().front(), env, scopeTyVars ) ) {
+    if( NameExpr *name = dynamic_cast< NameExpr* >( expr->get_function() ) ) {
+      if( name->get_name() == "*?" ) {
+        Expression *ret = expr->get_args().front();
+        expr->get_args().clear();
+        delete expr;
+        return ret->acceptMutator( *this );
+      }
+    }
+  }
+  return PolyMutator::mutate( expr );
+}
+
+Expression *
+Pass1::mutate( AddressExpr *addrExpr )
+{
+  assert( !addrExpr->get_arg()->get_results().empty() );
+  mutateExpression( addrExpr->get_arg() );
+  if( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars ) ) {
+    Expression *ret = addrExpr->get_arg();
+    delete ret->get_results().front();
+    ret->get_results().front() = addrExpr->get_results().front()->clone();
+    addrExpr->set_arg( 0 );
+    delete addrExpr;
+    return ret;
+  } else {
+    return addrExpr;
+  }
+}
+
+Statement* 
+Pass1::mutate(ReturnStmt *retStmt)
+{
+  // a cast expr on a polymorphic return value is either redundant or invalid
+  while( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) {
+    retStmt->set_expr( castExpr->get_arg() );
+    retStmt->get_expr()->set_env( castExpr->get_env() );
+    castExpr->set_env( 0 );
+    castExpr->set_arg( 0 );
+    delete castExpr;
+  }
+  if( retval && retStmt->get_expr() ) {
+    assert( !retStmt->get_expr()->get_results().empty() );
+    if( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
+///       retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
+      TypeInstType *typeInst = dynamic_cast< TypeInstType* >( retval->get_type() );
+      assert( typeInst );
+      std::map< std::string, DeclarationWithType* >::const_iterator assignIter = assignOps.find( typeInst->get_name() );
+      if( assignIter == assignOps.end() ) {
+        throw SemanticError( "Attempt to return dtype or ftype object in ", retStmt->get_expr() );
+      }
+      ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
+      Expression *retParm = new NameExpr( retval->get_name() );
+      retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
+      assignExpr->get_args().push_back( retParm );
+      assignExpr->get_args().push_back( retStmt->get_expr() );
+      stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) );
+    } else {
+      useRetval = true;
+      stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( retStmt->get_expr() ) ) );
+      useRetval = false;
+    }
+    retStmt->set_expr( 0 );
+  } else {
+    retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
+  }
+  return retStmt;
+}
+
+Type* 
+Pass1::mutate( PointerType *pointerType )
+{
+  TyVarMap oldtyVars = scopeTyVars;
+  makeTyVarMap( pointerType, scopeTyVars );
+  
+  Type* ret = Mutator::mutate( pointerType );
+  
+  scopeTyVars = oldtyVars;
+  return ret;
+}
+
+Type* 
+Pass1::mutate( FunctionType *functionType )
+{
+  TyVarMap oldtyVars = scopeTyVars;
+  makeTyVarMap( functionType, scopeTyVars );
+  
+  Type* ret = Mutator::mutate( functionType );
+  
+  scopeTyVars = oldtyVars;
+  return ret;
+}
+
+void
+Pass1::doEndScope()
+{
+  adapters.clear();
+}
+
+////////////////////////////////////////// Pass2 ////////////////////////////////////////////////////
+
+Pass2::Pass2()
+{
+}
+
+void 
+Pass2::addAdapters( FunctionType *functionType )
+{
+  std::list< DeclarationWithType* > &paramList = functionType->get_parameters();
+  std::list< FunctionType* > functions;
+  for( std::list< DeclarationWithType* >::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {
+    Type *orig = (*arg)->get_type();
+    findAndReplaceFunction( orig, functions, scopeTyVars, needsAdapter );
+    (*arg)->set_type( orig );
+  }
+  std::set< std::string > adaptersDone;
+  for( std::list< FunctionType* >::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
+    std::string mangleName = SymTab::Mangler::mangle( *funType );
+    if( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
+      paramList.push_front( new ObjectDecl( "_adapter" + mangleName, Declaration::NoStorageClass, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0 ) );
+      adaptersDone.insert( adaptersDone.begin(), mangleName );
+    }
+  }
+///  deleteAll( functions );
+}
+
+template< typename DeclClass >
+DeclClass* 
+Pass2::handleDecl( DeclClass *decl, Type *type )
+{
+  DeclClass *ret = static_cast< DeclClass* >( Mutator::mutate( decl ) );
+
+  return ret;
+}
+
+DeclarationWithType* 
+Pass2::mutate( FunctionDecl *functionDecl )
+{
+  return handleDecl( functionDecl, functionDecl->get_functionType() );
+}
+
+ObjectDecl* 
+Pass2::mutate( ObjectDecl *objectDecl )
+{
+  return handleDecl( objectDecl, objectDecl->get_type() );
+}
+
+TypeDecl* 
+Pass2::mutate( TypeDecl *typeDecl )
+{
+  scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
+  if( typeDecl->get_base() ) {
+    return handleDecl( typeDecl, typeDecl->get_base() );
+  } else {
+    return Mutator::mutate( typeDecl );
+  }
+}
+
+TypedefDecl* 
+Pass2::mutate( TypedefDecl *typedefDecl )
+{
+  return handleDecl( typedefDecl, typedefDecl->get_base() );
+}
+
+Type* 
+Pass2::mutate( PointerType *pointerType )
+{
+  TyVarMap oldtyVars = scopeTyVars;
+  makeTyVarMap( pointerType, scopeTyVars );
+  
+  Type* ret = Mutator::mutate( pointerType );
+  
+  scopeTyVars = oldtyVars;
+  return ret;
+}
+
+Type *
+Pass2::mutate( FunctionType *funcType )
+{
+  TyVarMap oldtyVars = scopeTyVars;
+  makeTyVarMap( funcType, scopeTyVars );
+  
+  std::string typeName;
+  if( isPolyRet( funcType, typeName ) ) {
+    DeclarationWithType *ret = funcType->get_returnVals().front();
+    ret->set_type( new PointerType( Type::Qualifiers(), ret->get_type() ) );
+    funcType->get_parameters().push_front( ret );
+    funcType->get_returnVals().pop_front();
+  }
+  
+  std::list< DeclarationWithType* >::iterator last = funcType->get_parameters().begin();
+  std::list< DeclarationWithType* > inferredParams;
+  ObjectDecl *newObj = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
+///   ObjectDecl *newFunPtr = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
+  for( std::list< TypeDecl* >::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
+    ObjectDecl *thisParm;
+    if( (*tyParm)->get_kind() == TypeDecl::Any ) {
+      thisParm = newObj->clone();
+      thisParm->set_name( (*tyParm)->get_name() );
+      last = funcType->get_parameters().insert( last, thisParm );
+      ++last;
+    }
+    for( std::list< DeclarationWithType* >::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
+///       *assert = (*assert)->acceptMutator( *this );
+      inferredParams.push_back( *assert );
+    }
+    (*tyParm)->get_assertions().clear();
+  }
+  delete newObj;
+  funcType->get_parameters().splice( last, inferredParams );
+  addAdapters( funcType );
+  mutateAll( funcType->get_returnVals(), *this );
+  mutateAll( funcType->get_parameters(), *this );
+  
+  scopeTyVars = oldtyVars;
+  return funcType;
+}
+
+////////////////////////////////////////// Pass3 ////////////////////////////////////////////////////
+
+template< typename DeclClass >
+DeclClass* 
+Pass3::handleDecl( DeclClass *decl, Type *type )
+{
+  TyVarMap oldtyVars = scopeTyVars;
+  makeTyVarMap( type, scopeTyVars );
+  
+  DeclClass *ret = static_cast< DeclClass* >( Mutator::mutate( decl ) );
+  ScrubTyVars::scrub( decl, scopeTyVars );
+
+  scopeTyVars = oldtyVars;
+  return ret;
+}
+
+ObjectDecl* 
+Pass3::mutate( ObjectDecl *objectDecl )
+{
+  return handleDecl( objectDecl, objectDecl->get_type() );
+}
+
+DeclarationWithType* 
+Pass3::mutate( FunctionDecl *functionDecl )
+{
+  return handleDecl( functionDecl, functionDecl->get_functionType() );
+}
+
+TypedefDecl* 
+Pass3::mutate( TypedefDecl *typedefDecl )
+{
+  return handleDecl( typedefDecl, typedefDecl->get_base() );
+}
+
+TypeDecl* 
+Pass3::mutate( TypeDecl *typeDecl )
+{
+///   Initializer *init = 0;
+///   std::list< Expression *> designators;
+///   scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
+///   if( typeDecl->get_base() ) {
+///     init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );
+///   }
+///   return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );
+
+  scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
+  return Mutator::mutate( typeDecl );
+}
+
+Type* 
+Pass3::mutate( PointerType *pointerType )
+{
+  TyVarMap oldtyVars = scopeTyVars;
+  makeTyVarMap( pointerType, scopeTyVars );
+  
+  Type* ret = Mutator::mutate( pointerType );
+  
+  scopeTyVars = oldtyVars;
+  return ret;
+}
+
+Type* 
+Pass3::mutate( FunctionType *functionType )
+{
+  TyVarMap oldtyVars = scopeTyVars;
+  makeTyVarMap( functionType, scopeTyVars );
+  
+  Type* ret = Mutator::mutate( functionType );
+  
+  scopeTyVars = oldtyVars;
+  return ret;
+}
+
+Statement*
+Pass3::mutate( DeclStmt *declStmt )
+{
+  if( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( declStmt->get_decl() ) ) {
+    if( isPolyVal( objectDecl->get_type(), scopeTyVars ) ) {
+      TypeInstType *typeInst = dynamic_cast< TypeInstType* >( objectDecl->get_type() );
+      assert( typeInst );
+      UntypedExpr *alloc = new UntypedExpr( new NameExpr( "alloca" ) );
+      alloc->get_args().push_back( new NameExpr( typeInst->get_name() ) );
+      UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
+      assign->get_args().push_back( new VariableExpr( objectDecl ) );
+      assign->get_args().push_back( alloc );
+      stmtsToAddAfter.push_back( new ExprStmt( noLabels, assign ) );
+    }
+  }
+  return Mutator::mutate( declStmt );
+}
+    
+} // anonymous namespace
+
+} // namespace GenPoly
Index: translator/GenPoly/Box.h
===================================================================
--- translator/GenPoly/Box.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/GenPoly/Box.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,21 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Box.h,v 1.2 2005/08/29 20:14:13 rcbilson Exp $
+ *
+ */
+
+#ifndef GENPOLY_BOX_H
+#define GENPOLY_BOX_H
+
+#include <list>
+
+#include "SynTree/SynTree.h"
+
+namespace GenPoly {
+
+void box( std::list< Declaration* >& translationUnit );
+
+} // namespace GenPoly
+
+#endif /* #ifndef GENPOLY_BOX_H */
Index: translator/GenPoly/CopyParams.cc
===================================================================
--- translator/GenPoly/CopyParams.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/GenPoly/CopyParams.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,97 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: CopyParams.cc,v 1.3 2005/08/29 20:14:13 rcbilson Exp $
+ *
+ */
+
+#include <set>
+#include <map>
+#include <cassert>
+
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Visitor.h"
+#include "UniqueName.h"
+
+
+namespace GenPoly {
+
+class CopyParams : public Visitor
+{
+public:
+  CopyParams();
+  
+  virtual void visit( FunctionDecl *funcDecl );
+  virtual void visit( AddressExpr *addrExpr );
+
+private:
+  std::set< UniqueId > modVars;
+  UniqueName namer;
+};
+
+void
+copyParams( std::list< Declaration* > &translationUnit )
+{
+  CopyParams copier;
+  acceptAll( translationUnit, copier );
+}
+
+CopyParams::CopyParams()
+  : namer( "_cp" )
+{
+}
+
+static const std::list< Label > noLabels;
+
+void 
+CopyParams::visit( FunctionDecl *funcDecl )
+{
+  if( funcDecl->get_statements() ) {
+    funcDecl->get_statements()->accept( *this );
+    
+    if( !modVars.empty() ) {
+      std::map< std::string, DeclarationWithType* > assignOps;
+      // assume that the assignment operator is the first assert param after any "type" parameter
+      for( std::list< TypeDecl* >::const_iterator tyVar = funcDecl->get_functionType()->get_forall().begin(); tyVar != funcDecl->get_functionType()->get_forall().end(); ++tyVar ) {
+        if( (*tyVar)->get_kind() == TypeDecl::Any ) {
+          assert( !(*tyVar)->get_assertions().empty() );
+          assignOps[ (*tyVar)->get_name() ] = (*tyVar)->get_assertions().front();
+        }
+      }
+      for( std::list< DeclarationWithType* >::iterator param = funcDecl->get_functionType()->get_parameters().begin(); param != funcDecl->get_functionType()->get_parameters().end(); ++param ) {
+        std::set< UniqueId >::const_iterator var = modVars.find( (*param)->get_uniqueId() );
+        if( var != modVars.end() ) {
+          TypeInstType *typeInst = dynamic_cast< TypeInstType* >( (*param)->get_type() );
+          assert( typeInst );
+          std::map< std::string, DeclarationWithType* >::const_iterator assignOp = assignOps.find( typeInst->get_name() );
+          if( assignOp != assignOps.end() ) {
+            DeclarationWithType *oldParam = *param;
+            *param = (*param)->clone();
+            (*param)->set_name( namer.newName() );
+            ApplicationExpr *assign = new ApplicationExpr( new VariableExpr( assignOp->second ) );
+            assign->get_args().push_back( new VariableExpr( oldParam ) );
+            assign->get_args().push_back( new VariableExpr( *param ) );
+            funcDecl->get_statements()->get_kids().push_front( new ExprStmt( noLabels, assign ) );
+            funcDecl->get_statements()->get_kids().push_front( new DeclStmt( noLabels, oldParam ) );
+          }
+          modVars.erase( var );
+        }
+      }
+    }
+  }
+}
+
+void 
+CopyParams::visit( AddressExpr *addrExpr )
+{
+  if( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( addrExpr->get_arg() ) ) {
+    if( dynamic_cast< TypeInstType* >( varExpr->get_var()->get_type() ) ) {
+      modVars.insert( varExpr->get_var()->get_uniqueId() );
+    }
+  }
+}
+
+} // namespace GenPoly
Index: translator/GenPoly/CopyParams.h
===================================================================
--- translator/GenPoly/CopyParams.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/GenPoly/CopyParams.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,19 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: CopyParams.h,v 1.2 2005/08/29 20:14:13 rcbilson Exp $
+ *
+ */
+
+#ifndef GENPOLY_COPYPARAMS_H
+#define GENPOLY_COPYPARAMS_H
+
+#include "SynTree/SynTree.h"
+
+namespace GenPoly {
+
+void copyParams( std::list< Declaration* > &translationUnit );
+
+} // namespace GenPoly
+
+#endif /* #ifndef GENPOLY_COPYPARAMS_H */
Index: translator/GenPoly/FindFunction.cc
===================================================================
--- translator/GenPoly/FindFunction.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/GenPoly/FindFunction.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,89 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: FindFunction.cc,v 1.5 2005/08/29 20:14:13 rcbilson Exp $
+ *
+ */
+
+#include "FindFunction.h"
+#include "SynTree/Type.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Visitor.h"
+
+namespace GenPoly {
+
+class FindFunction : public Mutator
+{
+public:
+  FindFunction( std::list< FunctionType* > &functions, const TyVarMap &tyVars, bool replaceMode, FindFunctionPredicate predicate );
+  
+  virtual Type *mutate( FunctionType *functionType );
+  virtual Type *mutate( PointerType *pointerType );
+  
+private:
+  void handleForall( const std::list< TypeDecl* > &forall );
+
+  std::list< FunctionType* > &functions;
+  TyVarMap tyVars;
+  bool replaceMode;
+  FindFunctionPredicate predicate;
+};
+
+void
+findFunction( Type *type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate )
+{
+  FindFunction finder( functions, tyVars, false, predicate );
+  type->acceptMutator( finder );
+}
+
+void
+findAndReplaceFunction( Type *&type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate )
+{
+  FindFunction finder( functions, tyVars, true, predicate );
+  type = type->acceptMutator( finder );
+}
+
+FindFunction::FindFunction( std::list< FunctionType* > &functions, const TyVarMap &tyVars, bool replaceMode, FindFunctionPredicate predicate )
+  : functions( functions ), tyVars( tyVars ), replaceMode( replaceMode ), predicate( predicate )
+{
+}
+
+void
+FindFunction::handleForall( const std::list< TypeDecl* > &forall )
+{
+  for( std::list< TypeDecl* >::const_iterator i = forall.begin(); i != forall.end(); ++i ) {
+    TyVarMap::iterator var = tyVars.find( (*i)->get_name() );
+    if( var != tyVars.end() ) {
+      tyVars.erase( var );
+    }
+  }
+}
+
+Type* 
+FindFunction::mutate( FunctionType *functionType )
+{
+  TyVarMap oldTyVars = tyVars;
+  handleForall( functionType->get_forall() );
+  mutateAll( functionType->get_returnVals(), *this );
+  Type *ret = functionType;
+  if( predicate( functionType, tyVars ) ) {
+    functions.push_back( functionType );
+    if( replaceMode ) {
+      ret = new FunctionType( Type::Qualifiers(), true );
+    }
+  }
+  tyVars = oldTyVars;
+  return ret;
+}
+
+Type *
+FindFunction::mutate( PointerType *pointerType )
+{
+  TyVarMap oldTyVars = tyVars;
+  handleForall( pointerType->get_forall() );
+  Type *ret = Mutator::mutate( pointerType );
+  tyVars = oldTyVars;
+  return ret;
+}
+
+} // namespace GenPoly
Index: translator/GenPoly/FindFunction.h
===================================================================
--- translator/GenPoly/FindFunction.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/GenPoly/FindFunction.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,23 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: FindFunction.h,v 1.4 2005/08/29 20:14:13 rcbilson Exp $
+ *
+ */
+
+#ifndef FINDFUNCTION_H
+#define FINDFUNCTION_H
+
+#include "SynTree/SynTree.h"
+#include "GenPoly.h"
+
+namespace GenPoly {
+
+typedef bool (*FindFunctionPredicate)( FunctionType*, const TyVarMap& );
+
+void findFunction( Type *type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate );
+void findAndReplaceFunction( Type *&type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate );
+
+} // namespace GenPoly
+
+#endif /* #ifndef FINDFUNCTION_H */
Index: translator/GenPoly/GenPoly.cc
===================================================================
--- translator/GenPoly/GenPoly.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/GenPoly/GenPoly.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,52 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: GenPoly.cc,v 1.4 2005/08/29 20:14:13 rcbilson Exp $
+ *
+ */
+
+#include "GenPoly.h"
+#include "SynTree/Type.h"
+
+
+namespace GenPoly {
+
+bool
+isPolyVal( Type *type, const TyVarMap &tyVars )
+{
+  if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
+    if( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// A function needs an adapter if it returns a polymorphic value or if any of its
+// parameters have polymorphic type
+bool
+needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars )
+{
+  bool needsAdapter = false;
+  if( !adaptee->get_returnVals().empty() && isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
+    needsAdapter = true;
+  }
+  for( std::list< DeclarationWithType* >::const_iterator innerArg = adaptee->get_parameters().begin(); !needsAdapter && innerArg != adaptee->get_parameters().end(); ++innerArg ) {
+    if( isPolyVal( (*innerArg)->get_type(), tyVars ) ) {
+      needsAdapter = true;
+    }
+  }
+  
+  return needsAdapter;
+}
+
+void 
+printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap )
+{
+  for( TyVarMap::const_iterator i = tyVarMap.begin(); i != tyVarMap.end(); ++i ) {
+    os << i->first << " (" << i->second << ") ";
+  }
+  os << std::endl;
+}
+
+} // namespace GenPoly
Index: translator/GenPoly/GenPoly.h
===================================================================
--- translator/GenPoly/GenPoly.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/GenPoly/GenPoly.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,22 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: GenPoly.h,v 1.4 2005/08/29 20:14:13 rcbilson Exp $
+ *
+ */
+
+#include <map>
+#include <string>
+#include <iostream>
+#include "SynTree/Declaration.h"
+
+namespace GenPoly {
+
+typedef std::map< std::string, TypeDecl::Kind > TyVarMap;
+
+bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars );
+bool isPolyFun( FunctionType *fun, const TyVarMap &tyVars );
+bool isPolyVal( Type *type, const TyVarMap &tyVars );
+void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap );
+
+} // namespace GenPoly
Index: translator/GenPoly/Lvalue.cc
===================================================================
--- translator/GenPoly/Lvalue.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/GenPoly/Lvalue.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,168 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Lvalue.cc,v 1.5 2005/08/29 20:14:13 rcbilson Exp $
+ *
+ */
+
+#include <cassert>
+
+#include "Lvalue.h"
+
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Visitor.h"
+#include "SynTree/Mutator.h"
+#include "SymTab/Indexer.h"
+#include "ResolvExpr/Resolver.h"
+#include "ResolvExpr/typeops.h"
+
+#include "UniqueName.h"
+#include "utility.h"
+
+
+namespace GenPoly {
+
+namespace {
+
+const std::list<Label> noLabels;
+
+class Pass1 : public Mutator
+{
+public:
+  Pass1();
+  
+  virtual Expression *mutate( ApplicationExpr *appExpr );
+  virtual Statement *mutate( ReturnStmt *appExpr );
+  virtual DeclarationWithType *mutate( FunctionDecl *funDecl );
+
+private:
+  DeclarationWithType* retval;
+};
+
+class Pass2 : public Visitor
+{
+public:
+  virtual void visit( FunctionType *funType );
+
+private:
+};
+
+} // namespace
+
+void
+convertLvalue( std::list< Declaration* >& translationUnit )
+{
+  Pass1 p1;
+  Pass2 p2;
+  mutateAll( translationUnit, p1 );
+  acceptAll( translationUnit, p2 );
+}
+
+namespace {
+
+bool
+isLvalueRet( FunctionType *function )
+{
+  if( !function->get_returnVals().empty() ) {
+    return function->get_returnVals().front()->get_type()->get_isLvalue();
+  } else {
+    return false;
+  }
+}
+
+bool
+isIntrinsicApp( ApplicationExpr *appExpr )
+{
+  if( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( appExpr->get_function() ) ) {
+    return varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic;
+  } else {
+    return false;
+  }
+}
+
+Pass1::Pass1()
+{
+}
+
+DeclarationWithType* 
+Pass1::mutate( FunctionDecl *funcDecl )
+{
+  if( funcDecl->get_statements() ) {
+    DeclarationWithType* oldRetval = retval;
+    retval = 0;
+    if( !LinkageSpec::isBuiltin( funcDecl->get_linkage() ) && isLvalueRet( funcDecl->get_functionType() ) ) {
+      retval = funcDecl->get_functionType()->get_returnVals().front();
+    }
+    // fix expressions and return statements in this function
+    funcDecl->set_statements( funcDecl->get_statements()->acceptMutator( *this ) );
+    retval = oldRetval;
+  }
+  return funcDecl;
+}
+
+Expression* 
+Pass1::mutate( ApplicationExpr *appExpr )
+{
+  appExpr->get_function()->acceptMutator( *this );
+  mutateAll( appExpr->get_args(), *this );
+  
+  assert( !appExpr->get_function()->get_results().empty() );
+
+  PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
+  assert( pointer );
+  FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
+  assert( function );
+
+  std::string typeName;
+  if( isLvalueRet( function ) && !isIntrinsicApp( appExpr ) ) {
+    UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
+    deref->get_results().push_back( appExpr->get_results().front() );
+    appExpr->get_results().front() = new PointerType( Type::Qualifiers(), deref->get_results().front()->clone() );
+    deref->get_args().push_back( appExpr );
+    return deref;
+  } else {
+    return appExpr;
+  }
+}
+
+Statement* 
+Pass1::mutate(ReturnStmt *retStmt)
+{
+  if( retval && retStmt->get_expr() ) {
+    assert( !retStmt->get_expr()->get_results().empty() );
+    while( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) {
+      retStmt->set_expr( castExpr->get_arg() );
+      retStmt->get_expr()->set_env( castExpr->get_env() );
+      castExpr->set_env( 0 );
+      castExpr->set_arg( 0 );
+      delete castExpr;
+    }
+    if( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
+      retStmt->set_expr( new AddressExpr( retStmt->get_expr()->acceptMutator( *this ) ) );
+    } else {
+      throw SemanticError( "Attempt to return non-lvalue from an lvalue-qualified function" );
+    }
+  }
+  return retStmt;
+}
+
+void 
+Pass2::visit( FunctionType *funType )
+{
+  std::string typeName;
+  if( isLvalueRet( funType ) ) {
+    DeclarationWithType *retParm = funType->get_returnVals().front();
+    
+    // make a new parameter that is a pointer to the type of the old return value
+    retParm->set_type( new PointerType( Type::Qualifiers(), retParm->get_type() ) );
+  }
+  
+  Visitor::visit( funType );
+}
+
+} // namespace
+
+} // namespace GenPoly
Index: translator/GenPoly/Lvalue.h
===================================================================
--- translator/GenPoly/Lvalue.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/GenPoly/Lvalue.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,21 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Lvalue.h,v 1.2 2005/08/29 20:14:13 rcbilson Exp $
+ *
+ */
+
+#ifndef GENPOLY_LVALUE_H
+#define GENPOLY_LVALUE_H
+
+#include <list>
+
+#include "SynTree/SynTree.h"
+
+namespace GenPoly {
+
+void convertLvalue( std::list< Declaration* >& translationUnit );
+
+} // namespace GenPoly
+
+#endif /* #ifndef GENPOLY_LVALUE_H */
Index: translator/GenPoly/PolyMutator.cc
===================================================================
--- translator/GenPoly/PolyMutator.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/GenPoly/PolyMutator.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,188 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: PolyMutator.cc,v 1.7 2005/08/29 20:14:13 rcbilson Exp $
+ *
+ */
+
+#include "PolyMutator.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Mutator.h"
+
+
+namespace GenPoly {
+
+namespace {
+const std::list<Label> noLabels;
+}
+
+PolyMutator::PolyMutator()
+  : env( 0 )
+{
+}
+
+void
+PolyMutator::mutateStatementList( std::list< Statement* > &statements )
+{
+  for( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
+    if( !stmtsToAddAfter.empty() ) {
+      statements.splice( i, stmtsToAddAfter );
+    }
+    *i = (*i)->acceptMutator( *this );
+    if( !stmtsToAdd.empty() ) {
+      statements.splice( i, stmtsToAdd );
+    }
+  }
+  if( !stmtsToAddAfter.empty() ) {
+    statements.splice( statements.end(), stmtsToAddAfter );
+  }
+}
+
+Statement*
+PolyMutator::mutateStatement( Statement *stmt )
+{
+  Statement *newStmt = maybeMutate( stmt, *this );
+  if( !stmtsToAdd.empty() || !stmtsToAddAfter.empty() ) {
+    CompoundStmt *compound = new CompoundStmt( noLabels );
+    compound->get_kids().splice( compound->get_kids().end(), stmtsToAdd );
+    compound->get_kids().push_back( newStmt );
+    compound->get_kids().splice( compound->get_kids().end(), stmtsToAddAfter );
+    doEndScope();
+    return compound;
+  } else {
+    return newStmt;
+  }
+}
+
+Expression*
+PolyMutator::mutateExpression( Expression *expr )
+{
+  if( expr ) {
+    if( expr->get_env() ) {
+      env = expr->get_env();
+    }
+    return expr->acceptMutator( *this );
+  } else {
+    return expr;
+  }
+}
+
+CompoundStmt*
+PolyMutator::mutate(CompoundStmt *compoundStmt)
+{
+  mutateStatementList( compoundStmt->get_kids() );
+  doEndScope();
+  return compoundStmt;
+}
+
+Statement*
+PolyMutator::mutate(IfStmt *ifStmt)
+{
+  ifStmt->set_thenPart(  mutateStatement( ifStmt->get_thenPart() ) );
+  ifStmt->set_elsePart(  mutateStatement( ifStmt->get_elsePart() ) );
+  ifStmt->set_condition(  mutateExpression( ifStmt->get_condition() ) );
+  return ifStmt;
+}
+
+Statement*
+PolyMutator::mutate(WhileStmt *whileStmt)
+{
+  whileStmt->set_body(  mutateStatement( whileStmt->get_body() ) );
+  whileStmt->set_condition(  mutateExpression( whileStmt->get_condition() ) );
+  return whileStmt;
+}
+
+Statement*
+PolyMutator::mutate(ForStmt *forStmt)
+{
+  forStmt->set_body(  mutateStatement( forStmt->get_body() ) );
+  forStmt->set_initialization(  maybeMutate( forStmt->get_initialization(), *this ) );
+  forStmt->set_condition(  mutateExpression( forStmt->get_condition() ) );
+  forStmt->set_increment(  mutateExpression( forStmt->get_increment() ) );
+  return forStmt;
+}
+
+Statement*
+PolyMutator::mutate(SwitchStmt *switchStmt)
+{
+  mutateStatementList( switchStmt->get_branches() );
+  switchStmt->set_condition( mutateExpression( switchStmt->get_condition() ) );
+  return switchStmt;
+}
+
+Statement*
+PolyMutator::mutate(ChooseStmt *switchStmt)
+{
+  mutateStatementList( switchStmt->get_branches() );
+  switchStmt->set_condition( mutateExpression( switchStmt->get_condition() ) );
+  return switchStmt;
+}
+
+Statement*
+PolyMutator::mutate(CaseStmt *caseStmt)
+{
+  mutateStatementList( caseStmt->get_statements() );
+  caseStmt->set_condition(  mutateExpression( caseStmt->get_condition() ) );
+
+  return caseStmt;
+}
+
+Statement*
+PolyMutator::mutate(TryStmt *tryStmt)
+{
+  tryStmt->set_block(  maybeMutate( tryStmt->get_block(), *this ) );
+  mutateAll( tryStmt->get_catchers(), *this );
+  
+  return tryStmt;
+}
+
+Statement*
+PolyMutator::mutate(CatchStmt *cathStmt)
+{
+  cathStmt->set_body(  mutateStatement( cathStmt->get_body() ) );
+  cathStmt->set_decl(  maybeMutate( cathStmt->get_decl(), *this ) );
+  return cathStmt;
+}
+
+Statement* 
+PolyMutator::mutate(ReturnStmt *retStmt)
+{
+  retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
+  return retStmt;
+}
+
+Statement* 
+PolyMutator::mutate(ExprStmt *exprStmt)
+{
+  exprStmt->set_expr( mutateExpression( exprStmt->get_expr() ) );
+  return exprStmt;
+}
+
+
+Expression* 
+PolyMutator::mutate(UntypedExpr *untypedExpr)
+{
+  for( std::list< Expression* >::iterator i = untypedExpr->get_args().begin(); i != untypedExpr->get_args().end(); ++i ) {
+    *i = mutateExpression( *i );
+  }
+  return untypedExpr;
+}
+ 
+/* static class method */
+void 
+PolyMutator::makeTyVarMap( Type *type, TyVarMap &tyVarMap )
+{
+  for( std::list< TypeDecl* >::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) {
+    assert( *tyVar );
+    tyVarMap[ (*tyVar)->get_name() ] = (*tyVar)->get_kind();
+  }
+  if( PointerType *pointer = dynamic_cast< PointerType* >( type ) ) {
+    makeTyVarMap( pointer->get_base(), tyVarMap );
+  }
+}
+
+/* static class method */
+} // namespace GenPoly
Index: translator/GenPoly/PolyMutator.h
===================================================================
--- translator/GenPoly/PolyMutator.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/GenPoly/PolyMutator.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: PolyMutator.h,v 1.8 2005/08/29 20:14:13 rcbilson Exp $
+ *
+ */
+
+#ifndef GENPOLY_POLYMUTATOR_H
+#define GENPOLY_POLYMUTATOR_H
+
+#include <map>
+#include <string>
+#include <list>
+
+#include "GenPoly.h"
+
+#include "SynTree/SynTree.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Mutator.h"
+
+namespace GenPoly {
+
+class PolyMutator : public Mutator
+{
+public:
+  PolyMutator();
+
+  virtual CompoundStmt* mutate(CompoundStmt *compoundStmt);
+  virtual Statement* mutate(IfStmt *ifStmt);
+  virtual Statement* mutate(WhileStmt *whileStmt);
+  virtual Statement* mutate(ForStmt *forStmt);
+  virtual Statement* mutate(SwitchStmt *switchStmt);
+  virtual Statement* mutate(ChooseStmt *chooseStmt);
+  virtual Statement* mutate(CaseStmt *caseStmt);
+  virtual Statement* mutate(TryStmt *returnStmt);
+  virtual Statement* mutate(CatchStmt *catchStmt);
+  virtual Statement* mutate(ExprStmt *catchStmt);
+  virtual Statement* mutate(ReturnStmt *catchStmt);
+  
+  virtual Expression* mutate(UntypedExpr *untypedExpr);
+  
+  // template method
+  virtual void doEndScope() {}
+
+protected:
+  void mutateStatementList( std::list< Statement* > &statements );
+  Statement* mutateStatement( Statement *stmt );
+  Expression* mutateExpression( Expression *expr );
+  static void makeTyVarMap( Type *type, TyVarMap &tyVarMap );
+  
+  TyVarMap scopeTyVars;
+  TypeSubstitution *env;
+  std::list< Statement* > stmtsToAdd;
+  std::list< Statement* > stmtsToAddAfter;
+};
+
+} // namespace 
+
+#endif /* #ifndef GENPOLY_POLYMUTATOR_H */
Index: translator/GenPoly/ScrubTyVars.cc
===================================================================
--- translator/GenPoly/ScrubTyVars.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/GenPoly/ScrubTyVars.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,52 @@
+#include "GenPoly.h"
+#include "ScrubTyVars.h"
+
+#include "SynTree/Mutator.h"
+#include "SynTree/Type.h"
+
+
+namespace GenPoly {
+
+Type* 
+ScrubTyVars::mutate( TypeInstType *typeInst )
+{
+  TyVarMap::const_iterator tyVar = tyVars.find( typeInst->get_name() );
+  if( doAll || tyVar != tyVars.end() ) {
+    switch( tyVar->second ) {
+    case TypeDecl::Any:
+    case TypeDecl::Dtype:
+    {
+      PointerType *ret = new PointerType( Type::Qualifiers(), new VoidType( typeInst->get_qualifiers() ) );
+      delete typeInst;
+      return ret;
+    }
+      
+    case TypeDecl::Ftype:
+      delete typeInst;
+      return new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) );
+    }
+  }
+  return typeInst;
+}
+
+Type* 
+ScrubTyVars::mutate( PointerType *pointer )
+{
+  if( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( pointer->get_base() ) ) {
+    if( doAll || tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
+      Type *ret = mutate( typeInst );
+///       std::cout << "pointer is ";
+///       pointer->print( std::cout );
+///       std::cout << std::endl << "ret is ";
+///       ret->print( std::cout );
+///       std::cout << std::endl;
+      ret->get_qualifiers() += pointer->get_qualifiers();
+      pointer->set_base( 0 );
+      delete pointer;
+      return ret;
+    }
+  }
+  return Mutator::mutate( pointer );
+}
+
+} // namespace GenPoly
Index: translator/GenPoly/ScrubTyVars.h
===================================================================
--- translator/GenPoly/ScrubTyVars.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/GenPoly/ScrubTyVars.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,57 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: ScrubTyVars.h,v 1.4 2005/08/29 20:14:13 rcbilson Exp $
+ *
+ */
+
+#ifndef GENPOLY_SCRUBTYVARS_H
+#define GENPOLY_SCRUBTYVARS_H
+
+#include "GenPoly.h"
+
+#include "SynTree/SynTree.h"
+#include "SynTree/Mutator.h"
+
+namespace GenPoly {
+
+class ScrubTyVars : public Mutator
+{
+public:
+  ScrubTyVars( bool doAll, const TyVarMap &tyVars ): doAll( doAll ), tyVars( tyVars ) {}
+  
+  template< typename SynTreeClass >
+  static SynTreeClass *scrub( SynTreeClass *target, const TyVarMap &tyVars );
+  template< typename SynTreeClass >
+  static SynTreeClass *scrub( SynTreeClass *target );
+  
+  virtual Type* mutate( TypeInstType *typeInst );
+  virtual Type* mutate( PointerType *pointer );
+
+private:
+  bool doAll;
+  const TyVarMap &tyVars;
+};
+
+/* static class method */
+template< typename SynTreeClass >
+SynTreeClass *
+ScrubTyVars::scrub( SynTreeClass *target, const TyVarMap &tyVars )
+{
+  ScrubTyVars scrubber( false, tyVars );
+  return static_cast< SynTreeClass* >( target->acceptMutator( scrubber ) );
+}
+
+/* static class method */
+template< typename SynTreeClass >
+SynTreeClass *
+ScrubTyVars::scrub( SynTreeClass *target )
+{
+  TyVarMap tyVars;
+  ScrubTyVars scrubber( true, tyVars );
+  return static_cast< SynTreeClass* >( target->acceptMutator( scrubber ) );
+}
+
+} // namespace GenPoly
+
+#endif /* #ifndef GENPOLY_SCRUBTYVARS_H */
Index: translator/GenPoly/Specialize.cc
===================================================================
--- translator/GenPoly/Specialize.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/GenPoly/Specialize.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,206 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Specialize.cc,v 1.4 2005/08/29 20:14:13 rcbilson Exp $
+ *
+ */
+
+#include <cassert>
+
+#include "Specialize.h"
+#include "PolyMutator.h"
+
+#include "SynTree/Declaration.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Type.h"
+#include "SynTree/TypeSubstitution.h"
+#include "SynTree/Mutator.h"
+#include "ResolvExpr/FindOpenVars.h"
+#include "UniqueName.h"
+#include "utility.h"
+
+
+namespace GenPoly {
+
+const std::list<Label> noLabels;
+
+class Specialize : public PolyMutator
+{
+public:
+  Specialize( std::string paramPrefix = "_p" );
+  
+  virtual Expression* mutate(ApplicationExpr *applicationExpr);
+  virtual Expression* mutate(AddressExpr *castExpr);
+  virtual Expression* mutate(CastExpr *castExpr);
+  virtual Expression* mutate(LogicalExpr *logicalExpr);
+  virtual Expression* mutate(ConditionalExpr *conditionalExpr);
+  virtual Expression* mutate(CommaExpr *commaExpr);
+
+private:
+  Expression *doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams = 0 );
+  void handleExplicitParams( ApplicationExpr *appExpr );
+  
+  UniqueName thunkNamer;
+  std::string paramPrefix;
+};
+
+void
+convertSpecializations( std::list< Declaration* >& translationUnit )
+{
+  Specialize specializer;
+  mutateAll( translationUnit, specializer );
+}
+
+Specialize::Specialize( std::string paramPrefix )
+  : thunkNamer( "_thunk" ), paramPrefix( paramPrefix )
+{
+}
+
+bool
+needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env )
+{
+  if( env ) {
+    using namespace ResolvExpr;
+    OpenVarSet openVars, closedVars;
+    AssertionSet need, have;
+    findOpenVars( formalType, openVars, closedVars, need, have, false );
+    findOpenVars( actualType, openVars, closedVars, need, have, true );
+    for( OpenVarSet::const_iterator openVar = openVars.begin(); openVar != openVars.end(); ++openVar ) {
+      Type *boundType = env->lookup( openVar->first );
+      if( !boundType ) continue;
+      if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( boundType ) ) {
+        if( closedVars.find( typeInst->get_name() ) == closedVars.end() ) {
+          return true;
+        }
+      } else {
+        return true;
+      }
+    }
+    return false;
+  } else {
+    return false;
+  }
+}
+
+Expression*
+Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams )
+{
+  if( needsSpecialization( formalType, actual->get_results().front(), env ) ) {
+    PointerType *ptrType;
+    FunctionType *funType;
+    if( ( ptrType = dynamic_cast< PointerType* >( formalType ) ) && ( funType = dynamic_cast< FunctionType* >( ptrType->get_base() ) ) ) {
+      FunctionType *newType = funType->clone();
+      if( env ) {
+        TypeSubstitution newEnv( *env );
+        // it is important to replace only occurrences of type variables that occur free in the
+        // thunk's type
+        newEnv.applyFree( newType );
+      }
+      FunctionDecl *thunkFunc = new FunctionDecl( thunkNamer.newName(), Declaration::NoStorageClass, LinkageSpec::C, newType, new CompoundStmt( std::list< std::string >() ), false );
+      thunkFunc->fixUniqueId();
+      
+      UniqueName paramNamer( paramPrefix );
+      ApplicationExpr *appExpr = new ApplicationExpr( actual );
+      for( std::list< DeclarationWithType* >::iterator param = thunkFunc->get_functionType()->get_parameters().begin(); param != thunkFunc->get_functionType()->get_parameters().end(); ++param ) {
+        (*param)->set_name( paramNamer.newName() );
+        appExpr->get_args().push_back( new VariableExpr( *param ) );
+      }
+      appExpr->set_env( maybeClone( env ) );
+      if( inferParams ) {
+        appExpr->get_inferParams() = *inferParams;
+      }
+      
+      // handle any specializations that may still be present
+      std::string oldParamPrefix = paramPrefix;
+      paramPrefix += "p";
+      std::list< Statement* > oldStmts;
+      oldStmts.splice( oldStmts.end(), stmtsToAdd );
+      handleExplicitParams( appExpr );
+      paramPrefix = oldParamPrefix;
+      thunkFunc->get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd );
+      stmtsToAdd.splice( stmtsToAdd.end(), oldStmts );
+      
+      Statement *appStmt;
+      if( funType->get_returnVals().empty() ) {
+        appStmt = new ExprStmt( noLabels, appExpr );
+      } else {
+        appStmt = new ReturnStmt( noLabels, appExpr );
+      }
+      thunkFunc->get_statements()->get_kids().push_back( appStmt );
+      stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) );
+      return new AddressExpr( new VariableExpr( thunkFunc ) );
+    } else {
+      return actual;
+    }
+  } else {
+    return actual;
+  }
+}
+
+void
+Specialize::handleExplicitParams( ApplicationExpr *appExpr )
+{
+  // create thunks for the explicit parameters
+  assert( !appExpr->get_function()->get_results().empty() );
+  PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
+  assert( pointer );
+  FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
+  std::list< DeclarationWithType* >::iterator formal;
+  std::list< Expression* >::iterator actual;
+  for( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) {
+    *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr->get_inferParams() );
+  }
+}
+
+Expression* 
+Specialize::mutate(ApplicationExpr *appExpr)
+{
+  appExpr->get_function()->acceptMutator( *this );
+  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);
+  
+  return appExpr;
+}
+
+Expression* 
+Specialize::mutate(AddressExpr *addrExpr)
+{
+  addrExpr->get_arg()->acceptMutator( *this );
+  addrExpr->set_arg( doSpecialization( addrExpr->get_results().front(), addrExpr->get_arg() ) );
+  return addrExpr;
+}
+
+Expression* 
+Specialize::mutate(CastExpr *castExpr)
+{
+  castExpr->get_arg()->acceptMutator( *this );
+  castExpr->set_arg( doSpecialization( castExpr->get_results().front(), castExpr->get_arg() ) );
+  return castExpr;
+}
+
+Expression* 
+Specialize::mutate(LogicalExpr *logicalExpr)
+{
+  return logicalExpr;
+}
+
+Expression* 
+Specialize::mutate(ConditionalExpr *condExpr)
+{
+  return condExpr;
+}
+
+Expression* 
+Specialize::mutate(CommaExpr *commaExpr)
+{
+  return commaExpr;
+}
+
+} // namespace GenPoly
Index: translator/GenPoly/Specialize.h
===================================================================
--- translator/GenPoly/Specialize.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/GenPoly/Specialize.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,21 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Specialize.h,v 1.2 2005/08/29 20:14:13 rcbilson Exp $
+ *
+ */
+
+#ifndef GENPOLY_SPECIALIZE_H
+#define GENPOLY_SPECIALIZE_H
+
+#include <list>
+
+#include "SynTree/SynTree.h"
+
+namespace GenPoly {
+
+void convertSpecializations( std::list< Declaration* >& translationUnit );
+
+} // namespace GenPoly
+
+#endif /* #ifndef GENPOLY_SPECIALIZE_H */
Index: translator/GenPoly/module.mk
===================================================================
--- translator/GenPoly/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/GenPoly/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,9 @@
+SRC += GenPoly/Box.cc \
+       GenPoly/GenPoly.cc \
+       GenPoly/PolyMutator.cc \
+       GenPoly/ScrubTyVars.cc \
+       GenPoly/Lvalue.cc \
+       GenPoly/Specialize.cc \
+       GenPoly/CopyParams.cc \
+       GenPoly/FindFunction.cc
+       
Index: translator/InitTweak/Association.cc
===================================================================
--- translator/InitTweak/Association.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/InitTweak/Association.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,9 @@
+#include "Association.h"
+
+Association::~Association() {}
+
+SingleName::~SingleName() {}
+PointAssociation::~PointAssociation() {}
+
+const int RangeAssociation::RangeAssociation::UNDEF = -1;
+RangeAssociation::~RangeAssociation() {}
Index: translator/InitTweak/Association.h
===================================================================
--- translator/InitTweak/Association.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/InitTweak/Association.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,277 @@
+#ifndef _ASSOCIATE_H_
+#define _ASSOCIATE_H_
+
+#include <map>
+#include <list>
+#include <string>
+#include <vector>
+#include <iostream>
+#include <stdexcept>
+#include <algorithm>
+
+#include "SynTree/Expression.h"
+#include "diet_map.h"
+
+class Association;
+class SingleName;
+class PointAssociation;
+class RangeAssociation;
+
+// ** exceptions
+class AssocException : public std::exception {
+public:
+  AssocException() {}
+  AssocException( std::string _what ) : what( _what ) {}
+  ~AssocException() throw () {}
+
+  std::string get_what() const { return what; }
+  void set_what( std::string newValue ) { what = newValue; }
+private:
+  std::string what;
+};
+
+// ** visitors
+class AssociationVisitor {
+public:
+  AssociationVisitor() {}
+  virtual ~AssociationVisitor() {}
+
+  virtual void visit( SingleName * ) = 0;
+  virtual void visit( PointAssociation * ) = 0;
+  virtual void visit( RangeAssociation * ) = 0;
+};
+
+// ** containers
+class Association {
+ public:
+  virtual ~Association();
+
+  virtual Association *clone() = 0;
+  virtual long int add_single( std::string, Expression *) = 0;
+  virtual long int add_single( long int, Expression *expr) = 0;
+
+  virtual Association *operator[]( int idx ) = 0;
+  virtual Association *operator[]( std::string ) = 0;
+
+  //  virtual AssociationIterator *get_iterator() = 0;
+
+  virtual void accept( AssociationVisitor & ) = 0;
+  virtual void display( std::ostream & ) = 0;
+};
+
+class SingleName : public Association {
+public:
+  SingleName( Expression *initExpr = 0 ) : expr( initExpr ) {}
+  virtual ~SingleName();
+
+  virtual SingleName *clone() {
+    return 0; // XXX!
+  }
+
+  virtual long int add_single( long int idx, Expression *newExpr) {
+    if( expr == 0 ) //|| *expr == *newExpr )
+      expr = newExpr;
+    return 0;
+  }
+
+  virtual long int add_single( std::string str, Expression *newExpr) {
+    if( expr == 0 ) //|| *expr == *newExpr )
+      expr = newExpr;
+    return 0;
+  }
+
+  virtual Association *operator[]( int idx ) { assert(false); }
+  virtual Association *operator[]( std::string idx ) { assert(false); }
+
+  virtual void accept( AssociationVisitor &v ) { v.visit( this ); }
+  virtual void display( std::ostream &os ) {
+    os << "Single association" << std::endl;
+  }
+
+  Expression *get_expr() const { return expr; }
+
+private:
+  Expression *expr;
+  Expression *deflt;
+};
+
+class PointAssociation : public Association {
+public:
+  typedef std::map< std::string, std::pair< long int, Association *> > map_type;
+
+  PointAssociation() {}
+  PointAssociation( const PointAssociation &other ) {
+    copy( other.anonym.begin(), other.anonym.end(), back_inserter( anonym ));
+  }
+
+  virtual ~PointAssociation();
+
+  virtual PointAssociation *clone() {
+    return ( new PointAssociation( *this ) );
+  }
+
+  virtual long int add_single( long int idx, Expression *expr) {
+    long int ret;
+
+    if( idx >= (long int)ordering.size() ) throw AssocException("extra (spurious) members");
+
+    if ( ordering[ idx ] == "")
+      std::cerr << "Checkpoint 2" << std::endl;
+    else {
+      assert( table[ordering[idx]].second != 0 );
+      ret = idx;
+      table[ ordering[idx] ].second->add_single("", expr );
+    }
+    return ret;
+  }
+
+  virtual long int add_single( std::string idx, Expression *expr) {
+    if( idx == "" )
+      std::cerr << "Checkpoint 1" << std::endl;
+    else {
+      map_type::iterator j;
+      if (  (j = table.find( idx )) == table.end() )  // this doesn't amount for reachable members deeper down the structure, fix
+	throw AssocException("No such member");
+      else
+	return add_single( j->second.first, expr );
+    }
+
+    return -1;
+  }
+
+  void add_member( std::string str ) {
+    if ( table.find( str ) != table.end() ) return;
+    ordering.push_back( str );
+    if( str != "" ) {
+      std::pair<long int, Association *> p( ordering.size() - 1, 0 );
+      table.insert( std::pair< std::string, std::pair<long int, Association *> >(str, p) );
+    }
+    return;
+  }
+
+  virtual void set_member( std::string str, Association *assoc ) {
+    if( str == "" )
+      anonym.push_back( assoc );
+    else  if ( table.find( str ) == table.end() )
+      throw AssocException( "no such member" );
+    else
+      table[ str ] = std::pair<long int, Association *>(ordering.size() - 1, assoc);
+
+    return;
+  }
+
+  virtual Association *operator[]( int idx ) {
+    if( ordering[idx] == "" ) {
+      std::cerr << "Error, anonymous members not implemented yet" << std::endl;
+      throw 0;
+    } else
+      return table[ ordering[idx] ].second;
+  }
+
+  virtual Association *operator[]( std::string idx ) {
+    if ( table.find( idx ) == table.end() )
+      throw AssocException("Member not found");
+    else
+      return table[ idx ].second;
+  }
+
+  /*
+  virtual AssociationIterator *get_iterator() {
+    PointAssocIterator *it;
+    return it;
+  }
+  */
+
+  void accept( AssociationVisitor &v ) { v.visit( this ); }
+
+  virtual void display( std::ostream &os ) {
+    os << "Point association: " << std::endl;
+    for( map_type::iterator i = table.begin(); i != table.end(); i++ ) {
+      os << "Member [" << i->first << ", index = " << i->second.first << "]";
+      if ( i->second.second != 0 )
+	i->second.second->display( os );
+      else
+	std::cerr << "No recursive association" << std::endl;
+
+      os << std::endl;
+    }
+  }
+
+  const int size() const { return ordering.size(); }
+
+private:
+  PointAssociation &operator=(const PointAssociation &);
+  std::vector<std::string> ordering;
+  std::list< Association * > anonym;
+  std::map< std::string, std::pair<long int, Association *> > table;
+};
+
+class RangeAssociation : public Association {
+public:
+  static const int UNDEF;
+  RangeAssociation( int _hi= UNDEF ) : hi( _hi ) {
+    std::cerr << "Constructed RangeAssociation with: [" << hi << "]" << std::endl;
+  }
+
+  virtual ~RangeAssociation();
+
+  virtual RangeAssociation *clone() {
+    return 0; // XXX !!!!
+  }
+
+  virtual Association *operator[]( int idx ) {
+    return 0; // XXX !!!
+  }
+
+  virtual Association *operator[]( std::string idx ) { assert(false); return 0; }
+
+  /*
+  virtual AssociationIterator *get_iterator() {
+    RangeAssocIterator *it;
+    return it;
+  }
+  */
+
+  virtual long int add_single( long int idx, Expression *newExpr) { return 0; }
+  virtual long int add_single( std::string, Expression *) { return 0; }
+  void accept( AssociationVisitor &v ) { v.visit( this ); }
+  virtual void display( std::ostream &os ) {
+    os << "Range association, with limit: " << std::endl;
+  }
+
+private:
+  int hi;
+  diet::diet_tree<int> tree;
+  /*
+  for( diet_tree<int>::iterator i = tree.begin(); i != tree.end(); i++ )
+    std::cout << "--(" << (*i).first << ", " << (*i).second << ")--" << std::endl;
+  diet_tree<int> tree;
+  tree.insert(100,200);
+  */
+};
+
+// ** builders
+class AssociationBuilder {
+public:
+  /* AssociationBuilder( Declaration * ) */
+  virtual ~AssociationBuilder() {}
+  virtual Association *get_assoc() = 0;
+  virtual Association *grab_assoc() = 0;
+  virtual void set_assoc(   Association * ) = 0;
+};
+
+class AssociationFiller {
+public:
+  // AssociationFiller( Declaration * ) {}
+  virtual ~AssociationFiller() {}
+  virtual Association *get_assoc() = 0;
+  virtual void set_assoc( Association * ) = 0;
+};
+
+#endif //#define _ASSOCIATE_H_
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/InitTweak/BasicInit.cc
===================================================================
--- translator/InitTweak/BasicInit.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/InitTweak/BasicInit.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,265 @@
+#include <list>
+#include <cassert>
+#include <iostream>
+#include <iterator>
+#include <algorithm>
+
+#include "utility.h"
+
+#include "SynTree/Type.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Initializer.h"
+
+#include "BasicInit.h"
+#include "NameCollector.h"
+#include "NameAssociation.h"
+
+namespace InitTweak {
+
+  CompoundStmt* BasicInit::mutate(CompoundStmt *compoundStmt)
+  {
+    index.visit( compoundStmt );
+
+    std::list< Statement * > &kids = compoundStmt->get_kids();
+    std::list< Statement * > newKids;
+
+    for ( std::list< Statement * >::iterator i = kids.begin(); i!= kids.end(); i++ ) {
+      //BasicInit newMut(  );
+      (*i)->acceptMutator( *this );
+      newKids.push_back( *i );
+
+      if ( has_bindings() ) { //       if ( get_bindings() != 0  ) {
+	std::list< Statement *> newSt = get_statements();
+	//newSt.push_back( *i );
+	newKids.splice( newKids.end(), newSt );
+	bindings = 0;
+	stmts.clear();
+      }
+    }
+
+    compoundStmt->get_kids() = newKids;
+    return compoundStmt;
+  }
+
+  Statement * BasicInit::mutate(DeclStmt *declStmt) {
+
+    declStmt->accept( index );
+
+    ObjectDecl *odecl = 0;
+
+    if( ( odecl = dynamic_cast<ObjectDecl *>(declStmt->get_decl()) ) != 0 ){
+
+      Initializer *init = odecl->get_init();
+      if ( init == 0 ) return declStmt;
+
+      if ( Classify::type( odecl->get_type() ) == Classify::COMPOUND_T )
+	if ( Classify::initializer(init) == Classify::SINGLE_I )
+	  throw( 0 ); // mismatch of type and initializer
+	else {
+	  NameInCollection *col = Classify::declaration( odecl, &index );
+	  bindings = NameAssociation< Expression *, BreakInitializer >::createNameAssoc(col);
+	  bindings->add_value( std::string(""), BreakInitializer(init) );
+	  BasicInit::build_statements( bindings, odecl->get_name(), stmts );
+	}
+      else
+	if ( Classify::initializer(init) == Classify::COMPOUND_I )
+	  throw( 0 ); // mismatch of type and initializer
+	else {
+	  // Single inits
+	  SingleInit *sinit = dynamic_cast< SingleInit * > ( init );
+	  assert( sinit != 0);
+
+	  std::list<Expression *> args;
+	  args.push_back( new AddressExpr( new NameExpr( odecl->get_name() )) );    // have to get address of object
+	  args.push_back( sinit->get_value() );
+	  // replace declaration with initialization
+	  stmts.push_back(new ExprStmt(std::list<Label>(), new UntypedExpr(new NameExpr("?=?"), args)));
+	}
+
+      delete init;
+      odecl->set_init( 0 );
+    } else {
+      // no declaration statement
+    }
+
+    return declStmt;
+  }
+
+  ExprStmt *assignFromDecl( DeclStmt *declStmt )
+  {
+    ObjectDecl *decl;
+    if ( (decl = dynamic_cast<ObjectDecl *>( declStmt->get_decl() )) != 0 )
+      {
+	SingleInit *init;
+	if ( (init = dynamic_cast<SingleInit *>(decl->get_init())) != 0 )
+	  {
+	  }
+      }
+
+    return 0;
+  }
+
+  bool isDeclStmtP(Statement *stmt)
+  {
+    return ( dynamic_cast< DeclStmt *>(stmt) != 0 );
+  }
+
+  BasicInit::Classify::TypeKind BasicInit::Classify::type( Type *toClassify ) {
+    if ( toClassify == 0 ) return NULL_T;
+
+    if ( dynamic_cast< StructInstType * >(toClassify) ||
+	 dynamic_cast< UnionInstType * >(toClassify) ||
+	 dynamic_cast< ArrayType * >(toClassify)         )
+      return COMPOUND_T;
+    else
+      return SINGLE_T;
+  }
+
+  BasicInit::Classify::InitKind BasicInit::Classify::initializer( Initializer *init) {
+    if ( init == 0 ) return NULL_I;
+    if ( dynamic_cast< ListInit * >(init) )
+      return COMPOUND_I;
+    if ( dynamic_cast< SingleInit * >(init) )
+      return SINGLE_I;
+
+    return NULL_I; // shouldn't be here anyways
+  }
+
+  NameInCollection *
+  BasicInit::Classify::declaration( ObjectDecl *objdecl, SymTab::Indexer *index ) {
+    assert ( index != 0 );
+
+    ReferenceToType *reftype;
+    if( (reftype = dynamic_cast< StructInstType * >( objdecl->get_type() )) != 0 ){
+      StructDecl *strDecl = index->lookupStruct( reftype->get_name() );
+      if ( strDecl != 0 ) {
+	NameCollectionBuilder bld;
+	NameCollector nc( bld );
+	strDecl->accept( nc );
+	NameInCollection *col = nc.get_builder().get_collection();
+	nc.get_builder().set_collection( 0 );
+
+	return col;
+      } else
+	throw( SemanticError( std::string("No structure of name: ") + reftype->get_name() ) );
+    } else {
+      throw(SemanticError( reftype->get_name() + std::string("is not a reference to type") ));
+      return 0;
+    }
+  }
+
+  std::list< Statement * >
+  BasicInit::Classify::matchInit( NameInCollection *col,
+				  ObjectDecl *toInitialize,
+				  Initializer *init ) {
+    assert ( col != 0 );
+
+    std::list< Statement * > arranged(0); //( col->size() ); 
+    std::fill( arranged.begin(), arranged.end(), (Statement *)0 );
+    int current = 0;
+
+    if ( init == 0 )
+      // no initializer... shouldn't even bother... fix this. 
+      return arranged;
+
+    {
+      ListInit *li = dynamic_cast< ListInit * >( init );
+
+      if ( li != 0 ) {
+	for( std::list<Initializer *>::iterator i = li->begin_initializers();
+	                                                 i != li->end_initializers();
+	      i++) {
+	  std::list<Expression *> d_orig = (*i)->get_designators();
+
+	  NameInCollection *corrsp; // corresponding element to this initializer
+	  if ( ! d_orig.empty() ) {
+	    // 1) has designators
+	    std::list<NameExpr *> des;
+	    std::transform( d_orig.begin(), d_orig.end(),
+			    std::back_inserter( des ), cast_ptr<Expression, NameExpr > );
+
+	    for( std::list<NameExpr *>::iterator j = des.begin(); j != des.end(); j++ ) {
+	      // check for existence of the element
+
+	      if ( (corrsp = (*col)[ (*j)->get_name() ]) != 0 ) {
+		// current++;
+		SingleInit *sinit;
+		if ( (sinit = dynamic_cast< SingleInit * >( *i )) != 0 )
+		  arranged.push_back( constructAssgn( corrsp->get_name(), toInitialize, sinit ) );
+		else
+		  ; // recursive call to matchInit
+	      } else
+		// error, member doesn't exist
+		return arranged; // throw( 0 ); // XXX
+	    }
+	  } else {
+	    // 2) doesn't have designators
+	    if ( (corrsp = (*col)[ current++ ]) != 0 ) {
+	      SingleInit *sinit;
+	      if ( (sinit = dynamic_cast< SingleInit * >( *i )) != 0 )
+		arranged.push_back( constructAssgn( corrsp->get_name(), toInitialize, sinit ) );
+	      else
+		; // recursive call to matchInit
+	    } else {
+	      // Shouldn't be here... probably too many elements in initializer?
+	    }
+	  }
+	}
+      }
+    }
+
+    return arranged;
+  }
+
+  Statement *BasicInit::Classify::constructAssgn( std::string membName, ObjectDecl *toInit, SingleInit *sinit ) {
+    std::list< Expression * > args;
+    args.push_back(new AddressExpr( new UntypedMemberExpr( membName, new NameExpr(toInit->get_name()) )));
+    args.push_back( sinit->get_value() );
+    Statement *ret = new ExprStmt(std::list<Label>(),
+						    new UntypedExpr(new NameExpr("?=?"), args));
+    return ret;
+  }
+
+  void BasicInit::build_statements( NameAssociation< Expression *, BreakInitializer > *assoc,
+				    std::string aggName, std::list< Statement *> &stmts ) {
+    assert( assoc != 0 );
+    static std::list< std::string > prefix;
+
+    NameInCollection *col = assoc->get_collection();
+    if ( col->isComposite() ) {
+      VariousNames *vc = dynamic_cast< VariousNames * >( col ); 
+      for( VariousNames::key_iterator it = vc->keys_begin(); it != vc->keys_end(); it++ ) {
+	prefix.push_back( *it );
+	if ( (*assoc)[ *it ] != 0 )
+	  build_statements( (*assoc)[ *it ], aggName, stmts );
+
+	prefix.pop_back();
+      }
+    } else {
+      SingleNameAssoc< Expression *, BreakInitializer > *sa = \
+	dynamic_cast< SingleNameAssoc< Expression *, BreakInitializer > * >( assoc );
+      assert( sa != 0 );
+
+      Expression * rh = sa->get_data();
+
+      if (rh != 0) {
+	// construct assignment statement list
+	Expression *lh = new NameExpr ( aggName );
+	for ( std::list< std::string >::iterator i = prefix.begin(); i != prefix.end(); i++ )
+	  lh = new UntypedMemberExpr( *i, lh );
+
+	std::list< Expression * > args;
+	args.push_back( new AddressExpr(lh) ); 	args.push_back( rh );
+
+	stmts.push_back( new ExprStmt(std::list<Label>(), 
+					       new UntypedExpr(new NameExpr("?=?"), args)) );
+      }
+    }
+
+    return;
+  }
+
+} // namespace InitTweak
+
Index: translator/InitTweak/BasicInit.h
===================================================================
--- translator/InitTweak/BasicInit.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/InitTweak/BasicInit.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,216 @@
+#ifndef _BASINIT_H_
+#define _BASINIT_H_
+
+#include <list>
+
+#include "SynTree/Visitor.h"
+#include "SymTab/Indexer.h"
+
+#include "SynTree/Type.h"
+#include "SynTree/Initializer.h"
+#include "SynTree/Expression.h"
+#include "NameInCollection.h"
+#include "NameAssociation.h"
+
+namespace InitTweak {
+
+  bool isDeclStmtP(Statement *stmt);
+
+  class BreakInitializer;
+  class BreakDesignator;
+
+  class BasicInit: public Mutator
+    {
+    public:
+      BasicInit() : bindings( 0 ) {}
+      BasicInit( SymTab::Indexer &_index ) : bindings( 0 ), index( _index ) {}
+      BasicInit( const BasicInit &other ) {
+	bindings = other.get_bindings();
+	index = other.index;
+      }
+
+      ~BasicInit() { /* delete bindings; bindings = 0; */ }
+
+      NameAssociation< Expression *, BreakInitializer > *get_bindings() const { return bindings; }
+      void set_bindings( NameAssociation< Expression *, BreakInitializer > *newValue ) {
+	bindings = newValue;
+      }
+
+      bool has_bindings() {
+	return ( get_bindings() != 0 || ! stmts.empty() );
+      }
+
+      virtual ObjectDecl     *mutate( ObjectDecl *objectDecl )
+      { index.visit( objectDecl ); return objectDecl; }
+      virtual TypeDecl       *mutate( TypeDecl *typeDecl )
+      { index.visit( typeDecl ); return typeDecl; }
+      virtual TypedefDecl    *mutate( TypedefDecl *typeDecl )
+      { index.visit( typeDecl ); return typeDecl; }
+      virtual StructDecl     *mutate( StructDecl *aggregateDecl )
+      { index.visit( aggregateDecl ); return aggregateDecl; }
+      virtual UnionDecl      *mutate( UnionDecl *aggregateDecl )
+      { index.visit( aggregateDecl ); return aggregateDecl; }
+      virtual EnumDecl       *mutate( EnumDecl *aggregateDecl )
+      { index.visit( aggregateDecl ); return aggregateDecl; }
+
+      virtual Type           *mutate( StructInstType *aggrInst )
+      { index.visit( aggrInst ); return aggrInst; }
+      virtual Type           *mutate( UnionInstType *aggrInst )
+      { index.visit( aggrInst ); return aggrInst; }
+
+      virtual CompoundStmt   *mutate(CompoundStmt *compoundStmt);
+      virtual Statement *mutate(DeclStmt *declStmt);
+
+      std::list< Statement *> get_statements() const { return stmts;  }
+
+      static void build_statements( NameAssociation< Expression *, BreakInitializer > *assoc,
+				    std::string aggName, std::list< Statement *> &stmts );
+    private:
+      NameAssociation< Expression *, BreakInitializer > *bindings;
+      Statement *assignFromDecl( DeclStmt *declStmt );
+      SymTab::Indexer index;
+      std::list< Statement *> stmts;
+
+      class Classify {
+      public:
+	enum TypeKind { NULL_T, SINGLE_T, COMPOUND_T };
+	enum InitKind { NULL_I, SINGLE_I, COMPOUND_I };
+
+	static TypeKind type( Type * );
+	static InitKind initializer( Initializer *);
+
+	static NameInCollection *declaration( ObjectDecl *objdecl, SymTab::Indexer *index );
+	static std::list< Statement * >
+	   matchInit( NameInCollection *, ObjectDecl *, Initializer * );
+	static Statement *constructAssgn( std::string membname, ObjectDecl *toInit, SingleInit *sinit );
+
+	// static std::list< Statement * > constructListAssgn( NameAssociation<Expression *, BreakDesignator > assoc );
+      };
+  };
+
+  class BreakInitializer {
+    enum InitKind { EMPTY, SINGLE, COMPOUND };
+
+    class BreakDesignator;
+    typedef BreakDesignator NameSplitter;
+
+  public:
+    typedef std::list<Initializer *>::iterator element_iterator;
+    typedef std::list< NameSplitter >::iterator name_iterator;
+
+    BreakInitializer ( Initializer *_init ) : kind( EMPTY ), sinit(0), cinit(0) {
+      std::list<Expression *> temp;
+
+      if( ( sinit=dynamic_cast< SingleInit * >(_init) ) != 0 ) {
+	kind = SINGLE;
+	temp = sinit->get_designators();
+      } else if ( ( cinit=dynamic_cast< ListInit * >(_init) ) != 0 ) {
+	kind = COMPOUND;
+	temp = cinit->get_designators();
+      }
+
+      std::transform( temp.begin(), temp.end(), std::back_inserter( designators ),
+		      ctor_noptr<NameSplitter, Expression *> );
+
+    }
+
+    //BreakInitializer( const BreakInitializer &other ) { this.col = other.col; }
+    ~BreakInitializer () {}
+
+    BreakInitializer set_name( NameSplitter &name ) {
+      designators.clear();
+      designators.push_back( name );
+
+      return *this;
+    }
+
+    element_iterator element_begin() {
+      assert( cinit != 0 );
+      return cinit->begin_initializers();
+    }
+    element_iterator element_end() {
+      assert( cinit != 0 );
+      return cinit->end_initializers();
+    }
+
+    name_iterator names_begin() { return designators.begin(); }
+    name_iterator names_end() { return designators.end(); }
+
+    int names_size() const { return designators.size(); }
+
+    bool has_index() const { return ! designators.empty(); }
+    bool is_single() const { return kind == SINGLE; }
+    bool is_composite() const { return kind == COMPOUND;  }
+
+    Expression *get_value() {
+      switch ( kind ) {
+      case EMPTY:
+	return 0;
+	break;
+      case SINGLE:
+	return sinit->get_value();
+	break;
+      case COMPOUND:
+	assert(false);
+	break;
+      default:
+	assert(false);
+      }
+      return 0;
+    }
+
+    // attributes
+  private:
+    InitKind kind;
+    SingleInit *sinit;
+    ListInit *cinit;
+    std::list< BreakDesignator > designators;
+
+    // helper classes
+  public:
+    class BreakDesignator {
+    public:
+      BreakDesignator( Expression *exp ) {
+	Expression *prfx = exp;
+	UntypedMemberExpr *me = 0;
+
+	do {
+	  if ( (me=dynamic_cast< UntypedMemberExpr * >( prfx )) == 0 ) break;
+	  blown_struct.push_front( me->get_member() );
+	  prfx = me->get_aggregate();
+	} while( prfx != 0 );
+
+	NameExpr *ne;
+	if ( (ne=dynamic_cast< NameExpr * >( prfx )) != 0 ) 
+	  blown_struct.push_front( ne->get_name() );
+      }
+
+      BreakDesignator( std::string name ) {
+	blown_struct.push_front( name );
+      }
+
+      bool is_flat() const { return blown_struct.size() == 1; }
+      bool is_nested() const { return blown_struct.size() > 1; }
+
+      std::string get_name() { return blown_struct.front(); }
+
+      BreakDesignator &name_remainder() {
+	blown_struct.pop_front();
+	return *this;
+      }
+
+    private:
+      std::list< std::string > blown_struct;
+    };
+
+  };
+
+} // namespace InitTweak
+
+#endif // #ifndef _BASINIT_H_
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/InitTweak/DeclarationHoister.cc
===================================================================
--- translator/InitTweak/DeclarationHoister.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/InitTweak/DeclarationHoister.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,49 @@
+#include <list>
+#include <cassert>
+#include <iostream>
+#include <iterator>
+#include <algorithm>
+
+#include "utility.h"
+
+#include "SynTree/Statement.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Declaration.h"
+
+#include "DeclarationHoister.h"
+
+
+namespace InitTweak {
+
+  CompoundStmt* DeclarationHoister::mutate(CompoundStmt *compoundStmt) {
+    typedef std::list<Statement *>::iterator stmt_it;
+    // 1. collect Declaration Statements  in this scope
+    std::list<Statement *> &kids = compoundStmt->get_kids();
+    std::list<Statement *>::iterator result = kids.begin();
+    std::list< stmt_it > decls;
+
+    while ( result !=  kids.end() ) {
+      result = std::find_if(result, kids.end(), cast_ptr< Statement, DeclStmt > );
+
+      if ( result != kids.end() ) {
+	decls.push_back( result );
+	std::advance( result, 1 );
+      } 
+    } 
+
+    for( std::list< stmt_it >::reverse_iterator i = decls.rbegin(); i!= decls.rend(); i++ ){
+      kids.push_front( **i );
+      kids.erase( *i );
+    }
+
+    return compoundStmt;
+  }
+} // namespace InitTweak
+
+
+
+
+
+
+
+
Index: translator/InitTweak/DeclarationHoister.h
===================================================================
--- translator/InitTweak/DeclarationHoister.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/InitTweak/DeclarationHoister.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,19 @@
+#include "SynTree/Visitor.h"
+#include "SymTab/Indexer.h"
+
+namespace InitTweak {
+
+  bool isDeclStmtP(Statement *stmt);
+
+  class DeclarationHoister: public Mutator {
+  public:
+    virtual CompoundStmt   *mutate(CompoundStmt *compoundStmt);
+  };
+
+}  // namespace InitTweak
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/InitTweak/InitExpander.cc
===================================================================
--- translator/InitTweak/InitExpander.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/InitTweak/InitExpander.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,35 @@
+#include <list>
+#include <stack>
+#include <cassert>
+#include <algorithm>
+
+
+#include "utility.h"
+#include "InitExpander.h"
+#include "InitModel.h"
+
+namespace InitTweak {
+
+  InitExpander::InitExpander() {}
+
+  InitExpander::~InitExpander() {}
+
+  ObjectDecl *InitExpander::mutate( ObjectDecl *objectDecl ) {
+    index.visit( objectDecl );
+
+    if( objectDecl->get_init() == 0 ) return objectDecl;
+
+    InitModelBuilder builder( objectDecl );
+    builder.get_assoc()->display( std::cerr ); // xxx
+    InitModelFiller filler( builder.get_assoc(), objectDecl->get_init(), true );
+    // filler.get_assoc()->display( std::cerr ); // xxx
+    InitUnspooler exp;
+    filler.get_assoc()->accept( exp );
+    objectDecl->set_init( exp.grab_initializer() );
+    objectDecl->get_init()->print( std::cerr );
+
+    return objectDecl;
+  }
+
+} // namespace InitTweak
+
Index: translator/InitTweak/InitExpander.h
===================================================================
--- translator/InitTweak/InitExpander.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/InitTweak/InitExpander.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,66 @@
+#ifndef _INIT_EXPANDER_H_
+#define _INIT_EXPANDER_H_
+
+#include <string>
+
+#include "utility.h"
+#include "SynTree/Mutator.h"
+#include "SymTab/Indexer.h"
+
+#include "SynTree/Statement.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+
+namespace InitTweak {
+
+  class InitExpander : public Mutator
+  {
+    typedef Mutator Parent;
+
+  public:
+    InitExpander();
+    ~InitExpander();
+
+    virtual ObjectDecl *mutate( ObjectDecl * );
+
+    // indexer runs
+    virtual FunctionDecl   *mutate( FunctionDecl *functionDecl )
+    {
+      functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
+      mutateAll( functionDecl->get_oldDecls(), *this );
+      functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
+
+      index.visit( functionDecl );
+      return functionDecl;
+    }
+
+    virtual TypeDecl       *mutate( TypeDecl *typeDecl )
+    { index.visit( typeDecl ); return typeDecl; }
+    virtual TypedefDecl    *mutate( TypedefDecl *typeDecl )
+    { index.visit( typeDecl ); return typeDecl; }
+    virtual StructDecl     *mutate( StructDecl *aggregateDecl )
+    { index.visit( aggregateDecl ); return aggregateDecl; }
+    virtual UnionDecl      *mutate( UnionDecl *aggregateDecl )
+    { index.visit( aggregateDecl ); return aggregateDecl; }
+    virtual EnumDecl       *mutate( EnumDecl *aggregateDecl )
+    { index.visit( aggregateDecl ); return aggregateDecl; }
+
+    virtual Type           *mutate( StructInstType *aggrInst )
+    { index.visit( aggrInst ); return aggrInst; }
+    virtual Type           *mutate( UnionInstType *aggrInst )
+    { index.visit( aggrInst ); return aggrInst; }
+
+  private:
+    SymTab::Indexer index;
+  };  // class InitExpander
+
+} // namespace InitTweak
+
+
+#endif // #ifndef _INIT_EXPANDER_H_
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/InitTweak/InitModel.cc
===================================================================
--- translator/InitTweak/InitModel.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/InitTweak/InitModel.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,209 @@
+#include "SynTree/Constant.h"
+#include "InitModel.h"
+
+#include <cassert>
+#include <cstdlib>
+#include <algorithm>
+
+namespace InitTweak {
+
+  InitModelBuilder::InitModelBuilder( Declaration *_decl )
+    : taken( false ), decl( 0 ), building(0) {
+
+    ObjectDecl *_odecl = dynamic_cast< ObjectDecl * >( _decl );
+    assert( _odecl != 0 );
+    Type *objectType = _odecl->get_type();
+
+    /* this to be replaced by dynamic dispatch */
+    if( dynamic_cast< BasicType * >(objectType) != 0 ) {
+      if( building == 0 ) building = new SingleName;
+    } else if( ReferenceToType *rt = dynamic_cast< ReferenceToType * >(objectType) ) {
+      rt->accept( *this );
+    } else if( ArrayType *at = dynamic_cast< ArrayType * >(objectType) ) {
+      at->accept( *this );
+    } else // if (tuples)
+      std::cerr << "Got something else" << std::endl;
+
+    if ( decl != 0 ) init();
+  }
+
+  InitModelBuilder::~InitModelBuilder() { if( !taken ) { delete building; building = 0; } }
+
+  void InitModelBuilder::init() {
+    assert( decl != 0 );
+    decl->accept( *this );
+  }
+
+  // Visitor interface
+  void InitModelBuilder::visit( ArrayType *at ) {
+    if( building == 0 ) building = new RangeAssociation(interpretDimension( at->get_dimension() ));
+    decl = 0;
+    return;
+  }
+
+  void InitModelBuilder::visit( StructInstType *st ) {
+    if( building == 0 ) building = new PointAssociation;
+    decl = st->get_baseStruct();
+    return;
+  }
+
+  void InitModelBuilder::visit( UnionInstType *ut ) {
+    decl = ut->get_baseUnion();
+    return;
+  }
+  void InitModelBuilder::visit( EnumInstType * ) {}
+
+  void InitModelBuilder::visit( StructDecl *aggregateDecl) {
+    PointAssociation *pa = dynamic_cast< PointAssociation * >( building );
+    assert( pa != 0 );
+    std::list< Declaration * > mem = aggregateDecl->get_members();
+
+    for( std::list<Declaration *>::iterator i = mem.begin(); i != mem.end(); i++ ) {
+      pa->add_member( (*i)->get_name() );
+      InitModelBuilder rec(*i);
+      pa->set_member( (*i)->get_name(), rec.grab_assoc() );
+    }
+
+    return;
+  }
+
+  void InitModelBuilder::visit( UnionDecl *) {}
+  void InitModelBuilder::visit( EnumDecl *) {}
+
+  // InitModelBuilder::ConstantFolder
+  void InitModelBuilder::ConstantFolder::visit( ConstantExpr *cnst ) {
+    Constant *c = cnst->get_constant();
+    assert (c != 0);
+    if ( BasicType *bt = dynamic_cast<BasicType *>( c->get_type() ) ) {
+      if( bt->isInteger() ) {
+	// need more intelligence here, not necessarily base 10
+	value = std::strtol( c->get_value().c_str(), NULL, 10 );
+	return;
+      } else
+	std::cerr << "Basic type but not integer" << std::endl;
+    }
+    throw 0;
+  }
+
+  // InitModelFiller
+  InitModelFiller::InitModelFiller( Association *_model, Initializer *_init, bool _topLevel )
+      : model( _model ), orgInit( _init ), topLevel( _topLevel ), next( 0 ) {
+    //next = model.begin();
+    if ( orgInit != 0 ) init();
+  }
+
+  void InitModelFiller::init() {
+    assert( model != 0 ); // change it into a reference
+    assert( orgInit != 0 );
+    orgInit->accept( *this );
+  }
+
+  void InitModelFiller::visit( SingleInit *singleInit ) {
+    std::list< Expression *> &des = singleInit->get_designators();
+
+    if( topLevel ) {
+      assert ( des.empty() );
+      assert ( dynamic_cast< SingleName * >(model) != 0 );
+      try {
+	model->add_single( next++, singleInit->get_value() );
+      } catch (...) {
+	std::cerr << "Illegal initialization" << std::endl;
+      }
+      return;
+    }
+
+    if( des.empty() ) {
+      assert( model != 0 );
+      try {
+	model->add_single( next++, singleInit->get_value() );
+      } catch ( AssocException &e ) {
+	throw SemanticError( "Illegal initialization: " + e.get_what() );
+      } catch ( ... ) {
+	std::cerr << "Shouldn't be here" << std::endl;
+      }
+      return;
+    }
+
+    // not general enough (does not contend well with designated arrays)
+    std::list<std::string> desnames;
+    std::transform( des.begin(), des.end(), back_inserter(desnames), Initializer::designator_name );
+
+    for ( std::list<std::string>::iterator i = desnames.begin(); i != desnames.end(); i++ ) {
+      try {
+	next = model->add_single( *i, singleInit->get_value() );
+	next++;
+      } catch ( AssocException &e ) {
+	throw SemanticError( "Illegal initialization: " + e.get_what() );
+      } catch ( ... ) {
+	std::cerr << "Shouldn't happen, check association" << std::endl;
+      }
+    }
+
+    return;
+  }
+
+  void InitModelFiller::visit( ListInit *listInit ) {
+    assert( listInit != 0 );
+
+    // designators
+    std::list< Expression *> &des = listInit->get_designators();
+    std::list< Initializer *> &ini = listInit->get_initializers();
+
+    if (! des.empty() ) {
+      if (topLevel)
+	throw SemanticError( "Invalid initializer: designated at top level." );
+
+      std::list<Expression *> des2;
+      std::copy (des.begin(), des.end(), back_inserter( des2 ));
+      std::list< Expression * > empty;
+      listInit->set_designators( empty );
+      for ( std::list<Expression *>::iterator i = des2.begin(); i != des2.end(); i++ ) {
+	Association * newModel = 0;
+	if( NameExpr *n = dynamic_cast< NameExpr * >( *i ) )
+	  try {
+	    newModel = (*model)[ n->get_name() ];
+	  } catch( AssocException &e ) {
+	    std::cerr << "Didn't find member: " << e.get_what() << std::endl;
+	  }
+	else // if( RangeExpr *r = dynamic_cast< RangeExpr * >( *i ) )
+	  std::cerr << "Invalid designator specification" << std::endl;
+
+	InitModelFiller rec( newModel, listInit, true );
+      }
+
+    } else
+      if (topLevel) {
+	topLevel = false;
+	for ( std::list<Initializer*>::iterator i = ini.begin(); i != ini.end(); i++ )
+	  (*i)->accept(*this);
+      } else
+	// next available uninitialized member
+	InitModelFiller rec( (*model)[next++], listInit, true );
+  }
+
+  void InitUnspooler::visit( SingleName *single ) {
+    assert(init == 0 && single != 0);
+    std::list< Expression * > empty;
+    init = new SingleInit( single->get_expr(), empty );
+    return;
+  }
+
+  void InitUnspooler::visit( PointAssociation *pa ) {
+    assert( pa != 0 );
+
+    std::list< Initializer * > contents;
+    for( int i = 0; i < pa->size(); i++ )
+      if ( (*pa)[i] != 0 ) {
+	InitUnspooler rec;
+	(*pa)[i]->accept( rec );
+	assert( rec.get_initializer() != 0 );
+	contents.push_back( rec.grab_initializer() );
+      }
+
+    init = new ListInit( contents );
+    return;
+  }
+
+
+
+} // namespace InitTweak
Index: translator/InitTweak/InitModel.h
===================================================================
--- translator/InitTweak/InitModel.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/InitTweak/InitModel.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,120 @@
+#ifndef _INITTWEAK_MODEL_H_
+#define _INITTWEAK_MODEL_H_
+
+#include "Association.h"
+#include "SemanticError.h"
+#include "SynTree/Visitor.h"
+
+#include "SynTree/Initializer.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Type.h"
+
+namespace InitTweak {
+
+  class InitModelBuilder : public AssociationBuilder, public Visitor {
+  public:
+    InitModelBuilder( Declaration * );
+    ~InitModelBuilder();
+
+    virtual Association *grab_assoc() { taken = true; return building; }
+    virtual Association *get_assoc() { return building; }
+    void set_assoc( Association *newAssoc ) { building = newAssoc; }
+
+    void init();
+    static int interpretDimension( Expression *exp ) {
+      ConstantFolder folder( exp );
+      try {
+	return folder.get_constant();
+      } catch (...) {
+	throw SemanticError("Invalid array dimension");
+      }
+    }
+
+    // types
+    virtual void visit( ArrayType * );
+    virtual void visit( StructInstType * );
+    virtual void visit( UnionInstType * );
+    virtual void visit( EnumInstType * );
+    virtual void visit( ContextInstType * ) { throw 0; }
+    virtual void visit( TypeInstType * )    { throw 0; }
+    // virtual void visit( TupleType *tupleType );
+    // declarations
+    virtual void visit( StructDecl *);
+    virtual void visit( UnionDecl *);
+    virtual void visit( EnumDecl *);
+
+  private:
+    class ConstantFolder : public Visitor {
+    public:
+      ConstantFolder( Expression *_expr = 0 ): expr(_expr) {}
+      int get_constant() throw() { expr->accept( *this ); return value; }
+      void set_constant( Expression *newExp ) { expr = newExp; }
+      // Visitor interface
+      void visit( Expression * ) { throw 0; }
+      void visit( NameExpr * ) { throw 0; }
+      void visit( CastExpr * ) { throw 0; }
+      void visit( UntypedMemberExpr * ) { throw 0; }
+      void visit( VariableExpr * ) { throw 0; }
+      void visit( ConstantExpr * );
+      void visit( SizeofExpr * ) { throw 0; }
+      void visit( AttrExpr * ) { throw 0; }
+      void visit( LogicalExpr * ) { throw 0; }
+      void visit( ConditionalExpr * ) { throw 0; }
+      void visit( CommaExpr * ) { throw 0; }
+    private:
+      Expression *expr;
+      int value;
+    };
+
+    bool taken;
+    Declaration *decl;  // ?
+    Association *building;
+  };
+
+  class InitModelFiller : public AssociationFiller, public Visitor {
+  public:
+    InitModelFiller( Association *, Initializer *, bool _topLevel = false );
+    ~InitModelFiller() { /* pointers in here are not owned by object (never created by object either) */ }
+    virtual Association *get_assoc() { return model; }
+    virtual void set_assoc( Association *newAssoc ) { model = newAssoc; }
+
+    void init();
+    // Visitor interface
+    virtual void visit( MemberInit *memberInit ) { throw 0; }
+    virtual void visit( ElementInit *elementInit ) { throw 0; }
+    virtual void visit( SingleInit *singleInit );
+    virtual void visit( ListInit *listInit );
+
+  private:
+    Association *model;
+    Initializer *orgInit;
+    bool topLevel;
+    long int next;
+  };
+
+  class InitUnspooler : public AssociationVisitor {
+  public:
+    InitUnspooler() : init(0), taken( false ) {}
+    virtual ~InitUnspooler() { if (!taken && (init != 0)) { delete init; init = 0; } }
+    Initializer *get_initializer() { return init; }
+    Initializer *grab_initializer() { taken = true; return init; }
+
+    virtual void visit( SingleName * );
+    virtual void visit( PointAssociation * );
+    virtual void visit( RangeAssociation * ) { std::cerr << "InitUnspooler - In a range assoc" << std::endl; return; }
+
+  private:
+    Initializer *init;
+    bool taken;
+  };
+
+} // namespace InitTweak
+
+#endif // #define _INITTWEAK_MODEL_H_
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/InitTweak/Mutate.cc
===================================================================
--- translator/InitTweak/Mutate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/InitTweak/Mutate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,24 @@
+#include "SynTree/Mutator.h"
+
+#include "Mutate.h"
+#include "InitExpander.h"
+//#include "BasicInit.h"
+//#include "DeclarationHoister.h"
+//#include "NameCollector.h"
+
+namespace InitTweak {
+
+  void mutate( std::list< Declaration * > translationUnit )
+  {
+    //BasicInit bi;
+    InitExpander ini;
+    //DeclarationHoister dh;
+
+    //mutateAll( translationUnit, bi );
+    mutateAll( translationUnit, ini );
+    //mutateAll( translationUnit, dh );
+  }
+
+} // namespace InitTweak
+
+
Index: translator/InitTweak/Mutate.h
===================================================================
--- translator/InitTweak/Mutate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/InitTweak/Mutate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,20 @@
+#ifndef INIT_MUTATE_H
+#define INIT_MUTATE_H
+
+#include <list>
+
+#include "SynTree/Declaration.h"
+
+namespace InitTweak {
+
+  void mutate( std::list< Declaration* > translationUnit );
+
+} // namespace InitTweak
+
+#endif // #ifndef INIT_MUTATE_H
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/InitTweak/diet_map.h
===================================================================
--- translator/InitTweak/diet_map.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/InitTweak/diet_map.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,207 @@
+#include <cassert>
+#include <string>
+#include <stack>
+
+namespace diet {
+  /* A DIET ( Discrete Interval Encoding Tree ) range-map
+   */
+
+  class diet_tree_exception : public std::exception {
+  public:
+    diet_tree_exception() {}
+    diet_tree_exception( std::string _what ) : what( _what ) {}
+    ~diet_tree_exception() throw () {}
+
+    std::string get_what() const { return what; }
+    void set_what( std::string newValue ) { what = newValue; }
+  private:
+    std::string what;
+  };
+
+  template < typename T > class diet_tree_node;
+  template < typename T > class diet_tree_iterator;
+
+  template< typename key_type >
+  class diet_tree {
+    typedef key_type OrderedValue;
+    typedef OrderedValue T;
+    friend class diet_tree_iterator<T>;
+  public:
+    typedef OrderedValue value_type;
+    typedef diet_tree_iterator<OrderedValue> iterator;
+    typedef std::pair<value_type, value_type> pair_type;
+
+    diet_tree() : root(0), left(0), right(0) {}
+    ~diet_tree() {
+      if( root != 0 ) { delete root; root = 0; }
+      if( left != 0 ) { delete left; left = 0; }
+      if( right != 0 ) { delete right; right = 0; }
+    }
+
+    void insert( value_type _lo, value_type _hi ) {
+      if ( _lo > _hi ) return; // throw exception?
+      if ( root == 0 )
+	root = new diet_tree_node<value_type>(_lo, _hi);
+      else {
+	value_type lo = root->get_lo(), hi = root->get_hi();
+	if( _lo < lo ) {
+	  if( _hi > hi ) {
+	    /* can either minimize the work or minimize the number of nodes.
+	       Let's minimize the work. */
+	    if ( left == 0 ) left = new diet_tree<T>();
+	    left->insert( _lo, lo );
+	    if ( right == 0 ) right = new diet_tree<T>();
+	    right->insert( _hi, hi );
+	    return;
+	  } else if( _hi < lo ) {
+	    if ( left == 0 ) left = new diet_tree<T>();
+	    left->insert( _lo, _hi );
+	  } else if( _hi <= hi ) {
+	    if ( left == 0 ) left = new diet_tree<T>();
+	    left->insert( _lo, _hi );
+	    root->set_range(_hi,hi);
+	  }
+	} else if (_lo >= lo && _hi <= hi ) {
+	  root->set_range(_lo,_hi);
+	} else if ( _hi > hi) {
+	  if( _lo > hi ) {
+	    if ( right == 0 ) right = new diet_tree<T>();
+	    right->insert( _lo, _hi );
+	  } else if( _lo < hi ) {
+	    root->set_range(lo, _lo);
+	    if ( right == 0 ) right = new diet_tree<T>();
+	    right->insert(_lo, _hi);
+	  }
+	}
+      }
+      return;
+    }
+
+    void insert( std::pair<value_type, value_type> p ) {
+      insert(p.first, p.second);
+    }
+
+    pair_type get_range_pair() const {
+      return pair_type(root->get_lo(),root->get_hi());
+    }
+
+    /*
+    void display( std::ostream &os = std::cout ) {
+      if ( root != 0 ) {
+	if ( left != 0 ) left->display(os);
+	os << "(" << root->get_lo() << ", " << root->get_hi() << ")" << std::endl;
+	if ( right != 0 ) right->display(os);
+      }
+      return;
+    }
+    */
+
+    iterator begin() { return iterator( this ); }
+    iterator end() { return iterator( (diet_tree< value_type > *)0 ); }
+
+  protected:
+    diet_tree( diet_tree_node< OrderedValue > *_root ) : root( _root ) {}
+  private:
+    diet_tree_node< value_type > *root;
+    diet_tree< value_type > *left, *right;
+  };
+
+  template< typename OrderedValue >
+  class diet_tree_node {
+  public:
+    typedef OrderedValue value_type;
+
+    diet_tree_node( const OrderedValue &_lo, const OrderedValue &_hi )
+      : lo( _lo ), hi( _hi ) {
+      if ( lo >= hi ) throw diet_tree_exception( "Invalid range" );
+    }
+
+    void set_range(const OrderedValue &newLo, const OrderedValue &newHi)
+    { lo = newLo; hi = newHi; }
+    OrderedValue get_lo() const { return lo; }
+    OrderedValue get_hi() const { return hi; }
+
+  private:
+    OrderedValue lo, hi;
+  };
+
+  /* forward iterator */
+  template < typename T >
+  class diet_tree_iterator {
+    typedef diet_tree_iterator<T> self;
+    typedef typename diet_tree<T>::pair_type pair_type;
+
+  public:
+    //    typedef forward_iterator_tag iterator_category;
+
+    diet_tree_iterator( diet_tree<T> *_tree ) : current( _tree ) {
+      // current is allowed to be 0 only for `end'
+      if (_tree != 0) go_leftmost();
+    }
+
+    ~diet_tree_iterator() {}
+    pair_type operator*() {
+      if ( current == 0 ) throw diet_tree_exception( "Invalid dereference" );
+      return current->get_range_pair();
+    }
+
+    bool operator==( const diet_tree_iterator<T> &other ) { return current == other.current;  }
+    bool operator!=( const diet_tree_iterator<T> &other ) { return current != other.current;  }
+
+    diet_tree_iterator<T> operator++() {
+      assert(current != 0);
+      if ( current->right == 0 )
+	if ( !st.empty() )
+	  { current = st.top(); st.pop(); }
+	else
+	  current = 0;
+      else {
+	current = current->right;
+	go_leftmost();
+      }
+      return *this;
+    }
+
+    diet_tree_iterator<T> operator++(int) {
+      self temp = *this;
+      this->operator++();
+      return temp;
+    }
+
+  private:
+    void go_leftmost() {
+      assert(current != 0);
+      diet_tree<T> *next = 0;
+      while( current->left != 0 ) {
+	next = current->left; st.push( current ); current = next;
+      }
+      return;
+    }
+
+    void defrag() {
+      /* join adjacent trees */
+      return;
+    }
+
+    diet_tree<T> *current;
+    std::stack< diet_tree<T> * > st;
+  };
+
+  template < typename Key, typename Value >
+  class diet_tree_assoc_node : public diet_tree_node<Key> {
+  public:
+    typedef Key key_type;
+    typedef Value data_type;
+    typedef std::pair<Key,Value> value_type;
+  private:
+    Value data;
+  };
+
+} // namespace diet
+
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/InitTweak/module.mk
===================================================================
--- translator/InitTweak/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/InitTweak/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,6 @@
+SRC += InitTweak/InitModel.cc \
+       InitTweak/InitExpander.cc \
+       InitTweak/Mutate.cc     \
+       InitTweak/Association.cc     \
+	$(NULL)
+
Index: translator/MakeLibCfa.cc
===================================================================
--- translator/MakeLibCfa.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/MakeLibCfa.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,106 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: MakeLibCfa.cc,v 1.6 2005/08/29 20:14:14 rcbilson Exp $
+ *
+ */
+
+#include "MakeLibCfa.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Initializer.h"
+#include "SynTree/Visitor.h"
+#include "CodeGen/OperatorTable.h"
+#include "UniqueName.h"
+
+
+namespace LibCfa {
+
+class MakeLibCfa : public Visitor
+{
+public:
+  void visit( FunctionDecl* funcDecl );
+  void visit( ObjectDecl* objDecl );
+  
+  std::list< Declaration* > &get_newDecls() { return newDecls; }
+  
+private:
+  std::list< Declaration* > newDecls;
+};
+
+void
+makeLibCfa( std::list< Declaration* > &prelude )
+{
+  MakeLibCfa maker;
+  acceptAll( prelude, maker );
+  prelude.splice( prelude.end(), maker.get_newDecls() );
+}
+
+void 
+MakeLibCfa::visit( FunctionDecl* origFuncDecl )
+{
+  if( origFuncDecl->get_linkage() != LinkageSpec::Intrinsic ) return;
+  
+  FunctionDecl *funcDecl = origFuncDecl->clone();
+  CodeGen::OperatorInfo opInfo;
+  bool lookResult = CodeGen::operatorLookup( funcDecl->get_name(), opInfo );
+  assert( lookResult );
+  assert( !funcDecl->get_statements() );
+  UntypedExpr *newExpr = new UntypedExpr( new NameExpr( funcDecl->get_name() ) );
+  UniqueName paramNamer( "_p" );
+  std::list< DeclarationWithType* >::iterator param = funcDecl->get_functionType()->get_parameters().begin();
+  assert( param != funcDecl->get_functionType()->get_parameters().end() );
+  if( (*param)->get_name() == "" ) {
+    (*param)->set_name( paramNamer.newName() );
+    (*param)->set_linkage( LinkageSpec::C );
+  }
+  switch( opInfo.type ) {
+  case CodeGen::OT_INDEX:
+  case CodeGen::OT_CALL:
+  case CodeGen::OT_PREFIX:
+  case CodeGen::OT_POSTFIX:
+  case CodeGen::OT_INFIX:
+    newExpr->get_args().push_back( new VariableExpr( *param ) );
+    break;
+    
+  case CodeGen::OT_PREFIXASSIGN:
+  case CodeGen::OT_POSTFIXASSIGN:
+  case CodeGen::OT_INFIXASSIGN:
+  {
+    newExpr->get_args().push_back( new VariableExpr( *param ) );
+///     UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
+///     deref->get_args().push_back( new VariableExpr( *param ) );
+///     newExpr->get_args().push_back( deref );
+    break;
+  }
+    
+  case CodeGen::OT_CONSTANT:
+    assert( false );
+  }
+  for( param++; param != funcDecl->get_functionType()->get_parameters().end(); ++param ) {
+    if( (*param)->get_name() == "" ) {
+      (*param)->set_name( paramNamer.newName() );
+      (*param)->set_linkage( LinkageSpec::C );
+    }
+    newExpr->get_args().push_back( new VariableExpr( *param ) );
+  }
+  funcDecl->set_statements( new CompoundStmt( std::list< Label >() ) );
+  funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( std::list< Label >(), newExpr ) );
+  newDecls.push_back( funcDecl );
+}
+
+void 
+MakeLibCfa::visit( ObjectDecl* origObjDecl )
+{
+  if( origObjDecl->get_linkage() != LinkageSpec::Intrinsic ) return;
+  
+  ObjectDecl *objDecl = origObjDecl->clone();
+  assert( !objDecl->get_init() );
+  std::list< Expression* > noDesignators;
+  objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), noDesignators ) );
+  newDecls.push_back( objDecl );
+}
+
+} // namespace LibCfa
Index: translator/MakeLibCfa.h
===================================================================
--- translator/MakeLibCfa.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/MakeLibCfa.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,20 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: MakeLibCfa.h,v 1.2 2005/08/29 20:14:14 rcbilson Exp $
+ *
+ */
+
+#ifndef LIBCFA_MAKELIBCFA_H
+#define LIBCFA_MAKELIBCFA_H
+
+#include <list>
+#include <SynTree/SynTree.h>
+
+namespace LibCfa {
+
+void makeLibCfa( std::list< Declaration* > &prelude );
+
+} // namespace LibCfa
+
+#endif /* #ifndef LIBCFA_MAKELIBCFA_H */
Index: translator/Makefile
===================================================================
--- translator/Makefile	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Makefile	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,59 @@
+# This makefile is adapted from Peter Miller's article
+# "Recursive Make Considered Harmful"
+#
+# http://www.pcug.org.au/~millerp/rmch/recu-make-cons-harm.html
+
+MODULES := Common Parser SynTree SymTab ResolvExpr CodeGen ControlStruct GenPoly Tuples InitTweak Designators #Try ArgTweak Explain
+TARGET := cfa-cpp
+
+all: $(TARGET)
+
+# look for include files in each of the modules
+CXX := g++
+CXXFLAGS += -Wno-deprecated -Wall -g -DDEBUG_ALL -I. -I Common -MMD
+INSTALL=/usr/bin/install -c
+
+# this is the back-end compiler, used to compile libcfa & builtins to link with user code
+BACKEND_CC := /u/pabuhr/bin/gcc
+
+# uncomment the definition of this variable to enable purify
+#  (do a "purerun" first)
+#PURIFY := purify --cache-dir=$(HOME)/tmp
+
+# extra libraries if required
+LIBS :=
+
+# each module will add to this
+SRC := main.cc MakeLibCfa.cc
+
+# other things that ought to be cleaned up
+EXTRA_OUTPUT := core
+
+# include the description for each module
+include $(patsubst %,%/module.mk,$(MODULES))
+
+# determine the object files
+OBJ := $(patsubst %.cc,%.o,$(filter %.cc,$(SRC))) \
+       $(patsubst %.y,%.tab.o,$(filter %.y,$(SRC))) \
+       $(patsubst %.l,%.yy.o,$(filter %.l,$(SRC)))
+
+# include the C include dependencies
+DEPS := $(OBJ:.o=.d)
+-include $(DEPS)
+
+# link the program
+$(TARGET): $(OBJ)
+	$(PURIFY) $(CXX) -o $@ $(OBJ) $(LIBS)
+
+#installing
+install: $(TARGET)
+	$(INSTALL) -d /u/pabuhr/software/cfa/cfa-cc/lib
+	$(INSTALL) $(TARGET) /u/pabuhr/software/cfa/cfa-cc/lib
+
+# clean-up rule
+clean:
+	rm -f $(OBJ) $(DEPS) $(TARGET) tags $(EXTRA_OUTPUT)
+	find . -name "Expected*" -prune -o \( -name "*.tst" -o -name "report" \) -print | xargs rm -f
+	find . -name "core*" -print | xargs rm -f
+
+distclean: clean
Index: translator/Makefile.in
===================================================================
--- translator/Makefile.in	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Makefile.in	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,59 @@
+# This makefile is adapted from Peter Miller's article
+# "Recursive Make Considered Harmful"
+#
+# http://www.pcug.org.au/~millerp/rmch/recu-make-cons-harm.html
+
+MODULES := Common Parser SynTree SymTab ResolvExpr CodeGen ControlStruct GenPoly Tuples InitTweak Designators #Try ArgTweak Explain
+TARGET := cfa-cpp
+
+all: $(TARGET)
+
+# look for include files in each of the modules
+CXX := @CXX@
+CXXFLAGS += -Wno-deprecated -Wall -g -DDEBUG_ALL -I. -I Common -MMD
+INSTALL=@INSTALL@
+
+# this is the back-end compiler, used to compile libcfa & builtins to link with user code
+BACKEND_CC := @BACKEND_CC@
+
+# uncomment the definition of this variable to enable purify
+#  (do a "purerun" first)
+#PURIFY := purify --cache-dir=$(HOME)/tmp
+
+# extra libraries if required
+LIBS :=
+
+# each module will add to this
+SRC := main.cc MakeLibCfa.cc
+
+# other things that ought to be cleaned up
+EXTRA_OUTPUT := core
+
+# include the description for each module
+include $(patsubst %,%/module.mk,$(MODULES))
+
+# determine the object files
+OBJ := $(patsubst %.cc,%.o,$(filter %.cc,$(SRC))) \
+       $(patsubst %.y,%.tab.o,$(filter %.y,$(SRC))) \
+       $(patsubst %.l,%.yy.o,$(filter %.l,$(SRC)))
+
+# include the C include dependencies
+DEPS := $(OBJ:.o=.d)
+-include $(DEPS)
+
+# link the program
+$(TARGET): $(OBJ)
+	$(PURIFY) $(CXX) -o $@ $(OBJ) $(LIBS)
+
+#installing
+install: $(TARGET)
+	$(INSTALL) -d @CFA_LIBDIR@
+	$(INSTALL) $(TARGET) @CFA_LIBDIR@
+
+# clean-up rule
+clean:
+	rm -f $(OBJ) $(DEPS) $(TARGET) tags $(EXTRA_OUTPUT)
+	find . -name "Expected*" -prune -o \( -name "*.tst" -o -name "report" \) -print | xargs rm -f
+	find . -name "core*" -print | xargs rm -f
+
+distclean: clean
Index: translator/Parser.old/DeclarationNode.cc
===================================================================
--- translator/Parser.old/DeclarationNode.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser.old/DeclarationNode.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,1102 @@
+#include <string>
+#include <list>
+#include <iterator>
+#include <algorithm>
+#include <cassert>
+
+#include "ParseNode.h"
+#include "TypeData.h"
+#include "utility.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Initializer.h"
+#include "SemanticError.h"
+#include "UniqueName.h"
+#include "LinkageSpec.h"
+
+using namespace std;
+
+/* these must remain in the same order as the corresponding DeclarationNode enumerations */
+const char *DeclarationNode::qualifierName[] = { "const", "restrict", "volatile", "lvalue" };
+const char *DeclarationNode::basicTypeName[] = { "char", "int", "float", "double", "void", "bool", "complex", "imaginary" };
+const char *DeclarationNode::modifierName[] = { "signed", "unsigned", "short", "long" };
+const char *DeclarationNode::tyConName[] = { "struct", "union", "context" };
+const char *DeclarationNode::typeClassName[] = { "type", "dtype", "ftype" };
+
+UniqueName DeclarationNode::anonymous( "__anonymous" );
+
+extern LinkageSpec::Type linkage;		/* defined in cfa.y */
+
+DeclarationNode*
+DeclarationNode::clone() const
+{
+  DeclarationNode *newnode = new DeclarationNode( filename, lineno );
+  newnode->type = maybeClone( type );
+  newnode->name = name;
+  newnode->storageClasses = storageClasses;
+  newnode->bitfieldWidth = maybeClone( bitfieldWidth );
+  newnode->hasEllipsis = hasEllipsis;
+  newnode->initializer = initializer;
+  newnode->next = maybeClone( next );
+  newnode->linkage = linkage;
+  return newnode;
+}
+
+DeclarationNode::DeclarationNode( char *filename, int lineno )
+  : ParseNode( "", filename, lineno ), type( 0 ), bitfieldWidth( 0 ), initializer( 0 ), hasEllipsis( false ), linkage( ::linkage )
+{
+}
+
+DeclarationNode::~DeclarationNode()
+{
+  delete type;
+  delete bitfieldWidth;
+  delete initializer;
+}
+
+bool
+DeclarationNode::get_hasEllipsis() const
+{
+  return hasEllipsis;
+}
+
+const char *storageClassName[] =
+{
+  // order must correspond with DeclarationNode::StorageClass
+  "static",
+  "auto",
+  "extern",
+  "register",
+  "inline",
+  "fortran",
+};
+
+void
+DeclarationNode::print( std::ostream &os, int indent ) const
+{
+  os << string(indent,  ' ');
+  if( name == "" ) {
+///     os << "An unnamed ";
+  } else {
+    os << name << ": a ";
+  }
+  if( linkage != LinkageSpec::Cforall ) {
+    os << LinkageSpec::toString( linkage ) << " ";
+  }
+  printEnums( storageClasses.begin(), storageClasses.end(), storageClassName, os );
+  if( type ) {
+    type->print( os, indent );
+  } else {
+    os << "untyped entity ";
+  }
+  if( bitfieldWidth ) {
+    os << endl << string(indent+2,  ' ') << "with bitfield width ";
+    bitfieldWidth->printOneLine( os );
+  }
+
+  if( initializer != 0 ) {
+    os << endl << string(indent+2,  ' ') << "with initializer ";
+    initializer->printOneLine( os );
+  }
+
+  os << endl;
+}
+
+void
+DeclarationNode::printList( std::ostream &os, int indent ) const
+{
+  ParseNode::printList( os, indent );
+  if( hasEllipsis ) {
+    os << string( indent, ' ' )  << "and a variable number of other arguments" << endl;
+  }
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newFunction( struct token &tok, DeclarationNode *ret, DeclarationNode *param, StatementNode *body )
+{
+  DeclarationNode *newnode = new DeclarationNode( tok.filename, tok.lineno );
+  newnode->name = assign_strptr( tok.str );
+
+  newnode->type = new TypeData( TypeData::Function );
+  newnode->type->function->params = param;
+  newnode->type->function->body = body;
+  if( body ) {
+    newnode->type->function->hasBody = true;
+  }
+
+  if( ret ) {
+    newnode->type->base = ret->type;
+    ret->type = 0;
+    delete ret;
+  }
+
+  return newnode;
+}
+
+DeclarationNode *
+DeclarationNode::newFunction( char *filename, int lineno, DeclarationNode *ret, DeclarationNode *param, StatementNode *body )
+{
+  DeclarationNode *newnode = new DeclarationNode( filename, lineno );
+
+  newnode->type = new TypeData( TypeData::Function );
+  newnode->type->function->params = param;
+  newnode->type->function->body = body;
+  if( body ) {
+    newnode->type->function->hasBody = true;
+  }
+
+  if( ret ) {
+    newnode->type->base = ret->type;
+    ret->type = 0;
+    delete ret;
+  }
+
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newQualifier( Qualifier q, char *filename, int lineno )
+{
+  DeclarationNode *newnode = new DeclarationNode( filename, lineno );
+  newnode->type = new TypeData();
+  newnode->type->qualifiers.push_back( q );
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newStorageClass( StorageClass sc, char *filename, int lineno )
+{
+  DeclarationNode *newnode = new DeclarationNode( filename, lineno );
+  newnode->storageClasses.push_back( sc );
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newBasicType( BasicType bt, char *filename, int lineno )
+{
+  DeclarationNode *newnode = new DeclarationNode( filename, lineno );
+  newnode->type = new TypeData( TypeData::Basic );
+  newnode->type->basic->typeSpec.push_back( bt );
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newModifier( Modifier mod, char *filename, int lineno )
+{
+  DeclarationNode *newnode = new DeclarationNode( filename, lineno );
+  newnode->type = new TypeData( TypeData::Basic );
+  newnode->type->basic->modifiers.push_back( mod );
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newForall( DeclarationNode* forall, char *filename, int lineno )
+{
+  DeclarationNode *newnode = new DeclarationNode( filename, lineno );
+  newnode->type = new TypeData( TypeData::Unknown );
+  newnode->type->forall = forall;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newFromTypedef( struct token &tok )
+{
+  DeclarationNode *newnode = new DeclarationNode( tok.filename, tok.lineno );
+  newnode->type = new TypeData( TypeData::SymbolicInst );
+  newnode->type->symbolic->name = assign_strptr( tok.str );
+  newnode->type->symbolic->isTypedef = true;
+  newnode->type->symbolic->params = 0;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newAggregate( TyCon kind, struct token &tok, DeclarationNode *formals, ExpressionNode *actuals, DeclarationNode *fields )
+{
+  DeclarationNode *newnode = new DeclarationNode( tok.filename, tok.lineno );
+  newnode->type = new TypeData( TypeData::Aggregate );
+  newnode->type->aggregate->kind = kind;
+  newnode->type->aggregate->name = assign_strptr( tok.str );
+  if( newnode->type->aggregate->name == "" ) {
+    newnode->type->aggregate->name = DeclarationNode::anonymous.newName();
+  }
+  newnode->type->aggregate->params = formals;
+  newnode->type->aggregate->actuals = actuals;
+  newnode->type->aggregate->members = fields;
+  return newnode;
+}
+
+DeclarationNode *
+DeclarationNode::newAggregate( TyCon kind, char *filename, int lineno, DeclarationNode *formals, ExpressionNode *actuals, DeclarationNode *fields )
+{
+  DeclarationNode *newnode = new DeclarationNode( filename, lineno );
+  newnode->type = new TypeData( TypeData::Aggregate );
+  newnode->type->aggregate->kind = kind;
+  newnode->type->aggregate->name = DeclarationNode::anonymous.newName();
+  newnode->type->aggregate->params = formals;
+  newnode->type->aggregate->actuals = actuals;
+  newnode->type->aggregate->members = fields;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newEnum( struct token &tok, DeclarationNode *constants )
+{
+  DeclarationNode *newnode = new DeclarationNode( tok.filename, tok.lineno );
+  newnode->name = assign_strptr( tok.str );
+  newnode->type = new TypeData( TypeData::Enum );
+  newnode->type->enumeration->name = newnode->name;
+  if( newnode->type->enumeration->name == "" ) {
+    newnode->type->enumeration->name = DeclarationNode::anonymous.newName();
+  }
+  newnode->type->enumeration->constants = constants;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newEnum( char *filename, int lineno, DeclarationNode *constants )
+{
+  DeclarationNode *newnode = new DeclarationNode( filename, lineno );
+  newnode->type = new TypeData( TypeData::Enum );
+  newnode->type->enumeration->name = newnode->name;
+  newnode->type->enumeration->name = DeclarationNode::anonymous.newName();
+  newnode->type->enumeration->constants = constants;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newEnumConstant( struct token &tok, ExpressionNode *constant )
+{
+  DeclarationNode *newnode = new DeclarationNode( tok.filename, tok.lineno );
+  newnode->name = assign_strptr( tok.str );
+  // do something with the constant
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newName( struct token &tok )
+{
+  DeclarationNode *newnode = new DeclarationNode( tok.filename, tok.lineno );
+  newnode->name = assign_strptr( tok.str );
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newFromTypeGen( struct token &tok, ExpressionNode *params )
+{
+  DeclarationNode *newnode = new DeclarationNode( tok.filename, tok.lineno );
+  newnode->type = new TypeData( TypeData::SymbolicInst );
+  newnode->type->symbolic->name = assign_strptr( tok.str );
+  newnode->type->symbolic->isTypedef = false;
+  newnode->type->symbolic->actuals = params;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newTypeParam( TypeClass tc, std::string* name, char *filename, int lineno )
+{
+  DeclarationNode *newnode = new DeclarationNode( filename, lineno );
+  newnode->name = assign_strptr( name );
+  newnode->type = new TypeData( TypeData::Variable );
+  newnode->type->variable->tyClass = tc;
+  newnode->type->variable->name = newnode->name;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newContext( struct token &tok, DeclarationNode *params, DeclarationNode *asserts )
+{
+  DeclarationNode *newnode = new DeclarationNode( tok.filename, tok.lineno );
+  newnode->type = new TypeData( TypeData::Aggregate );
+  newnode->type->aggregate->kind = Context;
+  newnode->type->aggregate->params = params;
+  newnode->type->aggregate->members = asserts;
+  newnode->type->aggregate->name = assign_strptr( tok.str );
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newContextUse( struct token &tok, ExpressionNode *params )
+{
+  DeclarationNode *newnode = new DeclarationNode( tok.filename, tok.lineno );
+  newnode->type = new TypeData( TypeData::AggregateInst );
+  newnode->type->aggInst->aggregate = new TypeData( TypeData::Aggregate );
+  newnode->type->aggInst->aggregate->aggregate->kind = Context;
+  newnode->type->aggInst->aggregate->aggregate->name = assign_strptr( tok.str );
+  newnode->type->aggInst->params = params;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newTypeDecl( struct token &tok, DeclarationNode *typeParams )
+{
+  DeclarationNode *newnode = new DeclarationNode( tok.filename, tok.lineno );
+  newnode->name = assign_strptr( tok.str );
+  newnode->type = new TypeData( TypeData::Symbolic );
+  newnode->type->symbolic->isTypedef = false;
+  newnode->type->symbolic->params = typeParams;
+  newnode->type->symbolic->name = newnode->name;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newPointer( DeclarationNode *qualifiers, char *filename, int lineno )
+{
+  DeclarationNode *newnode = new DeclarationNode( filename, lineno );
+  newnode->type = new TypeData( TypeData::Pointer );
+  return newnode->addQualifiers( qualifiers );
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newArray( ExpressionNode *size, DeclarationNode *qualifiers, bool isStatic, char *filename, int lineno )
+{
+  DeclarationNode *newnode = new DeclarationNode( filename, lineno );
+  newnode->type = new TypeData( TypeData::Array );
+  newnode->type->array->dimension = size;
+  newnode->type->array->isStatic = isStatic;
+  newnode->type->array->isVarLen = false;
+  return newnode->addQualifiers( qualifiers );
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newVarArray( DeclarationNode *qualifiers, char *filename, int lineno )
+{
+  DeclarationNode *newnode = new DeclarationNode( filename, lineno );
+  newnode->type = new TypeData( TypeData::Array );
+  newnode->type->array->dimension = 0;
+  newnode->type->array->isStatic = false;
+  newnode->type->array->isVarLen = true;
+  return newnode->addQualifiers( qualifiers );
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newBitfield( ExpressionNode *size )
+{
+  DeclarationNode *newnode = new DeclarationNode( size->get_filename(), size->get_lineno() );
+  newnode->bitfieldWidth = size;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newTuple( DeclarationNode *members, char *filename, int lineno )
+{
+  DeclarationNode *newnode = new DeclarationNode( filename, lineno );
+  newnode->type = new TypeData( TypeData::Tuple );
+  newnode->type->tuple->members = members;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newTypeof( ExpressionNode *expr, char *filename, int lineno )
+{
+  DeclarationNode *newnode = new DeclarationNode( filename, lineno );
+  newnode->type = new TypeData( TypeData::Typeof );
+  newnode->type->typeexpr->expr = expr;
+  return newnode;
+}
+
+static void
+addQualifiersToType( TypeData *&src, TypeData *dst )
+{
+  if( src && dst ) {
+    if( src->forall && dst->kind == TypeData::Function ) {
+      if( dst->forall ) {
+	dst->forall->appendList( src->forall );
+      } else {
+	dst->forall = src->forall;
+      }
+      src->forall = 0;
+    }
+    if( dst->base ) {
+      addQualifiersToType( src, dst->base );
+    } else if( dst->kind == TypeData::Function ) {
+      dst->base = src;
+      src = 0;
+    } else {
+      dst->qualifiers.splice( dst->qualifiers.end(), src->qualifiers );
+    }
+  }
+}
+      
+DeclarationNode *
+DeclarationNode::addQualifiers( DeclarationNode *q )
+{
+  if( q ) {
+    storageClasses.splice( storageClasses.end(), q->storageClasses );
+    if( q->type ) {
+      if( !type ) {
+	type = new TypeData;
+      }
+      addQualifiersToType( q->type, type );
+      if( q->type && q->type->forall ) {
+        if( type->forall ) {
+          type->forall->appendList( q->type->forall );
+        } else {
+          type->forall = q->type->forall;
+        }
+        q->type->forall = 0;
+      }
+    }
+  }
+  lineno = min( lineno, q->lineno );
+  delete q;
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::copyStorageClasses( DeclarationNode *q )
+{
+  storageClasses = q->storageClasses;
+  return this;
+}
+
+static void
+addTypeToType( TypeData *&src, TypeData *&dst )
+{
+  if( src && dst ) {
+    if( src->forall && dst->kind == TypeData::Function ) {
+      if( dst->forall ) {
+        dst->forall->appendList( src->forall );
+      } else {
+        dst->forall = src->forall;
+      }
+      src->forall = 0;
+    }
+    if( dst->base ) {
+      addTypeToType( src, dst->base );
+    } else {
+      switch( dst->kind ) {
+      case TypeData::Unknown:
+	src->qualifiers.splice( src->qualifiers.end(), dst->qualifiers );
+	dst = src;
+	src = 0;
+	break;
+
+      case TypeData::Basic:
+	dst->qualifiers.splice( dst->qualifiers.end(), src->qualifiers );
+        if( src->kind != TypeData::Unknown ) {
+	  assert( src->kind == TypeData::Basic );
+	  dst->basic->modifiers.splice( dst->basic->modifiers.end(), src->basic->modifiers );
+	  dst->basic->typeSpec.splice( dst->basic->typeSpec.end(), src->basic->typeSpec );
+	}
+	break;
+
+      default:
+        switch( src->kind ) {
+        case TypeData::Aggregate:
+        case TypeData::Enum:
+          dst->base = new TypeData( TypeData::AggregateInst );
+          dst->base->aggInst->aggregate = src;
+          if( src->kind == TypeData::Aggregate ) {
+            dst->base->aggInst->params = maybeClone( src->aggregate->actuals );
+          }
+          dst->base->qualifiers.splice( dst->base->qualifiers.end(), src->qualifiers );
+          src = 0;
+          break;
+          
+        default:
+          if( dst->forall ) {
+            dst->forall->appendList( src->forall );
+          } else {
+            dst->forall = src->forall;
+          }
+          src->forall = 0;
+          dst->base = src;
+          src = 0;
+        }
+      }
+    }
+  }
+}
+
+DeclarationNode *
+DeclarationNode::addType( DeclarationNode *o )
+{
+  if( o ) {
+    storageClasses.splice( storageClasses.end(), o->storageClasses );
+    if ( o->type ) {
+      if( !type ) {
+        if( o->type->kind == TypeData::Aggregate || o->type->kind == TypeData::Enum ) {
+	  type = new TypeData( TypeData::AggregateInst );
+	  type->aggInst->aggregate = o->type;
+	  if( o->type->kind == TypeData::Aggregate ) {
+	    type->aggInst->params = maybeClone( o->type->aggregate->actuals );
+          }
+          type->qualifiers.splice( type->qualifiers.end(), o->type->qualifiers );
+	} else {
+	  type = o->type;
+	}
+	o->type = 0;
+      } else {
+	addTypeToType( o->type, type );
+      }
+    }
+    if( o->bitfieldWidth ) {
+      bitfieldWidth = o->bitfieldWidth;
+    }
+  }
+  lineno = min( lineno, o->lineno );
+  delete o;
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::addTypedef()
+{
+  TypeData *newtype = new TypeData( TypeData::Symbolic );
+  newtype->symbolic->params = 0;
+  newtype->symbolic->isTypedef = true;
+  newtype->symbolic->name = name;
+  newtype->base = type;
+  type = newtype;
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::addAssertions( DeclarationNode* assertions )
+{
+  assert( type );
+  switch( type->kind ) {
+  case TypeData::Symbolic:
+    if( type->symbolic->assertions ) {
+      type->symbolic->assertions->appendList( assertions );
+    } else {
+      type->symbolic->assertions = assertions;
+    }
+    break;
+    
+  case TypeData::Variable:
+    if( type->variable->assertions ) {
+      type->variable->assertions->appendList( assertions );
+    } else {
+      type->variable->assertions = assertions;
+    }
+    break;
+    
+  default:
+    assert( false );
+  }
+    
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::addName( struct token &tok )
+{
+  name = assign_strptr( tok.str );
+  lineno = min( lineno, tok.lineno );
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::addBitfield( ExpressionNode *size )
+{
+  bitfieldWidth = size;
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::addVarArgs()
+{
+  assert( type );
+  hasEllipsis = true;
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::addFunctionBody( StatementNode *body )
+{
+  assert( type );
+  assert( type->kind == TypeData::Function );
+  assert( type->function->body == 0 );
+  type->function->body = body;
+  type->function->hasBody = true;
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::addOldDeclList( DeclarationNode *list )
+{
+  assert( type );
+  assert( type->kind == TypeData::Function );
+  assert( type->function->oldDeclList == 0 );
+  type->function->oldDeclList = list;
+  return this;
+}
+
+static void
+setBase( TypeData *&type, TypeData *newType )
+{
+  if( type ) {
+    TypeData *prevBase = type;
+    TypeData *curBase = type->base;
+    while( curBase != 0 ) {
+      prevBase = curBase;
+      curBase = curBase->base;
+    }
+    prevBase->base = newType;
+  } else {
+    type = newType;
+  }
+}
+
+DeclarationNode *
+DeclarationNode::addPointer( DeclarationNode *p )
+{
+  if( p ) {
+    assert( p->type->kind == TypeData::Pointer );
+    setBase( type, p->type );
+    p->type = 0;
+    delete p;
+  }
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::addArray( DeclarationNode *a )
+{
+  if( a ) {
+    assert( a->type->kind == TypeData::Array );
+    setBase( type, a->type );
+    a->type = 0;
+    delete a;
+  }
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::addNewPointer( DeclarationNode *p )
+{
+  if( p ) {
+    assert( p->type->kind == TypeData::Pointer );
+    if( type ) {
+      switch( type->kind ) {
+      case TypeData::Aggregate:
+      case TypeData::Enum:
+        p->type->base = new TypeData( TypeData::AggregateInst );
+        p->type->base->aggInst->aggregate = type;
+       	if( type->kind == TypeData::Aggregate ) {
+       	  p->type->base->aggInst->params = maybeClone( type->aggregate->actuals );
+       	}
+        p->type->base->qualifiers.splice( p->type->base->qualifiers.end(), type->qualifiers );
+        break;
+        
+      default:
+        p->type->base = type;
+      }
+      type = 0;
+    }
+    delete this;
+    return p;
+  } else {
+    return this;
+  }
+}
+
+static TypeData *
+findLast( TypeData *a )
+{
+  assert( a );
+  TypeData *cur = a;
+  while( cur->base ) {
+    cur = cur->base;
+  }
+  return cur;
+}
+
+DeclarationNode *
+DeclarationNode::addNewArray( DeclarationNode *a )
+{
+  if( a ) {
+    assert( a->type->kind == TypeData::Array );
+    TypeData *lastArray = findLast( a->type );
+    if( type ) {  
+      switch( type->kind ) {
+      case TypeData::Aggregate:
+      case TypeData::Enum:
+        lastArray->base = new TypeData( TypeData::AggregateInst );
+        lastArray->base->aggInst->aggregate = type;
+        if( type->kind == TypeData::Aggregate ) {
+          lastArray->base->aggInst->params = maybeClone( type->aggregate->actuals );
+        }
+        lastArray->base->qualifiers.splice( lastArray->base->qualifiers.end(), type->qualifiers );
+        break;
+        
+      default:
+        lastArray->base = type;
+      }
+      type = 0;
+    }
+    delete this;
+    return a;
+  } else {
+    return this;
+  }
+}
+
+DeclarationNode *
+DeclarationNode::addParamList( DeclarationNode *params )
+{
+  TypeData *ftype = new TypeData( TypeData::Function );
+  ftype->function->params = params;
+  setBase( type, ftype );
+  return this;
+}
+
+static TypeData*
+addIdListToType( TypeData *type, DeclarationNode *ids )
+{
+  if( type ) {
+    if( type->kind != TypeData::Function ) {
+      type->base = addIdListToType( type->base, ids );
+    } else {
+      type->function->idList = ids;
+    }
+    return type;
+  } else {
+    TypeData *newtype = new TypeData( TypeData::Function );
+    newtype->function->idList = ids;
+    return newtype;
+  }
+}
+    
+DeclarationNode *
+DeclarationNode::addIdList( DeclarationNode *ids )
+{
+  type = addIdListToType( type, ids );
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::addInitializer( InitializerNode *init )
+{
+  //assert
+  initializer = init;
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::cloneBaseType( struct token &tok )
+{
+  DeclarationNode *newnode = new DeclarationNode( tok.filename, tok.lineno );
+  TypeData *srcType = type;
+  while( srcType->base ) {
+    srcType = srcType->base;
+  }
+  newnode->type = maybeClone( srcType );
+  if( newnode->type->kind == TypeData::AggregateInst ) {
+    // don't duplicate members
+    if( newnode->type->aggInst->aggregate->kind == TypeData::Enum ) {
+      delete newnode->type->aggInst->aggregate->enumeration->constants;
+      newnode->type->aggInst->aggregate->enumeration->constants = 0;
+    } else {
+      assert( newnode->type->aggInst->aggregate->kind == TypeData::Aggregate );
+      delete newnode->type->aggInst->aggregate->aggregate->members;
+      newnode->type->aggInst->aggregate->aggregate->members = 0;
+    }
+  }
+  newnode->type->forall = maybeClone( type->forall );
+  newnode->storageClasses = storageClasses;
+  newnode->name = assign_strptr( tok.str );
+  return newnode;
+}
+
+DeclarationNode *
+DeclarationNode::cloneBaseType( DeclarationNode *o )
+{
+  if( o ) {
+    o->storageClasses.insert( o->storageClasses.end(), storageClasses.begin(), storageClasses.end() );
+    if ( type ) {
+      TypeData *srcType = type;
+      while( srcType->base ) {
+	srcType = srcType->base;
+      }
+      TypeData *newType = srcType->clone();
+      if( newType->kind == TypeData::AggregateInst ) {
+        // don't duplicate members
+        if( newType->aggInst->aggregate->kind == TypeData::Enum ) {
+          delete newType->aggInst->aggregate->enumeration->constants;
+          newType->aggInst->aggregate->enumeration->constants = 0;
+        } else {
+          assert( newType->aggInst->aggregate->kind == TypeData::Aggregate );
+          delete newType->aggInst->aggregate->aggregate->members;
+          newType->aggInst->aggregate->aggregate->members = 0;
+        }
+      }
+      newType->forall = maybeClone( type->forall );
+      if( !o->type ) {
+	o->type = newType;
+      } else {
+	addTypeToType( newType, o->type );
+	delete newType;
+      }
+    }
+  }
+  return o;
+}
+
+DeclarationNode *
+DeclarationNode::cloneType( struct token &tok )
+{
+  DeclarationNode *newnode = new DeclarationNode( tok.filename, tok.lineno );
+  newnode->type = maybeClone( type );
+  newnode->storageClasses = storageClasses;
+  newnode->name = assign_strptr( tok.str );
+  return newnode;
+}
+
+DeclarationNode *
+DeclarationNode::cloneType( DeclarationNode *o )
+{
+  if( o ) {
+    o->storageClasses.insert( o->storageClasses.end(), storageClasses.begin(), storageClasses.end() );
+    if ( type ) {
+      TypeData *newType = type->clone();
+      if( !o->type ) {
+	o->type = newType;
+      } else {
+	addTypeToType( newType, o->type );
+	delete newType;
+      }
+    }
+  }
+  return o;
+}
+
+DeclarationNode *
+DeclarationNode::appendList( DeclarationNode *node )
+{
+  if( node != 0 ) {
+    set_link( node );
+  }
+  return this;
+}
+
+DeclarationNode*
+DeclarationNode::extractAggregate() const
+{
+  if( type ) {
+    TypeData *ret = type->extractAggregate();
+    if( ret ) {
+      DeclarationNode *newnode = new DeclarationNode( filename, lineno );
+      newnode->type = ret;
+      return newnode;
+    } else {
+      return 0;
+    }
+  } else {
+    return 0;
+  }
+}
+
+void buildList( const DeclarationNode *firstNode, std::list< Declaration* > &outputList )
+{
+  SemanticError errors;
+  std::back_insert_iterator< std::list< Declaration* > > out( outputList );
+  const DeclarationNode *cur = firstNode;
+  while( cur ) {
+    try {
+      if( DeclarationNode *extr = cur->extractAggregate() ) {
+	// handle the case where a structure declaration is contained within an object or type
+	// declaration
+	Declaration *decl = extr->build();
+	if( decl ) {
+	  *out++ = decl;
+	}
+      }
+      Declaration *decl = cur->build();
+      if( decl ) {
+        *out++ = decl;
+      }
+    } catch( SemanticError &e ) {
+      errors.append( e );
+    }
+    cur = dynamic_cast< DeclarationNode* >( cur->get_link() );
+  }
+  if( !errors.isEmpty() ) {
+    throw errors;
+  }
+}
+
+void buildList( const DeclarationNode *firstNode, std::list< DeclarationWithType* > &outputList )
+{
+  SemanticError errors;
+  std::back_insert_iterator< std::list< DeclarationWithType* > > out( outputList );
+  const DeclarationNode *cur = firstNode;
+  while( cur ) {
+    try {
+///       if( DeclarationNode *extr = cur->extractAggregate() ) {
+/// 	// handle the case where a structure declaration is contained within an object or type
+/// 	// declaration
+/// 	Declaration *decl = extr->build();
+/// 	if( decl ) {
+///           *out++ = decl;
+/// 	}
+///       }
+      Declaration *decl = cur->build();
+      if( decl ) {
+        if( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
+          *out++ = dwt;
+        } else if( StructDecl *agg = dynamic_cast< StructDecl* >( decl ) ) {
+          StructInstType *inst = new StructInstType( Type::Qualifiers(), agg->get_name() );
+          *out++ = new ObjectDecl( "", Declaration::NoStorageClass, linkage, 0, inst, 0 );
+          delete agg;
+        } else if( UnionDecl *agg = dynamic_cast< UnionDecl* >( decl ) ) {
+          UnionInstType *inst = new UnionInstType( Type::Qualifiers(), agg->get_name() );
+          *out++ = new ObjectDecl( "", Declaration::NoStorageClass, linkage, 0, inst, 0 );
+        }
+      }
+    } catch( SemanticError &e ) {
+      errors.append( e );
+    }
+    cur = dynamic_cast< DeclarationNode* >( cur->get_link() );
+  }
+  if( !errors.isEmpty() ) {
+    throw errors;
+  }
+}
+
+void buildTypeList( const DeclarationNode *firstNode, std::list< Type* > &outputList )
+{
+  SemanticError errors;
+  std::back_insert_iterator< std::list< Type* > > out( outputList );
+  const DeclarationNode *cur = firstNode;
+  while( cur ) {
+    try {
+      *out++ = cur->buildType();
+    } catch( SemanticError &e ) {
+      errors.append( e );
+    }
+    cur = dynamic_cast< DeclarationNode* >( cur->get_link() );
+  }
+  if( !errors.isEmpty() ) {
+    throw errors;
+  }
+}
+
+Declaration *
+DeclarationNode::build() const
+{
+
+  if( !type ) {
+    if( buildInline() ) {
+      throw SemanticError( "invalid inline specification in declaration of ", this );
+    } else {
+      return new ObjectDecl( name, buildStorageClass(), linkage, maybeBuild< Expression >( bitfieldWidth ), 0, maybeBuild< Initializer >( initializer ) );
+    }
+  } else {
+    Declaration *newDecl = type->buildDecl( name, buildStorageClass(), maybeBuild< Expression >( bitfieldWidth ), buildInline(), linkage, maybeBuild< Initializer >(initializer) );
+    return newDecl;
+  }
+  // we should never get here
+  assert( false );
+  return 0;
+}
+
+Type *
+DeclarationNode::buildType() const
+{
+
+  assert( type );
+  
+  switch( type->kind ) {
+  case TypeData::Enum:
+    return new EnumInstType( type->buildQualifiers(), type->enumeration->name );
+    
+  case TypeData::Aggregate: {
+    ReferenceToType *ret;
+    switch( type->aggregate->kind ) {
+    case DeclarationNode::Struct:
+      ret = new StructInstType( type->buildQualifiers(), type->aggregate->name );
+      break;
+
+    case DeclarationNode::Union:
+      ret = new UnionInstType( type->buildQualifiers(), type->aggregate->name );
+      break;
+
+    case DeclarationNode::Context:
+      ret = new ContextInstType( type->buildQualifiers(), type->aggregate->name );
+      break;
+
+    default:
+      assert( false );
+    }
+    buildList( type->aggregate->actuals, ret->get_parameters() );
+    return ret;
+  }
+  
+  case TypeData::Symbolic: {
+    TypeInstType *ret = new TypeInstType( type->buildQualifiers(), type->symbolic->name );
+    buildList( type->symbolic->actuals, ret->get_parameters() );
+    return ret;
+  }
+  
+  default:
+    return type->build();
+  }
+}
+
+Declaration::StorageClass 
+DeclarationNode::buildStorageClass() const
+{
+  static const Declaration::StorageClass scMap[] = {  
+    Declaration::Static,
+    Declaration::Auto,
+    Declaration::Extern,
+    Declaration::Register,
+    Declaration::NoStorageClass, // inline
+    Declaration::Fortran
+  };  
+  
+  Declaration::StorageClass ret = Declaration::NoStorageClass;
+  for( std::list< StorageClass >::const_iterator i = storageClasses.begin(); i != storageClasses.end(); ++i ) {
+    assert( unsigned( *i ) < sizeof( scMap ) / sizeof( scMap[0] ) );
+    if( *i == Inline ) continue;
+    if( ret == Declaration::NoStorageClass ) {
+      ret = scMap[ *i ];
+    } else {
+      throw SemanticError( "invalid combination of storage classes in declaration of ", this );
+    }
+  }
+  return ret;
+}
+
+bool 
+DeclarationNode::buildInline() const
+{
+  std::list< StorageClass >::const_iterator first = std::find( storageClasses.begin(), storageClasses.end(), Inline );
+  if( first == storageClasses.end() ) {
+    return false;
+  } else {
+    std::list< StorageClass >::const_iterator next = std::find( ++first, storageClasses.end(), Inline );
+    if( next == storageClasses.end() ) {
+      return true;
+    } else {
+      throw SemanticError( "duplicate inline specification in declaration of ", this );
+    }
+  }
+  // we should never get here
+  return false;
+}
Index: translator/Parser.old/ExpressionNode.cc
===================================================================
--- translator/Parser.old/ExpressionNode.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser.old/ExpressionNode.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,795 @@
+/* -*- C++ -*- */
+#include <cassert>
+#include <cctype>
+#include <algorithm>
+
+#include "ParseNode.h"
+#include "SynTree/Type.h"
+#include "SynTree/Constant.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Declaration.h"
+#include "UnimplementedError.h"
+#include "parseutility.h"
+#include "utility.h"
+
+using namespace std;
+
+/// ExpressionNode::ExpressionNode() : ParseNode(), argName( 0 ) {
+/// }
+
+ExpressionNode::ExpressionNode( std::string *name_, char *filename, int lineno )
+  : ParseNode( *name_, filename, lineno ), argName( 0 )
+{
+  delete name_;
+}
+
+ExpressionNode::ExpressionNode( const ExpressionNode &other )
+  : ParseNode( other.name, other.filename, other.lineno )
+{
+  if( other.argName ) {
+    argName = other.argName->clone();
+  } else {
+    argName = 0;
+  }
+}
+
+ExpressionNode * ExpressionNode::set_asArgName( struct token &tok ) {
+  argName = new VarRefNode( tok );
+  return this;
+}
+
+ExpressionNode * ExpressionNode::set_asArgName( ExpressionNode *aDesignator ) {
+  argName = aDesignator;
+  return this;
+}
+
+void ExpressionNode::printDesignation( std::ostream &os, int indent ) const {
+  if( argName ) {
+    os << string(' ', indent) << "(designated by:  ";
+    argName->printOneLine(os, indent );
+    os << ")" << std::endl;
+  }
+}
+
+NullExprNode::NullExprNode( char *filename, int lineno )
+  : ExpressionNode( &nullstr, filename, lineno )
+{
+}
+
+NullExprNode *
+NullExprNode::clone() const
+{
+  return new NullExprNode( filename, lineno );
+}
+
+void
+NullExprNode::print(std::ostream & os, int indent) const
+{
+  printDesignation(os);
+  os << "null expression";
+}
+
+void
+NullExprNode::printOneLine(std::ostream & os, int indent) const
+{
+  printDesignation(os);
+  os << "null";
+}
+
+Expression *
+NullExprNode::build() const
+{
+  return 0;
+}
+
+CommaExprNode *ExpressionNode::add_to_list(ExpressionNode *exp){
+  return new CommaExprNode(this, exp );
+}
+
+//  enum ConstantNode::Type =  { Integer, Float, Character, String, Range }
+
+/// ConstantNode::ConstantNode() :
+///   ExpressionNode(), sign(true), longs(0), size(0)
+/// {}
+
+ConstantNode::ConstantNode( struct token &tok ) :
+  ExpressionNode( tok.str, tok.filename, tok.lineno ), sign(true), longs(0), size(0)
+{}
+
+ConstantNode::ConstantNode( Type t, struct token &tok ) :
+  ExpressionNode( tok.str, tok.filename, tok.lineno ), type(t), sign(true), longs(0), size(0)
+{
+  if( tok.str ) {
+    value = *tok.str;
+    delete tok.str;
+  } else {
+    value = "";
+  }
+
+  classify(value);
+}
+
+ConstantNode::ConstantNode( const ConstantNode &other )
+  : ExpressionNode( other ), type( other.type ), value( other.value ), sign( other.sign ), base( other.base ), longs( other.longs ), size( other.size )
+{
+}
+
+// for some reason, std::tolower doesn't work as an argument to std::transform in g++ 3.1
+inline char
+tolower_hack( char c )
+{
+  return std::tolower( c );
+}
+
+void ConstantNode::classify(std::string &str){
+  switch(type){
+    case Integer:
+    case Float:
+      {
+	std::string sfx("");
+	char c;
+	int i = str.length() - 1;
+
+	while( i >= 0 && !isxdigit(c = str.at(i--)) )
+	  sfx += c;
+
+	value = str.substr( 0, i + 2 );
+
+	// get rid of underscores
+	value.erase(remove(value.begin(), value.end(), '_'), value.end());
+
+	std::transform(sfx.begin(), sfx.end(), sfx.begin(), tolower_hack);
+
+	if( sfx.find("ll") != string::npos ){
+	  longs = 2;
+	} else if (sfx.find("l") != string::npos ){
+	  longs = 1;
+	}
+
+	assert((longs >= 0) && (longs <= 2));
+
+	if( sfx.find("u") != string::npos )
+	  sign = false;
+
+	break;
+      }
+    case Character:
+      {
+	// remove underscores from hex and oct escapes
+	if(str.substr(1,2) == "\\x")
+	  value.erase(remove(value.begin(), value.end(), '_'), value.end());
+
+	break;
+      }
+  default:
+    // shouldn't be here
+    ;
+  }
+}
+
+ConstantNode::Type ConstantNode::get_type(void) const {
+  return type;
+}
+
+ConstantNode*
+ConstantNode::append( std::string *newValue )
+{
+  if( newValue ) {
+    if (type == String){
+      std::string temp = *newValue;
+      value.resize( value.size() - 1 );
+      value += newValue->substr(1, newValue->size());
+    } else
+      value += *newValue;
+
+    delete newValue;
+  }
+  return this;
+}
+
+void ConstantNode::printOneLine(std::ostream &os, int indent ) const
+{
+  os << string(indent, ' ');
+  printDesignation(os);
+
+  switch( type ) {
+    /* integers */
+  case Integer:
+      os << value ;
+      break;
+  case Float:
+    os << value ;
+    break;
+
+  case Character:
+    os << "'" << value << "'";
+    break;
+
+  case String:
+    os << '"' << value << '"';
+    break;
+  }
+
+  os << ' ';
+}
+
+void ConstantNode::print(std::ostream &os, int indent ) const
+{
+  printOneLine( os, indent );
+  os << endl;
+}
+
+Expression *ConstantNode::build() const {
+  Type::Qualifiers q;
+  BasicType *bt;
+
+  switch(get_type()){
+  case Integer:
+    /* Cfr. standard 6.4.4.1 */
+    //bt.set_kind(BasicType::SignedInt);
+    bt = new BasicType(q, BasicType::SignedInt);
+    break;
+
+  case Float:
+    bt = new BasicType(q, BasicType::Float);
+    break;
+
+  case Character:
+    bt = new BasicType(q, BasicType::Char);
+    break;
+
+  case String:
+    // string should probably be a primitive type
+    ArrayType *at;
+    std::string value = get_value();
+    at = new ArrayType(q, new BasicType(q, BasicType::Char),
+				new ConstantExpr( Constant( new BasicType(q, BasicType::SignedInt),
+									      toString( value.size() - 1 ) ) ),  // account for '\0'
+				false, false );
+
+    return new ConstantExpr( Constant(at, value), maybeBuild< Expression >( get_argName() ) );
+  }
+
+  return new ConstantExpr(  Constant(bt, get_value()),  maybeBuild< Expression >( get_argName() ) );
+}
+
+
+/// VarRefNode::VarRefNode() : isLabel(false) {}
+
+VarRefNode::VarRefNode( struct token &tok, bool labelp ) :
+  ExpressionNode( tok.str, tok.filename, tok.lineno ), isLabel(labelp) {}
+
+VarRefNode::VarRefNode( const VarRefNode &other )
+  : ExpressionNode( other ), isLabel( other.isLabel )
+{
+}
+
+Expression *VarRefNode::build() const {
+  return new NameExpr( get_name(), maybeBuild< Expression >( get_argName() ) );
+}
+
+void VarRefNode::printOneLine(std::ostream &os, int indent ) const {
+  printDesignation(os);
+  os << get_name() << ' ';
+}
+
+void VarRefNode::print(std::ostream &os, int indent ) const {
+  printDesignation(os);
+  os << '\r' << string(indent, ' ') << "Referencing: ";
+
+  os << "Variable: " << get_name();
+
+  os << endl;
+}
+
+std::string nullstr = "";
+
+OperatorNode::OperatorNode( Type t, char *filename, int lineno )
+  : ExpressionNode( &nullstr, filename, lineno ), type(t) {}
+
+OperatorNode::OperatorNode( const OperatorNode &other )
+  : ExpressionNode( other ), type( other.type )
+{
+}
+
+OperatorNode::~OperatorNode() {}
+
+OperatorNode::Type OperatorNode::get_type(void) const{
+  return type;
+}
+
+void OperatorNode::printOneLine( std::ostream &os, int indent ) const
+{
+  printDesignation(os);
+  os << OpName[ type ] << ' ';
+}
+
+void OperatorNode::print( std::ostream &os, int indent ) const{
+  printDesignation(os);
+  os << '\r' << string(indent, ' ') << "Operator: " << OpName[type] << endl;
+
+  return;
+}
+
+std::string OperatorNode::get_typename(void) const{
+  return string(OpName[ type ]);
+}
+
+const char *OperatorNode::OpName[] =
+  { "TupleC",  "Comma", "TupleFieldSel",// "TuplePFieldSel", //n-adic
+    // triadic
+    "Cond",   "NCond",
+    // diadic
+    "SizeOf",      "AlignOf", "CompLit", "Plus",    "Minus",   "Mul",     "Div",     "Mod",      "Or",
+      "And",       "BitOr",   "BitAnd",  "Xor",     "Cast",    "LShift",  "RShift",  "LThan",   "GThan",
+      "LEThan",    "GEThan", "Eq",      "Neq",     "Assign",  "MulAssn", "DivAssn", "ModAssn", "PlusAssn",
+      "MinusAssn", "LSAssn", "RSAssn",  "AndAssn", "ERAssn",  "OrAssn",  "Index",   "FieldSel","PFieldSel",
+      "Range",
+    // monadic
+    "UnPlus", "UnMinus", "AddressOf", "PointTo", "Neg", "BitNeg", "Incr", "IncrPost", "Decr", "DecrPost", "LabelAddress"
+  };
+
+/// CompositeExprNode::CompositeExprNode(void) : ExpressionNode(), function( 0 ), arguments( 0 ) {
+/// }
+
+CompositeExprNode::CompositeExprNode( struct token &tok )
+  : ExpressionNode( tok.str, tok.filename, tok.lineno ), function( 0 ), arguments( 0 )
+{
+}
+
+CompositeExprNode::CompositeExprNode(ExpressionNode *f, ExpressionNode *args)
+  : ExpressionNode( &nullstr, f->filename, min( f->get_lineno(), args->get_lineno() ) ), function(f), arguments(args)
+{
+}
+
+CompositeExprNode::CompositeExprNode(ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2)
+  : ExpressionNode( &nullstr, f->filename, min( f->get_lineno(), arg1->get_lineno() ) ), function(f), arguments(arg1)
+{
+  arguments->set_link(arg2);
+}
+
+CompositeExprNode::CompositeExprNode( const CompositeExprNode &other )
+  : ExpressionNode( other ), function( maybeClone( other.function ) )
+{
+  ParseNode *cur = other.arguments;
+  while( cur ) {
+    if( arguments ) {
+      arguments->set_link( cur->clone() );
+    } else {
+      arguments = (ExpressionNode*)cur->clone();
+    }
+    cur = cur->get_link();
+  }
+}
+
+CompositeExprNode::~CompositeExprNode()
+{
+  delete function;
+  delete arguments;
+}
+
+// the names that users use to define operator functions
+static const char *opFuncName[] =
+  { "",  "", "",
+    "",   "",
+    // diadic
+    "",   "", "", "?+?",    "?-?",   "?*?",     "?/?",     "?%?",     "",       "",
+      "?|?",  "?&?",  "?^?",     "",    "?<<?",  "?>>?",  "?<?",   "?>?",    "?<=?",
+      "?>=?", "?==?",      "?!=?",     "?=?",  "?*=?", "?/=?", "?%=?", "?+=?", "?-=?",
+      "?<<=?", "?>>=?",  "?&=?", "?^=?",  "?|=?",  "?[?]",   "","","Range",
+    // monadic
+    "+?", "-?", "", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "LabAddress"
+  };
+
+Expression *CompositeExprNode::build() const {
+  OperatorNode *op;
+  std::list<Expression *> args;
+
+  buildList(get_args(), args);
+
+  if (!( op = dynamic_cast<OperatorNode *>(function)) ){
+    // a function as opposed to an operator
+    return new UntypedExpr(function->build(), args, maybeBuild< Expression >( get_argName() ));
+
+  } else {
+
+    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:
+      // 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(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:
+    case OperatorNode::PointTo:
+    case OperatorNode::Neg:
+    case OperatorNode::BitNeg:
+    case OperatorNode::LabelAddress:
+      return new UntypedExpr( new NameExpr( opFuncName[ 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( expr_node->build(), maybeBuild< Expression >( get_argName() ) );
+        } else {
+          return new CastExpr(expr_node->build(),targetType, maybeBuild< Expression >( get_argName() ) );
+        }
+      }
+
+    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::AlignOf:
+    case OperatorNode::SizeOf:
+      {
+/// 	bool isSizeOf = (op->get_type() == OperatorNode::SizeOf);
+
+	if( TypeValueNode * arg = dynamic_cast<TypeValueNode *>(get_args()) ) {
+          return new SizeofExpr(arg->get_decl()->buildType());
+        } else {
+	  return new SizeofExpr(args.front());
+        }
+      }
+
+    case OperatorNode::CompLit:
+      throw UnimplementedError( "C99 compound literals" );
+
+      // the short-circuited operators
+    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:
+      {
+        assert(args.size() == 3);
+        std::list< Expression* >::const_iterator i = args.begin();
+        Expression *arg1 = notZeroExpr( *i++ );
+        Expression *arg2 = *i++;
+        Expression *arg3 = *i++;
+        return new ConditionalExpr( arg1, arg2, arg3 );
+      }
+
+    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:
+      {
+        TupleExpr *ret = new TupleExpr();
+        std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) );
+        return ret;
+      }
+
+    default:
+      // shouldn't happen
+      return 0;
+    }
+  }
+}
+
+void CompositeExprNode::printOneLine(std::ostream &os, int indent) const
+{
+  printDesignation(os);
+  os << "( ";
+  function->printOneLine( os, indent );
+  for( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
+    cur->printOneLine( os, indent );
+  }
+  os << ") ";
+}
+
+void CompositeExprNode::print(std::ostream &os, int indent) const
+{
+  printDesignation(os);
+  os << '\r' << string(indent, ' ') << "Application of: " << endl;
+  function->print( os, indent + ParseNode::indent_by );
+
+  os << '\r' << string(indent, ' ') ;
+  if( arguments ) {
+    os << "... on arguments: " << endl;
+    arguments->printList(os, indent + ParseNode::indent_by);
+  } else
+    os << "... on no arguments: " << endl;
+}
+
+void CompositeExprNode::set_function(ExpressionNode *f){
+  function = f;
+}
+
+void CompositeExprNode::set_args(ExpressionNode *args){
+  arguments = args;
+}
+
+ExpressionNode *CompositeExprNode::get_function(void) const {
+  return function;
+}
+
+ExpressionNode *CompositeExprNode::get_args(void) const {
+  return arguments;
+}
+
+void CompositeExprNode::add_arg(ExpressionNode *arg){
+  if(arguments)
+    arguments->set_link(arg);
+  else
+    set_args(arg);
+}
+
+/// CommaExprNode::CommaExprNode(): CompositeExprNode(new OperatorNode(OperatorNode::Comma)) {}
+
+CommaExprNode::CommaExprNode(ExpressionNode *exp)
+  : CompositeExprNode( new OperatorNode( OperatorNode::Comma, exp->get_filename(), exp->get_lineno() ), exp )
+ {
+ }
+
+CommaExprNode::CommaExprNode(ExpressionNode *exp1, ExpressionNode *exp2)
+  : CompositeExprNode(new OperatorNode(OperatorNode::Comma, exp1->get_filename(), exp1->get_lineno()), exp1, exp2)
+{
+}
+
+CommaExprNode *CommaExprNode::add_to_list(ExpressionNode *exp){
+  add_arg(exp);
+
+  return this;
+}
+
+CommaExprNode::CommaExprNode( const CommaExprNode &other )
+  : CompositeExprNode( other )
+{
+}
+
+ValofExprNode::ValofExprNode(StatementNode *s)
+  : ExpressionNode( &nullstr, s->get_filename(), s->get_lineno() ), body(s)
+{
+}
+
+ValofExprNode::ValofExprNode( const ValofExprNode &other )
+  : ExpressionNode( other ), body( maybeClone( body ) )
+{
+}
+
+ValofExprNode::~ValofExprNode() {
+  delete body;
+}
+
+void ValofExprNode::print( std::ostream &os, int indent ) const {
+  printDesignation(os);
+  os << string(indent, ' ') << "Valof Expression:" << std::endl;
+  get_body()->print(os, indent + 4);
+}
+
+void ValofExprNode::printOneLine( std::ostream &, int indent ) const
+{
+  assert( false );
+}
+
+Expression *ValofExprNode::build() const {
+  return new UntypedValofExpr ( get_body()->build(), maybeBuild< Expression >( get_argName() ) );
+}
+
+ForCtlExprNode::ForCtlExprNode(ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr)
+  throw (SemanticError)
+  : ExpressionNode( &nullstr, init_->get_filename(), init_->get_lineno() ), condition(cond), change(incr)
+{
+  if(init_ == 0)
+    init = 0;
+  else {
+    DeclarationNode *decl;
+    ExpressionNode *exp;
+
+    if((decl = dynamic_cast<DeclarationNode *>(init_)) != 0)
+      init = new StatementNode(decl);
+    else if((exp = dynamic_cast<ExpressionNode *>(init_)) != 0)
+      init = new StatementNode(StatementNode::Exp, exp->get_filename(), exp->get_lineno(), exp);
+    else
+      throw SemanticError("Error in for control expression");
+  }
+}
+
+ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
+  : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) )
+{
+}
+
+ForCtlExprNode::~ForCtlExprNode(){
+  delete init;
+  delete condition;
+  delete change;
+}
+
+Expression *ForCtlExprNode::build() const {
+  // this shouldn't be used!
+  assert( false );
+  return 0;
+}
+
+void ForCtlExprNode::print( std::ostream &os, int indent ) const{
+  os << string(indent,' ') << "For Control Expression -- : " << endl;
+
+  os << "\r" << string(indent + 2,' ') << "initialization: ";
+  if(init != 0)
+    init->print(os, indent + 4);
+
+  os << "\n\r" << string(indent + 2,' ') << "condition: ";
+  if(condition != 0)
+    condition->print(os, indent + 4);
+  os << "\n\r" << string(indent + 2,' ') << "increment: ";
+  if(change != 0)
+    change->print(os, indent + 4);
+}
+
+void
+ForCtlExprNode::printOneLine( std::ostream &, int indent ) const
+{
+  assert( false );
+}
+
+TypeValueNode::TypeValueNode(DeclarationNode *decl)
+  : ExpressionNode( &nullstr, decl->get_filename(), decl->get_lineno() ), decl( decl )
+{
+}
+
+TypeValueNode::TypeValueNode( const TypeValueNode &other )
+  : ExpressionNode( other ), decl( maybeClone( other.decl ) )
+{
+}
+
+Expression *
+TypeValueNode::build() const
+{
+  return new TypeExpr( decl->buildType() );
+}
+
+void
+TypeValueNode::print(std::ostream &os, int indent) const
+{
+  os << std::string( indent, ' ' ) << "Type:";
+  get_decl()->print(os, indent + 2);
+}
+
+void
+TypeValueNode::printOneLine(std::ostream &os, int indent) const
+{
+  os << "Type:";
+  get_decl()->print(os, indent + 2);
+}
+
+ExpressionNode *flattenCommas( ExpressionNode *list )
+{
+  if( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) )
+    {
+      OperatorNode *op;
+           if ( (op = dynamic_cast< OperatorNode * >( composite->get_function() )) && (op->get_type() == OperatorNode::Comma) )
+	     {
+	         if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
+		   composite->add_arg( next );
+		 return flattenCommas( composite->get_args() );
+	     }
+    }
+
+  if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
+    list->set_next( flattenCommas( next ) );
+
+  return list;
+}
+
+// Local Variables: //
+// mode: C++                //
+// compile-command: "gmake" //
+// End: //
Index: translator/Parser.old/InitializerNode.cc
===================================================================
--- translator/Parser.old/InitializerNode.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser.old/InitializerNode.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,107 @@
+#include "ParseNode.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Initializer.h"
+#include "utility.h"
+#include "SemanticError.h"
+// #include <cstdlib> // for strtol
+#include <cassert>
+
+InitializerNode::InitializerNode( ExpressionNode *_expr, bool aggrp, ExpressionNode *des )
+  : ParseNode( "", _expr->get_filename(), _expr->get_lineno() ), expr( _expr ), aggregate( aggrp ), designator( des ), kids( 0 )
+{
+  if( des && des->get_lineno() < lineno ) {
+    lineno = des->get_lineno();
+  }
+
+  if ( aggrp )
+    kids = dynamic_cast< InitializerNode *>( get_link() );
+
+  if ( kids != 0 )
+    set_link( 0 );
+}
+
+InitializerNode::InitializerNode( InitializerNode *init, bool aggrp, ExpressionNode *des )
+  : ParseNode( "", init->get_filename(), init->get_lineno() ), aggregate( aggrp ), designator( des ), kids( 0 )
+{
+  if( des && des->get_lineno() < lineno ) {
+    lineno = des->get_lineno();
+  }
+
+  if (init != 0)
+    set_link(init);
+
+  if ( aggrp )
+      kids = dynamic_cast< InitializerNode *>( get_link() );
+
+  if ( kids != 0 )
+    set_next( 0 );
+}
+
+InitializerNode::~InitializerNode() {
+  delete expr;
+}
+
+void InitializerNode::print( std::ostream &os, int indent ) const {
+  os << std::string(indent, ' ') << "Initializer expression" << std::endl;
+}
+
+void InitializerNode::printOneLine( std::ostream &os ) const {
+  if (!aggregate)
+    {
+
+      if ( designator != 0 )
+	{
+	  os << "designated by: (";
+	  ExpressionNode  *curdes = designator;
+	  while( curdes != 0){
+	    curdes->printOneLine(os);
+	    curdes = (ExpressionNode *)(curdes->get_link());
+	    if(curdes) os << ", ";
+	  }
+	  os << ")";
+	}
+
+      if (expr) expr->printOneLine(os);
+    }
+  else  // It's an aggregate
+    {
+      os << "[";
+      if( next_init() != 0 ) 
+	next_init()->printOneLine(os);
+
+      if (aggregate) os << "]";
+    }
+  
+  InitializerNode * moreInit;
+  if  ( get_link() != 0 && ((moreInit = dynamic_cast< InitializerNode * >( get_link() ) ) != 0) ) 
+    moreInit->printOneLine( os );
+}
+
+Initializer *InitializerNode::build() const {
+  if ( aggregate )
+    {
+      assert( next_init() != 0 );
+
+      std::list< Initializer *> initlist;
+      buildList<Initializer, InitializerNode>( next_init(), initlist );
+
+      std::list< Expression *> designlist;
+      if ( designator != 0 )
+	buildList<Expression, ExpressionNode>( designator, designlist );
+
+      return new ListInit( initlist, designlist );
+    }
+  else
+    {
+      std::list< Expression *> designators;
+
+      if ( designator != 0 ) 
+	buildList<Expression, ExpressionNode>( designator, designators );
+
+      return new SingleInit( get_expression()->build(), designators );
+    }
+
+  return 0;  // shouldn't be here
+}
+
+
Index: translator/Parser.old/LinkageSpec.cc
===================================================================
--- translator/Parser.old/LinkageSpec.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser.old/LinkageSpec.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,111 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: LinkageSpec.cc,v 1.3 2003/01/29 14:55:08 rcbilson Exp $
+ *
+ */
+
+#include <string>
+#include <cassert>
+
+#include "LinkageSpec.h"
+#include "SemanticError.h"
+
+/* static class method */
+LinkageSpec::Type 
+LinkageSpec::fromString( const std::string &stringSpec )
+{
+  if( stringSpec == "\"Cforall\"" ) {
+    return Cforall;
+  } else if( stringSpec == "\"C\"" ) {
+    return C;
+  } else {
+    throw SemanticError( "Invalid linkage specifier " + stringSpec );
+  }
+}
+
+/* static class method */
+std::string 
+LinkageSpec::toString( LinkageSpec::Type linkage )
+{
+  switch( linkage ) {
+  case Intrinsic:
+    return "intrinsic";
+    
+  case Cforall:
+    return "Cforall";
+    
+  case C:
+    return "C";
+    
+  case AutoGen:
+    return "automatically generated";
+    
+  case Compiler:
+    return "compiler built-in";
+  }
+  assert( false );
+  return "";
+}
+
+/* static class method */
+bool 
+LinkageSpec::isDecoratable( Type t )
+{
+  switch( t ) {
+  case Intrinsic:
+  case Cforall:
+  case AutoGen:
+    return true;
+    
+  case C:
+  case Compiler:
+    return false;
+  }
+  assert( false );
+  return false;
+}
+
+/* static class method */
+bool 
+LinkageSpec::isGeneratable( Type t )
+{
+  switch( t ) {
+  case Intrinsic:
+  case Cforall:
+  case AutoGen:
+  case C:
+    return true;
+    
+  case Compiler:
+    return false;
+  }
+  assert( false );
+  return false;
+}
+
+/* static class method */
+bool 
+LinkageSpec::isOverloadable( Type t )
+{
+  return isDecoratable( t );
+}
+
+/* static class method */
+bool 
+LinkageSpec::isBuiltin( Type t )
+{
+  switch( t ) {
+  case Cforall:
+  case AutoGen:
+  case C:
+    return false;
+    
+  case Intrinsic:
+  case Compiler:
+    return true;
+  }
+  assert( false );
+  return false;
+}
+
Index: translator/Parser.old/LinkageSpec.h
===================================================================
--- translator/Parser.old/LinkageSpec.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser.old/LinkageSpec.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,33 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: LinkageSpec.h,v 1.3 2003/01/29 14:55:08 rcbilson Exp $
+ *
+ */
+
+#ifndef LINKAGESPEC_H
+#define LINKAGESPEC_H
+
+#include <string>
+
+struct LinkageSpec
+{
+  enum Type
+  {
+    Intrinsic,		// C built-in defined in prelude
+    Cforall,		// ordinary
+    C,			// not overloadable, not mangled
+    AutoGen,		// built by translator (struct assignment)
+    Compiler		// gcc internal
+  };
+  
+  static Type fromString( const std::string& );
+  static std::string toString( Type );
+  
+  static bool isDecoratable( Type );
+  static bool isGeneratable( Type );
+  static bool isOverloadable( Type );
+  static bool isBuiltin( Type );
+};
+
+#endif /* #ifndef LINKAGESPEC_H */
Index: translator/Parser.old/ParseNode.cc
===================================================================
--- translator/Parser.old/ParseNode.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser.old/ParseNode.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,97 @@
+/* -*- C++ -*- */
+#include "ParseNode.h"
+using namespace std;
+
+// Builder
+int ParseNode::indent_by = 4;
+
+// ParseNode::ParseNode(void): next( 0 ) {};
+ParseNode::ParseNode( std::string _name, char *filename, int lineno )
+  : name(_name), next( 0 ), filename( filename ), lineno( lineno )
+{
+}
+
+ParseNode *ParseNode::set_name (string _name) {
+  name = _name;
+
+  return this;
+}
+
+ParseNode *ParseNode::set_name (string *_name) {
+  name = *_name; // deep copy
+  delete _name;
+
+  return this;
+}
+
+ParseNode::~ParseNode(void){
+  delete next;
+};
+
+string ParseNode::get_name(void) {
+  return name;
+}
+
+ParseNode *ParseNode::get_link(void) const {
+  return next;
+}
+
+ParseNode *ParseNode::get_last(void) {
+  ParseNode * current = this;
+
+  while(current->get_link() != 0)
+    current = current->get_link();
+
+  return current;
+}
+
+ParseNode *ParseNode::set_link(ParseNode *_next){
+  ParseNode *follow;
+
+  if(_next == 0) return this;
+
+  for(follow = this; follow->next != 0; follow = follow->next);
+  follow->next = _next;
+
+  return this;
+}
+
+const string ParseNode::get_name(void) const {
+  return name;
+}
+
+void ParseNode::print(std::ostream &os, int indent) const
+{
+}
+
+
+void ParseNode::printList(std::ostream &os, int indent) const
+{
+  print( os, indent );
+
+  if( next ) {
+    next->printList( os, indent );
+  }
+}
+
+ParseNode &ParseNode::operator,(ParseNode &p){
+  set_link(&p);
+
+  return *this;
+}
+
+ParseNode *mkList(ParseNode &pn){
+  /* it just relies on `operator,' to take care of the "arguments" and provides
+     a nice interface to an awful-looking address-of, rendering, for example
+         (StatementNode *)(&(*$5 + *$7)) into (StatementNode *)mkList(($5, $7))
+     (although "nice"  is probably not the word)
+  */
+
+  return &pn;
+}
+
+
+// Local Variables: //
+// mode: C++                //
+// compile-command: "gmake" //
+// End: //
Index: translator/Parser.old/ParseNode.h
===================================================================
--- translator/Parser.old/ParseNode.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser.old/ParseNode.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,525 @@
+#ifndef PARSENODE_H
+#define PARSENODE_H
+
+#include <iostream>
+#include <string>
+#include <list>
+#include <iterator>
+
+#include "lex.h"
+#include "utility.h"
+#include "SynTree/SynTree.h"
+#include "SynTree/Declaration.h"
+#include "SemanticError.h"
+#include "UniqueName.h"
+
+class ExpressionNode;
+class CompositeExprNode;
+class CommaExprNode;
+class StatementNode;
+class CompoundStmtNode;
+class DeclarationNode;
+class InitializerNode;
+
+// Builder
+class ParseNode {
+public:
+//  ParseNode(void);
+  ParseNode( std::string, char *filename, int lineno );
+  virtual ~ParseNode(void);
+
+  ParseNode *set_name (std::string) ;
+  ParseNode *set_name (std::string *) ;
+
+  std::string get_name(void);
+
+  ParseNode *get_link(void) const;
+  ParseNode *get_last(void);
+  ParseNode *set_link(ParseNode *);
+  void set_next( ParseNode *newlink ) { next = newlink; }
+
+  char *get_filename() const { return filename; }
+  int get_lineno() const { return lineno; }
+
+  virtual ParseNode *clone() const { return 0; };
+
+  const std::string get_name(void) const;
+  virtual void print( std::ostream &, int indent = 0 ) const;
+  virtual void printList( std::ostream &, int indent = 0 ) const;
+
+  ParseNode &operator,(ParseNode &);
+
+protected:
+  std::string name;
+  ParseNode *next;
+  static int indent_by;
+  char *filename;
+  int lineno;
+};
+
+ParseNode *mkList(ParseNode &);
+
+class ExpressionNode : public ParseNode {
+public:
+//  ExpressionNode();
+  ExpressionNode( std::string*, char *filename, int lineno );
+  ExpressionNode( const ExpressionNode &other );
+  virtual ~ExpressionNode() { /* can't delete asArgName because it might be referenced elsewhere */ };
+
+  virtual ExpressionNode *clone() const = 0;
+
+  virtual CommaExprNode *add_to_list(ExpressionNode *);
+
+  ExpressionNode *get_argName() const { return argName; }
+  ExpressionNode *set_asArgName( std::string *aName );
+  ExpressionNode *set_asArgName( ExpressionNode *aDesignator );
+
+  virtual void print(std::ostream &, int indent = 0) const = 0;
+  virtual void printOneLine(std::ostream &, int indent = 0) const = 0;
+
+  virtual Expression *build() const = 0;
+protected:
+  void printDesignation (std::ostream &, int indent = 0) const;
+
+private:
+  ExpressionNode *argName;
+};
+
+// NullExprNode is used in tuples as a place-holder where a tuple component is omitted
+// e.g., [ 2, , 3 ]
+class NullExprNode : public ExpressionNode
+{
+public:
+  NullExprNode( char *filename, int lineno );
+
+  virtual NullExprNode *clone() const;
+
+  virtual void print(std::ostream &, int indent = 0) const;
+  virtual void printOneLine(std::ostream &, int indent = 0) const;
+
+  virtual Expression *build() const;
+};
+
+class ConstantNode : public ExpressionNode {
+public:
+  enum Type {
+    Integer, Float, Character, String /* , Range, EnumConstant  */
+  };
+
+  ConstantNode();
+  ConstantNode( struct token & );
+  ConstantNode( Type, struct token & );
+  ConstantNode( const ConstantNode &other );
+
+  virtual ConstantNode *clone() const { return new ConstantNode( *this ); }
+
+  Type get_type(void) const ;
+  virtual void print(std::ostream &, int indent = 0) const;
+  virtual void printOneLine(std::ostream &, int indent = 0) const;
+
+  std::string get_value() const { return value; }
+  ConstantNode *append( std::string *newValue );
+
+  Expression *build() const;
+
+private:
+  void classify(std::string &);
+  Type type;
+  std::string value;
+  bool sign;
+  short base;
+  int longs, size;
+};
+
+class VarRefNode : public ExpressionNode {
+public:
+  VarRefNode();
+  VarRefNode( struct token &tok, bool isLabel = false );
+  VarRefNode( const VarRefNode &other );
+
+  virtual Expression *build() const ;
+
+  virtual VarRefNode *clone() const { return new VarRefNode( *this ); }
+
+  virtual void print(std::ostream &, int indent = 0) const;
+  virtual void printOneLine(std::ostream &, int indent = 0) const;
+private:
+  bool isLabel;
+};
+
+class TypeValueNode : public ExpressionNode
+{
+public:
+  TypeValueNode(DeclarationNode *);
+  TypeValueNode( const TypeValueNode &other );
+
+  DeclarationNode *get_decl() const { return decl; }
+
+  virtual Expression *build() const ;
+
+  virtual TypeValueNode *clone() const { return new TypeValueNode( *this ); }
+
+  virtual void print(std::ostream &, int indent = 0) const;
+  virtual void printOneLine(std::ostream &, int indent = 0) const;
+private:
+  DeclarationNode *decl;
+};
+
+class OperatorNode : public ExpressionNode {
+public:
+  enum Type { TupleC, Comma, TupleFieldSel,
+              Cond, NCond, 
+	      SizeOf, AlignOf, CompLit, Plus, Minus, Mul, Div, Mod, Or, And, 
+	        BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq, 
+	        Assign, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn, 
+	        ERAssn, OrAssn, Index, FieldSel, PFieldSel, Range,
+              UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, LabelAddress
+            };
+
+  OperatorNode(Type t, char *filename, int lineno);
+  OperatorNode( const OperatorNode &other );
+  virtual ~OperatorNode();
+
+  virtual OperatorNode *clone() const { return new OperatorNode( *this ); }
+
+  Type get_type(void) const;
+  std::string get_typename(void) const;
+
+  virtual void print(std::ostream &, int indent = 0) const;
+  virtual void printOneLine(std::ostream &, int indent = 0) const;
+
+  virtual Expression *build() const { return 0; }
+  
+private:
+  Type type;
+  static const char *OpName[];
+};
+
+
+class CompositeExprNode : public ExpressionNode {
+public:
+//  CompositeExprNode(void);
+  CompositeExprNode( struct token & );
+  CompositeExprNode(ExpressionNode *f, ExpressionNode *args = 0);
+  CompositeExprNode(ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2);
+  CompositeExprNode( const CompositeExprNode &other );
+  virtual ~CompositeExprNode();
+
+  virtual CompositeExprNode *clone() const { return new CompositeExprNode( *this ); }
+  virtual Expression *build() const;
+
+  virtual void print(std::ostream &, int indent = 0) const;
+  virtual void printOneLine(std::ostream &, int indent = 0) const;
+
+  void set_function(ExpressionNode *);
+  void set_args(ExpressionNode *);
+
+  void add_arg(ExpressionNode *);
+
+  ExpressionNode *get_function() const;
+  ExpressionNode *get_args() const;
+
+private:
+  ExpressionNode *function;
+  ExpressionNode *arguments;
+};
+
+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 ); }
+};
+
+class ForCtlExprNode : public ExpressionNode {
+public:
+  ForCtlExprNode(ParseNode *, ExpressionNode *, ExpressionNode *) throw (SemanticError);
+  ForCtlExprNode( const ForCtlExprNode &other );
+  ~ForCtlExprNode();
+
+  StatementNode *get_init() const { return init; }
+  ExpressionNode *get_condition() const { return condition; }
+  ExpressionNode *get_change() const { return change; }
+
+  virtual ForCtlExprNode *clone() const { return new ForCtlExprNode( *this ); }
+  virtual Expression *build() const;
+
+  virtual void print( std::ostream &, int indent = 0 ) const;
+  virtual void printOneLine( std::ostream &, int indent = 0 ) const;
+private:
+  StatementNode *init;
+  ExpressionNode *condition;
+  ExpressionNode *change;
+};
+
+class ValofExprNode : public ExpressionNode {
+public:
+//  ValofExprNode();
+  ValofExprNode( StatementNode *s = 0 );
+  ValofExprNode( const ValofExprNode &other );
+  ~ValofExprNode();
+  
+  virtual ValofExprNode *clone() const { return new ValofExprNode( *this ); }
+
+  StatementNode *get_body() const { return body; }
+  void print( std::ostream &, int indent = 0 ) const;
+  void printOneLine( std::ostream &, int indent = 0 ) const;
+  Expression *ValofExprNode::build() const;
+
+private:
+  StatementNode *body;
+};
+
+class TypeData;
+
+class DeclarationNode : public ParseNode
+{
+public:
+  enum Qualifier { Const, Restrict, Volatile, Lvalue };
+  enum StorageClass { Static, Auto, Extern, Register, Inline, Fortran };
+  enum BasicType { Char, Int, Float, Double, Void, Bool, Complex, Imaginary };
+  enum Modifier { Signed, Unsigned, Short, Long };
+  enum TyCon { Struct, Union, Context };
+  enum TypeClass { Type, Dtype, Ftype };
+
+  static const char *qualifierName[];
+  static const char *basicTypeName[];
+  static const char *modifierName[];
+  static const char *tyConName[];
+  static const char *typeClassName[];
+
+  static DeclarationNode *newFunction( struct token &name, DeclarationNode *ret, DeclarationNode *param,
+				       StatementNode *body );
+  static DeclarationNode *newFunction( char *filename, int lineno, DeclarationNode *ret, DeclarationNode *param,
+				       StatementNode *body );
+  static DeclarationNode *newQualifier( Qualifier, char *filename, int lineno );
+  static DeclarationNode *newStorageClass( StorageClass, char *filename, int lineno );
+  static DeclarationNode *newBasicType( BasicType, char *filename, int lineno );
+  static DeclarationNode *newModifier( Modifier, char *filename, int lineno );
+  static DeclarationNode *newForall( DeclarationNode*, char *filename, int lineno );
+  static DeclarationNode *newFromTypedef( struct token & );
+  static DeclarationNode *newAggregate( TyCon kind, char *filename, int lineno, DeclarationNode *formals, ExpressionNode *actuals, DeclarationNode *fields );
+  static DeclarationNode *newAggregate( TyCon kind, struct token &, DeclarationNode *formals, ExpressionNode *actuals, DeclarationNode *fields );
+  static DeclarationNode *newEnum( struct token &, DeclarationNode *constants );
+  static DeclarationNode *newEnum( char *filename, int lineno, DeclarationNode *constants );
+  static DeclarationNode *newEnumConstant( struct token &name, ExpressionNode *constant );
+  static DeclarationNode *newName( struct token &tok );
+  static DeclarationNode *newFromTypeGen( struct token &tok, ExpressionNode *params );
+  static DeclarationNode *newTypeParam( TypeClass, std::string*, char *filename, int lineno );
+  static DeclarationNode *newContext( struct token &name, DeclarationNode *params, DeclarationNode *asserts );
+  static DeclarationNode *newContextUse( struct token &name, ExpressionNode *params );
+  static DeclarationNode *newTypeDecl( struct token &name, DeclarationNode *typeParams );
+  static DeclarationNode *newPointer( DeclarationNode *qualifiers, char *filename, int lineno );
+  static DeclarationNode *newArray( ExpressionNode *size, DeclarationNode *qualifiers, bool isStatic, char *filename, int lineno );
+  static DeclarationNode *newVarArray( DeclarationNode *qualifiers, char *filename, int lineno );
+  static DeclarationNode *newBitfield( ExpressionNode *size );
+  static DeclarationNode *newTuple( DeclarationNode *members, char *filename, int lineno );
+  static DeclarationNode *newTypeof( ExpressionNode *expr, char *filename, int lineno );
+
+  DeclarationNode *addQualifiers( DeclarationNode* );
+  DeclarationNode *copyStorageClasses( DeclarationNode* );
+  DeclarationNode *addType( DeclarationNode* );
+  DeclarationNode *addTypedef();
+  DeclarationNode *addAssertions( DeclarationNode* );
+  DeclarationNode *addName( struct token & );
+  DeclarationNode *addBitfield( ExpressionNode *size );
+  DeclarationNode *addVarArgs();
+  DeclarationNode *addFunctionBody( StatementNode *body );
+  DeclarationNode *addOldDeclList( DeclarationNode *list );
+  DeclarationNode *addPointer( DeclarationNode *qualifiers );
+  DeclarationNode *addArray( DeclarationNode *array );
+  DeclarationNode *addNewPointer( DeclarationNode *pointer );
+  DeclarationNode *addNewArray( DeclarationNode *array );
+  DeclarationNode *addParamList( DeclarationNode *list );
+  DeclarationNode *addIdList( DeclarationNode *list );       // old-style functions
+  DeclarationNode *addInitializer( InitializerNode *init );
+
+  DeclarationNode *cloneType( struct token &newName );
+  DeclarationNode *cloneType( DeclarationNode *existing );
+  DeclarationNode *cloneBaseType( struct token &newName );
+  DeclarationNode *cloneBaseType( DeclarationNode *newdecl );
+
+  DeclarationNode *appendList( DeclarationNode * );
+
+  DeclarationNode *clone() const;
+  void print( std::ostream &, int indent = 0 ) const;
+  void printList( std::ostream &, int indent = 0 ) const;
+
+  Declaration *build() const;
+  Type *buildType() const;
+
+  bool get_hasEllipsis() const;
+  std::string get_name() const { return name; }
+  LinkageSpec::Type get_linkage() const { return linkage; }
+  DeclarationNode *extractAggregate() const;
+
+  DeclarationNode( char *filename, int lineno );
+  ~DeclarationNode();
+private:
+  Declaration::StorageClass buildStorageClass() const;
+  bool buildInline() const;
+
+  TypeData *type;
+  std::string name;
+  std::list< StorageClass > storageClasses;
+  ExpressionNode *bitfieldWidth;
+  InitializerNode *initializer;
+  bool hasEllipsis;
+  LinkageSpec::Type linkage;
+
+  static UniqueName anonymous;
+};
+
+class StatementNode : public ParseNode {
+public:
+  enum Type { Exp,   If,        Switch,  Case,    Default,  Choose,   Fallthru, 
+              While, Do,        For,
+              Goto,  Continue,  Break,   Return,  Throw,
+              Try,   Catch,     Asm,
+	      Decl
+            };
+
+///   StatementNode( void );
+  StatementNode( struct token &tok );
+  StatementNode( char *filename, int lineno );
+  StatementNode( Type, char *filename, int lineno, ExpressionNode *e = 0, StatementNode *s = 0 );
+  StatementNode( Type, char *filename, int lineno, std::string *target );
+  StatementNode( DeclarationNode *decl );
+
+
+  ~StatementNode(void);
+
+  static StatementNode * newCatchStmt( char *filename, int lineno, DeclarationNode *d = 0, StatementNode *s = 0, bool catchRestP = false );
+
+  void set_control(ExpressionNode *);
+  StatementNode * set_block(StatementNode *);
+
+  ExpressionNode *get_control() const ;
+  StatementNode *get_block() const;
+  StatementNode::Type get_type(void) const;
+
+  StatementNode *add_label( struct token & );
+  std::list<std::string> *get_labels() const;
+
+  void addDeclaration( DeclarationNode *newDecl ) { decl = newDecl; }
+  void setCatchRest( bool newVal ) { isCatchRest = newVal; }
+
+  std::string get_target() const;
+
+  StatementNode *add_controlexp(ExpressionNode *);
+  StatementNode *append_block(StatementNode *);
+  StatementNode *append_last_case(StatementNode *);
+
+  void print( std::ostream &, int indent = 0) const;
+
+  virtual StatementNode *clone() const;
+
+  virtual Statement *build() const;
+
+private:
+  static const char *StType[];
+  Type type;
+  ExpressionNode *control;
+  StatementNode *block;
+  std::list<std::string> *labels;
+  std::string *target; // target label for jump statements
+  DeclarationNode *decl;
+
+  bool isCatchRest;
+};
+
+class CompoundStmtNode : public StatementNode {
+public:
+//  CompoundStmtNode(void);
+  CompoundStmtNode( struct token & );
+  CompoundStmtNode( char *filename, int lineno );
+  CompoundStmtNode(StatementNode *);
+  ~CompoundStmtNode();
+
+  void add_statement(StatementNode *);
+
+  void print( std::ostream &, int indent = 0 ) const;
+
+  virtual Statement *build() const;
+
+private:
+  StatementNode *first, *last;
+};
+
+class NullStmtNode : public CompoundStmtNode {
+public:
+  NullStmtNode( char *filename, int lineno ) : CompoundStmtNode( filename, lineno ) {}
+  Statement *build() const;
+  void print(std::ostream &, int indent = 0) const;
+};
+
+class InitializerNode : public ParseNode {
+public:
+  InitializerNode( ExpressionNode *, bool aggrp = false,  ExpressionNode *des = 0 );
+  InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode *des = 0 );
+  ~InitializerNode();
+
+  ExpressionNode *get_expression() const { return expr; }
+
+  InitializerNode *set_designators( ExpressionNode *des ) { designator = des;  return this; }
+  ExpressionNode *get_designators() const { return designator; }
+
+  InitializerNode *next_init() const { return kids; }
+
+  void print( std::ostream &, int indent = 0 ) const;
+  void printOneLine( std::ostream & ) const;
+
+  virtual Initializer *build() const;
+
+private:
+  ExpressionNode *expr;
+  bool aggregate;
+  ExpressionNode *designator; // may be list
+  InitializerNode *kids;
+};
+
+
+
+template< typename SynTreeType, typename NodeType >
+void
+buildList( const NodeType *firstNode, std::list< SynTreeType* > &outputList )
+{
+  SemanticError errors;
+  std::back_insert_iterator< std::list< SynTreeType* > > out( outputList );
+  const NodeType *cur = firstNode;
+
+  while( cur ) {
+    try {
+      SynTreeType *result = dynamic_cast< SynTreeType* >( cur->build() );
+      if( result ) {
+        *out++ = result;
+      } else {
+      }
+    } catch( SemanticError &e ) {
+      errors.append( e );
+    }
+    cur = dynamic_cast< NodeType* >( cur->get_link() );
+  }
+  if( !errors.isEmpty() ) {
+    throw errors;
+  }
+}
+
+// in DeclarationNode.cc
+void buildList( const DeclarationNode *firstNode, std::list< Declaration* > &outputList );
+void buildList( const DeclarationNode *firstNode, std::list< DeclarationWithType* > &outputList );
+void buildTypeList( const DeclarationNode *firstNode, std::list< Type* > &outputList );
+
+// in ExpressionNode.cc
+ExpressionNode *flattenCommas( ExpressionNode *list );
+
+#endif /* #ifndef PARSENODE_H */
+
+// Local Variables: //
+// mode: C++ //
+// compile-command: "gmake" //
+// End: //
Index: translator/Parser.old/Parser.cc
===================================================================
--- translator/Parser.old/Parser.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser.old/Parser.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Parser.cc,v 1.6 2002/11/15 20:07:18 rcbilson Exp $
+ *
+ */
+
+#include "Parser.h"
+#include "TypedefTable.h"
+#include "lex.h"
+#include "cfa.tab.h"
+
+/* global variables in cfa.y */
+extern int yyparse(void);
+
+extern int yydebug;
+extern LinkageSpec::Type linkage;
+
+extern TypedefTable typedefTable;
+extern DeclarationNode *theTree;
+/* end of globals */
+
+Parser *Parser::theParser = 0;
+
+Parser::Parser(): parseTree( 0 ), parseStatus( 1 ) {}
+
+Parser::~Parser()
+{
+  delete parseTree;
+}
+
+/* static class method */
+Parser &
+Parser::get_parser()
+{
+  if( theParser == 0 ) {
+    theParser = new Parser;
+  }
+  return *theParser;
+}
+
+void 
+Parser::parse( FILE *input )
+{
+  extern FILE *yyin;
+  yyin = input;
+  extern int yylineno;
+  yylineno = 1;
+  typedefTable.enterScope();
+  parseStatus = yyparse();
+  parseTree = theTree;
+}
+
+void
+Parser::set_debug( bool debug )
+{
+  yydebug = debug;
+}
+
+void 
+Parser::set_linkage( LinkageSpec::Type linkage )
+{
+  ::linkage = linkage;
+}
+
+
+void 
+Parser::freeTree()
+{
+  delete parseTree;
+  parseTree = 0;
+}
+
Index: translator/Parser.old/Parser.h
===================================================================
--- translator/Parser.old/Parser.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser.old/Parser.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * A singleton class to encapsulate the bison-generated parser
+ *
+ * $Id: Parser.h,v 1.4 2002/09/09 16:47:14 rcbilson Exp $
+ *
+ */
+
+#ifndef PARSER_H
+#define PARSER_H
+
+#include <cstdio>
+
+#include "Parser/ParseNode.h"
+#include "LinkageSpec.h"
+
+class Parser
+{
+public:
+  static Parser &get_parser();
+
+  /* do the actual parse */
+  void parse( FILE *input );
+
+  /* accessors to return the result of the parse */
+  DeclarationNode *get_parseTree() const { return parseTree; }
+  int get_parseStatus() const { return parseStatus; }
+
+  /* mutators to control parse options */
+  void set_debug( bool debug );
+  void set_linkage( LinkageSpec::Type linkage );
+
+  /* free the parse tree without actually destroying the parser */
+  void freeTree();
+
+  ~Parser();
+
+private:
+  Parser();
+  static Parser *theParser;
+  DeclarationNode *parseTree;
+  int parseStatus;
+};
+
+#endif /* #ifndef PARSER_H */
Index: translator/Parser.old/StatementNode.cc
===================================================================
--- translator/Parser.old/StatementNode.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser.old/StatementNode.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,433 @@
+/* -*- C++ -*- */
+#include <list>
+#include <algorithm>
+
+#include "ParseNode.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Expression.h"
+#include "parseutility.h"
+#include "utility.h"
+
+using namespace std;
+
+const char *StatementNode::StType[] =
+  { "Exp",   "If",       "Switch", "Case",    "Default",  "Choose",   "Fallthru", 
+    "While", "Do",       "For", 
+    "Goto",  "Continue", "Break",  "Return",  "Throw",
+    "Try",   "Catch",    "Asm",
+    "Decl"
+  };
+
+/// StatementNode::StatementNode(void) : 
+///   ParseNode(), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), decl( 0 ), isCatchRest ( false ) {}
+
+StatementNode::StatementNode( struct token &tok )
+  : ParseNode( *tok->str, tok->filename, tok->lineno ), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), decl( 0 ), isCatchRest ( false )
+{
+}
+
+StatementNode::StatementNode( char *filename, int lineno )
+  : ParseNode( "", filename, lineno ), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), decl( 0 ), isCatchRest ( false )
+{
+}
+
+StatementNode::StatementNode( DeclarationNode *decl )
+  : ParseNode( decl->get_name(), decl->get_filename(), decl->get_lineno() ), type( Decl ), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), isCatchRest ( false )
+{
+  if( decl ) {
+    if( DeclarationNode *agg = decl->extractAggregate() ) {
+      this->decl = agg;
+      StatementNode *nextStmt = new StatementNode;
+      nextStmt->type = Decl;
+      nextStmt->decl = decl;
+      next = nextStmt;
+      if( decl->get_link() ) {
+        next->set_next( new StatementNode( dynamic_cast< DeclarationNode* >( decl->get_link() ) ) );
+        decl->set_next( 0 );
+      }
+    } else {
+      if( decl->get_link() ) {
+        next = new StatementNode( dynamic_cast< DeclarationNode* >( decl->get_link() ) );
+        decl->set_next( 0 );
+      }
+      this->decl = decl;
+    }
+  }
+}
+
+StatementNode::StatementNode(Type t, char *filename, int lineno, ExpressionNode *ctrl_label, StatementNode *block_ )
+  : ParseNode( "", filename, lineno ), type(t), control(ctrl_label), block(block_), labels( 0 ), target( 0 ), decl( 0 ), isCatchRest ( false )
+{
+  if (t == Default)
+    control = 0;
+} 
+
+StatementNode::StatementNode(Type t, char *filename, int lineno, string *_target)
+  : ParseNode( "", filename, lineno ), type(t), control(0), block(0),   labels( 0 ), target(_target), decl( 0 ), isCatchRest ( false )
+{
+}
+
+StatementNode::~StatementNode(void){
+  delete control;
+  delete block;
+  delete labels;
+  delete target;
+  delete decl;
+}
+
+StatementNode * StatementNode::newCatchStmt( char *filename, int lineno, DeclarationNode *d, StatementNode *s, bool catchRestP ) {
+  StatementNode *ret = new StatementNode( StatementNode::Catch, filename, lineno, 0, s ); 
+  ret->addDeclaration( d );
+  ret->setCatchRest( catchRestP );
+
+  return ret;
+}
+
+std::string StatementNode::get_target() const{
+  if(target)
+    return *target;
+
+  return string("");
+}
+
+StatementNode *
+StatementNode::clone() const
+{
+  StatementNode *newnode = new StatementNode( type, filename, lineno, maybeClone( control ), maybeClone( block ) );
+  if( target ) {
+    newnode->target = new string( *target );
+  } else {
+    newnode->target = 0;
+  }
+  newnode->decl = maybeClone( decl );
+  return newnode;
+}
+
+void StatementNode::set_control(ExpressionNode *c){
+  control = c;
+}
+
+StatementNode * StatementNode::set_block(StatementNode *b){
+  block = b;
+
+  return this;
+}
+
+ExpressionNode *StatementNode::get_control(void) const {
+  return control;
+}
+
+StatementNode *StatementNode::get_block(void) const {
+  return block;
+}
+
+StatementNode::Type StatementNode::get_type(void) const {
+  return type;
+}
+
+StatementNode *StatementNode::add_label( struct token &l ){
+  if(l.str != 0){
+    if(labels == 0)
+      labels = new std::list<std::string>();
+
+    labels->push_front(*l.str); 
+    delete l.str;
+  }
+  lineno = min( lineno, l.lineno );
+
+  return this;
+}
+
+std::list<std::string> *StatementNode::get_labels() const
+{  return labels; }
+
+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){
+  if( stmt != 0)
+    if( block == 0 )
+      block = stmt;
+    else
+      block->set_link(stmt);
+
+  return this;
+}
+
+
+StatementNode *StatementNode::append_last_case(StatementNode *stmt){
+  if( stmt != 0 ) {
+    StatementNode *next = (StatementNode *)get_link();
+    if ( next && next->get_type() == StatementNode::Case )
+      next->append_last_case ( stmt );
+    else
+      if( block == 0 )
+	block = stmt;
+      else
+	block->set_link(stmt);
+  }
+
+  return this;
+}
+
+void StatementNode::print( std::ostream &os, int indent ) const {
+
+  if(labels != 0)
+    if(!labels->empty()){
+      std::list<std::string>::const_iterator i;
+
+      os << '\r' << string(indent, ' ');
+      for( i = labels->begin(); i != labels->end(); i++ )
+	os << *i << ":";
+      os << endl;
+    }
+
+  switch( type ) {
+  case Decl:
+    decl->print( os, indent );
+    break;
+  
+  case Exp:
+    if( control ) {
+      os << string( indent, ' ' );
+      control->print( os, indent );
+      os << endl;
+    } else 
+      os << string( indent, ' ' ) << "Null Statement" << endl;
+    break;
+
+  default:
+    os << '\r' << string(indent, ' ') << StatementNode::StType[type] << endl;
+
+    if   ( type == Catch )
+      if( decl ){
+	os << '\r' << string( indent + ParseNode::indent_by, ' ' ) << "Declaration: " << endl;
+	decl->print( os, indent + 2*ParseNode::indent_by);
+      } else if ( isCatchRest ) {
+	os << '\r' << string( indent + ParseNode::indent_by, ' ' ) << "Catches the rest " << endl;
+      } else {
+	; // should never reach here
+      }
+
+    if( control ){
+      os << '\r' << string( indent + ParseNode::indent_by, ' ' ) << "Expression: " << endl;
+      control->printList( os, indent + 2*ParseNode::indent_by);
+    }
+
+    if( block ){
+      os << '\r' << string( indent + ParseNode::indent_by, ' ' ) << "Branches of execution: " << endl;
+      block->printList( os, indent + 2*ParseNode::indent_by);  
+    }
+
+    if( target ){
+      os << '\r' << string( indent + ParseNode::indent_by, ' ' ) << "Target: " << get_target() << endl;
+    }
+
+    break;
+  }
+}
+
+Statement *StatementNode::build() const {
+
+  std::list<Statement *> branches;
+  std::list<Expression *> exps;
+  std::list<Label> labs;
+
+  if(labels != 0){
+    std::back_insert_iterator< std::list<Label> > lab_it(labs);
+    copy(labels->begin(), labels->end(), lab_it);
+  }
+
+  // try {
+  buildList<Statement, StatementNode>(get_block(), branches);
+  
+  switch( type ) {
+  case Decl:
+    return new DeclStmt( labs, maybeBuild< Declaration >( decl ) );
+
+  case Exp:
+    {
+      Expression *e = maybeBuild< Expression >( get_control() );
+
+      if(e)
+        return new ExprStmt( labs, e );
+      else
+        return new NullStmt( labs );
+    }
+
+  case If:
+    {
+      Statement *thenb = 0, *elseb = 0;
+
+      assert( branches.size() >= 1 );
+
+      thenb = branches.front();  branches.pop_front();
+      if(!branches.empty())
+	{ elseb = branches.front();  branches.pop_front(); }
+
+      return new IfStmt( labs, notZeroExpr( get_control()->build() ), thenb, elseb);
+    }
+
+  case While:
+    assert(branches.size() == 1);
+    return new WhileStmt( labs, notZeroExpr( get_control()->build() ), branches.front() );
+
+  case Do:
+    assert(branches.size() == 1);
+    return new WhileStmt( labs, notZeroExpr( get_control()->build() ), branches.front(), true );
+    
+  case For:
+    {
+      assert(branches.size() == 1);
+
+      ForCtlExprNode *ctl = dynamic_cast<ForCtlExprNode *>(get_control());
+      assert(ctl != 0);
+
+      Statement *stmt = 0;
+      if(ctl->get_init() != 0)
+	stmt = ctl->get_init()->build();
+
+      Expression *cond = 0;
+      if(ctl->get_condition() != 0)
+	cond = notZeroExpr( ctl->get_condition()->build() );
+
+      Expression *incr = 0;
+      if(ctl->get_change() != 0)
+	incr = ctl->get_change()->build();
+
+      return new ForStmt( labs, stmt, cond, incr, branches.front() );
+    }
+
+  case Switch:
+    // try{
+    return new SwitchStmt( labs, get_control()->build(), branches );
+
+  case Choose:
+    return new ChooseStmt( labs, get_control()->build(), branches );
+
+  case Fallthru:
+    return new FallthruStmt( labs );
+
+  case Case: 
+    return new CaseStmt( labs, get_control()->build(), branches);
+
+  case Default:
+    return new CaseStmt( labs, 0, branches, true);
+
+  case Goto:
+    {
+      if (get_target() == "")  { // computed goto
+	assert( get_control() != 0 );
+	return new BranchStmt( labs, get_control()->build(), BranchStmt::Goto );
+      }
+
+      return new BranchStmt( labs, get_target(), BranchStmt::Goto);
+    }
+
+  case Break:
+    return new BranchStmt( labs, get_target(), BranchStmt::Break);
+
+  case Continue:
+    return new BranchStmt( labs, get_target(), BranchStmt::Continue);
+
+  case Return:
+  case Throw :
+    buildList( get_control(), exps );
+    if( exps.size() ==0 )
+      return new ReturnStmt( labs, 0, type == Throw );
+    if( exps.size() > 0 )
+      return new ReturnStmt( labs, exps.back(), type == Throw );
+
+  case Try:
+    {
+      assert( branches.size() >= 0 );
+      CompoundStmt *tryBlock = dynamic_cast<CompoundStmt *>(branches.front());
+      branches.pop_front();
+      return new TryStmt( labs, tryBlock, branches );
+    }
+
+  case Catch:
+    {
+      assert( branches.size() == 1 );
+
+      return new CatchStmt( labs, maybeBuild< Declaration >( decl ), branches.front(), isCatchRest );
+    }
+
+  default:
+    // shouldn't be here
+    return 0;
+  }
+
+  // shouldn't be here
+}
+
+/// CompoundStmtNode::CompoundStmtNode(void)
+///   : first( 0 ), last( 0 )
+/// {
+/// }
+
+CompoundStmtNode::CompoundStmtNode( struct token &tok )
+  : StatementNode( *tok.str, tok.filename, tok.lineno ), first( 0 ), last( 0 )
+{
+}
+
+CompoundStmtNode::CompoundStmtNode(StatementNode *stmt)
+  : StatementNode( "", stmt->get_filename(), stmt->get_lineno() ), first(stmt)
+{
+  if( first ) {
+    last = (StatementNode *)(stmt->get_last());
+  } else {
+    last = 0;
+  }
+}
+
+CompoundStmtNode::~CompoundStmtNode()
+{
+  delete first;
+}
+
+void CompoundStmtNode::add_statement(StatementNode *stmt) {
+  if(stmt != 0){
+    last->set_link(stmt);
+    last = (StatementNode *)(stmt->get_link());
+  }
+}
+
+void CompoundStmtNode::print(ostream &os, int indent) const {
+  if( first ) {
+    first->printList( os, indent+2 );
+  }
+}
+
+Statement *CompoundStmtNode::build() const {
+
+  std::list<Label> labs;
+  std::list<std::string> *labels = get_labels();
+
+  if(labels != 0){
+    std::back_insert_iterator< std::list<Label> > lab_it(labs);
+    copy(labels->begin(), labels->end(), lab_it);
+  }
+
+  CompoundStmt *cs = new CompoundStmt( labs );
+  buildList( first, cs->get_kids() );
+  return cs;
+}
+
+void NullStmtNode::print(ostream &os, int indent) const {
+  os << "\r" << string(indent, ' ') << "Null Statement:" << endl;
+}
+
+Statement *NullStmtNode::build() const { 
+  return new NullStmt;
+}
+
+// Local Variables: //
+// mode: C++                //
+// compile-command: "gmake -f ../Makefile" //
+// End: //
Index: translator/Parser.old/TypeData.cc
===================================================================
--- translator/Parser.old/TypeData.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser.old/TypeData.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,1024 @@
+#include <cassert>
+#include <algorithm>
+#include <iterator>
+#include "utility.h"
+#include "TypeData.h"
+#include "SynTree/Type.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Statement.h"
+
+
+TypeData::TypeData( Kind k )
+  : kind( k ), base( 0 ), forall( 0 )
+{
+  switch( kind ) {
+  case Unknown:
+  case Pointer:
+  case EnumConstant:
+    // nothing else to initialize
+    break;
+
+  case Basic:
+    basic = new Basic_t;
+    break;
+
+  case Array:
+    array = new Array_t;
+    array->dimension = 0;
+    array->isVarLen = false;
+    array->isStatic = false;
+    break;
+
+  case Function:
+    function = new Function_t;
+    function->params = 0;
+    function->idList = 0;
+    function->oldDeclList = 0;
+    function->body = 0;
+    function->hasBody = false;
+    break;
+
+  case Aggregate:
+    aggregate = new Aggregate_t;
+    aggregate->params = 0;
+    aggregate->actuals = 0;
+    aggregate->members = 0;
+    break;
+
+  case AggregateInst:
+    aggInst = new AggInst_t;
+    aggInst->aggregate = 0;
+    aggInst->params = 0;
+    break;
+
+  case Enum:
+    enumeration = new Enumeration_t;
+    enumeration->constants = 0;
+    break;
+
+  case Symbolic:
+  case SymbolicInst:
+    symbolic = new Symbolic_t;
+    symbolic->params = 0;
+    symbolic->actuals = 0;
+    symbolic->assertions = 0;
+    break;
+
+  case Variable:
+    variable = new Variable_t;
+    variable->tyClass = DeclarationNode::Type;
+    variable->assertions = 0;
+    break;
+
+  case Tuple:
+    tuple = new Tuple_t;
+    tuple->members = 0;
+    break;
+  
+  case Typeof:
+    typeexpr = new Typeof_t;
+    typeexpr->expr = 0;
+    break;
+  }
+}
+
+TypeData::~TypeData()
+{
+  delete base;
+  delete forall;
+
+  switch( kind ) {
+  case Unknown:
+  case Pointer:
+  case EnumConstant:
+    // nothing to destroy
+    break;
+
+  case Basic:
+    delete basic;
+    break;
+
+  case Array:
+    delete array->dimension;
+    delete array;
+    break;
+
+  case Function:
+    delete function->params;
+    delete function->idList;
+    delete function->oldDeclList;
+    delete function->body;
+    delete function;
+    break;
+
+  case Aggregate:
+    delete aggregate->params;
+    delete aggregate->actuals;
+    delete aggregate->members;
+    delete aggregate;
+    break;
+
+  case AggregateInst:
+    delete aggInst->aggregate;
+    delete aggInst->params;
+    delete aggInst;
+    break;
+
+  case Enum:
+    delete enumeration->constants;
+    delete enumeration;
+    break;
+
+  case Symbolic:
+  case SymbolicInst:
+    delete symbolic->params;
+    delete symbolic->actuals;
+    delete symbolic->assertions;
+    delete symbolic;
+    break;
+
+  case Variable:
+    delete variable->assertions;
+    delete variable;
+    break;
+
+  case Tuple:
+    delete tuple->members;
+    delete tuple;
+    break;
+  
+  case Typeof:
+    delete typeexpr->expr;
+    delete typeexpr;
+    break;
+  }
+}
+
+TypeData *
+TypeData::clone() const
+{
+  TypeData *newtype = new TypeData( kind );
+  newtype->qualifiers = qualifiers;
+  newtype->base = maybeClone( base );
+  newtype->forall = maybeClone( forall );
+
+  switch( kind ) {
+  case Unknown:
+  case EnumConstant:
+  case Pointer:
+    // nothing else to copy
+    break;
+
+  case Basic:
+    newtype->basic->typeSpec = basic->typeSpec;
+    newtype->basic->modifiers = basic->modifiers;
+    break;
+
+  case Array:
+    newtype->array->dimension = maybeClone( array->dimension );
+    newtype->array->isVarLen = array->isVarLen;
+    newtype->array->isStatic = array->isStatic;
+    break;
+
+  case Function:
+    newtype->function->params = maybeClone( function->params );
+    newtype->function->idList = maybeClone( function->idList );
+    newtype->function->oldDeclList = maybeClone( function->oldDeclList );
+    newtype->function->body = maybeClone( function->body );
+    newtype->function->hasBody = function->hasBody;
+    break;
+
+  case Aggregate:
+    newtype->aggregate->params = maybeClone( aggregate->params );
+    newtype->aggregate->actuals = maybeClone( aggregate->actuals );
+    newtype->aggregate->members = maybeClone( aggregate->members );
+    newtype->aggregate->name = aggregate->name;
+    newtype->aggregate->kind = aggregate->kind;
+    break;
+
+  case AggregateInst:
+    newtype->aggInst->aggregate = maybeClone( aggInst->aggregate );
+    newtype->aggInst->params = maybeClone( aggInst->params );
+    break;
+
+  case Enum:
+    newtype->enumeration->name = enumeration->name;
+    newtype->enumeration->constants = maybeClone( enumeration->constants );
+    break;
+
+  case Symbolic:
+  case SymbolicInst:
+    newtype->symbolic->params = maybeClone( symbolic->params );
+    newtype->symbolic->actuals = maybeClone( symbolic->actuals );
+    newtype->symbolic->assertions = maybeClone( symbolic->assertions );
+    newtype->symbolic->isTypedef = symbolic->isTypedef;
+    newtype->symbolic->name = symbolic->name;
+    break;
+
+  case Variable:
+    newtype->variable->assertions = maybeClone( variable->assertions );
+    newtype->variable->name = variable->name;
+    newtype->variable->tyClass = variable->tyClass;
+    break;
+
+  case Tuple:
+    newtype->tuple->members = maybeClone( tuple->members );
+    break;
+    
+  case Typeof:
+    newtype->typeexpr->expr = maybeClone( typeexpr->expr );
+    break;
+  }
+  return newtype;
+}
+
+void 
+TypeData::print( std::ostream &os, int indent ) const
+{
+  using std::endl;
+  using std::string;
+
+  printEnums( qualifiers.begin(), qualifiers.end(), DeclarationNode::qualifierName, os );
+
+  if( forall ) {
+    os << "forall " << endl;
+    forall->printList( os, indent+4 );
+  }
+
+  switch( kind ) {
+  case Unknown:
+    os << "entity of unknown type ";
+    break;
+
+  case Pointer:
+    os << "pointer ";
+    if( base ) {
+      os << "to ";
+      base->print( os, indent );
+    }
+    break;
+
+  case EnumConstant:
+    os << "enumeration constant ";
+    break;
+
+  case Basic:
+    printEnums( basic->modifiers.begin(), basic->modifiers.end(), DeclarationNode::modifierName, os );
+    printEnums( basic->typeSpec.begin(), basic->typeSpec.end(), DeclarationNode::basicTypeName, os );
+    break;
+
+  case Array:
+    if( array->isStatic ) {
+      os << "static ";
+    }
+    if( array->dimension ) {
+      os << "array of ";
+      array->dimension->printOneLine( os, indent );
+    } else if ( array->isVarLen ) {
+      os << "variable-length array of ";
+    } else {
+      os << "open array of ";
+    }
+    if( base ) {
+      base->print( os, indent );
+    }
+    break;
+
+  case Function:
+    os << "function" << endl;
+    if ( function->params ) {
+      os << string( indent+2, ' ' ) << "with parameters " << endl;
+      function->params->printList( os, indent+4 );
+    } else {
+      os << string( indent+2, ' ' ) << "with no parameters " << endl;
+    }
+    if ( function->idList ) {
+      os << string( indent+2, ' ' ) << "with old-style identifier list " << endl;
+      function->idList->printList( os, indent+4 );
+    }
+    if ( function->oldDeclList ) {
+      os << string( indent+2, ' ' ) << "with old-style declaration list " << endl;
+      function->oldDeclList->printList( os, indent+4 );
+    }
+    os << string( indent+2, ' ' ) << "returning ";
+    if ( base ) {
+      base->print( os, indent+4 );
+    } else {
+      os << "nothing ";
+    }
+    os << endl;
+    if ( function->hasBody ) {
+      os << string( indent+2, ' ' ) << "with body " << endl;
+    }
+    if ( function->body ) {
+      function->body->printList( os, indent+2 );
+    }
+    break;
+
+  case Aggregate:
+    os << DeclarationNode::tyConName[ aggregate->kind ] << ' ' << aggregate->name << endl;
+    if( aggregate->params ) {
+      os << string( indent+2, ' ' ) << "with type parameters " << endl;
+      aggregate->params->printList( os, indent+4 );
+    }
+    if( aggregate->actuals ) {
+      os << string( indent+2, ' ' ) << "instantiated with actual parameters " << endl;
+      aggregate->actuals->printList( os, indent+4 );
+    }
+    if( aggregate->members ) {
+      os << string( indent+2, ' ' ) << "with members " << endl;
+      aggregate->members->printList( os, indent+4 );
+///     } else {
+///       os << string( indent+2, ' ' ) << "with no members " << endl;
+    }
+    break;
+
+  case AggregateInst:
+    if( aggInst->aggregate ) {
+      os << "instance of " ;
+      aggInst->aggregate->print( os, indent );
+    } else {
+      os << "instance of an unspecified aggregate ";
+    }
+    if( aggInst->params ) {
+      os << string( indent+2, ' ' ) << "with parameters " << endl;
+      aggInst->params->printList( os, indent+2 );
+    }
+    break;
+
+  case Enum:
+    os << "enumeration ";
+    if( enumeration->constants ) {
+      os << "with constants" << endl;
+      enumeration->constants->printList( os, indent+2 );
+    }
+    break;
+
+  case SymbolicInst:
+    os << "instance of type " << symbolic->name;
+    if( symbolic->actuals ) {
+      os << " with parameters" << endl;
+      symbolic->actuals->printList( os, indent + 2 );
+    }
+    break;
+
+  case Symbolic:
+    if( symbolic->isTypedef ) {
+      os << "typedef definition ";
+    } else {
+      os << "type definition ";
+    }
+    if( symbolic->params ) {
+      os << endl << string( indent+2, ' ' ) << "with parameters" << endl;
+      symbolic->params->printList( os, indent + 2 );
+    }
+    if( symbolic->assertions ) {
+      os << endl << string( indent+2, ' ' ) << "with assertions" << endl;
+      symbolic->assertions->printList( os, indent + 4 );
+      os << string( indent+2, ' ' );
+    }
+    if( base ) {
+      os << "for ";
+      base->print( os, indent + 2 );
+    }
+    break;
+
+  case Variable:
+    os << DeclarationNode::typeClassName[ variable->tyClass ] << " variable ";
+    if( variable->assertions ) {
+      os << endl << string( indent+2, ' ' ) << "with assertions" << endl;
+      variable->assertions->printList( os, indent + 4 );
+      os << string( indent+2, ' ' );
+    }
+    break;
+
+  case Tuple:
+    os << "tuple ";
+    if( tuple->members ) {
+      os << "with members " << endl;
+      tuple->members->printList( os, indent + 2 );
+    }
+    break;
+    
+  case Typeof:
+    os << "type-of expression ";
+    if( typeexpr->expr ) {
+      typeexpr->expr->print( os, indent + 2 );
+    }
+    break;
+  }
+}
+
+TypeData *
+TypeData::extractAggregate( bool toplevel ) const
+{
+  TypeData *ret = 0;
+
+  switch( kind ) {
+  case Aggregate:
+    if( !toplevel && aggregate->members ) {
+      ret = clone();
+      ret->qualifiers.clear();
+    }
+    break;
+
+  case Enum:
+    if( !toplevel && enumeration->constants ) {
+      ret = clone();
+      ret->qualifiers.clear();
+    }
+    break;
+
+  case AggregateInst:
+    if( aggInst->aggregate ) {
+      ret = aggInst->aggregate->extractAggregate( false );
+    }
+    break;
+
+  default:
+    if( base ) {
+      ret = base->extractAggregate( false );
+    }
+  }
+  return ret;
+}
+
+void
+buildForall( const DeclarationNode *firstNode, std::list< TypeDecl* > &outputList )
+{
+  
+  buildList( firstNode, outputList );
+  for( std::list< TypeDecl* >::iterator i = outputList.begin(); i != outputList.end(); ++i ) {
+    if( (*i)->get_kind() == TypeDecl::Any ) {
+      FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
+      assignType->get_parameters().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name() ) ), 0 ) );
+      assignType->get_parameters().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name() ), 0 ) );
+      assignType->get_returnVals().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name() ), 0 ) );
+      (*i)->get_assertions().push_front( new FunctionDecl( "?=?", Declaration::NoStorageClass, LinkageSpec::Cforall,  assignType, 0, false ) );
+    }
+  }
+}
+
+Declaration *
+TypeData::buildDecl( std::string name, Declaration::StorageClass sc, Expression *bitfieldWidth, bool isInline, LinkageSpec::Type linkage, Initializer *init ) const
+{
+
+  if ( kind == TypeData::Function ) {
+    FunctionDecl *decl;
+    if( function->hasBody ) {
+      if( function->body ) {
+        Statement *stmt = function->body->build();
+        CompoundStmt *body = dynamic_cast< CompoundStmt* >( stmt );
+        assert( body );
+        decl = new FunctionDecl( name, sc, linkage, buildFunction(), body, isInline );
+      } else {
+	// std::list<Label> ls;
+        decl = new FunctionDecl( name, sc, linkage, buildFunction(), new CompoundStmt( std::list<Label>() ), isInline );
+      }
+    } else {
+      decl = new FunctionDecl( name, sc, linkage, buildFunction(), 0, isInline );
+    }
+    for( DeclarationNode *cur = function->idList; cur != 0; cur = dynamic_cast< DeclarationNode* >( cur->get_link() ) ) {
+      if( cur->get_name() != "" ) {
+        decl->get_oldIdents().insert( decl->get_oldIdents().end(), cur->get_name() );
+      }
+    }
+    buildList( function->oldDeclList, decl->get_oldDecls() );
+    return decl;
+  } else if ( kind == TypeData::Aggregate ) {
+    return buildAggregate();
+  } else if ( kind == TypeData::Enum ) {
+    return buildEnum();
+  } else if ( kind == TypeData::Symbolic ) {
+    return buildSymbolic( name, sc );
+  } else if ( kind == TypeData::Variable ) {
+    return buildVariable();
+  } else {
+    if( isInline ) {
+      throw SemanticError( "invalid inline specification in declaration of ", this );
+    } else {
+      return new ObjectDecl( name, sc, linkage, bitfieldWidth, build(), init );
+    }
+  }
+  return 0;
+}
+
+Type *
+TypeData::build() const
+{
+
+  switch( kind ) {
+  case Unknown:
+    // fill in implicit int
+    return new BasicType( buildQualifiers(), BasicType::SignedInt );
+
+  case Basic:
+    return buildBasicType();
+
+  case Pointer:
+    return buildPointer();
+
+  case Array:
+    return buildArray();
+
+  case Function:
+    return buildFunction();
+
+  case AggregateInst:
+    return buildAggInst();
+
+  case EnumConstant:
+    // the name gets filled in later -- by SymTab::Validate
+    return new EnumInstType( buildQualifiers(), "" );
+
+  case SymbolicInst:
+    return buildSymbolicInst();;
+
+  case Tuple:
+    return buildTuple();
+  
+  case Typeof:
+    return buildTypeof();
+
+  case Symbolic:
+  case Enum:
+  case Aggregate:
+  case Variable:
+    assert( false );
+  }
+
+  return 0;
+}
+
+Type::Qualifiers
+TypeData::buildQualifiers() const
+{
+  Type::Qualifiers q;
+  for( std::list< DeclarationNode::Qualifier >::const_iterator i = qualifiers.begin(); i != qualifiers.end(); ++i ) {
+    switch( *i ) {
+    case DeclarationNode::Const:
+      q.isConst = true;
+      break;
+
+    case DeclarationNode::Volatile:
+      q.isVolatile = true;
+      break;
+
+    case DeclarationNode::Restrict:
+      q.isRestrict = true;
+      break;
+
+    case DeclarationNode::Lvalue:
+      q.isLvalue = true;
+      break;
+    }
+  }
+  return q;
+}
+
+Type*
+TypeData::buildBasicType() const
+{
+
+  static const BasicType::Kind kindMap[] = { BasicType::Char, BasicType::SignedInt, BasicType::Float, BasicType::Double,
+                                             BasicType::Char /* void */, BasicType::Bool, BasicType::DoubleComplex,
+					     BasicType::DoubleImaginary };
+
+  bool init = false;
+  bool sawDouble = false;
+  bool sawSigned = false;
+  BasicType::Kind ret;
+
+  for( std::list< DeclarationNode::BasicType >::const_iterator i = basic->typeSpec.begin(); i != basic->typeSpec.end(); ++i ) {
+    if( !init ) {
+      init = true;
+      if( *i == DeclarationNode::Void ) {
+        if( basic->typeSpec.size() != 1 || !basic->modifiers.empty() ) {
+	  throw SemanticError( "invalid type specifier \"void\" in type ", this );
+	} else {
+	  return new VoidType( buildQualifiers() );
+	}
+      } else {
+        ret = kindMap[ *i ];
+      }
+    } else {
+      switch( *i ) {
+      case DeclarationNode::Float:
+	if( sawDouble ) {
+	  throw SemanticError( "invalid type specifier \"float\" in type ", this );
+	} else {
+	  switch( ret ) {
+	  case BasicType::DoubleComplex:
+	    ret = BasicType::FloatComplex;
+	    break;
+
+	  case BasicType::DoubleImaginary:
+	    ret = BasicType::FloatImaginary;
+	    break;
+
+	  default:
+	    throw SemanticError( "invalid type specifier \"float\" in type ", this );
+	  }
+	}
+	break;
+
+      case DeclarationNode::Double:
+	if( sawDouble ) {
+	  throw SemanticError( "duplicate type specifier \"double\" in type ", this );
+	} else {
+	  switch( ret ) {
+	  case BasicType::DoubleComplex:
+	  case BasicType::DoubleImaginary:
+	    break;
+
+	  default:
+	    throw SemanticError( "invalid type specifier \"double\" in type ", this );
+	  }
+	}
+	break;
+	
+      case DeclarationNode::Complex:
+        switch( ret ) {
+        case BasicType::Float:
+          ret = BasicType::FloatComplex;
+          break;
+          
+        case BasicType::Double:
+          ret = BasicType::DoubleComplex;
+          break;
+
+	default:
+	  throw SemanticError( "invalid type specifier \"complex\" in type ", this );
+        }
+	break;
+        
+      case DeclarationNode::Imaginary:
+        switch( ret ) {
+        case BasicType::Float:
+          ret = BasicType::FloatImaginary;
+          break;
+          
+        case BasicType::Double:
+          ret = BasicType::DoubleImaginary;
+          break;
+
+	default:
+	  throw SemanticError( "invalid type specifier \"imaginary\" in type ", this );
+        }
+	break;
+        
+      default:
+	throw SemanticError( std::string( "invalid type specifier \"" ) + DeclarationNode::basicTypeName[ *i ] + "\" in type ", this );
+      }
+    }
+    if( *i == DeclarationNode::Double ) {
+      sawDouble = true;
+    }
+  }
+
+  for( std::list< DeclarationNode::Modifier >::const_iterator i = basic->modifiers.begin(); i != basic->modifiers.end(); ++i ) {
+    switch( *i ) {
+    case DeclarationNode::Long:
+      if( !init ) {
+	init = true;
+	ret = BasicType::LongSignedInt;
+      } else {
+	switch( ret ) {
+	case BasicType::SignedInt:
+	  ret = BasicType::LongSignedInt;
+	  break;
+
+	case BasicType::UnsignedInt:
+	  ret = BasicType::LongUnsignedInt;
+	  break;
+
+	case BasicType::LongSignedInt:
+	  ret = BasicType::LongLongSignedInt;
+	  break;
+
+	case BasicType::LongUnsignedInt:
+	  ret = BasicType::LongLongUnsignedInt;
+	  break;
+
+	case BasicType::Double:
+	  ret = BasicType::LongDouble;
+	  break;
+
+	case BasicType::DoubleComplex:
+	  ret = BasicType::LongDoubleComplex;
+	  break;
+
+	case BasicType::DoubleImaginary:
+	  ret = BasicType::LongDoubleImaginary;
+	  break;
+
+	default:
+	  throw SemanticError( "invalid type modifier \"long\" in type ", this );
+	}
+      }
+      break;
+
+    case DeclarationNode::Short:
+      if( !init ) {
+	init = true;
+	ret = BasicType::ShortSignedInt;
+      } else {
+	switch( ret ) {
+	case BasicType::SignedInt:
+	  ret = BasicType::ShortSignedInt;
+	  break;
+
+	case BasicType::UnsignedInt:
+	  ret = BasicType::ShortUnsignedInt;
+	  break;
+
+	default:
+	  throw SemanticError( "invalid type modifier \"short\" in type ", this );
+	}
+      }
+      break;
+
+    case DeclarationNode::Signed:
+      if( !init ) {
+	init = true;
+	ret = BasicType::SignedInt;
+      } else if( sawSigned ) {
+	throw SemanticError( "duplicate type modifer \"signed\" in type ", this );
+      } else {
+	switch( ret ) {
+	case BasicType::SignedInt:
+	case BasicType::ShortSignedInt:
+	  break;
+
+	case BasicType::Char:
+	  ret = BasicType::SignedChar;
+	  break;
+
+	default:
+	  throw SemanticError( "invalid type modifer \"signed\" in type ", this );
+	}
+      }
+      break;
+
+    case DeclarationNode::Unsigned:
+      if( !init ) {
+	init = true;
+	ret = BasicType::UnsignedInt;
+      } else if( sawSigned ) {
+	throw SemanticError( "invalid type modifer \"unsigned\" in type ", this );
+      } else {
+	switch( ret ) {
+	case BasicType::LongSignedInt:
+	  ret = BasicType::LongUnsignedInt;
+	  break;
+
+	case BasicType::SignedInt:
+	  ret = BasicType::UnsignedInt;
+	  break;
+
+	case BasicType::ShortSignedInt:
+	  ret = BasicType::ShortUnsignedInt;
+	  break;
+
+	case BasicType::Char:
+	  ret = BasicType::UnsignedChar;
+	  break;
+
+	default:
+	  throw SemanticError( "invalid type modifer \"unsigned\" in type ", this );
+	}
+      }
+      break;
+    }
+
+    if( *i == DeclarationNode::Signed ) {
+      sawSigned = true;
+    }
+  }
+
+  BasicType *bt;
+  if( !init ) {
+    bt = new BasicType( buildQualifiers(), BasicType::SignedInt );
+  } else {
+    bt = new BasicType( buildQualifiers(), ret );
+  }
+  buildForall( forall, bt->get_forall() );
+  return bt;
+}
+
+
+PointerType * 
+TypeData::buildPointer() const
+{
+  
+  PointerType *pt;
+  if( base ) {
+    pt = new PointerType( buildQualifiers(), base->build() );
+  } else {
+    pt = new PointerType( buildQualifiers(), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
+  }
+  buildForall( forall, pt->get_forall() );
+  return pt;
+}
+
+ArrayType * 
+TypeData::buildArray() const
+{
+  
+  ArrayType *at;
+  if( base ) {
+    at = new ArrayType( buildQualifiers(), base->build(), maybeBuild< Expression >( array->dimension ),
+	                  array->isVarLen, array->isStatic );
+  } else {
+    at = new ArrayType( buildQualifiers(), new BasicType( Type::Qualifiers(), BasicType::SignedInt ),
+	                  maybeBuild< Expression >( array->dimension ), array->isVarLen, array->isStatic );
+  }
+  buildForall( forall, at->get_forall() );
+  return at;
+}
+
+FunctionType *
+TypeData::buildFunction() const
+{
+  assert( kind == Function );
+
+
+  bool hasEllipsis = function->params ? function->params->get_hasEllipsis() : true;
+  FunctionType *ft = new FunctionType( buildQualifiers(), hasEllipsis );
+  buildList( function->params, ft->get_parameters() );
+  buildForall( forall, ft->get_forall() );
+  if( base ) {
+    switch( base->kind ) {
+    case Tuple:
+      buildList( base->tuple->members, ft->get_returnVals() );
+      break;
+
+    default:
+      ft->get_returnVals().push_back( dynamic_cast< DeclarationWithType* >( base->buildDecl( "", Declaration::NoStorageClass, 0, false, LinkageSpec::Cforall ) ) );
+    }
+  } else {
+    ft->get_returnVals().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 ) );
+  }
+  return ft;
+}
+
+AggregateDecl *
+TypeData::buildAggregate() const
+{
+  assert( kind == Aggregate );
+
+
+  AggregateDecl *at;
+  switch( aggregate->kind ) {
+  case DeclarationNode::Struct:
+    at = new StructDecl( aggregate->name );
+    break;
+    
+  case DeclarationNode::Union:
+    at = new UnionDecl( aggregate->name );
+    break;
+    
+  case DeclarationNode::Context:
+    at = new ContextDecl( aggregate->name );
+    break;
+    
+  default:
+    assert( false );
+  }
+  
+  buildList( aggregate->params, at->get_parameters() );
+  buildList( aggregate->members, at->get_members() );
+
+  return at;
+}
+
+/// namespace {
+/// Type*
+/// makeType( Declaration* decl )
+/// {
+///   if( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
+///     return dwt->get_type()->clone();
+///   } else {
+///     return 0;
+///   }
+/// }
+/// }
+
+ReferenceToType *
+TypeData::buildAggInst() const
+{
+  assert( kind == AggregateInst );
+
+
+  std::string name;
+
+  ReferenceToType *ret;
+  if( aggInst->aggregate->kind == Enum ) {
+    ret = new EnumInstType( buildQualifiers(), aggInst->aggregate->enumeration->name );
+  } else {
+    assert( aggInst->aggregate->kind == Aggregate );
+    switch( aggInst->aggregate->aggregate->kind ) {
+    case DeclarationNode::Struct:
+      ret = new StructInstType( buildQualifiers(), aggInst->aggregate->aggregate->name );
+      break;
+
+    case DeclarationNode::Union:
+      ret = new UnionInstType( buildQualifiers(), aggInst->aggregate->aggregate->name );
+      break;
+
+    case DeclarationNode::Context:
+      ret = new ContextInstType( buildQualifiers(), aggInst->aggregate->aggregate->name );
+      break;
+
+    default:
+      assert( false );
+    }
+  }
+  buildList( aggInst->params, ret->get_parameters() );
+  buildForall( forall, ret->get_forall() );
+  return ret;
+}
+
+NamedTypeDecl*
+TypeData::buildSymbolic( const std::string &name, Declaration::StorageClass sc ) const
+{
+  assert( kind == Symbolic );
+
+
+  NamedTypeDecl *ret;
+  if( symbolic->isTypedef ) {
+    ret = new TypedefDecl( name, sc, maybeBuild< Type >( base ) );
+  } else {
+    ret = new TypeDecl( name, sc, maybeBuild< Type >( base ), TypeDecl::Any );
+  }
+  buildList( symbolic->params, ret->get_parameters() );
+  buildList( symbolic->assertions, ret->get_assertions() );
+  return ret;
+}
+
+TypeDecl*
+TypeData::buildVariable() const
+{
+  assert( kind == Variable );
+
+
+  static const TypeDecl::Kind kindMap[] = { TypeDecl::Any, TypeDecl::Ftype, TypeDecl::Dtype };
+
+  TypeDecl *ret = new TypeDecl( variable->name, Declaration::NoStorageClass, 0, kindMap[ variable->tyClass ] );
+  buildList( variable->assertions, ret->get_assertions() );
+    
+  return ret;
+}
+
+EnumDecl* 
+TypeData::buildEnum() const
+{
+  assert( kind == Enum );
+
+
+  EnumDecl *ret = new EnumDecl( enumeration->name );
+  buildList( enumeration->constants, ret->get_members() );
+
+  return ret;
+}
+
+TypeInstType * 
+TypeData::buildSymbolicInst() const
+{
+  assert( kind == SymbolicInst );
+
+
+  TypeInstType *ret = new TypeInstType( buildQualifiers(), symbolic->name );
+  buildList( symbolic->actuals, ret->get_parameters() );
+  buildForall( forall, ret->get_forall() );
+
+  return ret;
+}
+
+TupleType * 
+TypeData::buildTuple() const
+{
+  assert( kind == Tuple );
+
+
+  TupleType *ret = new TupleType( buildQualifiers() );
+  buildTypeList( tuple->members, ret->get_types() );
+  buildForall( forall, ret->get_forall() );
+
+  return ret;
+}
+
+TypeofType * 
+TypeData::buildTypeof() const
+{
+  assert( kind == Typeof );
+
+
+  assert( typeexpr );
+  assert( typeexpr->expr );
+  TypeofType *ret = new TypeofType( buildQualifiers(), typeexpr->expr->build() );
+
+  return ret;
+}
+
Index: translator/Parser.old/TypeData.h
===================================================================
--- translator/Parser.old/TypeData.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser.old/TypeData.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,119 @@
+#ifndef TYPEDATA_H
+#define TYPEDATA_H
+
+#include <list>
+#include "ParseNode.h"
+#include "SynTree/SynTree.h"
+#include "SynTree/Type.h"
+#include "SynTree/Declaration.h"
+#include "SemanticError.h"
+#include "LinkageSpec.h"
+
+struct TypeData
+{
+  enum Kind { Unknown, Basic, Pointer, Array, Function, Aggregate, AggregateInst,
+	      Enum, EnumConstant, Symbolic, SymbolicInst, Variable, Tuple, Typeof } kind;
+
+  TypeData( Kind k = Unknown );
+  ~TypeData();
+  void print( std::ostream &, int indent = 0 ) const;
+  TypeData *clone() const;
+
+  Type *build() const;
+  FunctionType *buildFunction() const;
+
+  TypeData *base;
+  std::list< DeclarationNode::Qualifier > qualifiers;
+  DeclarationNode *forall;
+
+  struct Basic_t {
+    std::list< DeclarationNode::BasicType > typeSpec;
+    std::list< DeclarationNode::Modifier > modifiers;
+  };
+
+  struct Aggregate_t {
+    DeclarationNode::TyCon kind;
+    std::string name;
+    DeclarationNode *params;
+    ExpressionNode *actuals;	// holds actual parameters that will later be applied to AggInst
+    DeclarationNode *members;
+  };
+
+  struct AggInst_t {
+    TypeData *aggregate;
+    ExpressionNode *params;
+  };
+
+  struct Array_t {
+    ExpressionNode *dimension;
+    bool isVarLen;
+    bool isStatic;
+  };
+
+  struct Enumeration_t {
+    std::string name;
+    DeclarationNode *constants;
+  };
+
+  struct Function_t {
+    DeclarationNode *params;
+    DeclarationNode *idList; // old-style
+    DeclarationNode *oldDeclList;
+    StatementNode *body;
+    bool hasBody;
+  };
+
+  struct Symbolic_t {
+    std::string name;
+    bool isTypedef;
+    DeclarationNode *params;
+    ExpressionNode *actuals;
+    DeclarationNode *assertions;
+  };
+
+  struct Variable_t {
+    DeclarationNode::TypeClass tyClass;
+    std::string name;
+    DeclarationNode *assertions;
+  };
+
+  struct Tuple_t {
+    DeclarationNode *members;
+  };
+  
+  struct Typeof_t {
+    ExpressionNode *expr;
+  };
+
+  union {
+    Basic_t *basic;
+    Aggregate_t *aggregate;
+    AggInst_t *aggInst;
+    Array_t *array;
+    Enumeration_t *enumeration;
+    Function_t *function;
+    Symbolic_t *symbolic;
+    Variable_t *variable;
+    Tuple_t *tuple;
+    Typeof_t *typeexpr;
+  };
+
+  TypeData *extractAggregate( bool toplevel = true ) const;
+  /* helper function for DeclNodeImpl::build */
+  Declaration * buildDecl( std::string name, Declaration::StorageClass sc, Expression *bitfieldWidth, bool isInline, LinkageSpec::Type linkage, Initializer *init = 0 ) const;
+  /* helper functions for build() */
+  Type::Qualifiers buildQualifiers() const;
+  Type *buildBasicType() const;
+  PointerType * buildPointer() const;
+  ArrayType * buildArray() const;
+  AggregateDecl * buildAggregate() const;
+  ReferenceToType * buildAggInst() const;
+  NamedTypeDecl * buildSymbolic( const std::string &name, Declaration::StorageClass sc ) const;
+  TypeDecl* buildVariable() const;
+  EnumDecl* buildEnum() const;
+  TypeInstType * buildSymbolicInst() const;
+  TupleType * buildTuple() const;
+  TypeofType * buildTypeof() const;
+};
+
+#endif /* #ifndef TYPEDATA_H */
Index: translator/Parser.old/TypedefTable.cc
===================================================================
--- translator/Parser.old/TypedefTable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser.old/TypedefTable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,189 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: TypedefTable.cc,v 1.6 2003/05/19 19:19:23 rcbilson Exp $
+ *
+ */
+
+#include <map>
+#include <list>
+#include "TypedefTable.h"
+#include <iostream>
+using namespace std;
+
+#if 0
+#  define debugPrint(x) cerr << x
+#else
+#  define debugPrint(x)
+#endif
+
+TypedefTable::TypedefTable()
+    : currentScope(0)
+{
+}
+
+bool
+TypedefTable::isKind(string identifier, kind_t kind) const
+{
+    tableType::const_iterator id_pos = table.find(identifier);
+    if (id_pos == table.end()) {
+	return true;
+    } else {
+	return (*((*id_pos).second.begin())).kind == kind;
+    }
+}
+
+bool
+TypedefTable::isIdentifier(string identifier) const
+{
+    return isKind(identifier, ID);
+}
+
+bool
+TypedefTable::isTypedef(string identifier) const
+{
+    return isKind(identifier, TD);
+}
+
+bool
+TypedefTable::isTypegen(string identifier) const
+{
+    return isKind(identifier, TG);
+}
+
+void
+TypedefTable::addToScope(const std::string &identifier, kind_t kind, int scope)
+{
+  if( currentContext != "" && scope == contextScope ) {
+    DeferredEntry entry = { identifier, kind };
+    contexts[currentContext].push_back( entry );
+  } else {
+    debugPrint( "Adding " << identifier << " as type " << kind << " scope " << scope << " from scope " << currentScope << endl );
+    Entry newEntry = { scope, kind };
+    tableType::iterator curPos = table.find(identifier);
+    if (curPos == table.end()) {
+      list<Entry> newList;
+      newList.push_front(newEntry);
+      table[identifier] = newList;
+    } else {
+      list<Entry>::iterator listPos = (*curPos).second.begin();
+      while( listPos != (*curPos).second.end() && listPos->scope > scope ) {
+        listPos++;
+      }
+      (*curPos).second.insert(listPos, newEntry);
+    }
+  }
+}
+
+void
+TypedefTable::addToCurrentScope(const std::string &identifier, kind_t kind)
+{
+  addToScope( identifier, kind, currentScope );
+}
+
+void
+TypedefTable::addToCurrentScope(kind_t kind)
+{
+  addToCurrentScope( nextIdentifiers.top(), kind );
+}
+
+void
+TypedefTable::addToEnclosingScope(const std::string &identifier, kind_t kind)
+{
+  assert( currentScope >= 1 );
+  addToScope( identifier, kind, currentScope - 1 );
+}
+
+void
+TypedefTable::addToEnclosingScope(kind_t kind)
+{
+  addToEnclosingScope( nextIdentifiers.top(), kind );
+}
+
+void
+TypedefTable::addToEnclosingScope2(const std::string &identifier, kind_t kind)
+{
+  assert( currentScope >= 2 );
+  addToScope( identifier, kind, currentScope - 2 );
+}
+
+void
+TypedefTable::addToEnclosingScope2(kind_t kind)
+{
+  addToEnclosingScope2( nextIdentifiers.top(), kind );
+}
+
+void
+TypedefTable::setNextIdentifier( const std::string &identifier )
+{
+  nextIdentifiers.top() = identifier;
+}
+
+void
+TypedefTable::openContext( std::string contextName )
+{
+  map< string, deferListType >::iterator i = contexts.find( contextName );
+  if( i != contexts.end() ) {
+    deferListType &entries = i->second;
+    for (deferListType::iterator i = entries.begin(); i != entries.end(); i++) {
+      addToEnclosingScope( i->identifier, i->kind );
+    }
+  }
+}
+
+void
+TypedefTable::enterScope(void)
+{
+    currentScope += 1;
+    deferListStack.push( deferListType() );
+    nextIdentifiers.push( "" );
+    debugPrint( "Entering scope " << currentScope << ", nextIdentifiers size is " << nextIdentifiers.size() << endl );
+}
+
+void
+TypedefTable::leaveScope(void)
+{
+    debugPrint( "Leaving scope " << currentScope << endl );
+    for (tableType::iterator i = table.begin(); i != table.end(); i++) {
+	list<Entry> &declList = (*i).second;
+	while (!declList.empty() && declList.front().scope == currentScope) {
+	    declList.pop_front();
+	}
+	if( declList.empty() ) {
+	  table.erase( i );
+	}
+    }
+    currentScope -= 1;
+    for (deferListType::iterator i = deferListStack.top().begin(); i != deferListStack.top().end(); i++) {
+      addToCurrentScope( i->identifier, i->kind );
+    }
+    deferListStack.pop();
+    debugPrint( "nextIdentifiers size is " << nextIdentifiers.size() << " top is " << nextIdentifiers.top() << endl );
+    nextIdentifiers.pop();
+}
+
+void
+TypedefTable::enterContext( std::string contextName )
+{
+  currentContext = contextName;
+  contextScope = currentScope;
+}
+
+void
+TypedefTable::leaveContext(void)
+{
+  currentContext = "";
+}
+
+void
+TypedefTable::print(void) const
+{
+    for (tableType::const_iterator i = table.begin(); i != table.end(); i++) {
+	debugPrint( (*i).first << ": " );
+	list<Entry> declList = (*i).second;
+	for (list<Entry>::const_iterator j = declList.begin(); j != declList.end(); j++) {
+	    debugPrint( "(" << (*j).scope << " " << (*j).kind << ") " );
+	}
+	debugPrint( endl );
+    }
+}
Index: translator/Parser.old/TypedefTable.h
===================================================================
--- translator/Parser.old/TypedefTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser.old/TypedefTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,86 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: TypedefTable.h,v 1.5 2003/05/11 15:24:05 rcbilson Exp $
+ *
+ */
+
+#ifndef TYPEDEFTABLE_H
+#define TYPEDEFTABLE_H
+
+#include <map>
+#include <list>
+#include <string>
+#include <stack>
+
+class TypedefTable
+{
+  public:
+    enum kind_t { ID, TD, TG };
+  private:
+    struct Entry
+    {
+	int scope;
+	kind_t kind;
+    };
+    
+    struct DeferredEntry
+    {
+      std::string identifier;
+      kind_t kind;
+    };
+
+    typedef std::map<std::string, std::list<Entry> > tableType;
+    tableType table;
+
+    int currentScope;
+    std::string currentContext;
+    int contextScope;
+    
+    typedef std::list< DeferredEntry > deferListType;
+    std::stack< deferListType > deferListStack;
+    std::map< std::string, deferListType > contexts;
+    
+    std::stack< std::string > nextIdentifiers;
+
+    bool isKind(std::string identifier, kind_t kind) const;
+    void addToScope(const std::string &identifier, kind_t kind, int scope);
+  public:
+    TypedefTable();
+
+    bool isIdentifier(std::string identifier) const;
+    bool isTypedef(std::string identifier) const;
+    bool isTypegen(std::string identifier) const;
+    
+    // "addToCurrentScope" adds the identifier/type pair to the current scope This does less
+    // than you think it does, since each declaration is within its own scope.  Mostly useful for
+    // type parameters.
+    void addToCurrentScope(const std::string &identifier, kind_t kind);
+    void addToCurrentScope(kind_t kind);   // use nextIdentifiers.top()
+
+    // "addToEnclosingScope" adds the identifier/type pair to the scope that encloses the current
+    // one.  This is the right way to handle type and typedef names
+    void addToEnclosingScope(const std::string &identifier, kind_t kind);
+    void addToEnclosingScope(kind_t kind); // use nextIdentifiers.top()
+    
+    // "addToEnclosingScope2" adds the identifier/type pair to the scope that encloses the scope
+    // enclosing the the current one.  This is the right way to handle assertion names
+    void addToEnclosingScope2(const std::string &identifier, kind_t kind);
+    void addToEnclosingScope2(kind_t kind); // use nextIdentifiers.top()
+    
+    // set the next identifier to be used by an "add" operation without an identifier parameter
+    // within the current scope
+    void setNextIdentifier( const std::string &identifier );
+    
+    // dump the definitions from a pre-defined context into the current scope
+    void openContext( std::string contextName );
+    
+    void enterScope(void);
+    void leaveScope(void);
+    void enterContext( std::string contextName );
+    void leaveContext(void);
+
+    void print(void) const;
+};
+
+#endif /* ifndef TYPEDEFTABLE_H */
Index: translator/Parser.old/cfa.y
===================================================================
--- translator/Parser.old/cfa.y	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser.old/cfa.y	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,2699 @@
+/*                               -*- Mode: C -*-
+ *
+ * CForall Grammar Version 1.0, Copyright (C) Peter A. Buhr 2001 -- Permission is granted to copy this
+ *	grammar and to use it within software systems.  THIS GRAMMAR IS PROVIDED "AS IS" AND WITHOUT
+ *	ANY EXPRESS OR IMPLIED WARRANTIES.
+ *
+ * cfa.y --
+ *
+ * Author           : Peter A. Buhr
+ * Created On       : Sat Sep  1 20:22:55 2001
+ * Last Modified By : Peter A. Buhr
+ * Last Modified On : Tue Dec 17 08:47:30 2002
+ * Update Count     : 795
+ */
+
+/* This grammar is based on the ANSI99 C grammar, specifically parts of EXPRESSION and STATEMENTS, and on the
+   C grammar by James A. Roskind, specifically parts of DECLARATIONS and EXTERNAL DEFINITIONS.  While parts
+   have been copied, important changes have been made in all sections; these changes are sufficient to
+   constitute a new grammar.  In particular, this grammar attempts to be more syntactically precise, i.e., it
+   parses less incorrect language syntax that must be subsequently rejected by semantic checks.  Nevertheless,
+   there are still several semantic checks required and many are noted in the grammar. Finally, the grammar
+   is extended with GCC and CFA language extensions. */
+
+/* Acknowledgments to Richard Bilson, Glen Ditchfield, and Rodolfo Gabriel Esteves who all helped when I got
+   stuck with the grammar. */
+
+/* The root language for this grammar is ANSI99 C. All of ANSI99 is parsed, except for:
+
+   1. designation with '=' (use ':' instead)
+
+   Most of the syntactic extensions from ANSI90 to ANSI99 C are marked with the comment "ANSI99". This grammar
+   also has two levels of extensions. The first extensions cover most of the GCC C extensions, except for:
+
+   1. nested functions
+   2. generalized lvalues
+   3. designation with and without '=' (use ':' instead)
+   4. attributes not allowed in parenthesis of declarator
+
+   All of the syntactic extensions for GCC C are marked with the comment "GCC". The second extensions are for
+   Cforall (CFA), which fixes several of C's outstanding problems and extends C with many modern language
+   concepts. All of the syntactic extensions for CFA C are marked with the comment "CFA". As noted above,
+   there is one unreconcileable parsing problem between ANSI99 and CFA with respect to designators; this is
+   discussed in detail before the "designation" grammar rule. */
+
+%{
+#define YYDEBUG_LEXER_TEXT (yylval)			/* lexer loads this up each time */
+#define YYDEBUG 1					/* get the pretty debugging code to compile*/
+
+
+#include <cstdio>
+#include <stack>
+#include "TypedefTable.h"
+#include "lex.h"
+#include "ParseNode.h"
+#include "LinkageSpec.h"
+
+DeclarationNode *theTree = 0;				/* the resulting parse tree */
+LinkageSpec::Type linkage = LinkageSpec::Cforall;
+std::stack< LinkageSpec::Type > linkageStack;
+TypedefTable typedefTable;
+%}
+
+/************************* TERMINAL TOKENS ********************************/
+
+/* keywords */
+%token TYPEDEF
+%token AUTO EXTERN REGISTER STATIC
+%token INLINE						/* ANSI99 */
+%token FORTRAN						/* ANSI99, extension ISO/IEC 9899:1999 Section J.5.9(1) */
+%token CONST VOLATILE
+%token RESTRICT						/* ANSI99 */
+%token FORALL LVALUE					/* CFA */
+%token VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED
+%token BOOL COMPLEX IMAGINARY				/* ANSI99 */
+%token TYPEOF LABEL					/* GCC */
+%token ENUM STRUCT UNION
+%token TYPE FTYPE DTYPE CONTEXT				/* CFA */
+%token SIZEOF
+%token ALIGNOF ATTRIBUTE EXTENSION			/* GCC */
+%token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN
+%token CHOOSE FALLTHRU TRY CATCH THROW			/* CFA */
+%token ASM						/* ANSI99, extension ISO/IEC 9899:1999 Section J.5.10(1) */
+
+/* names and constants: lexer differentiates between identifier and typedef names */
+%token<tok> IDENTIFIER		TYPEDEFname		TYPEGENname
+%token<tok> INTEGERconstant	FLOATINGconstant	CHARACTERconstant       STRINGliteral
+%token<tok> ZERO		ONE			/* CFA */
+
+/* multi-character operators */
+%token ARROW			/* ->				*/
+%token ICR DECR			/* ++	--			*/
+%token LS RS			/* <<	>>			*/
+%token LE GE EQ NE		/* <=	>=	==	!=	*/
+%token ANDAND OROR		/* &&	||			*/
+%token ELLIPSIS			/* ...				*/
+
+%token MULTassign	DIVassign	MODassign	/* *=	/=	%=	*/
+%token PLUSassign	MINUSassign			/* +=	-=		*/
+%token LSassign		RSassign			/* <<=	>>=		*/
+%token ANDassign	ERassign	ORassign	/* &=	^=	|=	*/
+
+/* Types declaration */
+%union
+{
+  struct token tok;
+  ParseNode *pn;
+  ExpressionNode *en;
+  DeclarationNode *decl;
+  DeclarationNode::TyCon aggKey;
+  DeclarationNode::TypeClass tclass;
+  StatementNode *sn;
+  ConstantNode *constant;
+  InitializerNode *in;
+}
+
+%type<tok> zero_one  identifier  identifier_or_typedef_name
+%type<constant> string_literal_list
+
+/* expressions */
+%type<constant> constant
+%type<en> tuple			tuple_expression_list
+%type<en> unary_operator                assignment_operator
+%type<en> primary_expression		attribute_expression		postfix_expression	unary_expression
+%type<en> cast_expression		multiplicative_expression	additive_expression	shift_expression
+%type<en> relational_expression		equality_expression		AND_expression		exclusive_OR_expression
+%type<en> inclusive_OR_expression	logical_AND_expression		logical_OR_expression	conditional_expression
+%type<en> constant_expression		assignment_expression		assignment_expression_opt
+%type<en> comma_expression	comma_expression_opt
+%type<en> argument_expression_list	argument_expression		for_control_expression	assignment_opt
+%type<en> subrange
+
+/* statements */
+%type<sn> labeled_statement	compound_statement      expression_statement	selection_statement
+%type<sn> iteration_statement	jump_statement		exception_statement	asm_statement
+%type<sn> fall_through_opt fall_through
+%type<sn> statement		statement_list
+%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<sn> switch_clause_list_opt switch_clause_list choose_clause_list_opt choose_clause_list
+%type<pn> handler_list	handlers
+
+/* declarations */
+%type<decl> abstract_array abstract_declarator abstract_function abstract_parameter_array
+%type<decl> abstract_parameter_declaration abstract_parameter_declarator abstract_parameter_function
+%type<decl> abstract_parameter_ptr abstract_ptr
+
+%type<aggKey> aggregate_key
+%type<decl>  aggregate_name
+
+%type<decl> array_dimension array_parameter_1st_dimension array_parameter_dimension multi_array_dimension
+
+%type<decl> assertion assertion_list_opt
+
+%type<en>   bit_subrange_size_opt bit_subrange_size
+
+%type<decl> basic_declaration_specifier basic_type_name basic_type_specifier
+
+%type<decl> context_declaration context_declaration_list context_declaring_list context_specifier
+
+%type<decl> declaration declaration_list declaration_list_opt declaration_qualifier_list
+%type<decl> declaration_specifier declarator declaring_list
+
+%type<decl> elaborated_type_name
+
+%type<decl> enumerator_list enum_name
+%type<en> enumerator_value_opt
+
+%type<decl> exception_declaration external_definition external_definition_list external_definition_list_opt
+
+%type<decl> field_declaration field_declaration_list field_declarator field_declaring_list
+%type<en> field field_list
+
+%type<decl> function_array function_declarator function_definition function_no_ptr function_ptr
+
+%type<decl> identifier_parameter_array identifier_parameter_declarator identifier_parameter_function
+%type<decl> identifier_parameter_ptr identifier_list
+
+%type<decl> new_abstract_array new_abstract_declarator_no_tuple new_abstract_declarator_tuple
+%type<decl> new_abstract_function new_abstract_parameter_declaration new_abstract_parameter_list
+%type<decl> new_abstract_ptr new_abstract_tuple
+
+%type<decl> new_array_parameter_1st_dimension
+
+%type<decl> new_context_declaring_list new_declaration new_field_declaring_list
+%type<decl> new_function_declaration new_function_return new_function_specifier
+
+%type<decl> new_identifier_parameter_array new_identifier_parameter_declarator_no_tuple
+%type<decl> new_identifier_parameter_declarator_tuple new_identifier_parameter_ptr
+
+%type<decl> new_parameter_declaration new_parameter_list new_parameter_type_list new_parameter_type_list_opt
+
+%type<decl> new_typedef_declaration new_variable_declaration new_variable_specifier
+
+%type<decl> old_declaration old_declaration_list old_declaration_list_opt old_function_array
+%type<decl> old_function_declarator old_function_no_ptr old_function_ptr
+
+%type<decl> parameter_declaration parameter_list parameter_type_list
+%type<decl> parameter_type_list_opt
+
+%type<decl> paren_identifier paren_typedef
+
+%type<decl> storage_class storage_class_name storage_class_list
+
+%type<decl> sue_declaration_specifier sue_type_specifier
+
+%type<tclass> type_class
+%type<decl> type_declarator type_declarator_name type_declaring_list
+
+%type<decl> typedef typedef_array typedef_declaration typedef_declaration_specifier typedef_expression
+%type<decl> typedef_function typedef_parameter_array typedef_parameter_function typedef_parameter_ptr
+%type<decl> typedef_parameter_redeclarator typedef_ptr typedef_redeclarator typedef_type_specifier
+%type<decl> typegen_declaration_specifier typegen_type_specifier
+
+%type<decl> type_name type_name_no_function
+%type<decl> type_parameter type_parameter_list
+
+%type<en> type_name_list
+
+%type<decl> type_qualifier type_qualifier_name type_qualifier_list type_qualifier_list_opt type_specifier
+
+%type<decl> variable_abstract_array variable_abstract_declarator variable_abstract_function
+%type<decl> variable_abstract_ptr variable_array variable_declarator variable_function variable_ptr
+
+/* initializers */
+%type<in>  initializer initializer_list initializer_opt
+
+/* designators */
+%type<en>  designator designator_list designation
+
+
+/* Handle single shift/reduce conflict for dangling else by shifting the ELSE token. For example, this string
+   is ambiguous:
+   .---------.			matches IF '(' comma_expression ')' statement
+   if ( C ) S1 else S2
+   `-----------------'	matches IF '(' comma_expression ')' statement ELSE statement */
+
+%nonassoc THEN	/* rule precedence for IF '(' comma_expression ')' statement */
+%nonassoc ELSE	/* token precedence for start of else clause in IF statement */
+
+%start translation_unit					/* parse-tree root */
+
+%%
+/************************* Namespace Management ********************************/
+
+/* The grammar in the ANSI C standard is not strictly context-free, since it relies upon the distinct terminal
+   symbols "identifier" and "TYPEDEFname" that are lexically identical.  While it is possible to write a
+   purely context-free grammar, such a grammar would obscure the relationship between syntactic and semantic
+   constructs.  Hence, this grammar uses the ANSI style.
+
+   Cforall compounds this problem by introducing type names local to the scope of a declaration (for instance,
+   those introduced through "forall" qualifiers), and by introducing "type generators" -- parametrized types.
+   This latter type name creates a third class of identifiers that must be distinguished by the scanner.
+
+   Since the scanner cannot distinguish among the different classes of identifiers without some context
+   information, it accesses a data structure (the TypedefTable) to allow classification of an identifier that
+   it has just read.  Semantic actions during the parser update this data structure when the class of
+   identifiers change.
+
+   Because the Cforall language is block-scoped, there is the possibility that an identifier can change its
+   class in a local scope; it must revert to its original class at the end of the block.  Since type names can
+   be local to a particular declaration, each declaration is itself a scope.  This requires distinguishing
+   between type names that are local to the current declaration scope and those that persist past the end of
+   the declaration (i.e., names defined in "typedef" or "type" declarations).
+
+   The non-terminals "push" and "pop" derive the empty string; their only use is to denote the opening and
+   closing of scopes.  Every push must have a matching pop, although it is regrettable the matching pairs do
+   not always occur within the same rule.  These non-terminals may appear in more contexts than strictly
+   necessary from a semantic point of view.  Unfortunately, these extra rules are necessary to prevent parsing
+   conflicts -- the parser may not have enough context and look-ahead information to decide whether a new
+   scope is necessary, so the effect of these extra rules is to open a new scope unconditionally.  As the
+   grammar evolves, it may be neccesary to add or move around "push" and "pop" nonterminals to resolve
+   conflicts of this sort.  */
+
+push:
+		{
+		    typedefTable.enterScope();
+		}
+	;
+
+pop:
+		{
+		    typedefTable.leaveScope();
+		}
+	;
+
+/************************* CONSTANTS ********************************/
+
+constant:
+		/* ENUMERATIONconstant is not included here; it is treated as a variable with type
+		   "enumeration constant". */
+	INTEGERconstant		{ $$ = new ConstantNode(ConstantNode::Integer,   $1); }
+	| FLOATINGconstant	{ $$ = new ConstantNode(ConstantNode::Float,     $1); }
+	| CHARACTERconstant	{ $$ = new ConstantNode(ConstantNode::Character, $1); }
+	;
+
+identifier:
+	IDENTIFIER
+	| zero_one					/* CFA */
+	;
+
+zero_one:						/* CFA */
+	ZERO
+	| ONE
+	;
+
+string_literal_list:					/* juxtaposed strings are concatenated */
+	STRINGliteral				{ $$ = new ConstantNode(ConstantNode::String, $1); }
+	| string_literal_list STRINGliteral	{ $$ = $1->append( $2.str ); }
+	;
+
+/************************* EXPRESSIONS ********************************/
+
+primary_expression:
+	identifier					/* typedef name cannot be used as a variable name */
+		{ $$ = new VarRefNode($1); }
+	| constant
+		{ $$ = $1; }
+	| string_literal_list
+		{ $$ = $1; }
+	| '(' comma_expression ')'
+		{ $$ = $2; }
+	| '(' compound_statement ')'			/* GCC, lambda expression */
+		{ $$ = new ValofExprNode($2); }
+	;
+
+attribute_expression:					/* CFA, attribute */
+	primary_expression
+	| attribute_expression '!' identifier_or_typedef_name
+	| attribute_expression '!' type_qualifier
+	| attribute_expression '!' storage_class
+	| '<' type_name_no_function '>' '!' identifier_or_typedef_name	{ $$ = 0; }
+	| '<' type_name_no_function '>' '!' type_qualifier		{ $$ = 0; }
+	| '<' type_name_no_function '>' '!' storage_class		{ $$ = 0; }
+	;
+
+postfix_expression:
+	attribute_expression
+	| postfix_expression '[' push assignment_expression pop ']'
+		 /* CFA, comma_expression disallowed in the context because it results in a commom user error:
+		    subscripting a matrix with x[i,j] instead of x[i][j]. While this change is not backwards
+		    compatible, there seems to be 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, $2.filename, $2.lineno), $1, $4); }
+	| postfix_expression '(' argument_expression_list ')'
+		{ $$ = new CompositeExprNode($1, $3); }
+	| postfix_expression '.' identifier_or_typedef_name
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel, $2.filename, $2.lineno), $1,
+					     new VarRefNode($3)); }
+	| postfix_expression '.' '[' push field_list pop ']' /* CFA, tuple field selector */
+	| postfix_expression ARROW identifier_or_typedef_name
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel, $2.filename, $2.lineno), $1,
+					     new VarRefNode($3)); }
+	| postfix_expression ARROW '[' push field_list pop ']' /* CFA, tuple field selector */
+	| postfix_expression ICR
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::IncrPost, $2.filename, $2.lineno), $1); }
+	| postfix_expression DECR
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::DecrPost, $2.filename, $2.lineno), $1); }
+		/* GCC has priority: cast_expression */
+	| '(' type_name_no_function ')' '{' initializer_list comma_opt '}' /* ANSI99 */
+		{ $$ = 0; }
+	;
+
+argument_expression_list:
+	argument_expression
+	| argument_expression_list ',' argument_expression
+						{ $$ = (ExpressionNode *)($1->set_link($3)); }
+	;
+
+argument_expression:
+	/* empty */					/* use default argument */
+		{ $$ = 0; }
+	| assignment_expression
+	| identifier_or_typedef_name ':' assignment_expression
+                                                { $$ = $3->set_asArgName($1.str); }
+		/* Only a list of identifier_or_typedef_names is allowed in this context. However, there is
+		   insufficient look ahead to distinguish between this list of parameter names and a tuple, so
+		   the tuple form must be used with an appropriate semantic check. */
+	| '[' push assignment_expression pop ']' ':' assignment_expression
+						{ $$ = $7->set_asArgName($3.str); }
+	| '[' push assignment_expression ',' tuple_expression_list pop ']' ':' assignment_expression
+						{ $$ = $9->set_asArgName(new CompositeExprNode( new OperatorNode( OperatorNode::TupleC, $1.filename, $1.lineno ), (ExpressionNode *)$3->set_link( flattenCommas( $5 )))); }
+	;
+
+field_list:						/* CFA, tuple field selector */
+	field
+	| field_list ',' field                  { $$ = (ExpressionNode *)$1->set_link( $3 ); }
+	;
+
+field:							/* CFA, tuple field selector */
+	identifier_or_typedef_name
+						{ $$ = new VarRefNode( $1 ); }
+	| identifier_or_typedef_name '.' field
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel, $2.filename, $2.lineno), new VarRefNode( $1 ), $3); }
+	| identifier_or_typedef_name '.' '[' push field_list pop ']'
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel, $2.filename, $2.lineno), new VarRefNode( $1 ), $5); }
+	| identifier_or_typedef_name ARROW field
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel, $2.filename, $2.lineno), new VarRefNode( $1 ), $3); }
+	| identifier_or_typedef_name ARROW '[' push field_list pop ']'
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel, $2.filename, $2.lineno), new VarRefNode( $1 ), $5); }
+	;
+
+unary_expression:
+	postfix_expression
+	| ICR unary_expression
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Incr, $1.filename, $1.lineno), $2); }
+	| DECR unary_expression
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Decr, $1.filename, $1.lineno), $2); }
+	| EXTENSION cast_expression			/* GCC */
+		{ $$ = $2; }
+	| unary_operator cast_expression
+		{ $$ = new CompositeExprNode($1, $2); }
+	| '!' cast_expression
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Neg, $1.filename, $1.lineno), $2); }
+	| '*' cast_expression				/* CFA */
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PointTo, $1.filename, $1.lineno), $2); }
+		/* '*' is is separated from unary_operator because of shift/reduce conflict in:
+			{ * X; } // dereference X
+			{ * int X; } // CFA declaration of pointer to int
+		   '&' must be moved here if C++ reference variables are supported. */
+	| SIZEOF unary_expression
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::SizeOf, $1.filename, $1.lineno), $2); }
+	| SIZEOF '(' type_name_no_function ')'
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::SizeOf, $1.filename, $1.lineno), new TypeValueNode($3)); }
+	| ALIGNOF unary_expression			/* GCC, variable alignment */
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::AlignOf, $1.filename, $1.lineno), $2); }
+	| ALIGNOF '(' type_name_no_function ')'		/* GCC, type alignment */
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::AlignOf, $1.filename, $1.lineno), new TypeValueNode($3)); }
+	| ANDAND identifier_or_typedef_name		/* GCC, address of label */
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LabelAddress, $1.filename, $1.lineno),
+					     new VarRefNode($2, true)); }
+	;
+
+unary_operator:
+	'&'                               { $$ = new OperatorNode(OperatorNode::AddressOf, $1.filename, $1.lineno); }
+	| '+'                             { $$ = new OperatorNode(OperatorNode::UnPlus, $1.filename, $1.lineno); }
+	| '-'                             { $$ = new OperatorNode(OperatorNode::UnMinus, $1.filename, $1.lineno); }
+	| '~'                             { $$ = new OperatorNode(OperatorNode::BitNeg, $1.filename, $1.lineno); }
+	;
+
+cast_expression:
+	unary_expression
+	| '(' type_name_no_function ')' cast_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cast, $1.filename, $1.lineno),
+								       new TypeValueNode($2), $4); }
+	| '(' type_name_no_function ')' tuple
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cast, $1.filename, $1.lineno),
+								       new TypeValueNode($2), $4); }
+	;
+
+multiplicative_expression:
+	cast_expression
+	| multiplicative_expression '*' cast_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Mul, $2.filename, $2.lineno),$1,$3); }
+	| multiplicative_expression '/' cast_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Div, $2.filename, $2.lineno),$1,$3); }
+	| multiplicative_expression '%' cast_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Mod, $2.filename, $2.lineno),$1,$3); }
+	;
+
+additive_expression:
+	multiplicative_expression
+	| additive_expression '+' multiplicative_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Plus, $2.filename, $2.lineno),$1,$3); }
+	| additive_expression '-' multiplicative_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Minus, $2.filename, $2.lineno),$1,$3); }
+	;
+
+shift_expression:
+	additive_expression
+	| shift_expression LS additive_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LShift, $2.filename, $2.lineno),$1,$3); }
+	| shift_expression RS additive_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::RShift, $2.filename, $2.lineno),$1,$3); }
+	;
+
+relational_expression:
+	shift_expression
+	| relational_expression '<' shift_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LThan, $2.filename, $2.lineno),$1,$3); }
+	| relational_expression '>' shift_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::GThan, $2.filename, $2.lineno),$1,$3); }
+	| relational_expression LE shift_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LEThan, $2.filename, $2.lineno),$1,$3); }
+	| relational_expression GE shift_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::GEThan, $2.filename, $2.lineno),$1,$3); }
+	;
+
+equality_expression:
+	relational_expression
+	| equality_expression EQ relational_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Eq, $2.filename, $2.lineno), $1, $3); }
+	| equality_expression NE relational_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Neq, $2.filename, $2.lineno), $1, $3); }
+	;
+
+AND_expression:
+	equality_expression
+	| AND_expression '&' equality_expression
+						{ $$ =new CompositeExprNode(new OperatorNode(OperatorNode::BitAnd, $2.filename, $2.lineno), $1, $3); }
+	;
+
+exclusive_OR_expression:
+	AND_expression
+	| exclusive_OR_expression '^' AND_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Xor, $2.filename, $2.lineno), $1, $3); }
+	;
+
+inclusive_OR_expression:
+	exclusive_OR_expression
+	| inclusive_OR_expression '|' exclusive_OR_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::BitOr, $2.filename, $2.lineno), $1, $3); }
+	;
+
+logical_AND_expression:
+	inclusive_OR_expression
+	| logical_AND_expression ANDAND inclusive_OR_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::And, $2.filename, $2.lineno), $1, $3); }
+	;
+
+logical_OR_expression:
+	logical_AND_expression
+	| logical_OR_expression OROR logical_AND_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Or, $2.filename, $2.lineno), $1, $3); }
+	;
+
+conditional_expression:
+	logical_OR_expression
+	| logical_OR_expression '?' comma_expression ':' conditional_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cond, $2.filename, $2.lineno),
+								       (ExpressionNode *)mkList((*$1,*$3,*$5))); }
+	| logical_OR_expression '?' /* empty */ ':' conditional_expression /* GCC, omitted first operand */
+						{ $$=new CompositeExprNode(new OperatorNode(OperatorNode::NCond, $2.filename, $2.lineno),$1,$4); }
+	| logical_OR_expression '?' comma_expression ':' tuple /* CFA, tuple expression */
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cond, $2.filename, $2.lineno),
+								       (ExpressionNode *)mkList(( *$1, *$3, *$5 ))); }
+	;
+
+constant_expression:
+	conditional_expression
+	;
+
+assignment_expression:
+		/* CFA, assignment is separated from assignment_operator to ensure no assignment operations
+		   for tuples */
+	conditional_expression
+	| unary_expression '=' assignment_expression
+						{ $$ =new CompositeExprNode(new OperatorNode(OperatorNode::Assign, $2.filename, $2.lineno), $1, $3); }
+	| unary_expression assignment_operator assignment_expression
+						{ $$ =new CompositeExprNode($2, $1, $3); }
+	| tuple assignment_opt				/* CFA, tuple expression */
+		{
+		  if( $2 == 0 ) {
+		    $$ = $1;
+		  } else {
+		    $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Assign, $2.filename, $2.lineno ), $1, $2 );
+		  }
+		}
+	;
+
+assignment_expression_opt:
+	/* empty */
+		{ $$ = new NullExprNode; }
+	| assignment_expression
+	;
+
+tuple:							/* CFA, tuple */
+		/* CFA, one assignment_expression is factored out of comma_expression to eliminate a
+		   shift/reduce conflict with comma_expression in new_identifier_parameter_array and
+		   new_abstract_array */
+	'[' push pop ']'
+		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC, $1.filename, $1.lineno ) ); }
+	| '[' push assignment_expression pop ']'
+		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC, $1.filename, $1.lineno ), $3 ); }
+	| '[' push ',' tuple_expression_list pop ']'
+		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC, $1.filename, $1.lineno ), (ExpressionNode *)(new NullExprNode)->set_link( $4 ) ); }
+	| '[' push assignment_expression ',' tuple_expression_list pop ']'
+		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC, $1.filename, $1.lineno ), (ExpressionNode *)$3->set_link( flattenCommas( $5 ) ) ); }
+	;
+
+tuple_expression_list:
+	assignment_expression_opt
+	| tuple_expression_list ',' assignment_expression_opt
+		{ $$ = (ExpressionNode *)$1->set_link( $3 ); }
+	;
+
+assignment_operator:
+	MULTassign					{ $$ = new OperatorNode(OperatorNode::MulAssn, $1.filename, $1.lineno);   }
+	| DIVassign					{ $$ = new OperatorNode(OperatorNode::DivAssn, $1.filename, $1.lineno);   }
+	| MODassign					{ $$ = new OperatorNode(OperatorNode::ModAssn, $1.filename, $1.lineno);   }
+	| PLUSassign					{ $$ = new OperatorNode(OperatorNode::PlusAssn, $1.filename, $1.lineno);  }
+	| MINUSassign					{ $$ = new OperatorNode(OperatorNode::MinusAssn, $1.filename, $1.lineno); }
+	| LSassign					{ $$ = new OperatorNode(OperatorNode::LSAssn, $1.filename, $1.lineno);    }
+	| RSassign					{ $$ = new OperatorNode(OperatorNode::RSAssn, $1.filename, $1.lineno);    }
+	| ANDassign					{ $$ = new OperatorNode(OperatorNode::AndAssn, $1.filename, $1.lineno);   }
+	| ERassign					{ $$ = new OperatorNode(OperatorNode::ERAssn, $1.filename, $1.lineno);    }
+	| ORassign					{ $$ = new OperatorNode(OperatorNode::OrAssn, $1.filename, $1.lineno);    }
+	;
+
+comma_expression:
+	assignment_expression
+	| comma_expression ',' assignment_expression	/* { $$ = (ExpressionNode *)$1->add_to_list($3); } */
+			       { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Comma, $2.filename, $2.lineno),$1,$3); }
+	;
+
+comma_expression_opt:
+	/* empty */                                     { $$ = 0; }
+	| comma_expression
+	;
+
+/*************************** STATEMENTS *******************************/
+
+statement:
+	labeled_statement
+	| compound_statement
+	| expression_statement                          { $$ = $1; }
+	| selection_statement
+	| iteration_statement
+	| jump_statement
+	| exception_statement
+	| asm_statement
+	;
+
+labeled_statement:
+	identifier_or_typedef_name ':' attribute_list_opt statement
+		{ $$ = $4->add_label($1);}
+	;
+
+compound_statement:
+	'{' '}'
+		{ $$ = new CompoundStmtNode( (StatementNode *)0 ) }
+	| '{'
+		/* Two scopes are necessary because the block itself has a scope, but every declaration within
+		   the block also requires its own scope */
+	  push push
+	  label_declaration_opt				/* GCC, local labels */
+	  block_item_list pop '}'			/* ANSI99, intermix declarations and statements */
+		{ $$ = new CompoundStmtNode( $5 ); }
+	;
+
+block_item_list:					/* ANSI99 */
+	block_item
+	| block_item_list push block_item
+		{ if($1 != 0) { $1->set_link($3); $$ = $1; } }
+	;
+
+block_item:
+	declaration					/* CFA, new & old style declarations */
+		{ $$ = new StatementNode( $1 ); }
+	| EXTENSION declaration				/* GCC */
+		{ $$ = new StatementNode( $2 ); }
+	| statement pop
+	;
+
+statement_list:
+	statement
+	| statement_list statement
+		{ if($1 != 0) { $1->set_link($2); $$ = $1; } }
+	;
+
+expression_statement:
+	comma_expression_opt ';'
+		{ $$ = new StatementNode(StatementNode::Exp, $1, 0); }
+	;
+
+selection_statement:
+	IF '(' comma_expression ')' statement		%prec THEN
+		/* explicitly deal with the shift/reduce conflict on if/else */
+		{ $$ = new StatementNode(StatementNode::If, $1.filename, $1.lineno, $3, $5); }
+	| IF '(' comma_expression ')' statement ELSE statement
+		{ $$ = new StatementNode(StatementNode::If, $1.filename, $1.lineno, $3, (StatementNode *)mkList((*$5, *$7)) ); }
+	| SWITCH '(' comma_expression ')' case_clause	/* CFA */
+		{ $$ = new StatementNode(StatementNode::Switch, $1.filename, $1.lineno, $3, $5); }
+	| SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' /* CFA */
+		{ $$ = new StatementNode(StatementNode::Switch, $1.filename, $1.lineno, $3, $8); /* xxx */ }
+		/* The semantics of the declaration list is changed to include any associated initialization,
+		   which is performed *before* the transfer to the appropriate case clause.  Statements after
+		   the initial declaration list can never be executed, and therefore, are removed from the
+		   grammar even though C allows it. */
+	| CHOOSE '(' comma_expression ')' case_clause	/* CFA */
+		{ $$ = new StatementNode(StatementNode::Choose, $1.filename, $1.lineno, $3, $5); }
+	| CHOOSE '(' comma_expression ')' '{' push declaration_list_opt choose_clause_list_opt '}' /* CFA */
+		{ $$ = new StatementNode(StatementNode::Choose, $1.filename, $1.lineno, $3, $8); }
+	;
+
+/* CASE and DEFAULT clauses are only allowed in the SWITCH statement, precluding Duff's device. In addition, a
+   case clause allows a list of values and subranges. */
+
+case_value:						/* CFA */
+	constant_expression			{ $$ = $1; }
+	| constant_expression ELLIPSIS constant_expression /* GCC, subrange */
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range),$1,$3); }
+	| subrange					/* CFA, subrange */
+	;
+
+case_value_list:					/* CFA */
+	case_value
+	| case_value_list ',' case_value	{  $$ = (ExpressionNode *)($1->set_link($3)); }
+	;
+
+case_label:						/* CFA */
+	CASE case_value_list ':'		{  $$ = new StatementNode(StatementNode::Case, $1.filename, $1.lineno, $2, 0); }
+	| DEFAULT ':'			        {  $$ = new StatementNode(StatementNode::Default, $1.filename, $1.lineno);     }
+		/* A semantic check is required to ensure only one default clause per switch/choose
+		   statement. */
+	;
+
+case_label_list:					/* CFA */
+	case_label
+	| case_label_list case_label            { $$ = (StatementNode *)($1->set_link($2)); }
+	;
+
+case_clause:						/* CFA */
+	case_label_list statement		{  $$ = $1->append_last_case($2); }
+	;
+
+switch_clause_list_opt:					/* CFA */
+	/* empty */				{ $$ = 0; }
+	| switch_clause_list
+	;
+
+switch_clause_list:					/* CFA */
+	case_label_list statement_list
+						{ $$ = $1->append_last_case($2); }
+	| switch_clause_list case_label_list statement_list
+						{ $$ = (StatementNode *)($1->set_link($2->append_last_case($3))); }
+	;
+
+choose_clause_list_opt:					/* CFA */
+	/* empty */				{ $$ = 0; }
+	| choose_clause_list
+	;
+
+choose_clause_list:					/* CFA */
+	case_label_list fall_through
+		  { $$ = $1->append_last_case($2); }
+	| case_label_list statement_list fall_through_opt
+		  { $$ = $1->append_last_case((StatementNode *)mkList((*$2,*$3))); }
+	| choose_clause_list case_label_list fall_through
+		  { $$ = (StatementNode *)($1->set_link($2->append_last_case($3))); }
+	| choose_clause_list case_label_list statement_list fall_through_opt
+		  { $$ = (StatementNode *)($1->set_link($2->append_last_case((StatementNode *)mkList((*$3,*$4))))); }
+	;
+
+fall_through_opt:					/* CFA */
+	/* empty */				{ $$ = 0; }
+	| fall_through
+	;
+
+fall_through:						/* CFA */
+	FALLTHRU				{ $$ = new StatementNode(StatementNode::Fallthru, $1.filename, $1.lineno, 0, 0); }
+	| FALLTHRU ';'			        { $$ = new StatementNode(StatementNode::Fallthru, $1.filename, $1.lineno, 0, 0); }
+	;
+
+iteration_statement:
+	WHILE '(' comma_expression ')' statement
+						{ $$ = new StatementNode(StatementNode::While, $1.filename, $1.lineno, $3, $5); }
+	| DO statement WHILE '(' comma_expression ')' ';'
+						{ $$ = new StatementNode(StatementNode::Do, $1.filename, $1.lineno, $5, $2); }
+	| FOR '(' push for_control_expression ')' statement
+						{ $$ = new StatementNode(StatementNode::For, $1.filename, $1.lineno, $4, $6); }
+	;
+
+for_control_expression:
+	comma_expression_opt pop ';' comma_expression_opt ';' comma_expression_opt
+						{ $$ = new ForCtlExprNode($1, $4, $6); }
+	| declaration comma_expression_opt ';' comma_expression_opt /* ANSI99 */
+		/* Like C++, the loop index can be declared local to the loop. */
+						{ $$ = new ForCtlExprNode($1, $2, $4); }
+	;
+
+jump_statement:
+	GOTO identifier_or_typedef_name ';'
+						{ $$ = new StatementNode(StatementNode::Goto, $1.filename, $1.lineno, $2); }
+	| GOTO '*' comma_expression ';'		/* GCC, computed goto */
+		/* The syntax for the GCC computed goto violates normal expression precedence, e.g.,
+		   goto *i+3; => goto *(i+3); whereas normal operator precedence yields goto (*i)+3; */
+						{ $$ = new StatementNode(StatementNode::Goto, $1.filename, $1.lineno, $3); }
+	| CONTINUE ';'
+		/* A semantic check is required to ensure this statement appears only in the body of an
+		   iteration statement. */
+						{ $$ = new StatementNode(StatementNode::Continue, $1.filename, $1.lineno, 0, 0); }
+	| CONTINUE identifier_or_typedef_name ';'	/* CFA, multi-level continue */
+		/* A semantic check is required to ensure this statement appears only in the body of an
+		   iteration statement, and the target of the transfer appears only at the start of an
+		   iteration statement. */
+						{ $$ = new StatementNode(StatementNode::Continue, $1.filename, $1.lineno, $2); }
+	| BREAK ';'
+		/* A semantic check is required to ensure this statement appears only in the body of an
+		   iteration statement. */
+						{ $$ = new StatementNode(StatementNode::Break, $1.filename, $1.lineno, 0, 0); }
+	| BREAK identifier_or_typedef_name ';'		/* CFA, multi-level exit */
+		/* A semantic check is required to ensure this statement appears only in the body of an
+		   iteration statement, and the target of the transfer appears only at the start of an
+		   iteration statement. */
+						{ $$ = new StatementNode(StatementNode::Break, $1.filename, $1.lineno, $2 ); }
+	| RETURN comma_expression_opt ';'
+						{ $$ = new StatementNode(StatementNode::Return, $1.filename, $1.lineno, $2, 0); }
+	| THROW assignment_expression ';'
+						{ $$ = new StatementNode(StatementNode::Throw, $1.filename, $1.lineno, $2, 0); }
+	| THROW ';'
+                                                { $$ = new StatementNode(StatementNode::Throw, $1.filename, $1.lineno, 0, 0); }
+	;
+
+exception_statement:
+	TRY compound_statement handler_list
+			     { $$ = new StatementNode(StatementNode::Try, $1.filename, $1.lineno, 0,(StatementNode *)(mkList((*$2,*$3)))); }
+	;
+
+handler_list:
+		/* There must be at least one catch clause */
+	handlers
+	| CATCH '(' ELLIPSIS ')' compound_statement
+						{ $$ = StatementNode::newCatchStmt( $1.filename, $1.lineno, 0, $5, true ); }
+	| handlers CATCH '(' ELLIPSIS ')' compound_statement
+		/* ISO/IEC 9899:1999 Section 15.3(6) If present, a "..." handler shall be the last handler for
+		   its try block. */
+						{ $$ = $1->set_link( StatementNode::newCatchStmt( $2.filename, $2.lineno, 0, $6, true ) ); }
+	;
+
+handlers:
+	CATCH '(' push push exception_declaration pop ')' compound_statement pop
+						{ $$ = StatementNode::newCatchStmt($1.filename, $1.lineno, $5, $8); }
+	| handlers CATCH '(' push push exception_declaration pop ')' compound_statement pop
+						{ $$ = $1->set_link( StatementNode::newCatchStmt($2.filename, $2.lineno, $6, $9) );   }
+	;
+
+exception_declaration:
+		/* A semantic check is required to ensure type_specifier does not create a new type, e.g.:
+
+			catch ( struct { int i; } x ) ...
+
+		   This new type cannot catch any thrown type because of name equivalence among types. */
+	type_specifier
+	| type_specifier declarator
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    $$ = $2->addType( $1 );
+		}
+	| type_specifier variable_abstract_declarator
+		{   $$ = $2->addType( $1 ); }
+	| new_abstract_declarator_tuple identifier_or_typedef_name /* CFA */
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    $$ = $1->addName( $2 );
+		}
+	| new_abstract_declarator_tuple			/* CFA */
+	;
+
+asm_statement:
+	ASM type_qualifier_list_opt '(' constant_expression ')' ';'
+						{ $$ = new StatementNode(StatementNode::Asm, $1.filename, $1.lineno, 0, 0); }
+	| ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ')' ';' /* remaining GCC */
+						{ $$ = new StatementNode(StatementNode::Asm, $1.filename, $1.lineno, 0, 0); }
+	| ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ':' asm_operands_opt ')' ';'
+						{ $$ = new StatementNode(StatementNode::Asm, $1.filename, $1.lineno, 0, 0); }
+	| ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ':' asm_operands_opt ':'
+			asm_clobbers_list ')' ';'
+						{ $$ = new StatementNode(StatementNode::Asm, $1.filename, $1.lineno, 0, 0); }
+	;
+
+asm_operands_opt:					/* GCC */
+	/* empty */
+	| asm_operands_list
+	;
+
+asm_operands_list:					/* GCC */
+	asm_operand
+	| asm_operands_list ',' asm_operand
+	;
+
+asm_operand:						/* GCC */
+	STRINGliteral '(' constant_expression ')'	{}
+	;
+
+asm_clobbers_list:					/* GCC */
+	STRINGliteral				{}
+	| asm_clobbers_list ',' STRINGliteral
+	;
+
+/******************************* DECLARATIONS *********************************/
+
+declaration_list_opt:					/* used at beginning of switch statement */
+	pop
+		{ $$ = 0; }
+	| declaration_list
+	;
+
+declaration_list:
+	declaration
+	| declaration_list push declaration
+		{ $$ = $1->appendList( $3 ); }
+	;
+
+old_declaration_list_opt:				/* used to declare parameter types in K&R style functions */
+	pop
+		{ $$ = 0; }
+	| old_declaration_list
+	;
+
+old_declaration_list:
+	old_declaration
+	| old_declaration_list push old_declaration
+		{ $$ = $1->appendList( $3 ); }
+	;
+
+label_declaration_opt:					/* GCC, local label */
+	/* empty */
+	| label_declaration_list
+	;
+
+label_declaration_list:					/* GCC, local label */
+	LABEL label_list ';'
+	| label_declaration_list LABEL label_list ';'
+	;
+
+label_list:						/* GCC, local label */
+	identifier_or_typedef_name		{}
+	| label_list ',' identifier_or_typedef_name {}
+	;
+
+declaration:						/* CFA, new & old style declarations */
+	new_declaration
+	| old_declaration
+	;
+
+/* C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and
+   function declarations. CFA declarations use the same declaration tokens as in C; however, CFA places
+   declaration modifiers to the left of the base type, while C declarations place modifiers to the right of
+   the base type. CFA declaration modifiers are interpreted from left to right and the entire type
+   specification is distributed across all variables in the declaration list (as in Pascal).  ANSI C and the
+   new CFA declarations may appear together in the same program block, but cannot be mixed within a specific
+   declaration.
+
+	    CFA	    	    C
+	[10] int x;	int x[10];	// array of 10 integers
+	[10] * char y;	char *y[10];	// array of 10 pointers to char
+   */
+
+new_declaration:					/* CFA */
+	new_variable_declaration pop ';'
+	| new_typedef_declaration pop ';'
+	| new_function_declaration pop ';'
+	| type_declaring_list pop ';'
+	| context_specifier pop ';'
+	;
+
+new_variable_declaration:				/* CFA */
+	new_variable_specifier initializer_opt
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::ID);
+			$$ = $1;
+		}
+	| declaration_qualifier_list new_variable_specifier initializer_opt
+		/* declaration_qualifier_list also includes type_qualifier_list, so a semantic check is
+		   necessary to preclude them as a type_qualifier cannot appear in that context. */
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::ID);
+			$$ = $2->addQualifiers( $1 );
+		}
+	| new_variable_declaration pop ',' push identifier_or_typedef_name initializer_opt
+		{
+			typedefTable.addToEnclosingScope( *$5.str, TypedefTable::ID);
+			$$ = $1->appendList( $1->cloneType( $5 ) );
+		}
+	;
+
+new_variable_specifier:					/* CFA */
+		/* A semantic check is required to ensure asm_name only appears on declarations with implicit
+		   or explicit static storage-class */
+	new_abstract_declarator_no_tuple identifier_or_typedef_name asm_name_opt
+		{
+			typedefTable.setNextIdentifier( *$2.str );
+			$$ = $1->addName( $2 );
+		}
+	| new_abstract_tuple identifier_or_typedef_name asm_name_opt
+		{
+			typedefTable.setNextIdentifier( *$2.str );
+			$$ = $1->addName( $2 );
+		}
+	| type_qualifier_list new_abstract_tuple identifier_or_typedef_name asm_name_opt
+		{
+			typedefTable.setNextIdentifier( *$3.str );
+			$$ = $2->addQualifiers( $1 )->addName( $3 );
+		}
+	;
+
+new_function_declaration:				/* CFA */
+	new_function_specifier
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::ID);
+			$$ = $1;
+		}
+	| declaration_qualifier_list new_function_specifier
+		/* declaration_qualifier_list also includes type_qualifier_list, so a semantic check is
+		   necessary to preclude them as a type_qualifier cannot appear in this context. */
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::ID);
+			$$ = $2->addQualifiers( $1 );
+		}
+	| new_function_declaration pop ',' push identifier_or_typedef_name
+		{
+			typedefTable.addToEnclosingScope( *$5.str, TypedefTable::ID);
+			$$ = $1->appendList( $1->cloneType( $5 ) );
+		}
+	;
+
+new_function_specifier:					/* CFA */
+	'[' push pop ']' identifier '(' push new_parameter_type_list_opt pop ')'
+		{
+			typedefTable.setNextIdentifier( *($5.str) );
+			$$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0, $1.filename, $1.lineno ), $8, 0 );
+		}
+	| '[' push pop ']' TYPEDEFname '(' push new_parameter_type_list_opt pop ')'
+		{
+			typedefTable.setNextIdentifier( *($5.str) );
+			$$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0, $1.filename, $1.lineno ), $8, 0 );
+		}
+		/* identifier_or_typedef_name must be broken apart because of the sequence:
+
+		   '[' ']' identifier_or_typedef_name '(' new_parameter_type_list_opt ')'
+		   '[' ']' type_specifier
+
+		   type_specifier can resolve to just TYPEDEFname (e.g. typedef int T; int f( T );). Therefore
+		   this must be flattened to allow lookahead to the '(' without having to reduce
+		   identifier_or_typedef_name. */
+	| new_abstract_tuple identifier_or_typedef_name '(' push new_parameter_type_list_opt pop ')'
+		/* To obtain LR(1), this rule must be factored out from function return type (see
+		   new_abstract_declarator). */
+		{
+			$$ = DeclarationNode::newFunction( $2, $1, $5, 0 );
+		}
+	| new_function_return identifier_or_typedef_name '(' push new_parameter_type_list_opt pop ')'
+		{
+			$$ = DeclarationNode::newFunction( $2, $1, $5, 0 );
+		}
+	;
+
+new_function_return:					/* CFA */
+	'[' push new_parameter_list pop ']'
+		{ $$ = DeclarationNode::newTuple( $3, $1.filename, $1.lineno ); }
+	| '[' push new_parameter_list pop ',' push new_abstract_parameter_list pop ']'
+		/* To obtain LR(1), the last new_abstract_parameter_list is added into this flattened rule to
+		   lookahead to the ']'. */
+		{ $$ = DeclarationNode::newTuple( $3->appendList( $7 ), $1.filename, $1.lineno ); }
+	;
+
+new_typedef_declaration:				/* CFA */
+	TYPEDEF new_variable_specifier
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::TD);
+			$$ = $2->addTypedef();
+		}
+	| TYPEDEF new_function_specifier
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::TD);
+			$$ = $2->addTypedef();
+		}
+	| new_typedef_declaration pop ',' push identifier_or_typedef_name
+		{
+			typedefTable.addToEnclosingScope( *$5.str, TypedefTable::TD);
+			$$ = $1->appendList( $1->cloneType( $5 ) );
+		}
+	;
+
+/* Traditionally typedef is part of storage-class specifier for syntactic convenience only. Here, it is
+   factored out as a separate form of declaration, which syntactically precludes storage-class specifiers and
+   initialization. */
+
+typedef_declaration:
+	TYPEDEF type_specifier declarator
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::TD);
+			$$ = $3->addType( $2 )->addTypedef();
+		}
+	| typedef_declaration pop ',' push declarator
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::TD);
+			$$ = $1->appendList( $1->cloneBaseType( $5 )->addTypedef() );
+		}
+	| type_qualifier_list TYPEDEF type_specifier declarator /* remaining OBSOLESCENT (see 2) */
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::TD);
+			$$ = $4->addType( $3 )->addQualifiers( $1 )->addTypedef();
+		}
+	| type_specifier TYPEDEF declarator
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::TD);
+			$$ = $3->addType( $1 )->addTypedef();
+		}
+	| type_specifier TYPEDEF type_qualifier_list declarator
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::TD);
+			$$ = $4->addQualifiers($1)->addTypedef()->addType($1);
+		}
+	;
+
+typedef_expression:					/* GCC, naming expression type */
+	TYPEDEF identifier '=' assignment_expression
+		{
+			typedefTable.addToEnclosingScope(*($2.str), TypedefTable::TD);
+			$$ = DeclarationNode::newName( $2 ); // XXX
+		}
+	| typedef_expression pop ',' push identifier '=' assignment_expression
+		{
+			typedefTable.addToEnclosingScope(*($5.str), TypedefTable::TD);
+			$$ = DeclarationNode::newName( $5 ); // XXX
+		}
+	;
+
+old_declaration:
+	declaring_list pop ';'
+	| typedef_declaration pop ';'
+	| typedef_expression pop ';'			/* GCC, naming expression type */
+	| sue_declaration_specifier pop ';'
+	;
+
+declaring_list:
+		/* A semantic check is required to ensure asm_name only appears on declarations with implicit
+		   or explicit static storage-class */
+	declaration_specifier declarator asm_name_opt initializer_opt
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::ID);
+			$$ = ($2->addType( $1 ))->addInitializer($4);
+		}
+	| declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::ID);
+			$$ = $1->appendList( $1->cloneBaseType( $4->addInitializer($6) ) );
+		}
+	;
+
+declaration_specifier:					/* type specifier + storage class */
+	basic_declaration_specifier
+	| sue_declaration_specifier
+	| typedef_declaration_specifier
+	| typegen_declaration_specifier
+	;
+
+type_specifier:						/* declaration specifier - storage class */
+	basic_type_specifier
+	| sue_type_specifier
+	| typedef_type_specifier
+	| typegen_type_specifier
+	;
+
+type_qualifier_list_opt:				/* GCC, used in asm_statement */
+	/* empty */
+		{ $$ = 0; }
+	| type_qualifier_list
+	;
+
+type_qualifier_list:
+		/* A semantic check is necessary to ensure a type qualifier is appropriate for the kind of
+		   declaration.
+
+		   ISO/IEC 9899:1999 Section 6.7.3(4) : If the same qualifier appears more than once in the
+		   same specifier-qualifier-list, either directly or via one or more typedefs, the behavior is
+		   the same as if it appeared only once. */
+	type_qualifier
+	| type_qualifier_list type_qualifier
+		{ $$ = $1->addQualifiers( $2 ); }
+	;
+
+type_qualifier:
+	type_qualifier_name
+	| attribute
+		{ $$ = DeclarationNode::newQualifier( DeclarationNode::Const, $1.filename, $1.lineno ); }
+	;
+
+type_qualifier_name:
+	CONST
+		{ $$ = DeclarationNode::newQualifier( DeclarationNode::Const, $1.filename, $1.lineno ); }
+	| RESTRICT
+		{ $$ = DeclarationNode::newQualifier( DeclarationNode::Restrict, $1.filename, $1.lineno ); }
+	| VOLATILE
+		{ $$ = DeclarationNode::newQualifier( DeclarationNode::Volatile, $1.filename, $1.lineno ); }
+	| LVALUE					/* CFA */
+		{ $$ = DeclarationNode::newQualifier( DeclarationNode::Lvalue, $1.filename, $1.lineno ); }
+	| FORALL '(' 
+		{
+			typedefTable.enterScope();
+		}
+	  type_parameter_list ')'		/* CFA */
+		{
+			typedefTable.leaveScope();
+			$$ = DeclarationNode::newForall( $4, $1.filename, $1.lineno );
+		}
+	;
+
+declaration_qualifier_list:
+	storage_class_list
+	| type_qualifier_list storage_class_list	/* remaining OBSOLESCENT (see 2) */
+		{ $$ = $1->addQualifiers( $2 ); }
+	| declaration_qualifier_list type_qualifier_list storage_class_list
+		{ $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
+	;
+
+storage_class_list:
+		/* A semantic check is necessary to ensure a storage class is appropriate for the kind of
+		   declaration and that only one of each is specified, except for inline, which can appear
+		   with the others.
+
+		   ISO/IEC 9899:1999 Section 6.7.1(2) : At most, one storage-class specifier may be given in
+		   the declaration specifiers in a declaration. */
+	storage_class
+	| storage_class_list storage_class
+		{ $$ = $1->addQualifiers( $2 ); }
+	;
+
+storage_class:
+	storage_class_name
+	;
+
+storage_class_name:
+	AUTO
+		{ $$ = DeclarationNode::newStorageClass( DeclarationNode::Auto, $1.filename, $1.lineno ); }
+	| EXTERN
+		{ $$ = DeclarationNode::newStorageClass( DeclarationNode::Extern, $1.filename, $1.lineno ); }
+	| REGISTER
+		{ $$ = DeclarationNode::newStorageClass( DeclarationNode::Register, $1.filename, $1.lineno ); }
+	| STATIC
+		{ $$ = DeclarationNode::newStorageClass( DeclarationNode::Static, $1.filename, $1.lineno ); }
+	| INLINE					/* ANSI99 */
+		/* INLINE is essentially a storage class specifier for functions, and hence, belongs here. */
+		{ $$ = DeclarationNode::newStorageClass( DeclarationNode::Inline, $1.filename, $1.lineno ); }
+	| FORTRAN					/* ANSI99 */
+		{ $$ = DeclarationNode::newStorageClass( DeclarationNode::Fortran, $1.filename, $1.lineno ); }
+	;
+
+basic_type_name:
+	CHAR
+		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Char, $1.filename, $1.lineno ); }
+	| DOUBLE
+		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Double, $1.filename, $1.lineno ); }
+	| FLOAT
+		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Float, $1.filename, $1.lineno ); }
+	| INT
+		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Int, $1.filename, $1.lineno ); }
+	| LONG
+		{ $$ = DeclarationNode::newModifier( DeclarationNode::Long, $1.filename, $1.lineno ); }
+	| SHORT
+		{ $$ = DeclarationNode::newModifier( DeclarationNode::Short, $1.filename, $1.lineno ); }
+	| SIGNED
+		{ $$ = DeclarationNode::newModifier( DeclarationNode::Signed, $1.filename, $1.lineno ); }
+	| UNSIGNED
+		{ $$ = DeclarationNode::newModifier( DeclarationNode::Unsigned, $1.filename, $1.lineno ); }
+	| VOID
+		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Void, $1.filename, $1.lineno ); }
+	| BOOL						/* ANSI99 */
+		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Bool, $1.filename, $1.lineno ); }
+	| COMPLEX					/* ANSI99 */
+		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Complex, $1.filename, $1.lineno ); }
+	| IMAGINARY					/* ANSI99 */
+		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Imaginary, $1.filename, $1.lineno ); }
+	| TYPEOF '(' type_name ')'			/* GCC: typeof(x) y; */
+		{ $$ = $3; }
+	| TYPEOF '(' comma_expression ')'		/* GCC: typeof(a+b) y; */
+		{ $$ = DeclarationNode::newTypeof( $3, $1.filename, $1.lineno ); }
+	| '<' identifier '>'				/* CFA: <x> y; */
+		{ $$ = DeclarationNode::newName( $2 ); /* XXX */ }
+	| '<' '(' comma_expression ')' '>'		/* CFA: <(a+b)> y */
+		{ $$ = DeclarationNode::newName( $3 ); /* XXX */ }
+	;
+
+basic_declaration_specifier:
+		/* A semantic check is necessary for conflicting storage classes. */
+	basic_type_specifier
+	| declaration_qualifier_list basic_type_specifier
+		{ $$ = $2->addQualifiers( $1 ); }
+	| basic_declaration_specifier storage_class	/* remaining OBSOLESCENT (see 2) */
+		{ $$ = $1->addQualifiers( $2 ); }
+	| basic_declaration_specifier storage_class type_qualifier_list
+		{ $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
+	| basic_declaration_specifier storage_class basic_type_specifier
+		{ $$ = $3->addQualifiers( $2 )->addType( $1 ); }
+	;
+
+basic_type_specifier:
+		/* A semantic check is necessary for conflicting type qualifiers. */
+	basic_type_name
+	| type_qualifier_list basic_type_name
+		{ $$ = $2->addQualifiers( $1 ); }
+	| basic_type_specifier type_qualifier
+		{ $$ = $1->addQualifiers( $2 ); }
+	| basic_type_specifier basic_type_name
+		{ $$ = $1->addType( $2 ); }
+	;
+
+sue_declaration_specifier:
+	sue_type_specifier
+	| declaration_qualifier_list sue_type_specifier
+		{ $$ = $2->addQualifiers( $1 ); }
+	| sue_declaration_specifier storage_class	/* remaining OBSOLESCENT (see 2) */
+		{ $$ = $1->addQualifiers( $2 ); }
+	| sue_declaration_specifier storage_class type_qualifier_list
+		{ $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
+	;
+
+sue_type_specifier:
+	elaborated_type_name				/* struct, union, enum */
+	| type_qualifier_list elaborated_type_name
+		{ $$ = $2->addQualifiers( $1 ); }
+	| sue_type_specifier type_qualifier
+		{ $$ = $1->addQualifiers( $2 ); }
+	;
+
+typedef_declaration_specifier:
+	typedef_type_specifier
+	| declaration_qualifier_list typedef_type_specifier
+		{ $$ = $2->addQualifiers( $1 ); }
+	| typedef_declaration_specifier storage_class	/* remaining OBSOLESCENT (see 2) */
+		{ $$ = $1->addQualifiers( $2 ); }
+	| typedef_declaration_specifier storage_class type_qualifier_list
+		{ $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
+	;
+
+typedef_type_specifier:					/* typedef types */
+	TYPEDEFname
+		{ $$ = DeclarationNode::newFromTypedef( $1 ); }
+	| type_qualifier_list TYPEDEFname
+		{ $$ = DeclarationNode::newFromTypedef( $2 )->addQualifiers( $1 ); }
+	| typedef_type_specifier type_qualifier
+		{ $$ = $1->addQualifiers( $2 ); }
+	;
+
+elaborated_type_name:
+	aggregate_name
+	| enum_name
+	;
+
+aggregate_name:
+	aggregate_key '{' field_declaration_list '}'
+		{ $$ = DeclarationNode::newAggregate( $1, $2.filename, $2.lineno, 0, 0, $3 ); }
+	| aggregate_key identifier_or_typedef_name
+		{ $$ = DeclarationNode::newAggregate( $1, $2, 0, 0, 0 ); }
+	| aggregate_key identifier_or_typedef_name '{' field_declaration_list '}'
+		{ $$ = DeclarationNode::newAggregate( $1, $2, 0, 0, $4 ); }
+	| aggregate_key '(' push type_parameter_list pop ')' '{' field_declaration_list '}' /* CFA */
+		{ $$ = DeclarationNode::newAggregate( $1, $2.filename, $2.lineno, $4, 0, $8 ); }
+	| aggregate_key '(' push type_parameter_list pop ')' identifier_or_typedef_name /* CFA */
+		{ $$ = DeclarationNode::newAggregate( $1, $7, $4, 0, 0 ); }
+	| aggregate_key '(' push type_parameter_list pop ')' identifier_or_typedef_name '{' field_declaration_list '}' /* CFA */
+		{ $$ = DeclarationNode::newAggregate( $1, $7, $4, 0, $9 ); }
+	| aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' '{' field_declaration_list '}' /* CFA */
+		{ $$ = DeclarationNode::newAggregate( $1, $2.filename, $2.lineno, $4, $8, $11 ); }
+	| aggregate_key '(' push type_name_list pop ')' identifier_or_typedef_name /* CFA */
+		/* push and pop are only to prevent S/R conflicts */
+		{ $$ = DeclarationNode::newAggregate( $1, $7, 0, $4, 0 ); }
+	| aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' identifier_or_typedef_name '{' field_declaration_list '}' /* CFA */
+		{ $$ = DeclarationNode::newAggregate( $1, $10, $4, $8, $12 ); }
+	;
+
+aggregate_key:
+	STRUCT attribute_list_opt
+		{ $$ = DeclarationNode::Struct; }
+	| UNION attribute_list_opt
+		{ $$ = DeclarationNode::Union; }
+	;
+
+field_declaration_list:
+	field_declaration
+		{ $$ = $1; }
+	| field_declaration_list field_declaration
+		{ $$ = $1->appendList( $2 ); }
+	;
+
+field_declaration:
+	new_field_declaring_list ';'			/* CFA, new style field declaration */
+	| EXTENSION new_field_declaring_list ';'	/* GCC */
+		{ $$ = $2; }
+	| field_declaring_list ';'
+	| EXTENSION field_declaring_list ';'		/* GCC */
+		{ $$ = $2; }
+	;
+
+new_field_declaring_list:				/* CFA, new style field declaration */
+	new_abstract_declarator_tuple			/* CFA, no field name */
+	| new_abstract_declarator_tuple identifier_or_typedef_name
+		{ $$ = $1->addName( $2 ); }
+	| new_field_declaring_list ',' identifier_or_typedef_name
+		{ $$ = $1->appendList( $1->cloneType( $3 ) ); }
+	| new_field_declaring_list ','			/* CFA, no field name */
+		{ $$ = $1->appendList( $1->cloneType( 0 ) ); }
+	;
+
+field_declaring_list:
+	type_specifier field_declarator
+		{ $$ = $2->addType( $1 ); }
+	| field_declaring_list ',' attribute_list_opt field_declarator
+		{ $$ = $1->appendList( $1->cloneBaseType( $4 ) ); }
+	;
+
+field_declarator:
+	/* empty */					/* CFA, no field name */
+		{ $$ = 0; /* XXX */ }
+	| bit_subrange_size				/* no field name */
+		{ $$ = DeclarationNode::newBitfield( $1 ); }
+	| variable_declarator bit_subrange_size_opt
+		/* A semantic check is required to ensure bit_subrange only appears on base type int. */
+		{ $$ = $1->addBitfield( $2 ); }
+	| typedef_redeclarator bit_subrange_size_opt
+		/* A semantic check is required to ensure bit_subrange only appears on base type int. */
+		{ $$ = $1->addBitfield( $2 ); }
+	| variable_abstract_declarator			/* CFA, no field name */
+	;
+
+bit_subrange_size_opt:
+	/* empty */
+		{ $$ = 0; }
+	| bit_subrange_size
+		{ $$ = $1; }
+	;
+
+bit_subrange_size:
+	':' constant_expression
+		{ $$ = $2; }
+	;
+
+enum_key:
+	ENUM attribute_list_opt
+	;
+
+enum_name:
+	enum_key '{' enumerator_list comma_opt '}'
+		{ $$ = DeclarationNode::newEnum( $2.filename, $2.lineno, $3 ); }
+	| enum_key identifier_or_typedef_name '{' enumerator_list comma_opt '}'
+		{ $$ = DeclarationNode::newEnum( $2, $4 ); }
+	| enum_key identifier_or_typedef_name
+		{ $$ = DeclarationNode::newEnum( $2, 0 ); }
+	;
+
+enumerator_list:
+	identifier_or_typedef_name enumerator_value_opt
+		{ $$ = DeclarationNode::newEnumConstant( $1, $2 ); }
+	| enumerator_list ',' identifier_or_typedef_name enumerator_value_opt
+		{ $$ = $1->appendList( DeclarationNode::newEnumConstant( $3, $4 ) ); }
+	;
+
+enumerator_value_opt:
+	/* empty */
+		{ $$ = 0; }
+	| '=' constant_expression
+		{ $$ = $2; }
+	;
+
+/* Minimum of one parameter after which ellipsis is allowed only at the end. */
+
+new_parameter_type_list_opt:				/* CFA */
+	/* empty */
+		{ $$ = 0; }
+	| new_parameter_type_list
+	;
+
+new_parameter_type_list:				/* CFA, abstract + real */
+	new_abstract_parameter_list
+	| new_parameter_list
+	| new_parameter_list pop ',' push new_abstract_parameter_list
+		{ $$ = $1->appendList( $5 ); }
+	| new_abstract_parameter_list pop ',' push ELLIPSIS
+		{ $$ = $1->addVarArgs(); }
+	| new_parameter_list pop ',' push ELLIPSIS
+		{ $$ = $1->addVarArgs(); }
+	;
+
+new_parameter_list:					/* CFA */
+		/* To obtain LR(1) between new_parameter_list and new_abstract_tuple, the last
+		   new_abstract_parameter_list is factored out from new_parameter_list, flattening the rules
+		   to get lookahead to the ']'. */
+	new_parameter_declaration
+	| new_abstract_parameter_list pop ',' push new_parameter_declaration
+		{ $$ = $1->appendList( $5 ); }
+	| new_parameter_list pop ',' push new_parameter_declaration
+		{ $$ = $1->appendList( $5 ); }
+	| new_parameter_list pop ',' push new_abstract_parameter_list pop ',' push new_parameter_declaration
+		{ $$ = $1->appendList( $5 )->appendList( $9 ); }
+	;
+
+new_abstract_parameter_list:				/* CFA, new & old style abstract */
+	new_abstract_parameter_declaration
+	| new_abstract_parameter_list pop ',' push new_abstract_parameter_declaration
+		{ $$ = $1->appendList( $5 ); }
+	;
+
+parameter_type_list_opt:
+	/* empty */
+		{ $$ = 0; }
+	| parameter_type_list
+	;
+
+parameter_type_list:
+	parameter_list
+	| parameter_list pop ',' push ELLIPSIS
+		{ $$ = $1->addVarArgs(); }
+	;
+
+parameter_list:						/* abstract + real */
+	abstract_parameter_declaration
+	| parameter_declaration
+	| parameter_list pop ',' push abstract_parameter_declaration
+		{ $$ = $1->appendList( $5 ); }
+	| parameter_list pop ',' push parameter_declaration
+		{ $$ = $1->appendList( $5 ); }
+	;
+
+/* Provides optional identifier names (abstract_declarator/variable_declarator), no initialization, different
+   semantics for typedef name by using typedef_parameter_redeclarator instead of typedef_redeclarator, and
+   function prototypes. */
+
+new_parameter_declaration:				/* CFA, new & old style parameter declaration */
+	parameter_declaration
+	| new_identifier_parameter_declarator_no_tuple identifier_or_typedef_name assignment_opt
+		{ $$ = $1->addName( $2 ); }
+	| new_abstract_tuple identifier_or_typedef_name assignment_opt
+		/* To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator). */
+		{ $$ = $1->addName( $2 ); }
+	| type_qualifier_list new_abstract_tuple identifier_or_typedef_name assignment_opt
+		{ $$ = $2->addName( $3 )->addQualifiers( $1 ); }
+	| new_function_specifier
+	;
+
+new_abstract_parameter_declaration:			/* CFA, new & old style parameter declaration */
+	abstract_parameter_declaration
+	| new_identifier_parameter_declarator_no_tuple
+	| new_abstract_tuple
+		/* To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator). */
+	| type_qualifier_list new_abstract_tuple
+		{ $$ = $2->addQualifiers( $1 ); }
+	| new_abstract_function
+	;
+
+parameter_declaration:
+	declaration_specifier identifier_parameter_declarator assignment_opt
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID);
+		    $$ = $2->addType( $1 );
+		}
+	| declaration_specifier typedef_parameter_redeclarator assignment_opt
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID);
+		    $$ = $2->addType( $1 );
+		}
+	;
+
+abstract_parameter_declaration:
+	declaration_specifier
+	| declaration_specifier abstract_parameter_declarator
+		{ $$ = $2->addType( $1 ); }
+	;
+
+/* ISO/IEC 9899:1999 Section 6.9.1(6) : "An identifier declared as a typedef name shall not be redeclared as a
+   parameter." Because the scope of the K&R-style parameter-list sees the typedef first, the following is
+   based only on identifiers.  The ANSI-style parameter-list can redefine a typedef name. */
+
+identifier_list:					/* K&R-style parameter list => no types */
+	identifier
+		{ $$ = DeclarationNode::newName( $1 ); }
+	| identifier_list ',' identifier
+		{ $$ = $1->appendList( DeclarationNode::newName( $3 ) ); }
+	;
+
+identifier_or_typedef_name:
+	identifier
+	| TYPEDEFname
+	| TYPEGENname
+	;
+
+type_name_no_function:					/* sizeof, alignof, cast (constructor) */
+	new_abstract_declarator_tuple			/* CFA */
+	| type_specifier
+	| type_specifier variable_abstract_declarator
+		{ $$ = $2->addType( $1 ); }
+	;
+
+type_name:						/* typeof, assertion */
+	new_abstract_declarator_tuple			/* CFA */
+	| new_abstract_function				/* CFA */
+	| type_specifier
+	| type_specifier abstract_declarator
+		{ $$ = $2->addType( $1 ); }
+	;
+
+initializer_opt:
+	/* empty */                             { $$ = 0; }
+	| '=' initializer                       { $$ = $2; }
+	;
+
+initializer:
+	assignment_expression			{ $$ = new InitializerNode($1); }
+	| '{' initializer_list comma_opt '}'    { $$ = new InitializerNode($2, true); }
+	;
+
+initializer_list:
+	initializer
+	| designation initializer                            { $$ = $2->set_designators( $1 ); }
+	| initializer_list ',' initializer                   { $$ = (InitializerNode *)( $1->set_link($3) ); }
+	| initializer_list ',' designation initializer
+					   { $$ = (InitializerNode *)( $1->set_link( $4->set_designators($3) ) ); }
+	;
+
+/* There is an unreconcileable parsing problem between ANSI99 and CFA with respect to designators. The problem
+   is use of '=' to separator the designator from the initializer value, as in:
+
+	int x[10] = { [1] = 3 };
+
+   The string "[1] = 3" can be parsed as a designator assignment or a tuple assignment.  To disambiguate this
+   case, CFA changes the syntax from "=" to ":" as the separator between the designator and initializer. GCC
+   does uses ":" for field selection. The optional use of the "=" in GCC, or in this case ":", cannot be
+   supported either due to shift/reduce conflicts */
+
+designation:
+	designator_list ':'				/* ANSI99, CFA uses ":" instead of "=" */
+	| identifier_or_typedef_name ':'		/* GCC, field name */
+						       { $$ = new VarRefNode( $1 ); }
+	;
+
+designator_list:					/* ANSI99 */
+	designator
+	| designator_list designator                   { $$ = (ExpressionNode *)($1->set_link( $2 )); }
+	;
+
+designator:
+	'.' identifier_or_typedef_name			/* ANSI99, field name */
+						       { $$ = new VarRefNode( $2 ); }
+	| '[' push assignment_expression pop ']'	/* ANSI99, single array element */
+		/* assignment_expression used instead of constant_expression because of shift/reduce conflicts
+		   with tuple. */
+						       { $$ = $3; }
+	| '[' push subrange pop ']'			/* CFA, multiple array elements */
+						       { $$ = $3; }
+	| '[' push constant_expression ELLIPSIS constant_expression pop ']' /* GCC, multiple array elements */
+						       { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range, $1.filename, $1.lineno), $3, $5); }
+	| '.' '[' push field_list pop ']'		/* CFA, tuple field selector */
+						       { $$ = $4; }
+	;
+
+/* The CFA type system is based on parametric polymorphism, the ability to declare functions with type
+   parameters, rather than an object-oriented type system. This required four groups of extensions:
+
+   Overloading: function, data, and operator identifiers may be overloaded.
+
+   Type declarations: "type" is used to generate new types for declaring objects. Similarly, "dtype" is used
+       for object and incomplete types, and "ftype" is used for function types. Type declarations with
+       initializers provide definitions of new types. Type declarations with storage class "extern" provide
+       opaque types.
+
+   Polymorphic functions: A forall clause declares a type parameter. The corresponding argument is inferred at
+       the call site. A polymorphic function is not a template; it is a function, with an address and a type.
+
+   Specifications and Assertions: Specifications are collections of declarations parameterized by one or more
+       types. They serve many of the purposes of abstract classes, and specification hierarchies resemble
+       subclass hierarchies. Unlike classes, they can define relationships between types.  Assertions declare
+       that a type or types provide the operations declared by a specification.  Assertions are normally used
+       to declare requirements on type arguments of polymorphic functions.  */
+
+typegen_declaration_specifier:				/* CFA */
+	typegen_type_specifier
+	| declaration_qualifier_list typegen_type_specifier
+		{ $$ = $2->addQualifiers( $1 ); }
+	| typegen_declaration_specifier storage_class	/* remaining OBSOLESCENT (see 2) */
+		{ $$ = $1->addQualifiers( $2 ); }
+	| typegen_declaration_specifier storage_class type_qualifier_list
+		{ $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
+	;
+
+typegen_type_specifier:					/* CFA */
+	TYPEGENname '(' type_name_list ')'
+		{ $$ = DeclarationNode::newFromTypeGen( $1, $3 ); }
+	| type_qualifier_list TYPEGENname '(' type_name_list ')'
+		{ $$ = DeclarationNode::newFromTypeGen( $2, $4 )->addQualifiers( $1 ); }
+	| typegen_type_specifier type_qualifier
+		{ $$ = $1->addQualifiers( $2 ); }
+	;
+
+type_parameter_list:					/* CFA */
+	type_parameter assignment_opt
+	| type_parameter_list ',' type_parameter assignment_opt
+		{ $$ = $1->appendList( $3 ); }
+	;
+
+type_parameter:						/* CFA */
+	type_class identifier_or_typedef_name
+		{ typedefTable.addToEnclosingScope(*($2.str), TypedefTable::TD); }
+	  assertion_list_opt
+		{ $$ = DeclarationNode::newTypeParam( $1, $2.str )->addAssertions( $4 ); }
+	| type_specifier identifier_parameter_declarator
+	;
+
+type_class:						/* CFA */
+	TYPE
+		{ $$ = DeclarationNode::Type; }
+	| DTYPE
+		{ $$ = DeclarationNode::Ftype; }
+	| FTYPE
+		{ $$ = DeclarationNode::Dtype; }
+	;
+
+assertion_list_opt:					/* CFA */
+	/* empty */
+		{ $$ = 0; }
+	| assertion_list_opt assertion
+		{ $$ = $1 == 0 ? $2 : $1->appendList( $2 ); }
+	;
+
+assertion:						/* CFA */
+	'|' identifier_or_typedef_name '(' type_name_list ')'
+		{
+		    typedefTable.openContext( *($2.str) );
+		    $$ = DeclarationNode::newContextUse( $2, $4 );
+		}
+	| '|' '{' push context_declaration_list '}'
+		{ $$ = $4; }
+	| '|' '(' push type_parameter_list pop ')' '{' push context_declaration_list '}' '(' type_name_list ')'
+		{ $$ = 0; }
+	;
+
+type_name_list:						/* CFA */
+	type_name
+		{ $$ = new TypeValueNode( $1 ); }
+	| assignment_expression
+	| type_name_list ',' type_name
+		{ $$ = (ExpressionNode *)($1->set_link(new TypeValueNode( $3 ))); }
+	| type_name_list ',' assignment_expression
+		{ $$ = (ExpressionNode *)($1->set_link($3)); }
+	;
+
+type_declaring_list:					/* CFA */
+	TYPE type_declarator
+		{ $$ = $2; }
+	| storage_class_list TYPE type_declarator
+		{ $$ = $3->addQualifiers( $1 ); }
+	| type_declaring_list ',' type_declarator
+		{ $$ = $1->appendList( $3->copyStorageClasses( $1 ) ); }
+	;
+
+type_declarator:					/* CFA */
+	type_declarator_name assertion_list_opt
+		{ $$ = $1->addAssertions( $2 ); }
+	| type_declarator_name assertion_list_opt '=' type_name
+		{ $$ = $1->addAssertions( $2 )->addType( $4 ); }
+	;
+
+type_declarator_name:					/* CFA */
+	identifier_or_typedef_name
+		{
+		    typedefTable.addToEnclosingScope(*($1.str), TypedefTable::TD);
+		    $$ = DeclarationNode::newTypeDecl( $1, 0 );
+		}
+	| identifier_or_typedef_name '(' push type_parameter_list pop ')'
+		{
+		    typedefTable.addToEnclosingScope(*($1.str), TypedefTable::TG);
+		    $$ = DeclarationNode::newTypeDecl( $1, $4 );
+		}
+	;
+
+context_specifier:					/* CFA */
+	CONTEXT identifier_or_typedef_name '(' push type_parameter_list pop ')' '{' '}'
+		{
+		    typedefTable.addToEnclosingScope(*($2.str), TypedefTable::ID);
+		    $$ = DeclarationNode::newContext( $2, $5, 0 );
+		}
+	| CONTEXT identifier_or_typedef_name '(' push type_parameter_list pop ')' '{'
+		{
+		    typedefTable.enterContext( *($2.str) );
+		    typedefTable.enterScope();
+		}
+	  context_declaration_list '}'
+		{
+		    typedefTable.leaveContext();
+		    typedefTable.addToEnclosingScope(*($2.str), TypedefTable::ID);
+		    $$ = DeclarationNode::newContext( $2, $5, $10 );
+		}
+	;
+
+context_declaration_list:				/* CFA */
+	context_declaration
+	| context_declaration_list push context_declaration
+		{ $$ = $1->appendList( $3 ); }
+	;
+
+context_declaration:					/* CFA */
+	new_context_declaring_list pop ';'
+	| context_declaring_list pop ';'
+	;
+
+new_context_declaring_list:				/* CFA */
+	new_variable_specifier
+		{
+		    typedefTable.addToEnclosingScope2( TypedefTable::ID );
+		    $$ = $1;
+		}
+	| new_function_specifier
+		{
+		    typedefTable.addToEnclosingScope2( TypedefTable::ID );
+		    $$ = $1;
+		}
+	| new_context_declaring_list pop ',' push identifier_or_typedef_name
+		{
+		    typedefTable.addToEnclosingScope2( *($5.str), TypedefTable::ID );
+		    $$ = $1->appendList( $1->cloneType( $5 ) );
+		}
+	;
+
+context_declaring_list:					/* CFA */
+	type_specifier declarator
+		{
+		    typedefTable.addToEnclosingScope2( TypedefTable::ID);
+		    $$ = $2->addType( $1 );
+		}
+	| context_declaring_list pop ',' push declarator
+		{
+		    typedefTable.addToEnclosingScope2( TypedefTable::ID);
+		    $$ = $1->appendList( $1->cloneBaseType( $5 ) );
+		}
+	;
+
+/***************************** EXTERNAL DEFINITIONS *****************************/
+
+translation_unit:
+	/* empty */					/* empty input file */
+		{}
+	| external_definition_list
+		{
+		  if( theTree ) {
+		    theTree->appendList( $1 );
+		  } else {
+		    theTree = $1;
+		  }
+		}
+	;
+
+external_definition_list:
+	external_definition
+	| external_definition_list push external_definition
+		{
+		  if( $1 ) {
+		    $$ = $1->appendList( $3 );
+		  } else {
+		    $$ = $3;
+		  }
+		}
+	;
+
+external_definition_list_opt:
+	/* empty */
+		{
+		  $$ = 0;
+		}
+	| external_definition_list
+	;
+
+external_definition:
+	declaration
+	| function_definition
+	| asm_statement					/* GCC, global assembler statement */
+		{}
+	| EXTERN STRINGliteral
+		{
+		  linkageStack.push( linkage );
+		  linkage = LinkageSpec::fromString( *$2.str );
+		}
+	  '{' external_definition_list_opt '}'		/* C++-style linkage specifier */
+		{
+		  linkage = linkageStack.top();
+		  linkageStack.pop();
+		  $$ = $5;
+		}
+	| EXTENSION external_definition
+		{ $$ = $2; }
+	;
+
+function_definition:
+	new_function_specifier compound_statement	/* CFA */
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $1->addFunctionBody( $2 );
+		}
+	| declaration_qualifier_list new_function_specifier compound_statement /* CFA */
+		/* declaration_qualifier_list also includes type_qualifier_list, so a semantic check is
+		   necessary to preclude them as a type_qualifier cannot appear in this context. */
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 );
+		}
+
+	| declaration_specifier function_declarator compound_statement
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $2->addFunctionBody( $3 )->addType( $1 );
+		}
+
+		/* These rules are a concession to the "implicit int" type_specifier because there is a
+		   significant amount of code with functions missing a type-specifier on the return type.
+		   Parsing is possible because function_definition does not appear in the context of an
+		   expression (nested functions would preclude this concession). A function prototype
+		   declaration must still have a type_specifier. OBSOLESCENT (see 1) */
+	| function_declarator compound_statement
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $1->addFunctionBody( $2 );
+		}
+	| type_qualifier_list function_declarator compound_statement
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 );
+		}
+	| declaration_qualifier_list function_declarator compound_statement
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 );
+		}
+	| declaration_qualifier_list type_qualifier_list function_declarator compound_statement
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $3->addFunctionBody( $4 )->addQualifiers( $2 )->addQualifiers( $1 );
+		}
+
+		/* Old-style K&R function definition, OBSOLESCENT (see 4) */
+	| declaration_specifier old_function_declarator push old_declaration_list_opt compound_statement
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addType( $1 );
+		}
+	| old_function_declarator push old_declaration_list_opt compound_statement
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $1->addOldDeclList( $3 )->addFunctionBody( $4 );
+		}
+	| type_qualifier_list old_function_declarator push old_declaration_list_opt compound_statement
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addQualifiers( $1 );
+		}
+
+		/* Old-style K&R function definition with "implicit int" type_specifier, OBSOLESCENT (see 4) */
+	| declaration_qualifier_list old_function_declarator push old_declaration_list_opt compound_statement
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addQualifiers( $1 );
+		}
+	| declaration_qualifier_list type_qualifier_list old_function_declarator push old_declaration_list_opt
+			compound_statement
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $3->addOldDeclList( $5 )->addFunctionBody( $6 )->addQualifiers( $2 )->addQualifiers( $1 );
+		}
+	;
+
+declarator:
+	variable_declarator
+	| function_declarator
+	| typedef_redeclarator
+	;
+
+subrange:
+	constant_expression '~' constant_expression	/* CFA, integer subrange */
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range, $2.filename, $2.lineno), $1, $3); }
+	;
+
+asm_name_opt:						/* GCC */
+	/* empty */
+	| ASM '(' string_literal_list ')' attribute_list_opt
+	;
+
+attribute_list_opt:					/* GCC */
+	/* empty */
+	| attribute_list
+	;
+
+attribute_list:						/* GCC */
+	attribute
+	| attribute_list attribute
+	;
+
+attribute:						/* GCC */
+	ATTRIBUTE '(' '(' attribute_parameter_list ')' ')'
+	;
+
+attribute_parameter_list:				/* GCC */
+	attrib
+	| attribute_parameter_list ',' attrib
+	;
+
+attrib:							/* GCC */
+	/* empty */
+	| any_word
+	| any_word '(' comma_expression_opt ')'
+	;
+
+any_word:						/* GCC */
+	identifier_or_typedef_name {}
+	| storage_class_name {}
+	| basic_type_name {}
+	| type_qualifier {}
+	;
+
+/* ============================================================================
+   The following sections are a series of grammar patterns used to parse declarators. Multiple patterns are
+   necessary because the type of an identifier in wrapped around the identifier in the same form as its usage
+   in an expression, as in:
+
+	int (*f())[10] { ... };
+	... (*f())[3] += 1;	// definition mimics usage
+
+   Because these patterns are highly recursive, changes at a lower level in the recursion require copying some
+   or all of the pattern. Each of these patterns has some subtle variation to ensure correct syntax in a
+   particular context.
+   ============================================================================ */
+
+/* ----------------------------------------------------------------------------
+   The set of valid declarators before a compound statement for defining a function is less than the set of
+   declarators to define a variable or function prototype, e.g.:
+
+	valid declaration	invalid definition
+	-----------------	------------------
+	int f;			int f {}
+	int *f;			int *f {}
+	int f[10];		int f[10] {}
+	int (*f)(int);		int (*f)(int) {}
+
+   To preclude this syntactic anomaly requires separating the grammar rules for variable and function
+   declarators, hence variable_declarator and function_declarator.
+   ---------------------------------------------------------------------------- */
+
+/* This pattern parses a declaration of a variable that is not redefining a typedef name. The pattern
+   precludes declaring an array of functions versus a pointer to an array of functions. */
+
+variable_declarator:
+	paren_identifier attribute_list_opt
+	| variable_ptr
+	| variable_array attribute_list_opt
+	| variable_function attribute_list_opt
+	;
+
+paren_identifier:
+	identifier
+		{
+		    typedefTable.setNextIdentifier( *($1.str) );
+		    $$ = DeclarationNode::newName( $1 );
+		}
+	| '(' paren_identifier ')'			/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+variable_ptr:
+	'*' variable_declarator
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1.filename, $1.lineno ) ); }
+	| '*' type_qualifier_list variable_declarator
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1.filename, $1.lineno ) ); }
+	| '(' variable_ptr ')'
+		{ $$ = $2 }
+	;
+
+variable_array:
+	paren_identifier array_dimension
+		{ $$ = $1->addArray( $2 ); }
+	| '(' variable_ptr ')' array_dimension
+		{ $$ = $2->addArray( $4 ); }
+	| '(' variable_array ')' multi_array_dimension	/* redundant parenthesis */
+		{ $$ = $2->addArray( $4 ); }
+	| '(' variable_array ')'			/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+variable_function:
+	'(' variable_ptr ')' '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $2->addParamList( $6 ); }
+	| '(' variable_function ')'			/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+/* This pattern parses a function declarator that is not redefining a typedef name. Because functions cannot
+   be nested, there is no context where a function definition can redefine a typedef name. To allow nested
+   functions requires further separation of variable and function declarators in typedef_redeclarator.  The
+   pattern precludes returning arrays and functions versus pointers to arrays and functions. */
+
+function_declarator:
+	function_no_ptr attribute_list_opt
+	| function_ptr
+	| function_array attribute_list_opt
+	;
+
+function_no_ptr:
+	paren_identifier '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $1->addParamList( $4 ); }
+	| '(' function_ptr ')' '(' push parameter_type_list_opt pop ')'
+		{ $$ = $2->addParamList( $6 ); }
+	| '(' function_no_ptr ')'			/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+function_ptr:
+	'*' function_declarator
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1.filename, $1.lineno ) ); }
+	| '*' type_qualifier_list function_declarator
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1.filename, $1.lineno ) ); }
+	| '(' function_ptr ')'
+		{ $$ = $2; }
+	;
+
+function_array:
+	'(' function_ptr ')' array_dimension
+		{ $$ = $2->addArray( $4 ); }
+	| '(' function_array ')' multi_array_dimension	/* redundant parenthesis */
+		{ $$ = $2->addArray( $4 ); }
+	| '(' function_array ')'			/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+/* This pattern parses an old-style K&R function declarator (OBSOLESCENT, see 4) that is not redefining a
+   typedef name (see function_declarator for additional comments). The pattern precludes returning arrays and
+   functions versus pointers to arrays and functions. */
+
+old_function_declarator:
+	old_function_no_ptr
+	| old_function_ptr
+	| old_function_array
+	;
+
+old_function_no_ptr:
+	paren_identifier '(' identifier_list ')'	/* function_declarator handles empty parameter */
+		{ $$ = $1->addIdList( $3 ); }
+	| '(' old_function_ptr ')' '(' identifier_list ')'
+		{ $$ = $2->addIdList( $5 ); }
+	| '(' old_function_no_ptr ')'			/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+old_function_ptr:
+	'*' old_function_declarator
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1.filename, $1.lineno ) ); }
+	| '*' type_qualifier_list old_function_declarator
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1.filename, $1.lineno ) ); }
+	| '(' old_function_ptr ')'
+		{ $$ = $2; }
+	;
+
+old_function_array:
+	'(' old_function_ptr ')' array_dimension
+		{ $$ = $2->addArray( $4 ); }
+	| '(' old_function_array ')' multi_array_dimension /* redundant parenthesis */
+		{ $$ = $2->addArray( $4 ); }
+	| '(' old_function_array ')'			/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+/* This pattern parses a declaration for a variable or function prototype that redefines a typedef name, e.g.:
+
+	typedef int foo;
+	{
+	   int foo; // redefine typedef name in new scope
+	}
+
+   The pattern precludes declaring an array of functions versus a pointer to an array of functions, and
+   returning arrays and functions versus pointers to arrays and functions. */
+
+typedef_redeclarator:
+	paren_typedef attribute_list_opt
+	| typedef_ptr
+	| typedef_array attribute_list_opt
+	| typedef_function attribute_list_opt
+	;
+
+paren_typedef:
+	TYPEDEFname
+		{
+		typedefTable.setNextIdentifier( *($1.str) );
+		$$ = DeclarationNode::newName( $1 );
+		}
+	| '(' paren_typedef ')'
+		{ $$ = $2; }
+	;
+
+typedef_ptr:
+	'*' typedef_redeclarator
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1.filename, $1.lineno ) ); }
+	| '*' type_qualifier_list typedef_redeclarator
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1.filename, $1.lineno ) ); }
+	| '(' typedef_ptr ')'
+		{ $$ = $2; }
+	;
+
+typedef_array:
+	paren_typedef array_dimension
+		{ $$ = $1->addArray( $2 ); }
+	| '(' typedef_ptr ')' array_dimension
+		{ $$ = $2->addArray( $4 ); }
+	| '(' typedef_array ')' multi_array_dimension	/* redundant parenthesis */
+		{ $$ = $2->addArray( $4 ); }
+	| '(' typedef_array ')'				/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+typedef_function:
+	paren_typedef '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $1->addParamList( $4 ); }
+	| '(' typedef_ptr ')' '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $2->addParamList( $6 ); }
+	| '(' typedef_function ')'			/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+/* This pattern parses a declaration for a parameter variable or function prototype that is not redefining a
+   typedef name and allows the ANSI99 array options, which can only appear in a parameter list.  The pattern
+   precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays
+   and functions versus pointers to arrays and functions. */
+
+identifier_parameter_declarator:
+	paren_identifier attribute_list_opt
+	| identifier_parameter_ptr
+	| identifier_parameter_array attribute_list_opt
+	| identifier_parameter_function attribute_list_opt
+	;
+
+identifier_parameter_ptr:
+	'*' identifier_parameter_declarator
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1.filename, $1.lineno ) ); }
+	| '*' type_qualifier_list identifier_parameter_declarator
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1.filename, $1.lineno ) ); }
+	| '(' identifier_parameter_ptr ')'
+		{ $$ = $2; }
+	;
+
+identifier_parameter_array:
+	paren_identifier array_parameter_dimension
+		{ $$ = $1->addArray( $2 ); }
+	| '(' identifier_parameter_ptr ')' array_dimension
+		{ $$ = $2->addArray( $4 ); }
+	| '(' identifier_parameter_array ')' multi_array_dimension /* redundant parenthesis */
+		{ $$ = $2->addArray( $4 ); }
+	| '(' identifier_parameter_array ')'		/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+identifier_parameter_function:
+	paren_identifier '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $1->addParamList( $4 ); }
+	| '(' identifier_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $2->addParamList( $6 ); }
+	| '(' identifier_parameter_function ')'		/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+/* This pattern parses a declaration for a parameter variable or function prototype that is redefining a
+   typedef name, e.g.:
+
+	typedef int foo;
+	int f( int foo ); // redefine typedef name in new scope
+
+   and allows the ANSI99 array options, which can only appear in a parameter list.  In addition, the pattern
+   handles the special meaning of parenthesis around a typedef name:
+
+	ISO/IEC 9899:1999 Section 6.7.5.3(11) : "In a parameter declaration, a single typedef name in
+	parentheses is taken to be an abstract declarator that specifies a function with a single parameter,
+	not as redundant parentheses around the identifier."
+
+   which precludes the following cases:
+
+	typedef float T;
+	int f( int ( T [5] ) );			// see abstract_parameter_declarator
+	int g( int ( T ( int ) ) );		// see abstract_parameter_declarator
+	int f( int f1( T a[5] ) );		// see identifier_parameter_declarator
+	int g( int g1( T g2( int p ) ) );	// see identifier_parameter_declarator
+
+   In essence, a '(' immediately to the left of typedef name, T, is interpreted as starting a parameter type
+   list, and not as redundant parentheses around a redeclaration of T. Finally, the pattern also precludes
+   declaring an array of functions versus a pointer to an array of functions, and returning arrays and
+   functions versus pointers to arrays and functions. */
+
+typedef_parameter_redeclarator:
+	typedef attribute_list_opt
+	| typedef_parameter_ptr
+	| typedef_parameter_array attribute_list_opt
+	| typedef_parameter_function attribute_list_opt
+	;
+
+typedef:
+	TYPEDEFname
+		{
+		    typedefTable.setNextIdentifier( *($1.str) );
+		    $$ = DeclarationNode::newName( $1 );
+		}
+	;
+
+typedef_parameter_ptr:
+	'*' typedef_parameter_redeclarator
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1.filename, $1.lineno ) ); }
+	| '*' type_qualifier_list typedef_parameter_redeclarator
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1.filename, $1.lineno ) ); }
+	| '(' typedef_parameter_ptr ')'
+		{ $$ = $2; }
+	;
+
+typedef_parameter_array:
+	typedef array_parameter_dimension
+		{ $$ = $1->addArray( $2 ); }
+	| '(' typedef_parameter_ptr ')' array_parameter_dimension
+		{ $$ = $2->addArray( $4 ); }
+	;
+
+typedef_parameter_function:
+	typedef '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $1->addParamList( $4 ); }
+	| '(' typedef_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $2->addParamList( $6 ); }
+	;
+
+/* This pattern parses a declaration of an abstract variable or function prototype, i.e., there is no
+   identifier to which the type applies, e.g.:
+
+	sizeof( int );
+	sizeof( int [10] );
+
+   The pattern precludes declaring an array of functions versus a pointer to an array of functions, and
+   returning arrays and functions versus pointers to arrays and functions. */
+
+abstract_declarator:
+	abstract_ptr
+	| abstract_array attribute_list_opt
+	| abstract_function attribute_list_opt
+	;
+
+abstract_ptr:
+	'*'
+		{ $$ = DeclarationNode::newPointer( 0, $1.filename, $1.lineno ); }
+	| '*' type_qualifier_list
+		{ $$ = DeclarationNode::newPointer( $2, $1.filename, $1.lineno ); }
+	| '*' abstract_declarator
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1.filename, $1.lineno ) ); }
+	| '*' type_qualifier_list abstract_declarator
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1.filename, $1.lineno ) ); }
+	| '(' abstract_ptr ')'
+		{ $$ = $2; }
+	;
+
+abstract_array:
+	array_dimension
+	| '(' abstract_ptr ')' array_dimension
+		{ $$ = $2->addArray( $4 ); }
+	| '(' abstract_array ')' multi_array_dimension	/* redundant parenthesis */
+		{ $$ = $2->addArray( $4 ); }
+	| '(' abstract_array ')'			/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+abstract_function:
+	'(' push parameter_type_list_opt pop ')'	/* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = DeclarationNode::newFunction( 0, 0, $3, 0 ); }
+	| '(' abstract_ptr ')' '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $2->addParamList( $6 ); }
+	| '(' abstract_function ')'			/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+array_dimension:
+		/* Only the first dimension can be empty. */
+	'[' push pop ']'
+		{ $$ = DeclarationNode::newArray( 0, 0, false ); }
+	| '[' push pop ']' multi_array_dimension
+		{ $$ = DeclarationNode::newArray( 0, 0, false )->addArray( $5 ); }
+	| multi_array_dimension
+	;
+
+multi_array_dimension:
+	'[' push assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $3, 0, false ); }
+	| '[' push '*' pop ']'				/* ANSI99 */
+		{ $$ = DeclarationNode::newVarArray( 0 ); }
+	| multi_array_dimension '[' push assignment_expression pop ']'
+		{ $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); }
+	| multi_array_dimension '[' push '*' pop ']'	/* ANSI99 */
+		{ $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); }
+	;
+
+/* This pattern parses a declaration of a parameter abstract variable or function prototype, i.e., there is no
+   identifier to which the type applies, e.g.:
+
+	int f( int );		// abstract variable parameter; no parameter name specified
+	int f( int (int) );	// abstract function-prototype parameter; no parameter name specified
+
+   The pattern precludes declaring an array of functions versus a pointer to an array of functions, and
+   returning arrays and functions versus pointers to arrays and functions. */
+
+abstract_parameter_declarator:
+	abstract_parameter_ptr
+	| abstract_parameter_array attribute_list_opt
+	| abstract_parameter_function attribute_list_opt
+	;
+
+abstract_parameter_ptr:
+	'*'
+		{ $$ = DeclarationNode::newPointer( 0 ); }
+	| '*' type_qualifier_list
+		{ $$ = DeclarationNode::newPointer( $2 ); }
+	| '*' abstract_parameter_declarator
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
+	| '*' type_qualifier_list abstract_parameter_declarator
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
+	| '(' abstract_parameter_ptr ')'
+		{ $$ = $2; }
+	;
+
+abstract_parameter_array:
+	array_parameter_dimension
+	| '(' abstract_parameter_ptr ')' array_parameter_dimension
+		{ $$ = $2->addArray( $4 ); }
+	| '(' abstract_parameter_array ')' multi_array_dimension /* redundant parenthesis */
+		{ $$ = $2->addArray( $4 ); }
+	| '(' abstract_parameter_array ')'		/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+abstract_parameter_function:
+	'(' push parameter_type_list_opt pop ')'	/* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = DeclarationNode::newFunction( 0, 0, $3, 0 ); }
+	| '(' abstract_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $2->addParamList( $6 ); }
+	| '(' abstract_parameter_function ')'		/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+array_parameter_dimension:
+		/* Only the first dimension can be empty or have qualifiers. */
+	array_parameter_1st_dimension
+	| array_parameter_1st_dimension multi_array_dimension
+		{ $$ = $1->addArray( $2 ); }
+	| multi_array_dimension
+	;
+
+/* The declaration of an array parameter has additional syntax over arrays in normal variable declarations:
+
+	ISO/IEC 9899:1999 Section 6.7.5.2(1) : "The optional type qualifiers and the keyword static shall
+	appear only in a declaration of a function parameter with an array type, and then only in the
+	outermost array type derivation."
+   */
+
+array_parameter_1st_dimension:
+	'[' push pop ']'
+		{ $$ = DeclarationNode::newArray( 0, 0, false ); }
+	| '[' push type_qualifier_list '*' pop ']'	/* remaining ANSI99 */
+		{ $$ = DeclarationNode::newVarArray( $3 ); }
+	| '[' push type_qualifier_list assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $4, $3, false ); }
+	| '[' push STATIC assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $4, 0, true ); }
+	| '[' push STATIC type_qualifier_list assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $5, $4, true ); }
+	;
+
+/* This pattern parses a declaration of an abstract variable, i.e., there is no identifier to which the type
+   applies, e.g.:
+
+	sizeof( int ); // abstract variable; no identifier name specified
+
+   The pattern precludes declaring an array of functions versus a pointer to an array of functions, and
+   returning arrays and functions versus pointers to arrays and functions. */
+
+variable_abstract_declarator:
+	variable_abstract_ptr
+	| variable_abstract_array attribute_list_opt
+	| variable_abstract_function attribute_list_opt
+	;
+
+variable_abstract_ptr:
+	'*'
+		{ $$ = DeclarationNode::newPointer( 0 ); }
+	| '*' type_qualifier_list
+		{ $$ = DeclarationNode::newPointer( $2 ); }
+	| '*' variable_abstract_declarator
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
+	| '*' type_qualifier_list variable_abstract_declarator
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
+	| '(' variable_abstract_ptr ')'
+		{ $$ = $2; }
+	;
+
+variable_abstract_array:
+	array_dimension
+	| '(' variable_abstract_ptr ')' array_dimension
+		{ $$ = $2->addArray( $4 ); }
+	| '(' variable_abstract_array ')' multi_array_dimension /* redundant parenthesis */
+		{ $$ = $2->addArray( $4 ); }
+	| '(' variable_abstract_array ')'		/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+variable_abstract_function:
+	'(' variable_abstract_ptr ')' '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $2->addParamList( $6 ); }
+	| '(' variable_abstract_function ')'		/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+/* This pattern parses a new-style declaration for a parameter variable or function prototype that is either
+   an identifier or typedef name and allows the ANSI99 array options, which can only appear in a parameter
+   list. */
+
+new_identifier_parameter_declarator_tuple:		/* CFA */
+	new_identifier_parameter_declarator_no_tuple
+	| new_abstract_tuple
+	| type_qualifier_list new_abstract_tuple
+		{ $$ = $2->addQualifiers( $1 ); }
+	;
+
+new_identifier_parameter_declarator_no_tuple:		/* CFA */
+	new_identifier_parameter_ptr
+	| new_identifier_parameter_array
+	;
+
+new_identifier_parameter_ptr:				/* CFA */
+	'*' type_specifier
+		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
+	| type_qualifier_list '*' type_specifier
+		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
+	| '*' new_abstract_function
+		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
+	| type_qualifier_list '*' new_abstract_function
+		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
+	| '*' new_identifier_parameter_declarator_tuple
+		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
+	| type_qualifier_list '*' new_identifier_parameter_declarator_tuple
+		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
+	;
+
+new_identifier_parameter_array:				/* CFA */
+		/* Only the first dimension can be empty or have qualifiers. Empty dimension must be factored
+		   out due to shift/reduce conflict with new-style empty (void) function return type. */
+	'[' push pop ']' type_specifier
+		{ $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
+	| new_array_parameter_1st_dimension type_specifier
+		{ $$ = $2->addNewArray( $1 ); }
+	| '[' push pop ']' multi_array_dimension type_specifier
+		{ $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
+	| new_array_parameter_1st_dimension multi_array_dimension type_specifier
+		{ $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
+	| multi_array_dimension type_specifier
+		{ $$ = $2->addNewArray( $1 ); }
+	| '[' push pop ']' new_identifier_parameter_ptr
+		{ $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
+	| new_array_parameter_1st_dimension new_identifier_parameter_ptr
+		{ $$ = $2->addNewArray( $1 ); }
+	| '[' push pop ']' multi_array_dimension new_identifier_parameter_ptr
+		{ $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
+	| new_array_parameter_1st_dimension multi_array_dimension new_identifier_parameter_ptr
+		{ $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
+	| multi_array_dimension new_identifier_parameter_ptr
+		{ $$ = $2->addNewArray( $1 ); }
+	;
+
+new_array_parameter_1st_dimension:
+	'[' push type_qualifier_list '*' pop ']'	/* remaining ANSI99 */
+		{ $$ = DeclarationNode::newVarArray( $3 ); }
+	| '[' push type_qualifier_list assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $4, $3, false ); }
+	| '[' push declaration_qualifier_list assignment_expression pop ']'
+		/* declaration_qualifier_list must be used because of shift/reduce conflict with
+		   assignment_expression, so a semantic check is necessary to preclude them as a
+		   type_qualifier cannot appear in this context. */
+		{ $$ = DeclarationNode::newArray( $4, $3, true ); }
+	| '[' push declaration_qualifier_list type_qualifier_list assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $5, $4->addQualifiers( $3 ), true ); }
+	;
+
+/* This pattern parses a new-style declaration of an abstract variable or function prototype, i.e., there is
+   no identifier to which the type applies, e.g.:
+
+	[int] f( int );		// abstract variable parameter; no parameter name specified
+	[int] f( [int] (int) );	// abstract function-prototype parameter; no parameter name specified
+
+   These rules need LR(3):
+
+	new_abstract_tuple identifier_or_typedef_name
+	'[' new_parameter_list ']' identifier_or_typedef_name '(' new_parameter_type_list_opt ')'
+
+   since a function return type can be syntactically identical to a tuple type:
+
+	[int, int] t;
+	[int, int] f( int );
+
+   Therefore, it is necessary to look at the token after identifier_or_typedef_name to know when to reduce
+   new_abstract_tuple. To make this LR(1), several rules have to be flattened (lengthened) to allow
+   the necessary lookahead. To accomplish this, new_abstract_declarator has an entry point without tuple, and
+   tuple declarations are duplicated when appearing with new_function_specifier. */
+
+new_abstract_declarator_tuple:				/* CFA */
+	new_abstract_tuple
+	| type_qualifier_list new_abstract_tuple
+		{ $$ = $2->addQualifiers( $1 ); }
+	| new_abstract_declarator_no_tuple
+	;
+
+new_abstract_declarator_no_tuple:			/* CFA */
+	new_abstract_ptr
+	| new_abstract_array
+	;
+
+new_abstract_ptr:					/* CFA */
+	'*' type_specifier
+		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
+	| type_qualifier_list '*' type_specifier
+		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
+	| '*' new_abstract_function
+		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
+	| type_qualifier_list '*' new_abstract_function
+		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
+	| '*' new_abstract_declarator_tuple
+		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
+	| type_qualifier_list '*' new_abstract_declarator_tuple
+		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
+	;
+
+new_abstract_array:					/* CFA */
+		/* Only the first dimension can be empty. Empty dimension must be factored out due to
+		   shift/reduce conflict with empty (void) function return type. */
+	'[' push pop ']' type_specifier
+		{ $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
+	| '[' push pop ']' multi_array_dimension type_specifier
+		{ $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
+	| multi_array_dimension type_specifier
+		{ $$ = $2->addNewArray( $1 ); }
+	| '[' push pop ']' new_abstract_ptr
+		{ $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ) }
+	| '[' push pop ']' multi_array_dimension new_abstract_ptr
+		{ $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
+	| multi_array_dimension new_abstract_ptr
+		{ $$ = $2->addNewArray( $1 ); }
+	;
+
+new_abstract_tuple:					/* CFA */
+	'[' push new_abstract_parameter_list pop ']'
+		{ $$ = DeclarationNode::newTuple( $3 ); }
+	;
+
+new_abstract_function:					/* CFA */
+	'[' push pop ']' '(' new_parameter_type_list_opt ')'
+		{ $$ = DeclarationNode::newFunction( 0, DeclarationNode::newTuple( 0 ), $6, 0 ); }
+	| new_abstract_tuple '(' push new_parameter_type_list_opt pop ')'
+		{ $$ = DeclarationNode::newFunction( 0, $1, $4, 0 ); }
+	| new_function_return '(' push new_parameter_type_list_opt pop ')'
+		{ $$ = DeclarationNode::newFunction( 0, $1, $4, 0 ); }
+	;
+
+/* 1) ISO/IEC 9899:1999 Section 6.7.2(2) : "At least one type specifier shall be given in the declaration
+      specifiers in each declaration, and in the specifier-qualifier list in each structure declaration and
+      type name."
+
+   2) ISO/IEC 9899:1999 Section 6.11.5(1) : "The placement of a storage-class specifier other than at the
+      beginning of the declaration specifiers in a declaration is an obsolescent feature."
+
+   3) ISO/IEC 9899:1999 Section 6.11.6(1) : "The use of function declarators with empty parentheses (not
+      prototype-format parameter type declarators) is an obsolescent feature."
+
+   4) ISO/IEC 9899:1999 Section 6.11.7(1) : "The use of function definitions with separate parameter
+      identifier and declaration lists (not prototype-format parameter type and identifier declarators) is
+      an obsolescent feature."  */
+
+/************************* MISCELLANEOUS ********************************/
+
+comma_opt:						/* redundant comma */
+	/* empty */
+	| ','
+	;
+
+assignment_opt:
+	/* empty */
+		{ $$ = 0; }
+	| '=' assignment_expression
+		{ $$ = $2; }
+	;
+
+%%
+/* ----end of grammar----*/
+
+void yyerror(char *string) {
+    using std::cout;
+    using std::endl;
+    if( yyfilename ) {
+      cout << yyfilename << ":" << endl;
+    }
+    cout << yylineno << ": syntax error reading token " << *(yylval.str) << endl;
+}
+
+/* Local Variables: */
+/* fill-column: 110 */
+/* compile-command: "gmake" */
+/* End: */
Index: translator/Parser.old/lex.h
===================================================================
--- translator/Parser.old/lex.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser.old/lex.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,33 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: lex.h,v 1.1 2002/02/06 16:17:30 rcbilson Exp $
+ *
+ * Prototypes that enable Roskind's c5.y to compile with g++
+ * Richard Bilson       5 Jan 2001
+ *
+ */
+
+#ifndef PARSER_LEX_H
+#define PARSER_LEX_H
+
+int yylex();
+void yyerror(char *);
+extern int yylineno;
+extern char *yyfilename;
+extern "C" {
+#include <malloc.h>
+}
+
+struct token
+{
+  std::string *str;
+  char *filename;
+  int lineno;
+};
+
+/* External declarations for information sharing between lexer and scanner */
+#include "TypedefTable.h"
+extern TypedefTable typedefTable;
+
+#endif // ifndef PARSER_LEX_H
Index: translator/Parser.old/lex.l
===================================================================
--- translator/Parser.old/lex.l	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser.old/lex.l	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,363 @@
+/*                               -*- Mode: C -*- 
+ * 
+ * CForall Lexer Version 1.0, Copyright (C) Peter A. Buhr 2001 -- Permission is granted to copy this
+ *	grammar and to use it within software systems.  THIS GRAMMAR IS PROVIDED "AS IS" AND WITHOUT
+ *	ANY EXPRESS OR IMPLIED WARRANTIES.
+ * 
+ * lex.l -- 
+ * 
+ * Author           : Peter A. Buhr
+ * Created On       : Sat Sep 22 08:58:10 2001
+ * Last Modified By : Peter A. Buhr
+ * Last Modified On : Thu Jan 23 16:17:09 2003
+ * Update Count     : 191
+ */
+
+%option yylineno
+
+%{
+/* This lexer assumes the program has been preprocessed by cpp. Hence, all user level preprocessor
+   directive have been performed and removed from the source. The only exceptions are preprocessor
+   directives passed to the compiler (e.g., line-number directives) and C/C++ style comments, which
+   are ignored. */
+
+/*************** Includes and Defines *****************************/
+
+#include <string>
+
+#include "ParseNode.h"
+#include "cfa.tab.h" /* YACC generated definitions based on C++ grammar */
+#include "lex.h"
+
+char *yyfilename;
+
+#define WHITE_RETURN(x)		/* do nothing */
+#define NEWLINE_RETURN()	WHITE_RETURN('\n')
+#define RETURN_VAL(x)		yylval.tok.str = new std::string(yytext); yylval.tok.file = yyfilename; yylval.tok.line = yylineno; return(x)
+
+#define KEYWORD_RETURN(x)	RETURN_VAL(x)		/* keyword */
+#define IDENTIFIER_RETURN()	RETURN_VAL((typedefTable.isIdentifier(yytext) ? IDENTIFIER : typedefTable.isTypedef(yytext) ? TYPEDEFname : TYPEGENname))
+
+#define ASCIIOP_RETURN()	RETURN_VAL((int)yytext[0]) /* single character operator */
+#define NAMEDOP_RETURN(x)	RETURN_VAL(x)		/* multichar operator, with a name */
+
+#define NUMERIC_RETURN(x)	rm_underscore(); RETURN_VAL(x) /* numeric constant */
+
+void rm_underscore() {					/* remove underscores in constant or escape sequence */
+    int j = 0;
+    for ( int i = 0; i < yyleng; i += 1 ) {
+	if ( yytext[i] != '_' ) {
+	    yytext[j] = yytext[i];
+	    j += 1;
+	} // if
+    } // for
+    yyleng = j;
+    yytext[yyleng] = '\0';
+}
+
+%}
+
+octal [0-7]
+nonzero [1-9]
+decimal [0-9]
+hex [0-9a-fA-F]
+
+	/* identifier, GCC: $ in identifier */
+universal_char "\\"((u{hex_quad})|(U{hex_quad}{2}))
+identifier ([a-zA-Z_$]|{universal_char})([0-9a-zA-Z_$]|{universal_char})*
+
+	/*  numeric constants, CFA: '_' in constant */
+hex_quad {hex}{4}
+integer_suffix "_"?(([uU][lL]?)|([uU]("ll"|"LL")?)|([lL][uU]?)|("ll"|"LL")[uU]?)
+
+octal_digits ({octal})|({octal}({octal}|"_")*{octal})
+octal_prefix "0""_"?
+octal_constant (("0")|({octal_prefix}{octal_digits})){integer_suffix}?
+
+nonzero_digits ({nonzero})|({nonzero}({decimal}|"_")*{decimal})
+decimal_constant {nonzero_digits}{integer_suffix}?
+
+hex_digits ({hex})|({hex}({hex}|"_")*{hex})
+hex_prefix "0"[xX]"_"?
+hex_constant {hex_prefix}{hex_digits}{integer_suffix}?
+
+decimal_digits ({decimal})|({decimal}({decimal}|"_")*{decimal})
+fractional_constant ({decimal_digits}?"."{decimal_digits})|({decimal_digits}".")
+exponent "_"?[eE]"_"?[+-]?{decimal_digits}
+floating_suffix "_"?[flFL]
+floating_constant (({fractional_constant}{exponent}?)|({decimal_digits}{exponent})){floating_suffix}?
+
+binary_exponent "_"?[pP]"_"?[+-]?{decimal_digits}
+hex_fractional_constant ({hex_digits}?"."{hex_digits})|({hex_digits}".")
+hex_floating_constant {hex_prefix}(({hex_fractional_constant}{binary_exponent})|({hex_digits}{binary_exponent})){floating_suffix}?
+
+	/* character escape sequence, GCC: \e => esc character */
+simple_escape "\\"[abefnrtv'"?\\]
+octal_escape "\\"{octal}{1,3}
+hex_escape "\\""x"{hex}+
+escape_seq {simple_escape}|{octal_escape}|{hex_escape}|{universal_char}
+
+	/* display/white-space characters */
+h_tab [\011]
+form_feed [\014]
+v_tab [\013]
+c_return [\015]
+h_white [ ]|{h_tab}
+
+	/* operators */
+op_unary_only "~"|"!"
+op_unary_binary "+"|"-"|"*"
+op_unary_pre_post "++"|"--"
+op_unary {op_unary_only}|{op_unary_binary}|{op_unary_pre_post}
+
+op_binary_only "/"|"%"|"^"|"&"|"|"|"<"|">"|"="|"=="|"!="|"<<"|">>"|"<="|">="|"+="|"-="|"*="|"/="|"%="|"&="|"|="|"^="|"<<="|">>="
+op_binary_over {op_unary_binary}|{op_binary_only}
+op_binary_not_over "?"|"->"|"&&"|"||"
+operator {op_unary_pre_post}|{op_binary_over}|{op_binary_not_over}
+
+%x COMMENT
+
+%%
+	/* line directives */
+^{h_white}*"#"{h_white}*[0-9]+{h_white}*["][^"\n]+["][^\n]*"\n" {
+	char *end_num;
+	char *begin_string, *end_string;
+	char *filename;
+	long lineno, length;
+	lineno = strtol( yytext + 1, &end_num, 0 );
+	begin_string = strchr( end_num, '"' );
+	if( begin_string ) {
+	  end_string = strchr( begin_string + 1, '"' );
+	  if( end_string ) {
+	    length = end_string - begin_string - 1;
+	    filename = new char[ length + 1 ];
+	    memcpy( filename, begin_string + 1, length );
+	    filename[ length ] = '\0';
+	    //std::cout << "file " << filename << " line " << lineno << std::endl;
+	    yylineno = lineno;
+	    yyfilename = filename;
+	  }
+	}
+}
+
+	/* ignore preprocessor directives (for now) */
+^{h_white}*"#"[^\n]*"\n" ;
+
+	/* ignore C style comments */
+"/*"			{BEGIN COMMENT;}
+<COMMENT>.|\n		;
+<COMMENT>"*/"		{BEGIN 0;}
+
+	/* ignore C++ style comments */
+"//"[^\n]*"\n"		;
+
+	/* ignore whitespace */
+{h_white}+		{WHITE_RETURN(' ');}
+({v_tab}|{c_return}|{form_feed})+ {WHITE_RETURN(' ');}
+({h_white}|{v_tab}|{c_return}|{form_feed})*"\n" {NEWLINE_RETURN();}
+
+	/* keywords */
+__alignof		{KEYWORD_RETURN(ALIGNOF);}	/* GCC */
+__alignof__		{KEYWORD_RETURN(ALIGNOF);}	/* GCC */
+asm			{KEYWORD_RETURN(ASM);}
+__asm			{KEYWORD_RETURN(ASM);}		/* GCC */
+__asm__			{KEYWORD_RETURN(ASM);}		/* GCC */
+__attribute		{KEYWORD_RETURN(ATTRIBUTE);}	/* GCC */
+__attribute__		{KEYWORD_RETURN(ATTRIBUTE);}	/* GCC */
+auto			{KEYWORD_RETURN(AUTO);}
+_Bool			{KEYWORD_RETURN(BOOL);}		/* ANSI99 */
+break			{KEYWORD_RETURN(BREAK);}
+case			{KEYWORD_RETURN(CASE);}
+catch			{KEYWORD_RETURN(CATCH);}	/* CFA */
+char			{KEYWORD_RETURN(CHAR);}
+choose			{KEYWORD_RETURN(CHOOSE);}
+_Complex		{KEYWORD_RETURN(COMPLEX);}	/* ANSI99 */
+__complex		{KEYWORD_RETURN(COMPLEX);}	/* GCC */
+__complex__		{KEYWORD_RETURN(COMPLEX);}	/* GCC */
+const			{KEYWORD_RETURN(CONST);}
+__const			{KEYWORD_RETURN(CONST);}	/* GCC */
+__const__		{KEYWORD_RETURN(CONST);}	/* GCC */
+context			{KEYWORD_RETURN(CONTEXT);}
+continue		{KEYWORD_RETURN(CONTINUE);}
+default			{KEYWORD_RETURN(DEFAULT);}
+do			{KEYWORD_RETURN(DO);}
+double			{KEYWORD_RETURN(DOUBLE);}
+dtype			{KEYWORD_RETURN(DTYPE);}
+else			{KEYWORD_RETURN(ELSE);}
+enum			{KEYWORD_RETURN(ENUM);}
+__extension__		{KEYWORD_RETURN(EXTENSION);}	/* GCC */
+extern			{KEYWORD_RETURN(EXTERN);}
+fallthru		{KEYWORD_RETURN(FALLTHRU);}
+float			{KEYWORD_RETURN(FLOAT);}
+for			{KEYWORD_RETURN(FOR);}
+forall			{KEYWORD_RETURN(FORALL);}
+fortran			{KEYWORD_RETURN(FORTRAN);}
+ftype			{KEYWORD_RETURN(FTYPE);}
+goto			{KEYWORD_RETURN(GOTO);}
+if			{KEYWORD_RETURN(IF);}
+_Imaginary		{KEYWORD_RETURN(IMAGINARY);}	/* ANSI99 */
+__imag			{KEYWORD_RETURN(IMAGINARY);}	/* GCC */
+__imag__		{KEYWORD_RETURN(IMAGINARY);}	/* GCC */
+inline			{KEYWORD_RETURN(INLINE);}	/* ANSI99 */
+__inline		{KEYWORD_RETURN(INLINE);}	/* GCC */
+__inline__		{KEYWORD_RETURN(INLINE);}	/* GCC */
+int			{KEYWORD_RETURN(INT);}
+__label__		{KEYWORD_RETURN(LABEL);}	/* GCC */
+long			{KEYWORD_RETURN(LONG);}
+lvalue			{KEYWORD_RETURN(LVALUE);}
+register		{KEYWORD_RETURN(REGISTER);}
+restrict		{KEYWORD_RETURN(RESTRICT);}	/* ANSI99 */
+__restrict		{KEYWORD_RETURN(RESTRICT);}	/* GCC */
+__restrict__		{KEYWORD_RETURN(RESTRICT);}	/* GCC */
+return			{KEYWORD_RETURN(RETURN);}
+short			{KEYWORD_RETURN(SHORT);}
+signed			{KEYWORD_RETURN(SIGNED);}
+__signed		{KEYWORD_RETURN(SIGNED);}	/* GCC */
+__signed__		{KEYWORD_RETURN(SIGNED);}	/* GCC */
+sizeof			{KEYWORD_RETURN(SIZEOF);}
+static			{KEYWORD_RETURN(STATIC);}
+struct			{KEYWORD_RETURN(STRUCT);}
+switch			{KEYWORD_RETURN(SWITCH);}
+throw			{KEYWORD_RETURN(THROW);}	/* CFA */
+try			{KEYWORD_RETURN(TRY);}		/* CFA */
+type			{KEYWORD_RETURN(TYPE);}
+typedef			{KEYWORD_RETURN(TYPEDEF);}
+typeof			{KEYWORD_RETURN(TYPEOF);}	/* GCC */
+__typeof		{KEYWORD_RETURN(TYPEOF);}	/* GCC */
+__typeof__		{KEYWORD_RETURN(TYPEOF);}	/* GCC */
+union			{KEYWORD_RETURN(UNION);}
+unsigned		{KEYWORD_RETURN(UNSIGNED);}
+void			{KEYWORD_RETURN(VOID);}
+volatile		{KEYWORD_RETURN(VOLATILE);}
+__volatile		{KEYWORD_RETURN(VOLATILE);}	/* GCC */
+__volatile__		{KEYWORD_RETURN(VOLATILE);}	/* GCC */
+while			{KEYWORD_RETURN(WHILE);}
+
+	/* identifier */
+{identifier}		{IDENTIFIER_RETURN();}
+
+	/* numeric constants */
+"0"			{NUMERIC_RETURN(ZERO);}		/* CFA */
+"1"			{NUMERIC_RETURN(ONE);}		/* CFA */
+{decimal_constant}	{NUMERIC_RETURN(INTEGERconstant);}
+{octal_constant}	{NUMERIC_RETURN(INTEGERconstant);}
+{hex_constant}		{NUMERIC_RETURN(INTEGERconstant);}
+{floating_constant}	{NUMERIC_RETURN(FLOATINGconstant);}
+{hex_floating_constant}	{NUMERIC_RETURN(FLOATINGconstant);}
+
+	/* character constant, allows empty value */
+"L"?[']([^'\\\n]|{escape_seq})*['] {RETURN_VAL(CHARACTERconstant);}
+
+	/* string constant */
+"L"?["]([^"\\\n]|{escape_seq})*["] {RETURN_VAL(STRINGliteral);}
+
+	/* punctuation */
+"["			{ASCIIOP_RETURN();}
+"]"			{ASCIIOP_RETURN();}
+"("			{ASCIIOP_RETURN();}
+")"			{ASCIIOP_RETURN();}
+"{"			{ASCIIOP_RETURN();}
+"}"			{ASCIIOP_RETURN();}
+","			{ASCIIOP_RETURN();}		/* also operator */
+":"			{ASCIIOP_RETURN();}
+";"			{ASCIIOP_RETURN();}
+"."			{ASCIIOP_RETURN();}		/* also operator */
+"..."			{NAMEDOP_RETURN(ELLIPSIS);}
+
+	/* alternative ANSI99 brackets, "<:" & "<:<:" handled by preprocessor */
+"<:"			{RETURN_VAL('[');}
+":>"			{RETURN_VAL(']');}
+"<%"			{RETURN_VAL('{');}
+"%>"			{RETURN_VAL('}');}
+
+	/* operators */
+"!"			{ASCIIOP_RETURN();}
+"+"			{ASCIIOP_RETURN();}
+"-"			{ASCIIOP_RETURN();}
+"*"			{ASCIIOP_RETURN();}
+"/"			{ASCIIOP_RETURN();}
+"%"			{ASCIIOP_RETURN();}
+"^"			{ASCIIOP_RETURN();}
+"~"			{ASCIIOP_RETURN();}
+"&"			{ASCIIOP_RETURN();}
+"|"			{ASCIIOP_RETURN();}
+"<"			{ASCIIOP_RETURN();}
+">"			{ASCIIOP_RETURN();}
+"="			{ASCIIOP_RETURN();}
+"?"			{ASCIIOP_RETURN();}
+
+"++"			{NAMEDOP_RETURN(ICR);}
+"--"			{NAMEDOP_RETURN(DECR);}
+"=="			{NAMEDOP_RETURN(EQ);}
+"!="			{NAMEDOP_RETURN(NE);}
+"<<"			{NAMEDOP_RETURN(LS);}
+">>"			{NAMEDOP_RETURN(RS);}
+"<="			{NAMEDOP_RETURN(LE);}
+">="			{NAMEDOP_RETURN(GE);}
+"&&"			{NAMEDOP_RETURN(ANDAND);}
+"||"			{NAMEDOP_RETURN(OROR);}
+"->"			{NAMEDOP_RETURN(ARROW);}
+"+="			{NAMEDOP_RETURN(PLUSassign);}
+"-="			{NAMEDOP_RETURN(MINUSassign);}
+"*="			{NAMEDOP_RETURN(MULTassign);}
+"/="			{NAMEDOP_RETURN(DIVassign);}
+"%="			{NAMEDOP_RETURN(MODassign);}
+"&="			{NAMEDOP_RETURN(ANDassign);}
+"|="			{NAMEDOP_RETURN(ORassign);}
+"^="			{NAMEDOP_RETURN(ERassign);}
+"<<="			{NAMEDOP_RETURN(LSassign);}
+">>="			{NAMEDOP_RETURN(RSassign);}
+
+	/* CFA, operator identifier */
+{op_unary}"?"		{IDENTIFIER_RETURN();}		/* unary */
+"?"({op_unary_pre_post}|"()"|"[?]") {IDENTIFIER_RETURN();}
+"?"{op_binary_over}"?"	{IDENTIFIER_RETURN();}		/* binary */
+	/*
+	  This rule handles ambiguous cases with operator identifiers, e.g., "int *?*?()", where the
+	  string "*?*?"  can be lexed as "*"/"?*?" or "*?"/"*?". Since it is common practise to put
+	  a unary operator juxtaposed to an identifier, e.g., "*i", users will be annoyed if they
+	  cannot do this with respect to operator identifiers. Even with this special hack, there
+	  are 5 general cases that cannot be handled. The first case is for the function-call
+	  identifier "?()":
+
+	  int * ?()();	// declaration: space required after '*'
+	  * ?()();	// expression: space required after '*'
+
+	  Without the space, the string "*?()" is ambiguous without N character look ahead; it
+	  requires scanning ahead to determine if there is a '(', which is the start of an
+	  argument/parameter list.
+
+	  The 4 remaining cases occur in expressions:
+
+	  i++?i:0;		// space required before '?'
+	  i--?i:0;		// space required before '?'
+	  i?++i:0;		// space required after '?'
+	  i?--i:0;		// space required after '?'
+
+	  In the first two cases, the string "i++?" is ambiguous, where this string can be lexed as
+	  "i"/"++?" or "i++"/"?"; it requires scanning ahead to determine if there is a '(', which
+	  is the start of an argument list.  In the second two cases, the string "?++x" is
+	  ambiguous, where this string can be lexed as "?++"/"x" or "?"/"++x"; it requires scanning
+	  ahead to determine if there is a '(', which is the start of an argument list.
+	*/
+{op_unary}"?"(({op_unary_pre_post}|"[?]")|({op_binary_over}"?")) {
+			    // 1 or 2 character unary operator ?
+			    int i = yytext[1] == '?' ? 1 : 2;
+			    yyless( i );		/* put back characters up to first '?' */
+			    if ( i > 1 ) {
+				NAMEDOP_RETURN( yytext[0] == '+' ? ICR : DECR );
+			    } else {
+				ASCIIOP_RETURN();
+			    } // if
+			}
+
+	/* unknown characters */
+.			{printf("unknown character(s):\"%s\" on line %d\n", yytext, yylineno);}
+
+%%
+
+
+/* Local Variables: */
+/* fill-column: 100 */
+/* compile-command: "gmake" */
+/* End: */
Index: translator/Parser.old/lex.yy.cc
===================================================================
--- translator/Parser.old/lex.yy.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser.old/lex.yy.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,3070 @@
+#line 2 "Parser/lex.yy.cc"
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif	/* __STDC__ */
+#endif	/* ! __cplusplus */
+
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator).  This
+ * avoids problems with code like:
+ *
+ * 	if ( condition_holds )
+ *		yyless( 5 );
+ *	else
+ *		do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+		*yy_cp = yy_hold_char; \
+		YY_RESTORE_YY_MORE_OFFSET \
+		yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via yyrestart()), so that the user can continue scanning by
+	 * just pointing yyin at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+	};
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars;		/* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1;		/* whether we need to initialize */
+static int yy_start = 0;	/* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO(( FILE *input_file ));
+
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
+
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! yy_current_buffer ) \
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	yy_current_buffer->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! yy_current_buffer ) \
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+	yy_current_buffer->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+
+#define YY_USES_REJECT
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern int yylineno;
+int yylineno = 1;
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+	yytext_ptr = yy_bp; \
+	yyleng = (int) (yy_cp - yy_bp); \
+	yy_hold_char = *yy_cp; \
+	*yy_cp = '\0'; \
+	yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 150
+#define YY_END_OF_BUFFER 151
+static yyconst short int yy_acclist[636] =
+    {   0,
+      151,  149,  150,    7,  149,  150,    9,  150,    8,  149,
+      150,  110,  149,  150,  149,  150,   85,  149,  150,  115,
+      149,  150,  118,  149,  150,  149,  150,   97,  149,  150,
+       98,  149,  150,  113,  149,  150,  111,  149,  150,  101,
+      149,  150,  112,  149,  150,  104,  149,  150,  114,  149,
+      150,   86,   89,  149,  150,   87,   88,  149,  150,   88,
+      149,  150,  102,  149,  150,  103,  149,  150,  120,  149,
+      150,  122,  149,  150,  121,  149,  150,  123,  149,  150,
+       85,  149,  150,   95,  149,  150,  149,  150,   96,  149,
+      150,  116,  149,  150,   85,  149,  150,   85,  149,  150,
+
+       85,  149,  150,   85,  149,  150,   85,  149,  150,   85,
+      149,  150,   85,  149,  150,   85,  149,  150,   85,  149,
+      150,   85,  149,  150,   85,  149,  150,   85,  149,  150,
+       85,  149,  150,   85,  149,  150,   85,  149,  150,   85,
+      149,  150,   99,  149,  150,  119,  149,  150,  100,  149,
+      150,  117,  149,  150,    7,  149,  150,  149,  150,    4,
+      150,    4,  150,    7,    9,    8,  127,  145,   94,   85,
+      139,  109,  132,  140,   93,  137,  124,  135,  125,  136,
+      134,   91,    3,  138,   91,   89,   89,   89,   89,   88,
+       88,   88,   88,  107,  108,  106,  128,  130,  126,  131,
+
+      129,  142,   85,   85,   85,   85,   85,   85,   85,   85,
+       85,   85,   85,   33,   85,   85,   85,   85,   85,   85,
+       85,   85,   85,   85,   47,   85,   85,   85,   85,   85,
+       85,   85,   85,   85,   85,   85,   85,   85,   85,   85,
+      141,  133,    7,    2,    5,  105,   91,   91,    6,   89,
+       91,   89,   89,   89,   89,   90,   88,   88,   88,   88,
+      143,  144,  147,  146,   85,   85,   85,   85,   85,   85,
+       85,   85,   85,   85,   85,   85,   12,   85,   85,   85,
+       85,   85,   85,   85,   85,   85,   85,   85,   85,   85,
+       85,   85,   85,   42,   85,   85,   85,   85,   54,   85,
+
+       85,   85,   85,   85,   85,   85,   85,   85,   85,   85,
+       85,   85,   72,   85,   85,   85,   85,   85,   85,   85,
+      148,   91,   91,   89,   89,   90,   90,   90,   90,   88,
+       88,   85,   85,   85,   85,   85,   85,   85,   85,   85,
+       85,   85,   85,   85,   85,   85,   17,   85,   85,   20,
+       85,   85,   22,   85,   85,   85,   85,   85,   85,   85,
+       36,   85,   37,   85,   85,   85,   85,   85,   85,   85,
+       46,   85,   85,   56,   85,   85,   85,   85,   85,   85,
+       85,   85,   85,   85,   85,   85,   73,   85,   85,   85,
+       80,   85,   85,   85,   91,   90,   90,   92,   90,   90,
+
+       18,   85,   85,   85,   85,   13,   85,   85,   85,   85,
+       85,   85,   85,   85,   85,   85,   85,   85,   19,   85,
+       21,   85,   85,   27,   85,   85,   85,   85,   85,   35,
+       85,   85,   85,   41,   85,   85,   85,   45,   85,   85,
+       85,   85,   85,   85,   63,   85,   85,   85,   85,   85,
+       85,   71,   85,   85,   85,   78,   85,   85,   85,   84,
+       85,   92,   90,   92,   92,   90,   85,   85,   85,   85,
+       85,   85,   85,   85,   85,   49,   85,   85,   85,   85,
+       85,   85,   85,   23,   85,   85,   85,   85,   34,   85,
+       39,   85,   85,   43,   85,   85,   51,   85,   57,   85,
+
+       85,   85,   62,   85,   64,   85,   67,   85,   68,   85,
+       69,   85,   70,   85,   85,   75,   85,   85,   85,    1,
+        2,   92,   85,   85,   85,   14,   85,   85,   85,   28,
+       85,   85,   85,   85,   85,   85,   85,   85,   85,   30,
+       85,   85,   32,   85,   85,   44,   85,   85,   85,   74,
+       85,   85,   85,   24,   85,   85,   85,   85,   85,   85,
+       85,   50,   85,   52,   85,   85,   85,   65,   85,   76,
+       85,   85,   31,   85,   40,   85,   58,   85,   59,   85,
+       79,   85,   81,   85,   85,   10,   85,   85,   25,   85,
+       29,   85,   85,   85,   55,   85,   85,   85,   85,   85,
+
+       48,   85,   85,   85,   85,   85,   53,   85,   60,   85,
+       66,   85,   77,   85,   82,   85,   11,   85,   15,   85,
+       26,   85,   85,   85,   85,   85,   85,   61,   85,   83,
+       85,   16,   85,   38,   85
+    } ;
+
+static yyconst short int yy_accept[619] =
+    {   0,
+        1,    1,    1,    1,    1,    2,    4,    7,    9,   12,
+       15,   17,   20,   23,   26,   28,   31,   34,   37,   40,
+       43,   46,   49,   52,   56,   60,   63,   66,   69,   72,
+       75,   78,   81,   84,   87,   89,   92,   95,   98,  101,
+      104,  107,  110,  113,  116,  119,  122,  125,  128,  131,
+      134,  137,  140,  143,  146,  149,  152,  155,  158,  160,
+      162,  164,  165,  166,  166,  167,  168,  169,  169,  170,
+      170,  171,  171,  172,  173,  174,  175,  175,  176,  176,
+      177,  178,  179,  180,  181,  182,  182,  183,  184,  184,
+      185,  186,  187,  187,  187,  188,  189,  189,  189,  190,
+
+      191,  192,  193,  193,  194,  195,  196,  197,  198,  199,
+      200,  201,  202,  202,  202,  202,  202,  202,  202,  202,
+      202,  202,  202,  202,  202,  202,  202,  202,  202,  202,
+      202,  203,  204,  205,  206,  207,  208,  209,  210,  211,
+      212,  213,  214,  216,  217,  218,  219,  220,  221,  222,
+      223,  224,  225,  227,  228,  229,  230,  231,  232,  233,
+      234,  235,  236,  237,  238,  239,  240,  241,  242,  243,
+      244,  244,  244,  244,  245,  245,  246,  246,  246,  246,
+      246,  246,  246,  246,  246,  246,  246,  246,  246,  246,
+      246,  246,  246,  246,  246,  246,  246,  246,  246,  246,
+
+      247,  248,  248,  249,  249,  249,  250,  250,  251,  251,
+      251,  251,  252,  252,  253,  254,  255,  256,  256,  257,
+      257,  257,  258,  259,  260,  261,  261,  262,  263,  263,
+      264,  265,  265,  265,  265,  265,  265,  266,  267,  268,
+      269,  270,  271,  272,  273,  274,  275,  276,  277,  279,
+      280,  281,  282,  283,  284,  285,  286,  287,  288,  289,
+      290,  291,  292,  293,  294,  296,  297,  298,  299,  301,
+      302,  303,  304,  305,  306,  307,  308,  309,  310,  311,
+      312,  313,  315,  316,  317,  318,  319,  320,  321,  321,
+      321,  321,  322,  322,  322,  322,  322,  322,  322,  322,
+
+      322,  322,  322,  322,  322,  322,  322,  323,  323,  323,
+      323,  324,  324,  325,  326,  326,  326,  327,  328,  328,
+      329,  329,  330,  331,  332,  332,  332,  333,  334,  335,
+      336,  337,  338,  339,  340,  341,  342,  343,  344,  345,
+      346,  347,  349,  350,  352,  353,  355,  356,  357,  358,
+      359,  360,  361,  363,  365,  366,  367,  368,  369,  370,
+      371,  373,  374,  376,  377,  378,  379,  380,  381,  382,
+      383,  384,  385,  386,  387,  389,  390,  391,  393,  394,
+      395,  395,  395,  395,  395,  395,  395,  395,  395,  395,
+      395,  395,  396,  396,  396,  396,  396,  396,  396,  397,
+
+      398,  398,  399,  399,  400,  401,  401,  401,  401,  403,
+      404,  405,  406,  408,  409,  410,  411,  412,  413,  414,
+      415,  416,  417,  418,  419,  421,  423,  424,  426,  427,
+      428,  429,  430,  432,  433,  434,  436,  437,  438,  440,
+      441,  442,  443,  444,  445,  447,  448,  449,  450,  451,
+      452,  454,  455,  456,  458,  459,  460,  462,  462,  462,
+      462,  462,  462,  462,  462,  462,  462,  463,  463,  463,
+      464,  465,  466,  466,  467,  467,  468,  469,  470,  471,
+      472,  473,  474,  475,  476,  478,  479,  480,  481,  482,
+      483,  484,  486,  487,  488,  489,  491,  493,  494,  496,
+
+      497,  499,  501,  502,  503,  505,  507,  509,  511,  513,
+      515,  516,  518,  519,  520,  520,  522,  522,  522,  522,
+      522,  522,  523,  523,  523,  523,  524,  525,  526,  528,
+      529,  530,  532,  533,  534,  535,  536,  537,  538,  539,
+      540,  542,  543,  545,  546,  548,  549,  550,  552,  553,
+      554,  554,  554,  554,  554,  554,  556,  557,  558,  559,
+      560,  561,  562,  564,  566,  567,  568,  570,  572,  573,
+      575,  577,  579,  581,  583,  585,  585,  585,  585,  585,
+      586,  588,  589,  591,  593,  594,  595,  597,  598,  599,
+      600,  601,  601,  601,  601,  603,  604,  605,  606,  607,
+
+      609,  611,  613,  615,  617,  619,  621,  623,  624,  625,
+      626,  627,  628,  630,  632,  634,  636,  636
+    } ;
+
+static yyconst int yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        4,    5,    6,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    7,    8,    9,   10,   11,   12,   13,   14,   15,
+       16,   17,   18,   19,   20,   21,   22,   23,   24,   25,
+       25,   25,   25,   25,   25,   26,   26,   27,   28,   29,
+       30,   31,   32,    1,   33,   34,   35,   33,   36,   37,
+       11,   11,   38,   11,   11,   39,   11,   11,   11,   40,
+       11,   11,   11,   11,   41,   11,   11,   42,   11,   11,
+       43,   44,   45,   46,   47,    1,   48,   49,   50,   51,
+
+       52,   53,   54,   55,   56,   11,   57,   58,   59,   60,
+       61,   62,   11,   63,   64,   65,   66,   67,   68,   69,
+       70,   71,   72,   73,   74,   75,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst int yy_meta[76] =
+    {   0,
+        1,    1,    2,    1,    1,    1,    1,    1,    3,    1,
+        4,    1,    1,    3,    1,    1,    1,    1,    1,    1,
+        5,    1,    6,    6,    6,    7,    1,    1,    1,    1,
+        1,    3,    7,    7,    7,    7,    7,    4,    8,    9,
+       10,    4,    1,   11,    1,    1,   12,    6,    6,    7,
+        7,    6,    6,    4,    4,    4,    4,    8,    4,   11,
+        4,    9,   11,    4,   11,   10,   11,    4,   11,    4,
+        4,    1,    1,    1,    1
+    } ;
+
+static yyconst short int yy_base[678] =
+    {   0,
+        0,   74, 1651, 1650, 1666, 1669,   83, 1669,   89,   47,
+       69, 1621,   52,   67,   84, 1669, 1669,   69,   82, 1669,
+       85,   83,  101,  111,  160,    0, 1633, 1669,  112, 1633,
+       72,  219,  111, 1669,   78, 1669, 1632,  126,   82,   66,
+      101,  107,  131,  144,   77,  134,  149,   78,  189,  127,
+       67,   96,   99, 1669,  103, 1669, 1629,  218,  244, 1669,
+     1638,  269, 1669,  275,  281, 1669,  285,  170, 1669,  271,
+     1615,  163, 1669, 1669, 1669, 1669,  151, 1669,  276, 1669,
+     1626, 1669, 1625, 1669, 1669, 1635,  296, 1669, 1652, 1669,
+      327,  336,  346,  366,  172,  159,  209,  371,  194,    0,
+
+      225,  201,  378,  268, 1669, 1669, 1669, 1624, 1669, 1669,
+     1669, 1623, 1622,  176,  223, 1635,  231,  293,  309,  274,
+      379,  278,  325, 1618,  306,  314,  280,  333,    0,    0,
+     1669,  269,  355,  199,  376,  329,  356,  122,  383,  394,
+      159,  274,  321,  387,  371,  401,  389,  318,  402,  405,
+      406,  407, 1605,  408,  362,  412,  415,  409,  417,  414,
+      430,  420,  421,  431,  434,  438,  441, 1669, 1669,  497,
+      503, 1645,  509, 1669,  515, 1669, 1617,  457,  483,  489,
+      512,  516,  493,  520,  513,  523, 1614,  526,  527,  538,
+        0,    0,    0,    0,    0,  546,    0,    0,    0, 1669,
+
+      541,  561, 1669,  577, 1642, 1669,  559,    0,  595,  602,
+      549,  620,  640,  443, 1669, 1605, 1585,    0,  629,  562,
+      656,  454, 1669, 1603, 1583,  660, 1669, 1669, 1608, 1669,
+     1669,  559,  574, 1594,    0,    0,  470,  548,  589,  644,
+      507,  553,  596,  604,  571,  595,  627,  628, 1594,  631,
+      646,  649,  331,  633,  654,  655,  656,  561,  661,  662,
+      666,  669,  668,  674,  680,  667,  672,  618, 1593,  673,
+      686,  687,  688,  690,  691,  448,  694,  692,  693,  695,
+      697, 1592,  696,  703,  705,  711,  719,  707,  766,  763,
+     1603, 1669,  720,  744, 1589,  761,    0,    0,  797,    0,
+
+        0,  757,    0,    0,  837,  764,  771,  789,  812,  829,
+      854,  871, 1669, 1669,  764,  852,  881,  759,  880,  744,
+      756,  798, 1669, 1669,    0,    0,  734,  755,  813,  735,
+      783,  775,  784,  865,  821,  824,  867,  869,  871,  822,
+      873, 1589,  875, 1588,  879, 1587,  882,  891,  892,  893,
+      894,  831, 1586, 1585,  897,  896,  898,  906,  905,  901,
+     1584,  907, 1583,  910,  911,  914,  918,  913,  921,  922,
+      926,  930,  935,  925,  940,  927,  942, 1582,  944,  945,
+      989,  963,    0,    0,    0,    0,    0,  976,    0,    0,
+        0,  979,  988,  998,  968, 1024,  989,  955,  953, 1669,
+
+     1029, 1033, 1042, 1586, 1566, 1042,    0,    0, 1579, 1017,
+      984,  956,  987, 1025, 1030, 1020, 1033,  989, 1034, 1035,
+     1029, 1049, 1051, 1053, 1578, 1577, 1054, 1576, 1052, 1055,
+     1058, 1061, 1575, 1063, 1067, 1574, 1066, 1070, 1573, 1068,
+     1073, 1075, 1082, 1083, 1572,  955,  588, 1084, 1085, 1086,
+     1571, 1087, 1089, 1570, 1088, 1091, 1569, 1609,    0,    0,
+        0,    0,    0,    0, 1128, 1132, 1137, 1146, 1097, 1669,
+     1154, 1669, 1163, 1669,    0, 1498, 1121, 1123, 1137, 1102,
+     1138, 1141, 1148, 1154, 1159, 1160, 1161, 1152, 1165, 1164,
+     1167, 1497, 1174, 1178, 1180, 1495, 1463, 1179, 1433, 1183,
+
+     1432, 1431, 1182, 1185, 1430, 1412, 1411, 1410, 1408, 1407,
+     1092, 1403, 1184, 1189, 1443, 1669,    0, 1221,    0,    0,
+     1217, 1225, 1229, 1233,    0, 1194, 1193, 1216, 1401, 1225,
+     1223, 1226, 1227, 1237, 1241, 1242, 1244, 1246, 1248, 1250,
+     1399, 1251, 1398, 1252, 1374, 1235, 1255, 1365, 1258, 1260,
+        0,    0,    0, 1290,    0, 1353, 1261, 1264, 1263, 1266,
+     1275, 1267, 1338, 1281, 1283, 1196, 1287, 1289, 1282, 1337,
+     1317, 1124, 1032,  995,  994,    0,    0,    0,    0, 1277,
+     1294, 1288, 1295,  814, 1299, 1301,  772, 1300, 1302, 1307,
+     1306,    0,    0,    0,  749, 1308, 1312, 1315, 1313,  698,
+
+     1319,  532,  493, 1323,  437, 1324,  324, 1325, 1330, 1331,
+     1332, 1336,  246,  198,  171,  123, 1669, 1383, 1395, 1404,
+     1416, 1428, 1438, 1447, 1458, 1466, 1473, 1475, 1477, 1479,
+     1481, 1483, 1485, 1487, 1489, 1491, 1493, 1496, 1503, 1505,
+     1512, 1519, 1521, 1523, 1525, 1527, 1529, 1531, 1538, 1540,
+     1542, 1544, 1546, 1548, 1550, 1552, 1554, 1556, 1563, 1570,
+     1572, 1574, 1576, 1578, 1580, 1582, 1584, 1586, 1588, 1590,
+     1592, 1594, 1596, 1598, 1600, 1602, 1604
+    } ;
+
+static yyconst short int yy_def[678] =
+    {   0,
+      617,    1,  618,  618,  617,  617,  617,  617,  617,  617,
+      619,  620,  617,  617,  621,  617,  617,  617,  617,  617,
+      617,  617,  617,  617,  617,   25,  617,  617,  617,  617,
+      617,  617,  620,  617,  617,  617,  617,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  620,  620,  617,  617,  617,  617,  617,  622,  617,
+      617,  617,  617,  617,  617,  617,  617,  619,  617,  623,
+      620,  617,  617,  617,  617,  617,  621,  617,  624,  617,
+      617,  617,  617,  617,  617,  617,  617,  617,  625,  617,
+      617,   24,  617,  617,  617,  617,  626,  617,  617,   25,
+
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+      617,  617,  617,  617,  617,  617,  619,  621,  627,  628,
+      617,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  617,  617,  617,
+      622,  622,  622,  617,  622,  617,  617,  617,  617,  617,
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  619,
+      629,  630,  631,  632,  633,  621,  634,  635,  636,  617,
+
+      617,  617,  617,  617,  625,  617,  617,   92,  617,  617,
+      617,  617,  617,  617,  617,  617,  617,  637,  638,  626,
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+      617,  617,  617,  617,  639,  640,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  622,  641,
+      617,  617,  617,  617,  617,  619,  642,  643,  619,  644,
+
+      645,  621,  646,  647,  621,  617,  617,  617,  617,  617,
+      617,  617,  617,  617,  648,  637,  638,  617,  617,  617,
+      317,  617,  617,  617,  649,  650,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      641,  619,  651,  652,  299,  653,  654,  621,  655,  656,
+      305,  617,  617,  617,  648,  617,  648,  617,  617,  617,
+
+      617,  617,  617,  617,  617,  317,  657,  658,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  659,  660,  661,
+      662,  663,  664,  665,  617,  617,  617,  617,  648,  617,
+      617,  617,  617,  617,  666,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  659,  617,  667,  619,  668,  669,
+      621,  617,  617,  617,  670,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      671,  672,  673,  617,  674,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  675,  676,  677,  658,  620,
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  661,  663,  665,  620,  620,  620,  620,  620,  620,
+
+      620,  620,  620,  620,  620,  620,  620,  620,  620,  620,
+      620,  620,  620,  620,  620,  620,    0,  617,  617,  617,
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+      617,  617,  617,  617,  617,  617,  617
+    } ;
+
+static yyconst short int yy_nxt[1745] =
+    {   0,
+        6,    7,    8,    9,    9,    9,    7,   10,   11,    6,
+       12,   13,   14,   15,   16,   17,   18,   19,   20,   21,
+       22,   23,   24,   25,   26,   26,   27,   28,   29,   30,
+       31,   32,   12,   12,   12,   12,   12,   12,   33,   12,
+       12,   12,   34,   35,   36,   37,   38,   39,   40,   41,
+       42,   43,   44,   45,   12,   46,   12,   47,   12,   12,
+       12,   12,   48,   49,   50,   51,   52,   53,   12,   12,
+       12,   54,   55,   56,   57,   58,   66,   69,   67,   75,
+       58,   73,   74,   59,   62,   63,   64,   64,   64,   62,
+       64,   63,   65,   65,   65,   64,   76,   78,   80,   81,
+
+       67,  111,  112,   86,   83,   87,   87,   87,   87,   72,
+       72,   82,   70,   67,   84,   85,   67,   88,  129,  127,
+       72,   72,   89,  106,  128,   72,  165,   79,  138,  157,
+       90,   91,  168,   92,   92,   92,   93,  152,  107,   72,
+      108,  109,   72,  130,   72,  136,   94,  137,  139,   95,
+       72,   96,   97,  167,   72,  140,  166,   98,  142,  132,
+      133,  141,   94,  134,   78,   72,   72,  143,   99,   72,
+       72,  144,  135,  251,   72,  169,   96,   72,   69,   97,
+       91,  162,  100,  100,  100,  100,  153,   72,  145,  163,
+      146,  148,   72,  154,   79,   94,  164,  216,  101,  147,
+
+      102,  149,   72,  194,  150,  229,  103,  230,  151,  155,
+      214,   94,  215,   70,   72,  156,  217,  104,  256,  170,
+       63,   64,   64,   64,  170,  102,  113,  171,  195,  218,
+      114,  115,   72,  116,  215,  117,  118,  215,  119,  224,
+      120,   72,   72,  158,  159,  173,  174,  121,  122,  123,
+      173,  214,  229,  160,  230,  220,  161,  239,  225,  215,
+      229,  124,  230,  222,  125,  223,  175,  175,  175,  175,
+       62,   63,   64,   64,   64,   62,   64,   63,   64,   64,
+       64,   64,   64,   63,   65,   65,   65,   64,   69,   72,
+      223,  126,  177,  190,  190,  190,  178,  179,  196,  196,
+
+      196,  180,  181,  229,  182,  230,  183,  229,  223,  230,
+      231,  191,   72,  184,  185,  186,  197,   72,  201,  201,
+      201,  201,  229,   70,  230,  222,  257,  187,  231,  237,
+      188,  202,  203,  223,  203,  229,  192,  230,  229,  193,
+      230,  198,  204,  229,  199,  230,   78,  202,  203,   87,
+       87,   87,   87,  203,  229,  233,  230,  189,  208,  208,
+      208,   72,  202,  203,   72,  203,   91,   72,   93,   93,
+       93,   93,   72,  207,   72,  263,   79,  617,  202,  203,
+      345,   94,  209,  211,  203,  211,  258,  249,  212,  212,
+      212,  212,  210,   92,   92,   92,   93,   94,   72,   72,
+
+      100,  100,  100,  100,  617,   72,   94,  232,  229,   95,
+      230,   96,  213,   94,   72,  238,  101,  221,  102,   72,
+      250,  270,   94,  240,  226,  241,   72,  242,   99,   94,
+       72,  243,   72,  244,  260,  104,   96,   72,  245,  246,
+      247,  254,  248,  102,   72,   72,  252,  253,   72,   72,
+       72,   72,   72,  262,  255,   72,  259,   72,   72,  271,
+       72,  278,  264,   72,   72,  268,  261,  265,  272,  275,
+      276,  267,  269,   72,   72,  266,  279,   72,  273,  274,
+       72,   72,  281,  313,   72,  280,  291,  277,  292,  284,
+      282,   72,  283,  286,  323,  287,  288,  285,  170,   63,
+
+       64,   64,   64,  170,  173,  174,  171,  369,  313,  173,
+      173,  174,  291,   72,  292,  173,  289,  174,  291,  323,
+      292,  289,  291,  290,  292,  175,  175,  175,  175,  292,
+      327,  175,  175,  175,  175,  292,   72,  175,  175,  175,
+      175,  291,  291,  292,  292,  291,   69,  292,  293,  291,
+       72,  292,  291,  294,  292,  291,  291,  292,  292,   78,
+      296,  296,  296,  201,  201,  201,  201,  333,  302,  302,
+      302,  212,  212,  212,  212,   72,  202,  203,  306,  203,
+      306,   70,  218,  307,  307,  307,  307,  204,  229,   79,
+      230,   72,  202,  203,  202,  203,   72,  203,  203,  201,
+
+      201,  201,  201,  229,   72,  230,  328,  308,  617,  351,
+      202,  203,  202,  203,   72,  203,  203,  208,  208,  208,
+       93,  334,  338,  309,   93,   93,   93,   93,  202,  203,
+       94,   72,   72,   95,  203,   96,  329,   94,   72,   72,
+      507,  310,  311,  311,  311,  311,   94,   72,  221,  316,
+      339,  337,   99,   94,  335,  336,  203,  211,  203,  211,
+       96,   72,  212,  212,  212,  212,  312,  318,  319,  320,
+       72,   72,  203,  362,   72,  321,   72,  203,   93,   93,
+       93,   93,  100,  100,  100,  100,  322,   72,  341,   72,
+      319,  342,   72,  343,  320,  346,  340,   72,   72,   72,
+
+      344,  330,  221,  350,   72,   72,  226,  331,  332,   72,
+       72,   72,   72,  353,  347,   72,   72,   72,  348,  349,
+      355,  357,  352,   72,  354,  356,  363,  358,  360,   72,
+       72,   72,  361,   72,   72,   72,   72,   72,   72,   72,
+       72,   72,  365,  364,  359,  370,   72,  375,   72,  291,
+       72,  292,  366,  368,   72,  367,  371,  374,  372,  373,
+      377,  378,   72,  376,  380,  174,  379,  289,  174,   69,
+       78,  172,  289,  291,  290,  292,  617,   72,   72,  388,
+      388,  388,  404,  382,  382,  382,  307,  307,  307,  307,
+      412,  409,   72,  392,  392,  392,  392,  399,   72,  400,
+
+       79,  405,  406,  396,   70,   69,  306,  203,  306,  203,
+      397,  307,  307,  307,  307,   72,  410,  393,   72,  385,
+      385,  385,  385,  203,  400,  396,   72,   72,  203,  385,
+      385,  385,  385,  385,  201,  201,  201,  201,  400,  414,
+       70,  413,  415,  416,  385,  385,  385,  385,  385,  385,
+       78,  208,  208,  208,   93,  399,   72,   72,  309,  391,
+      391,  391,  391,  400,   72,   72,  411,   72,  418,  391,
+      391,  391,  391,  391,   72,  310,  311,  311,  311,  311,
+       79,  419,  433,  423,  391,  391,  391,  391,  391,  391,
+      203,  396,  203,  311,  311,  311,  311,  401,  398,  401,
+
+      312,  316,  402,  402,  402,  402,  203,  203,   72,  203,
+       72,  203,   72,  396,   72,  420,   72,  394,   72,  318,
+      319,  320,   72,  203,  422,   72,  403,  321,  203,  417,
+      424,  425,  421,  426,   72,   72,   72,   72,  322,   72,
+       72,   72,  319,  429,   72,  427,  320,  430,   72,   72,
+       72,  432,  439,   72,   72,  428,   72,   72,  431,  434,
+      435,   72,  436,  437,   72,   72,  440,  438,   72,   72,
+       72,   69,  446,   72,  442,  441,  443,  445,   72,  449,
+      444,  448,  447,   72,  450,   72,  454,   72,   72,   78,
+      452,  174,  451,  470,  396,  455,  457,  458,   72,   72,
+
+      453,  392,  392,  392,  392,  506,   70,  396,  456,  479,
+      392,  392,  392,  392,  397,  203,  396,  203,  470,   79,
+      311,  311,  311,  311,  203,  393,  203,   72,  396,  396,
+       72,  203,   72,  480,  465,  469,  203,   72,   72,  478,
+      203,  466,  485,  466,  394,  203,  467,  467,  467,  467,
+      396,  402,  402,  402,  402,  471,  471,  471,  471,  401,
+       72,  401,  617,   72,  402,  402,  402,  402,   72,  472,
+      468,  472,   72,   72,  477,   72,   72,   72,   72,  473,
+      617,  617,  617,  483,  484,  472,  487,  481,  406,  486,
+      472,  482,   72,  488,   72,   72,   72,   72,   72,  617,
+
+      491,   72,  490,  617,   72,  492,   72,  617,  489,   72,
+       72,   72,  496,   72,  494,  495,   72,  500,   72,  501,
+      493,  498,  497,  499,  502,   72,   72,   72,   72,   72,
+       72,   72,   72,  508,   72,   72,  617,  504,  511,  503,
+      510,  512,  505,  469,  548,   72,  514,  513,  529,  509,
+      392,  392,  392,  392,  467,  467,  467,  467,  617,  522,
+      522,  522,  522,  466,   72,  466,   72,   72,  467,  467,
+      467,  467,  526,  472,  465,  472,  471,  471,  471,  471,
+       72,   72,  527,  523,   72,  471,  471,  471,  471,  472,
+      472,   72,  472,  530,  472,   72,  528,   72,  531,  472,
+
+      473,  472,   72,   72,   72,  534,  472,   72,   72,  524,
+       72,  472,  532,  533,  537,  472,  538,   72,  536,  535,
+      472,   72,   72,   72,  539,   72,   72,   72,   72,   69,
+       78,  540,   72,  546,  547,  549,   72,   72,  541,   72,
+      557,  544,  545,  542,  543,  588,  550,  522,  522,  522,
+      522,  522,  522,  522,  522,  471,  471,  471,  471,   72,
+       79,  472,  556,  472,   70,  472,   72,  472,   72,   72,
+       72,  523,  561,  559,  560,  554,  558,  472,   72,  524,
+       72,  472,  472,  563,   72,   72,  472,   72,  565,   72,
+      562,   72,  564,   72,   72,   72,  567,  572,   72,  566,
+
+      568,   72,  570,   72,   72,  569,   72,   72,  574,   72,
+       72,  575,  522,  522,  522,  522,  581,  571,   72,  573,
+       72,  584,  585,  580,   72,   72,   72,  586,  582,  587,
+       72,   72,   72,  589,  583,  590,  554,   72,   72,  591,
+      596,  598,   72,   72,   72,   72,  595,  600,  602,   72,
+       72,   72,  597,  603,  605,   72,   72,  604,   72,  599,
+       72,  607,   72,  606,  601,  609,   72,   72,   72,  610,
+      611,  612,  608,   72,   72,   72,  613,  614,  615,   72,
+       72,   72,  616,   60,   60,   60,   60,   60,   60,   60,
+       60,   60,   60,   60,   60,   68,   72,   68,   68,   68,
+
+       68,   68,   68,   68,   68,   68,   68,   71,   72,   71,
+       71,   71,   71,   71,   71,   71,   77,   72,   77,   77,
+       77,   77,   77,   77,   77,   77,   77,   77,  172,  172,
+      172,  172,  172,  172,  172,  172,  172,  172,  172,  172,
+       68,   72,   72,   68,   72,  516,   72,   68,   68,   77,
+       72,   72,   77,   72,   72,   72,   77,   77,  205,  205,
+      205,  205,  205,  205,  205,  205,  205,  205,  205,  205,
+      219,  219,  219,   72,   72,   72,   72,  219,  235,  235,
+      236,  236,  297,  297,  298,  298,  299,  299,  300,  300,
+      301,  301,  303,  303,  304,  304,  305,  305,  315,  315,
+
+      317,  317,  317,  317,  317,  317,   72,  317,  325,  325,
+      326,  326,  381,  381,  381,  381,  381,  381,  381,  381,
+      381,  381,  381,  381,  383,  383,  384,  384,  386,  386,
+      387,  387,  389,  389,  390,  390,  395,  395,   72,  395,
+       72,   72,  395,  407,  407,  408,  408,  459,  459,  460,
+      460,  461,  461,  462,  462,  463,  463,  464,  464,  475,
+      475,  476,  476,  515,  515,  515,  515,  515,  515,  515,
+      515,  515,  515,  515,  515,  517,  517,  518,  518,  519,
+      519,   71,   71,  520,  520,  521,  521,  525,  525,  551,
+      551,  552,  552,  553,  553,  555,  555,  576,  576,  577,
+
+      577,  578,  578,  579,  579,  592,  592,  593,  593,  594,
+      594,  516,   72,   72,   72,   72,   72,   72,   72,   72,
+       72,   72,   72,  474,  474,   72,   72,   72,   72,   72,
+       72,   72,   72,  292,  292,   72,   72,   72,  231,  230,
+      324,  324,  314,  314,  206,  295,  291,  174,   72,  234,
+      231,  229,  228,  227,  206,  200,   67,   67,   72,  176,
+       67,  131,  110,  105,   72,  617,   61,   61,    5,  617,
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+      617,  617,  617,  617
+    } ;
+
+static yyconst short int yy_chk[1745] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    2,   10,   11,   10,   14,
+        2,   13,   13,    2,    7,    7,    7,    7,    7,    7,
+        9,    9,    9,    9,    9,    9,   14,   15,   18,   19,
+
+       18,   31,   31,   22,   21,   22,   22,   22,   22,   40,
+       51,   19,   11,   19,   21,   21,   21,   23,   35,   33,
+       45,   48,   23,   29,   33,   39,   51,   15,   40,   48,
+       23,   24,   55,   24,   24,   24,   24,   45,   29,   52,
+       29,   29,   53,   35,   41,   39,   24,   39,   41,   24,
+       42,   24,   24,   53,   33,   41,   52,   24,   42,   38,
+       38,   41,   24,   38,   77,  138,  616,   42,   24,   38,
+       50,   42,   38,  138,   43,   55,   24,   46,   68,   24,
+       25,   50,   25,   25,   25,   25,   46,   44,   43,   50,
+       43,   44,   47,   46,   77,   25,   50,   96,   25,   43,
+
+       25,   44,  141,   72,   44,  114,   25,  114,   44,   47,
+       95,   25,   95,   68,  615,   47,   96,   25,  141,   58,
+       58,   58,   58,   58,   58,   25,   32,   58,   72,   97,
+       32,   32,   49,   32,   99,   32,   32,   95,   32,  102,
+       32,  614,  134,   49,   49,   59,   59,   32,   32,   32,
+       59,   99,  115,   49,  115,   97,   49,  134,  102,   99,
+      117,   32,  117,  101,   32,  101,   59,   59,   59,   59,
+       62,   62,   62,   62,   62,   62,   64,   64,   64,   64,
+       64,   64,   65,   65,   65,   65,   65,   65,  127,  613,
+      101,   32,   67,   70,   70,   70,   67,   67,   79,   79,
+
+       79,   67,   67,  120,   67,  120,   67,  122,  104,  122,
+      118,   70,  132,   67,   67,   67,   79,  142,   87,   87,
+       87,   87,  118,  127,  118,  104,  142,   67,  119,  132,
+       67,   87,   87,  104,   87,  125,   70,  125,  119,   70,
+      119,   79,   87,  126,   79,  126,  128,   87,   87,   91,
+       91,   91,   91,   87,  123,  123,  123,   67,   92,   92,
+       92,  148,   91,   91,  143,   91,   93,  607,   93,   93,
+       93,   93,  136,   91,  253,  148,  128,   92,   91,   91,
+      253,   93,   92,   94,   91,   94,  143,  136,   94,   94,
+       94,   94,   93,   98,   98,   98,   98,   93,  133,  137,
+
+      103,  103,  103,  103,   92,  155,   98,  121,  121,   98,
+      121,   98,   94,  103,  145,  133,  103,   98,  103,  135,
+      137,  155,   98,  135,  103,  135,  139,  135,   98,  103,
+      144,  135,  147,  135,  145,  103,   98,  140,  135,  135,
+      135,  140,  135,  103,  146,  149,  139,  139,  150,  151,
+      152,  154,  158,  147,  140,  156,  144,  160,  157,  156,
+      159,  160,  149,  162,  163,  154,  146,  150,  157,  158,
+      159,  152,  154,  161,  164,  151,  160,  165,  157,  157,
+      605,  166,  162,  214,  167,  161,  178,  159,  178,  165,
+      163,  276,  164,  166,  222,  166,  167,  165,  170,  170,
+
+      170,  170,  170,  170,  171,  171,  170,  276,  214,  171,
+      173,  173,  179,  237,  179,  173,  175,  175,  180,  222,
+      180,  175,  183,  175,  183,  171,  171,  171,  171,  181,
+      237,  173,  173,  173,  173,  182,  603,  175,  175,  175,
+      175,  181,  185,  181,  185,  182,  190,  182,  184,  184,
+      241,  184,  186,  186,  186,  188,  189,  188,  189,  196,
+      190,  190,  190,  201,  201,  201,  201,  241,  196,  196,
+      196,  211,  211,  211,  211,  602,  201,  201,  202,  201,
+      202,  190,  220,  202,  202,  202,  202,  201,  232,  196,
+      232,  238,  201,  201,  207,  207,  242,  207,  201,  204,
+
+      204,  204,  204,  233,  258,  233,  238,  202,  220,  258,
+      207,  207,  204,  204,  245,  204,  207,  209,  209,  209,
+      209,  242,  245,  204,  210,  210,  210,  210,  204,  204,
+      209,  447,  239,  209,  204,  209,  239,  210,  246,  243,
+      447,  209,  212,  212,  212,  212,  209,  244,  210,  219,
+      246,  244,  209,  210,  243,  243,  212,  213,  212,  213,
+      209,  268,  213,  213,  213,  213,  212,  219,  219,  219,
+      247,  248,  212,  268,  250,  219,  254,  212,  221,  221,
+      221,  221,  226,  226,  226,  226,  219,  240,  248,  251,
+      219,  250,  252,  251,  219,  254,  247,  255,  256,  257,
+
+      252,  240,  221,  257,  259,  260,  226,  240,  240,  261,
+      266,  263,  262,  260,  255,  267,  270,  264,  256,  256,
+      262,  264,  259,  265,  261,  263,  270,  265,  266,  271,
+      272,  273,  267,  274,  275,  278,  279,  277,  280,  283,
+      281,  600,  272,  271,  265,  277,  284,  283,  285,  293,
+      288,  293,  273,  275,  286,  274,  278,  281,  279,  280,
+      285,  286,  287,  284,  288,  290,  287,  289,  289,  296,
+      302,  290,  289,  294,  289,  294,  321,  327,  330,  302,
+      302,  302,  320,  296,  296,  296,  306,  306,  306,  306,
+      330,  327,  595,  307,  307,  307,  307,  318,  328,  318,
+
+      302,  320,  321,  315,  296,  299,  308,  307,  308,  307,
+      315,  308,  308,  308,  308,  587,  328,  307,  332,  299,
+      299,  299,  299,  307,  318,  315,  331,  333,  307,  299,
+      299,  299,  299,  299,  309,  309,  309,  309,  322,  332,
+      299,  331,  333,  333,  299,  299,  299,  299,  299,  299,
+      305,  310,  310,  310,  310,  322,  329,  584,  309,  305,
+      305,  305,  305,  322,  335,  340,  329,  336,  335,  305,
+      305,  305,  305,  305,  352,  310,  311,  311,  311,  311,
+      305,  336,  352,  340,  305,  305,  305,  305,  305,  305,
+      311,  316,  311,  312,  312,  312,  312,  319,  316,  319,
+
+      311,  317,  319,  319,  319,  319,  311,  312,  334,  312,
+      337,  311,  338,  316,  339,  337,  341,  312,  343,  317,
+      317,  317,  345,  312,  339,  347,  319,  317,  312,  334,
+      341,  343,  338,  345,  348,  349,  350,  351,  317,  356,
+      355,  357,  317,  349,  360,  347,  317,  349,  359,  358,
+      362,  351,  360,  364,  365,  348,  368,  366,  350,  355,
+      356,  367,  357,  358,  369,  370,  362,  359,  374,  371,
+      376,  382,  369,  372,  365,  364,  366,  368,  373,  372,
+      367,  371,  370,  375,  373,  377,  376,  379,  380,  388,
+      375,  381,  374,  399,  398,  377,  380,  381,  446,  412,
+
+      375,  392,  392,  392,  392,  446,  382,  395,  379,  412,
+      393,  393,  393,  393,  395,  392,  398,  392,  399,  388,
+      394,  394,  394,  394,  393,  392,  393,  411,  397,  395,
+      413,  392,  418,  413,  393,  397,  392,  575,  574,  411,
+      393,  396,  418,  396,  394,  393,  396,  396,  396,  396,
+      397,  401,  401,  401,  401,  402,  402,  402,  402,  403,
+      410,  403,  406,  416,  403,  403,  403,  403,  414,  402,
+      396,  402,  421,  415,  410,  573,  417,  419,  420,  402,
+      406,  406,  406,  416,  417,  402,  420,  414,  406,  419,
+      402,  415,  422,  421,  423,  429,  424,  427,  430,  406,
+
+      424,  431,  423,  406,  432,  427,  434,  406,  422,  437,
+      435,  440,  432,  438,  430,  431,  441,  438,  442,  440,
+      429,  435,  434,  437,  441,  443,  444,  448,  449,  450,
+      452,  455,  453,  448,  456,  511,  469,  443,  452,  442,
+      450,  453,  444,  469,  511,  480,  456,  455,  480,  449,
+      465,  465,  465,  465,  466,  466,  466,  466,  469,  467,
+      467,  467,  467,  468,  477,  468,  478,  572,  468,  468,
+      468,  468,  477,  467,  465,  467,  471,  471,  471,  471,
+      479,  481,  478,  467,  482,  473,  473,  473,  473,  467,
+      471,  483,  471,  481,  467,  488,  479,  484,  482,  473,
+
+      471,  473,  485,  486,  487,  485,  471,  490,  489,  473,
+      491,  471,  483,  484,  488,  473,  489,  493,  487,  486,
+      473,  494,  498,  495,  490,  503,  500,  513,  504,  518,
+      521,  491,  514,  503,  504,  513,  527,  526,  493,  566,
+      527,  498,  500,  494,  495,  566,  514,  522,  522,  522,
+      522,  523,  523,  523,  523,  524,  524,  524,  524,  528,
+      521,  522,  526,  522,  518,  523,  531,  523,  530,  532,
+      533,  522,  532,  530,  531,  523,  528,  522,  546,  524,
+      534,  523,  522,  534,  535,  536,  523,  537,  536,  538,
+      533,  539,  535,  540,  542,  544,  538,  546,  547,  537,
+
+      539,  549,  542,  550,  557,  540,  559,  558,  549,  560,
+      562,  550,  554,  554,  554,  554,  558,  544,  561,  547,
+      580,  561,  562,  557,  564,  569,  565,  564,  559,  565,
+      567,  582,  568,  567,  560,  568,  554,  581,  583,  569,
+      581,  583,  585,  588,  586,  589,  580,  586,  589,  591,
+      590,  596,  582,  590,  596,  597,  599,  591,  598,  585,
+      571,  598,  601,  597,  588,  601,  604,  606,  608,  604,
+      606,  608,  599,  609,  610,  611,  609,  610,  611,  612,
+      570,  563,  612,  618,  618,  618,  618,  618,  618,  618,
+      618,  618,  618,  618,  618,  619,  556,  619,  619,  619,
+
+      619,  619,  619,  619,  619,  619,  619,  620,  548,  620,
+      620,  620,  620,  620,  620,  620,  621,  545,  621,  621,
+      621,  621,  621,  621,  621,  621,  621,  621,  622,  622,
+      622,  622,  622,  622,  622,  622,  622,  622,  622,  622,
+      623,  543,  541,  623,  529,  515,  512,  623,  623,  624,
+      510,  509,  624,  508,  507,  506,  624,  624,  625,  625,
+      625,  625,  625,  625,  625,  625,  625,  625,  625,  625,
+      626,  626,  626,  505,  502,  501,  499,  626,  627,  627,
+      628,  628,  629,  629,  630,  630,  631,  631,  632,  632,
+      633,  633,  634,  634,  635,  635,  636,  636,  637,  637,
+
+      638,  638,  638,  638,  638,  638,  497,  638,  639,  639,
+      640,  640,  641,  641,  641,  641,  641,  641,  641,  641,
+      641,  641,  641,  641,  642,  642,  643,  643,  644,  644,
+      645,  645,  646,  646,  647,  647,  648,  648,  496,  648,
+      492,  476,  648,  649,  649,  650,  650,  651,  651,  652,
+      652,  653,  653,  654,  654,  655,  655,  656,  656,  657,
+      657,  658,  658,  659,  659,  659,  659,  659,  659,  659,
+      659,  659,  659,  659,  659,  660,  660,  661,  661,  662,
+      662,  663,  663,  664,  664,  665,  665,  666,  666,  667,
+      667,  668,  668,  669,  669,  670,  670,  671,  671,  672,
+
+      672,  673,  673,  674,  674,  675,  675,  676,  676,  677,
+      677,  458,  457,  454,  451,  445,  439,  436,  433,  428,
+      426,  425,  409,  405,  404,  378,  363,  361,  354,  353,
+      346,  344,  342,  295,  291,  282,  269,  249,  234,  229,
+      225,  224,  217,  216,  205,  187,  177,  172,  153,  124,
+      116,  113,  112,  108,   89,   86,   83,   81,   71,   61,
+       57,   37,   30,   27,   12,    5,    4,    3,  617,  617,
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+      617,  617,  617,  617,  617,  617,  617,  617,  617,  617,
+      617,  617,  617,  617
+    } ;
+
+static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr;
+static char *yy_full_match;
+static int yy_lp;
+#define REJECT \
+{ \
+*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \
+yy_cp = yy_full_match; /* restore poss. backed-over text */ \
+++yy_lp; \
+goto find_rule; \
+}
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "Parser/lex.l"
+#define INITIAL 0
+/*                               -*- Mode: C -*- 
+ * 
+ * CForall Lexer Version 1.0, Copyright (C) Peter A. Buhr 2001 -- Permission is granted to copy this
+ *	grammar and to use it within software systems.  THIS GRAMMAR IS PROVIDED "AS IS" AND WITHOUT
+ *	ANY EXPRESS OR IMPLIED WARRANTIES.
+ * 
+ * lex.l -- 
+ * 
+ * Author           : Peter A. Buhr
+ * Created On       : Sat Sep 22 08:58:10 2001
+ * Last Modified By : Peter A. Buhr
+ * Last Modified On : Thu Jan 23 16:17:09 2003
+ * Update Count     : 191
+ */
+#line 19 "Parser/lex.l"
+/* This lexer assumes the program has been preprocessed by cpp. Hence, all user level preprocessor
+   directive have been performed and removed from the source. The only exceptions are preprocessor
+   directives passed to the compiler (e.g., line-number directives) and C/C++ style comments, which
+   are ignored. */
+
+/*************** Includes and Defines *****************************/
+
+#include <string>
+
+#include "ParseNode.h"
+#include "cfa.tab.h" /* YACC generated definitions based on C++ grammar */
+#include "lex.h"
+
+char *yyfilename;
+
+#define WHITE_RETURN(x)		/* do nothing */
+#define NEWLINE_RETURN()	WHITE_RETURN('\n')
+#define RETURN_VAL(x)		yylval.tok.str = new std::string(yytext); yylval.tok.file = yyfilename; yylval.tok.line = yylineno; return(x)
+
+#define KEYWORD_RETURN(x)	RETURN_VAL(x)		/* keyword */
+#define IDENTIFIER_RETURN()	RETURN_VAL((typedefTable.isIdentifier(yytext) ? IDENTIFIER : typedefTable.isTypedef(yytext) ? TYPEDEFname : TYPEGENname))
+
+#define ASCIIOP_RETURN()	RETURN_VAL((int)yytext[0]) /* single character operator */
+#define NAMEDOP_RETURN(x)	RETURN_VAL(x)		/* multichar operator, with a name */
+
+#define NUMERIC_RETURN(x)	rm_underscore(); RETURN_VAL(x) /* numeric constant */
+
+void rm_underscore() {					/* remove underscores in constant or escape sequence */
+    int j = 0;
+    for ( int i = 0; i < yyleng; i += 1 ) {
+	if ( yytext[i] != '_' ) {
+	    yytext[j] = yytext[i];
+	    j += 1;
+	} // if
+    } // for
+    yyleng = j;
+    yytext[yyleng] = '\0';
+}
+
+/* identifier, GCC: $ in identifier */
+/*  numeric constants, CFA: '_' in constant */
+/* character escape sequence, GCC: \e => esc character */
+/* display/white-space characters */
+/* operators */
+#define COMMENT 1
+
+#line 1108 "Parser/lex.yy.cc"
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO(( void ));
+#else
+extern int yywrap YY_PROTO(( void ));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines.  This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	if ( yy_current_buffer->yy_is_interactive ) \
+		{ \
+		int c = '*', n; \
+		for ( n = 0; n < max_size && \
+			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+			buf[n] = (char) c; \
+		if ( c == '\n' ) \
+			buf[n++] = (char) c; \
+		if ( c == EOF && ferror( yyin ) ) \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+		result = n; \
+		} \
+	else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+		  && ferror( yyin ) ) \
+		YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+	if ( yyleng > 0 ) \
+		yy_current_buffer->yy_at_bol = \
+				(yytext[yyleng - 1] == '\n'); \
+	YY_USER_ACTION
+
+YY_DECL
+	{
+	register yy_state_type yy_current_state;
+	register char *yy_cp, *yy_bp;
+	register int yy_act;
+
+#line 120 "Parser/lex.l"
+
+	/* line directives */
+#line 1265 "Parser/lex.yy.cc"
+
+	if ( yy_init )
+		{
+		yy_init = 0;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! yy_start )
+			yy_start = 1;	/* first start state */
+
+		if ( ! yyin )
+			yyin = stdin;
+
+		if ( ! yyout )
+			yyout = stdout;
+
+		if ( ! yy_current_buffer )
+			yy_current_buffer =
+				yy_create_buffer( yyin, YY_BUF_SIZE );
+
+		yy_load_buffer_state();
+		}
+
+	while ( 1 )		/* loops until end-of-file is reached */
+		{
+		yy_cp = yy_c_buf_p;
+
+		/* Support of yytext. */
+		*yy_cp = yy_hold_char;
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = yy_start;
+		yy_current_state += YY_AT_BOL();
+		yy_state_ptr = yy_state_buf;
+		*yy_state_ptr++ = yy_current_state;
+yy_match:
+		do
+			{
+			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+				{
+				yy_current_state = (int) yy_def[yy_current_state];
+				if ( yy_current_state >= 618 )
+					yy_c = yy_meta[(unsigned int) yy_c];
+				}
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			*yy_state_ptr++ = yy_current_state;
+			++yy_cp;
+			}
+		while ( yy_base[yy_current_state] != 1669 );
+
+yy_find_action:
+		yy_current_state = *--yy_state_ptr;
+		yy_lp = yy_accept[yy_current_state];
+find_rule: /* we branch to this label when backing up */
+		for ( ; ; ) /* until we find what rule we matched */
+			{
+			if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] )
+				{
+				yy_act = yy_acclist[yy_lp];
+					{
+					yy_full_match = yy_cp;
+					break;
+					}
+				}
+			--yy_cp;
+			yy_current_state = *--yy_state_ptr;
+			yy_lp = yy_accept[yy_current_state];
+			}
+
+		YY_DO_BEFORE_ACTION;
+
+		if ( yy_act != YY_END_OF_BUFFER )
+			{
+			int yyl;
+			for ( yyl = 0; yyl < yyleng; ++yyl )
+				if ( yytext[yyl] == '\n' )
+					++yylineno;
+			}
+
+do_action:	/* This label is used only to access EOF actions. */
+
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+case 1:
+YY_RULE_SETUP
+#line 122 "Parser/lex.l"
+{
+	char *end_num;
+	char *begin_string, *end_string;
+	char *filename;
+	long lineno, length;
+	lineno = strtol( yytext + 1, &end_num, 0 );
+	begin_string = strchr( end_num, '"' );
+	if( begin_string ) {
+	  end_string = strchr( begin_string + 1, '"' );
+	  if( end_string ) {
+	    length = end_string - begin_string - 1;
+	    filename = new char[ length + 1 ];
+	    memcpy( filename, begin_string + 1, length );
+	    filename[ length ] = '\0';
+	    //std::cout << "file " << filename << " line " << lineno << std::endl;
+	    yylineno = lineno;
+	    yyfilename = filename;
+	  }
+	}
+}
+	YY_BREAK
+/* ignore preprocessor directives (for now) */
+case 2:
+YY_RULE_SETUP
+#line 144 "Parser/lex.l"
+;
+	YY_BREAK
+/* ignore C style comments */
+case 3:
+YY_RULE_SETUP
+#line 147 "Parser/lex.l"
+{BEGIN COMMENT;}
+	YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 148 "Parser/lex.l"
+;
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 149 "Parser/lex.l"
+{BEGIN 0;}
+	YY_BREAK
+/* ignore C++ style comments */
+case 6:
+YY_RULE_SETUP
+#line 152 "Parser/lex.l"
+;
+	YY_BREAK
+/* ignore whitespace */
+case 7:
+YY_RULE_SETUP
+#line 155 "Parser/lex.l"
+{WHITE_RETURN(' ');}
+	YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 156 "Parser/lex.l"
+{WHITE_RETURN(' ');}
+	YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 157 "Parser/lex.l"
+{NEWLINE_RETURN();}
+	YY_BREAK
+/* keywords */
+case 10:
+YY_RULE_SETUP
+#line 160 "Parser/lex.l"
+{KEYWORD_RETURN(ALIGNOF);}	/* GCC */
+	YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 161 "Parser/lex.l"
+{KEYWORD_RETURN(ALIGNOF);}	/* GCC */
+	YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 162 "Parser/lex.l"
+{KEYWORD_RETURN(ASM);}
+	YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 163 "Parser/lex.l"
+{KEYWORD_RETURN(ASM);}		/* GCC */
+	YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 164 "Parser/lex.l"
+{KEYWORD_RETURN(ASM);}		/* GCC */
+	YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 165 "Parser/lex.l"
+{KEYWORD_RETURN(ATTRIBUTE);}	/* GCC */
+	YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 166 "Parser/lex.l"
+{KEYWORD_RETURN(ATTRIBUTE);}	/* GCC */
+	YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 167 "Parser/lex.l"
+{KEYWORD_RETURN(AUTO);}
+	YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 168 "Parser/lex.l"
+{KEYWORD_RETURN(BOOL);}		/* ANSI99 */
+	YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 169 "Parser/lex.l"
+{KEYWORD_RETURN(BREAK);}
+	YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 170 "Parser/lex.l"
+{KEYWORD_RETURN(CASE);}
+	YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 171 "Parser/lex.l"
+{KEYWORD_RETURN(CATCH);}	/* CFA */
+	YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 172 "Parser/lex.l"
+{KEYWORD_RETURN(CHAR);}
+	YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 173 "Parser/lex.l"
+{KEYWORD_RETURN(CHOOSE);}
+	YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 174 "Parser/lex.l"
+{KEYWORD_RETURN(COMPLEX);}	/* ANSI99 */
+	YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 175 "Parser/lex.l"
+{KEYWORD_RETURN(COMPLEX);}	/* GCC */
+	YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 176 "Parser/lex.l"
+{KEYWORD_RETURN(COMPLEX);}	/* GCC */
+	YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 177 "Parser/lex.l"
+{KEYWORD_RETURN(CONST);}
+	YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 178 "Parser/lex.l"
+{KEYWORD_RETURN(CONST);}	/* GCC */
+	YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 179 "Parser/lex.l"
+{KEYWORD_RETURN(CONST);}	/* GCC */
+	YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 180 "Parser/lex.l"
+{KEYWORD_RETURN(CONTEXT);}
+	YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 181 "Parser/lex.l"
+{KEYWORD_RETURN(CONTINUE);}
+	YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 182 "Parser/lex.l"
+{KEYWORD_RETURN(DEFAULT);}
+	YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 183 "Parser/lex.l"
+{KEYWORD_RETURN(DO);}
+	YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 184 "Parser/lex.l"
+{KEYWORD_RETURN(DOUBLE);}
+	YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 185 "Parser/lex.l"
+{KEYWORD_RETURN(DTYPE);}
+	YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 186 "Parser/lex.l"
+{KEYWORD_RETURN(ELSE);}
+	YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 187 "Parser/lex.l"
+{KEYWORD_RETURN(ENUM);}
+	YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 188 "Parser/lex.l"
+{KEYWORD_RETURN(EXTENSION);}	/* GCC */
+	YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 189 "Parser/lex.l"
+{KEYWORD_RETURN(EXTERN);}
+	YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 190 "Parser/lex.l"
+{KEYWORD_RETURN(FALLTHRU);}
+	YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 191 "Parser/lex.l"
+{KEYWORD_RETURN(FLOAT);}
+	YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 192 "Parser/lex.l"
+{KEYWORD_RETURN(FOR);}
+	YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 193 "Parser/lex.l"
+{KEYWORD_RETURN(FORALL);}
+	YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 194 "Parser/lex.l"
+{KEYWORD_RETURN(FORTRAN);}
+	YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 195 "Parser/lex.l"
+{KEYWORD_RETURN(FTYPE);}
+	YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 196 "Parser/lex.l"
+{KEYWORD_RETURN(GOTO);}
+	YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 197 "Parser/lex.l"
+{KEYWORD_RETURN(IF);}
+	YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 198 "Parser/lex.l"
+{KEYWORD_RETURN(IMAGINARY);}	/* ANSI99 */
+	YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 199 "Parser/lex.l"
+{KEYWORD_RETURN(IMAGINARY);}	/* GCC */
+	YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 200 "Parser/lex.l"
+{KEYWORD_RETURN(IMAGINARY);}	/* GCC */
+	YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 201 "Parser/lex.l"
+{KEYWORD_RETURN(INLINE);}	/* ANSI99 */
+	YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 202 "Parser/lex.l"
+{KEYWORD_RETURN(INLINE);}	/* GCC */
+	YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 203 "Parser/lex.l"
+{KEYWORD_RETURN(INLINE);}	/* GCC */
+	YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 204 "Parser/lex.l"
+{KEYWORD_RETURN(INT);}
+	YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 205 "Parser/lex.l"
+{KEYWORD_RETURN(LABEL);}	/* GCC */
+	YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 206 "Parser/lex.l"
+{KEYWORD_RETURN(LONG);}
+	YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 207 "Parser/lex.l"
+{KEYWORD_RETURN(LVALUE);}
+	YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 208 "Parser/lex.l"
+{KEYWORD_RETURN(REGISTER);}
+	YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 209 "Parser/lex.l"
+{KEYWORD_RETURN(RESTRICT);}	/* ANSI99 */
+	YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 210 "Parser/lex.l"
+{KEYWORD_RETURN(RESTRICT);}	/* GCC */
+	YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 211 "Parser/lex.l"
+{KEYWORD_RETURN(RESTRICT);}	/* GCC */
+	YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 212 "Parser/lex.l"
+{KEYWORD_RETURN(RETURN);}
+	YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 213 "Parser/lex.l"
+{KEYWORD_RETURN(SHORT);}
+	YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 214 "Parser/lex.l"
+{KEYWORD_RETURN(SIGNED);}
+	YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 215 "Parser/lex.l"
+{KEYWORD_RETURN(SIGNED);}	/* GCC */
+	YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 216 "Parser/lex.l"
+{KEYWORD_RETURN(SIGNED);}	/* GCC */
+	YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 217 "Parser/lex.l"
+{KEYWORD_RETURN(SIZEOF);}
+	YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 218 "Parser/lex.l"
+{KEYWORD_RETURN(STATIC);}
+	YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 219 "Parser/lex.l"
+{KEYWORD_RETURN(STRUCT);}
+	YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 220 "Parser/lex.l"
+{KEYWORD_RETURN(SWITCH);}
+	YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 221 "Parser/lex.l"
+{KEYWORD_RETURN(THROW);}	/* CFA */
+	YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 222 "Parser/lex.l"
+{KEYWORD_RETURN(TRY);}		/* CFA */
+	YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 223 "Parser/lex.l"
+{KEYWORD_RETURN(TYPE);}
+	YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 224 "Parser/lex.l"
+{KEYWORD_RETURN(TYPEDEF);}
+	YY_BREAK
+case 75:
+YY_RULE_SETUP
+#line 225 "Parser/lex.l"
+{KEYWORD_RETURN(TYPEOF);}	/* GCC */
+	YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 226 "Parser/lex.l"
+{KEYWORD_RETURN(TYPEOF);}	/* GCC */
+	YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 227 "Parser/lex.l"
+{KEYWORD_RETURN(TYPEOF);}	/* GCC */
+	YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 228 "Parser/lex.l"
+{KEYWORD_RETURN(UNION);}
+	YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 229 "Parser/lex.l"
+{KEYWORD_RETURN(UNSIGNED);}
+	YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 230 "Parser/lex.l"
+{KEYWORD_RETURN(VOID);}
+	YY_BREAK
+case 81:
+YY_RULE_SETUP
+#line 231 "Parser/lex.l"
+{KEYWORD_RETURN(VOLATILE);}
+	YY_BREAK
+case 82:
+YY_RULE_SETUP
+#line 232 "Parser/lex.l"
+{KEYWORD_RETURN(VOLATILE);}	/* GCC */
+	YY_BREAK
+case 83:
+YY_RULE_SETUP
+#line 233 "Parser/lex.l"
+{KEYWORD_RETURN(VOLATILE);}	/* GCC */
+	YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 234 "Parser/lex.l"
+{KEYWORD_RETURN(WHILE);}
+	YY_BREAK
+/* identifier */
+case 85:
+YY_RULE_SETUP
+#line 237 "Parser/lex.l"
+{IDENTIFIER_RETURN();}
+	YY_BREAK
+/* numeric constants */
+case 86:
+YY_RULE_SETUP
+#line 240 "Parser/lex.l"
+{NUMERIC_RETURN(ZERO);}		/* CFA */
+	YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 241 "Parser/lex.l"
+{NUMERIC_RETURN(ONE);}		/* CFA */
+	YY_BREAK
+case 88:
+YY_RULE_SETUP
+#line 242 "Parser/lex.l"
+{NUMERIC_RETURN(INTEGERconstant);}
+	YY_BREAK
+case 89:
+YY_RULE_SETUP
+#line 243 "Parser/lex.l"
+{NUMERIC_RETURN(INTEGERconstant);}
+	YY_BREAK
+case 90:
+YY_RULE_SETUP
+#line 244 "Parser/lex.l"
+{NUMERIC_RETURN(INTEGERconstant);}
+	YY_BREAK
+case 91:
+YY_RULE_SETUP
+#line 245 "Parser/lex.l"
+{NUMERIC_RETURN(FLOATINGconstant);}
+	YY_BREAK
+case 92:
+YY_RULE_SETUP
+#line 246 "Parser/lex.l"
+{NUMERIC_RETURN(FLOATINGconstant);}
+	YY_BREAK
+/* character constant, allows empty value */
+case 93:
+YY_RULE_SETUP
+#line 249 "Parser/lex.l"
+{RETURN_VAL(CHARACTERconstant);}
+	YY_BREAK
+/* string constant */
+case 94:
+YY_RULE_SETUP
+#line 252 "Parser/lex.l"
+{RETURN_VAL(STRINGliteral);}
+	YY_BREAK
+/* punctuation */
+case 95:
+YY_RULE_SETUP
+#line 255 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 96:
+YY_RULE_SETUP
+#line 256 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 97:
+YY_RULE_SETUP
+#line 257 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 98:
+YY_RULE_SETUP
+#line 258 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 99:
+YY_RULE_SETUP
+#line 259 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 100:
+YY_RULE_SETUP
+#line 260 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 101:
+YY_RULE_SETUP
+#line 261 "Parser/lex.l"
+{ASCIIOP_RETURN();}		/* also operator */
+	YY_BREAK
+case 102:
+YY_RULE_SETUP
+#line 262 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 103:
+YY_RULE_SETUP
+#line 263 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 104:
+YY_RULE_SETUP
+#line 264 "Parser/lex.l"
+{ASCIIOP_RETURN();}		/* also operator */
+	YY_BREAK
+case 105:
+YY_RULE_SETUP
+#line 265 "Parser/lex.l"
+{NAMEDOP_RETURN(ELLIPSIS);}
+	YY_BREAK
+/* alternative ANSI99 brackets, "<:" & "<:<:" handled by preprocessor */
+case 106:
+YY_RULE_SETUP
+#line 268 "Parser/lex.l"
+{RETURN_VAL('[');}
+	YY_BREAK
+case 107:
+YY_RULE_SETUP
+#line 269 "Parser/lex.l"
+{RETURN_VAL(']');}
+	YY_BREAK
+case 108:
+YY_RULE_SETUP
+#line 270 "Parser/lex.l"
+{RETURN_VAL('{');}
+	YY_BREAK
+case 109:
+YY_RULE_SETUP
+#line 271 "Parser/lex.l"
+{RETURN_VAL('}');}
+	YY_BREAK
+/* operators */
+case 110:
+YY_RULE_SETUP
+#line 274 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 111:
+YY_RULE_SETUP
+#line 275 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 112:
+YY_RULE_SETUP
+#line 276 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 113:
+YY_RULE_SETUP
+#line 277 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 114:
+YY_RULE_SETUP
+#line 278 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 115:
+YY_RULE_SETUP
+#line 279 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 116:
+YY_RULE_SETUP
+#line 280 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 117:
+YY_RULE_SETUP
+#line 281 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 118:
+YY_RULE_SETUP
+#line 282 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 119:
+YY_RULE_SETUP
+#line 283 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 120:
+YY_RULE_SETUP
+#line 284 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 121:
+YY_RULE_SETUP
+#line 285 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 122:
+YY_RULE_SETUP
+#line 286 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 123:
+YY_RULE_SETUP
+#line 287 "Parser/lex.l"
+{ASCIIOP_RETURN();}
+	YY_BREAK
+case 124:
+YY_RULE_SETUP
+#line 289 "Parser/lex.l"
+{NAMEDOP_RETURN(ICR);}
+	YY_BREAK
+case 125:
+YY_RULE_SETUP
+#line 290 "Parser/lex.l"
+{NAMEDOP_RETURN(DECR);}
+	YY_BREAK
+case 126:
+YY_RULE_SETUP
+#line 291 "Parser/lex.l"
+{NAMEDOP_RETURN(EQ);}
+	YY_BREAK
+case 127:
+YY_RULE_SETUP
+#line 292 "Parser/lex.l"
+{NAMEDOP_RETURN(NE);}
+	YY_BREAK
+case 128:
+YY_RULE_SETUP
+#line 293 "Parser/lex.l"
+{NAMEDOP_RETURN(LS);}
+	YY_BREAK
+case 129:
+YY_RULE_SETUP
+#line 294 "Parser/lex.l"
+{NAMEDOP_RETURN(RS);}
+	YY_BREAK
+case 130:
+YY_RULE_SETUP
+#line 295 "Parser/lex.l"
+{NAMEDOP_RETURN(LE);}
+	YY_BREAK
+case 131:
+YY_RULE_SETUP
+#line 296 "Parser/lex.l"
+{NAMEDOP_RETURN(GE);}
+	YY_BREAK
+case 132:
+YY_RULE_SETUP
+#line 297 "Parser/lex.l"
+{NAMEDOP_RETURN(ANDAND);}
+	YY_BREAK
+case 133:
+YY_RULE_SETUP
+#line 298 "Parser/lex.l"
+{NAMEDOP_RETURN(OROR);}
+	YY_BREAK
+case 134:
+YY_RULE_SETUP
+#line 299 "Parser/lex.l"
+{NAMEDOP_RETURN(ARROW);}
+	YY_BREAK
+case 135:
+YY_RULE_SETUP
+#line 300 "Parser/lex.l"
+{NAMEDOP_RETURN(PLUSassign);}
+	YY_BREAK
+case 136:
+YY_RULE_SETUP
+#line 301 "Parser/lex.l"
+{NAMEDOP_RETURN(MINUSassign);}
+	YY_BREAK
+case 137:
+YY_RULE_SETUP
+#line 302 "Parser/lex.l"
+{NAMEDOP_RETURN(MULTassign);}
+	YY_BREAK
+case 138:
+YY_RULE_SETUP
+#line 303 "Parser/lex.l"
+{NAMEDOP_RETURN(DIVassign);}
+	YY_BREAK
+case 139:
+YY_RULE_SETUP
+#line 304 "Parser/lex.l"
+{NAMEDOP_RETURN(MODassign);}
+	YY_BREAK
+case 140:
+YY_RULE_SETUP
+#line 305 "Parser/lex.l"
+{NAMEDOP_RETURN(ANDassign);}
+	YY_BREAK
+case 141:
+YY_RULE_SETUP
+#line 306 "Parser/lex.l"
+{NAMEDOP_RETURN(ORassign);}
+	YY_BREAK
+case 142:
+YY_RULE_SETUP
+#line 307 "Parser/lex.l"
+{NAMEDOP_RETURN(ERassign);}
+	YY_BREAK
+case 143:
+YY_RULE_SETUP
+#line 308 "Parser/lex.l"
+{NAMEDOP_RETURN(LSassign);}
+	YY_BREAK
+case 144:
+YY_RULE_SETUP
+#line 309 "Parser/lex.l"
+{NAMEDOP_RETURN(RSassign);}
+	YY_BREAK
+/* CFA, operator identifier */
+case 145:
+YY_RULE_SETUP
+#line 312 "Parser/lex.l"
+{IDENTIFIER_RETURN();}		/* unary */
+	YY_BREAK
+case 146:
+YY_RULE_SETUP
+#line 313 "Parser/lex.l"
+{IDENTIFIER_RETURN();}
+	YY_BREAK
+case 147:
+YY_RULE_SETUP
+#line 314 "Parser/lex.l"
+{IDENTIFIER_RETURN();}		/* binary */
+	YY_BREAK
+/*
+	  This rule handles ambiguous cases with operator identifiers, e.g., "int *?*?()", where the
+	  string "*?*?"  can be lexed as "*"/"?*?" or "*?"/"*?". Since it is common practise to put
+	  a unary operator juxtaposed to an identifier, e.g., "*i", users will be annoyed if they
+	  cannot do this with respect to operator identifiers. Even with this special hack, there
+	  are 5 general cases that cannot be handled. The first case is for the function-call
+	  identifier "?()":
+
+	  int * ?()();	// declaration: space required after '*'
+	  * ?()();	// expression: space required after '*'
+
+	  Without the space, the string "*?()" is ambiguous without N character look ahead; it
+	  requires scanning ahead to determine if there is a '(', which is the start of an
+	  argument/parameter list.
+
+	  The 4 remaining cases occur in expressions:
+
+	  i++?i:0;		// space required before '?'
+	  i--?i:0;		// space required before '?'
+	  i?++i:0;		// space required after '?'
+	  i?--i:0;		// space required after '?'
+
+	  In the first two cases, the string "i++?" is ambiguous, where this string can be lexed as
+	  "i"/"++?" or "i++"/"?"; it requires scanning ahead to determine if there is a '(', which
+	  is the start of an argument list.  In the second two cases, the string "?++x" is
+	  ambiguous, where this string can be lexed as "?++"/"x" or "?"/"++x"; it requires scanning
+	  ahead to determine if there is a '(', which is the start of an argument list.
+	*/
+case 148:
+YY_RULE_SETUP
+#line 343 "Parser/lex.l"
+{
+			    // 1 or 2 character unary operator ?
+			    int i = yytext[1] == '?' ? 1 : 2;
+			    yyless( i );		/* put back characters up to first '?' */
+			    if ( i > 1 ) {
+				NAMEDOP_RETURN( yytext[0] == '+' ? ICR : DECR );
+			    } else {
+				ASCIIOP_RETURN();
+			    } // if
+			}
+	YY_BREAK
+/* unknown characters */
+case 149:
+YY_RULE_SETUP
+#line 355 "Parser/lex.l"
+{printf("unknown character(s):\"%s\" on line %d\n", yytext, yylineno);}
+	YY_BREAK
+case 150:
+YY_RULE_SETUP
+#line 357 "Parser/lex.l"
+ECHO;
+	YY_BREAK
+#line 2177 "Parser/lex.yy.cc"
+			case YY_STATE_EOF(INITIAL):
+			case YY_STATE_EOF(COMMENT):
+				yyterminate();
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = yy_hold_char;
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed yyin at a new source and called
+			 * yylex().  If so, then we have to assure
+			 * consistency between yy_current_buffer and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			yy_n_chars = yy_current_buffer->yy_n_chars;
+			yy_current_buffer->yy_input_file = yyin;
+			yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state();
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+			yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++yy_c_buf_p;
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = yy_c_buf_p;
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer() )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				yy_did_buffer_switch_on_eof = 0;
+
+				if ( yywrap() )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * yytext, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				yy_c_buf_p =
+					yytext_ptr + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state();
+
+				yy_cp = yy_c_buf_p;
+				yy_bp = yytext_ptr + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				yy_c_buf_p =
+				&yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+				yy_current_state = yy_get_previous_state();
+
+				yy_cp = yy_c_buf_p;
+				yy_bp = yytext_ptr + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+	} /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+	{
+	register char *dest = yy_current_buffer->yy_ch_buf;
+	register char *source = yytext_ptr;
+	register int number_to_move, i;
+	int ret_val;
+
+	if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( yy_current_buffer->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+	else
+		{
+		int num_to_read =
+			yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+			YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = yy_current_buffer;
+
+			int yy_c_buf_p_offset =
+				(int) (yy_c_buf_p - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				int new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					yy_flex_realloc( (void *) b->yy_ch_buf,
+							 b->yy_buf_size + 2 );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = yy_current_buffer->yy_buf_size -
+						number_to_move - 1;
+#endif
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+			yy_n_chars, num_to_read );
+
+		yy_current_buffer->yy_n_chars = yy_n_chars;
+		}
+
+	if ( yy_n_chars == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			yyrestart( yyin );
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			yy_current_buffer->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	yy_n_chars += number_to_move;
+	yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+	yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+	yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+	return ret_val;
+	}
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+	{
+	register yy_state_type yy_current_state;
+	register char *yy_cp;
+
+	yy_current_state = yy_start;
+	yy_current_state += YY_AT_BOL();
+	yy_state_ptr = yy_state_buf;
+	*yy_state_ptr++ = yy_current_state;
+
+	for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+		{
+		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+			{
+			yy_current_state = (int) yy_def[yy_current_state];
+			if ( yy_current_state >= 618 )
+				yy_c = yy_meta[(unsigned int) yy_c];
+			}
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		*yy_state_ptr++ = yy_current_state;
+		}
+
+	return yy_current_state;
+	}
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+	{
+	register int yy_is_jam;
+
+	register YY_CHAR yy_c = 1;
+	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+		{
+		yy_current_state = (int) yy_def[yy_current_state];
+		if ( yy_current_state >= 618 )
+			yy_c = yy_meta[(unsigned int) yy_c];
+		}
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+	yy_is_jam = (yy_current_state == 617);
+	if ( ! yy_is_jam )
+		*yy_state_ptr++ = yy_current_state;
+
+	return yy_is_jam ? 0 : yy_current_state;
+	}
+
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+	{
+	register char *yy_cp = yy_c_buf_p;
+
+	/* undo effects of setting up yytext */
+	*yy_cp = yy_hold_char;
+
+	if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+		{ /* need to shift things up to make room */
+		/* +2 for EOB chars. */
+		register int number_to_move = yy_n_chars + 2;
+		register char *dest = &yy_current_buffer->yy_ch_buf[
+					yy_current_buffer->yy_buf_size + 2];
+		register char *source =
+				&yy_current_buffer->yy_ch_buf[number_to_move];
+
+		while ( source > yy_current_buffer->yy_ch_buf )
+			*--dest = *--source;
+
+		yy_cp += (int) (dest - source);
+		yy_bp += (int) (dest - source);
+		yy_current_buffer->yy_n_chars =
+			yy_n_chars = yy_current_buffer->yy_buf_size;
+
+		if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+			YY_FATAL_ERROR( "flex scanner push-back overflow" );
+		}
+
+	*--yy_cp = (char) c;
+
+	if ( c == '\n' )
+		--yylineno;
+
+	yytext_ptr = yy_bp;
+	yy_hold_char = *yy_cp;
+	yy_c_buf_p = yy_cp;
+	}
+#endif	/* ifndef YY_NO_UNPUT */
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+	{
+	int c;
+
+	*yy_c_buf_p = yy_hold_char;
+
+	if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+			/* This was really a NUL. */
+			*yy_c_buf_p = '\0';
+
+		else
+			{ /* need more input */
+			int offset = yy_c_buf_p - yytext_ptr;
+			++yy_c_buf_p;
+
+			switch ( yy_get_next_buffer() )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					yyrestart( yyin );
+
+					/* fall through */
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( yywrap() )
+						return EOF;
+
+					if ( ! yy_did_buffer_switch_on_eof )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return yyinput();
+#else
+					return input();
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					yy_c_buf_p = yytext_ptr + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) yy_c_buf_p;	/* cast for 8-bit char's */
+	*yy_c_buf_p = '\0';	/* preserve yytext */
+	yy_hold_char = *++yy_c_buf_p;
+
+	yy_current_buffer->yy_at_bol = (c == '\n');
+	if ( yy_current_buffer->yy_at_bol )
+		++yylineno;
+
+	return c;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+	{
+	if ( ! yy_current_buffer )
+		yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+	yy_init_buffer( yy_current_buffer, input_file );
+	yy_load_buffer_state();
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+	{
+	if ( yy_current_buffer == new_buffer )
+		return;
+
+	if ( yy_current_buffer )
+		{
+		/* Flush out information for old buffer. */
+		*yy_c_buf_p = yy_hold_char;
+		yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+		yy_current_buffer->yy_n_chars = yy_n_chars;
+		}
+
+	yy_current_buffer = new_buffer;
+	yy_load_buffer_state();
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (yywrap()) processing, but the only time this flag
+	 * is looked at is after yywrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	yy_did_buffer_switch_on_eof = 1;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+	{
+	yy_n_chars = yy_current_buffer->yy_n_chars;
+	yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+	yyin = yy_current_buffer->yy_input_file;
+	yy_hold_char = *yy_c_buf_p;
+	}
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+	{
+	YY_BUFFER_STATE b;
+
+	b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	yy_init_buffer( b, file );
+
+	return b;
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+	{
+	if ( ! b )
+		return;
+
+	if ( b == yy_current_buffer )
+		yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		yy_flex_free( (void *) b->yy_ch_buf );
+
+	yy_flex_free( (void *) b );
+	}
+
+
+#ifndef YY_ALWAYS_INTERACTIVE
+#ifndef YY_NEVER_INTERACTIVE
+extern int isatty YY_PROTO(( int ));
+#endif
+#endif
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+	{
+	yy_flush_buffer( b );
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+	b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+	b->yy_is_interactive = 0;
+#else
+	b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+	}
+
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+	{
+	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == yy_current_buffer )
+		yy_load_buffer_state();
+	}
+
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+	{
+	YY_BUFFER_STATE b;
+
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return 0;
+
+	b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = 0;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	yy_switch_to_buffer( b );
+
+	return b;
+	}
+#endif
+
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+	{
+	int len;
+	for ( len = 0; yy_str[len]; ++len )
+		;
+
+	return yy_scan_bytes( yy_str, len );
+	}
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+	{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	int i;
+
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = len + 2;
+	buf = (char *) yy_flex_alloc( n );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+	for ( i = 0; i < len; ++i )
+		buf[i] = bytes[i];
+
+	buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = yy_scan_buffer( buf, n );
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+	}
+#endif
+
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+	{
+	if ( yy_start_stack_ptr >= yy_start_stack_depth )
+		{
+		yy_size_t new_size;
+
+		yy_start_stack_depth += YY_START_STACK_INCR;
+		new_size = yy_start_stack_depth * sizeof( int );
+
+		if ( ! yy_start_stack )
+			yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+		else
+			yy_start_stack = (int *) yy_flex_realloc(
+					(void *) yy_start_stack, new_size );
+
+		if ( ! yy_start_stack )
+			YY_FATAL_ERROR(
+			"out of memory expanding start-condition stack" );
+		}
+
+	yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+	BEGIN(new_state);
+	}
+#endif
+
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+	{
+	if ( --yy_start_stack_ptr < 0 )
+		YY_FATAL_ERROR( "start-condition stack underflow" );
+
+	BEGIN(yy_start_stack[yy_start_stack_ptr]);
+	}
+#endif
+
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+	{
+	return yy_start_stack[yy_start_stack_ptr - 1];
+	}
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+	{
+	(void) fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+	}
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up yytext. */ \
+		yytext[yyleng] = yy_hold_char; \
+		yy_c_buf_p = yytext + n; \
+		yy_hold_char = *yy_c_buf_p; \
+		*yy_c_buf_p = '\0'; \
+		yyleng = n; \
+		} \
+	while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+	{
+	register int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+	}
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+	{
+	register int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+	}
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+	{
+	return (void *) malloc( size );
+	}
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+	{
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+	}
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+	{
+	free( ptr );
+	}
+
+#if YY_MAIN
+int main()
+	{
+	yylex();
+	return 0;
+	}
+#endif
+#line 357 "Parser/lex.l"
+
+
+
+/* Local Variables: */
+/* fill-column: 100 */
+/* compile-command: "gmake" */
+/* End: */
Index: translator/Parser.old/module.mk
===================================================================
--- translator/Parser.old/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser.old/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,42 @@
+###
+### This file is part of the Cforall project
+###
+### $Id: module.mk,v 1.8 2002/09/09 16:47:14 rcbilson Exp $
+###
+
+YACC=bison
+YFLAGS=-d --debug -v
+LEX=flex
+LFLAGS=
+
+SRC += Parser/cfa.y \
+       Parser/lex.l \
+       Parser/TypedefTable.cc \
+       Parser/ParseNode.cc \
+       Parser/DeclarationNode.cc \
+       Parser/ExpressionNode.cc \
+       Parser/StatementNode.cc \
+       Parser/InitializerNode.cc \
+       Parser/TypeData.cc \
+       Parser/LinkageSpec.cc \
+       Parser/parseutility.cc \
+       Parser/Parser.cc
+
+EXTRA_OUTPUT += Parser/cfa.tab.cc \
+                Parser/cfa.tab.h \
+		Parser/lex.yy.cc \
+		Parser/cfa.output
+
+LIBS += -lfl
+
+Parser/cfa.tab.cc: Parser/cfa.y
+	$(YACC) $(YFLAGS) $< 
+	-mv Parser/cfa.tab.c Parser/cfa.tab.cc
+
+Parser/cfa.tab.h: Parser/cfa.tab.cc
+
+Parser/lex.yy.cc: Parser/lex.l Parser/cfa.tab.h Parser/TypedefTable.h
+	$(LEX) $(LFLAGS) -o$@ $< 
+
+Parser/lex.yy.o: Parser/lex.yy.cc Parser/ParseNode.h
+	$(CXX) $(CXXFLAGS) -Wno-unused -c -o $@ $<
Index: translator/Parser.old/parseutility.cc
===================================================================
--- translator/Parser.old/parseutility.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser.old/parseutility.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,20 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: parseutility.cc,v 1.1 2002/09/02 20:30:42 rcbilson Exp $
+ *
+ */
+
+#include "parseutility.h"
+#include "SynTree/Type.h"
+#include "SynTree/Expression.h"
+
+
+Expression *
+notZeroExpr( Expression *orig )
+{
+      UntypedExpr *comparison = new UntypedExpr( new NameExpr( "?!=?" ) );
+      comparison->get_args().push_back( orig );
+      comparison->get_args().push_back( new NameExpr( "0" ) );
+      return new CastExpr( comparison, new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
+}
Index: translator/Parser.old/parseutility.h
===================================================================
--- translator/Parser.old/parseutility.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser.old/parseutility.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,15 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: parseutility.h,v 1.1 2002/09/02 20:30:42 rcbilson Exp $
+ *
+ */
+
+#ifndef PARSER_PARSEUTILITY_H
+#define PARSER_PARSEUTILITY_H
+
+#include "SynTree/SynTree.h"
+
+Expression *notZeroExpr( Expression *orig );
+
+#endif /* #ifndef PARSER_PARSEUTILITY_H */
Index: translator/Parser/DeclarationNode.cc
===================================================================
--- translator/Parser/DeclarationNode.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser/DeclarationNode.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,1076 @@
+#include <string>
+#include <list>
+#include <iterator>
+#include <algorithm>
+#include <cassert>
+
+#include "ParseNode.h"
+#include "TypeData.h"
+#include "utility.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Initializer.h"
+#include "SemanticError.h"
+#include "UniqueName.h"
+#include "LinkageSpec.h"
+
+using namespace std;
+
+/* these must remain in the same order as the corresponding DeclarationNode enumerations */
+const char *DeclarationNode::qualifierName[] = { "const", "restrict", "volatile", "lvalue" };
+const char *DeclarationNode::basicTypeName[] = { "char", "int", "float", "double", "void", "bool", "complex", "imaginary" };
+const char *DeclarationNode::modifierName[] = { "signed", "unsigned", "short", "long" };
+const char *DeclarationNode::tyConName[] = { "struct", "union", "context" };
+const char *DeclarationNode::typeClassName[] = { "type", "dtype", "ftype" };
+
+UniqueName DeclarationNode::anonymous( "__anonymous" );
+
+extern LinkageSpec::Type linkage;		/* defined in cfa.y */
+
+DeclarationNode*
+DeclarationNode::clone() const
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->type = maybeClone( type );
+  newnode->name = name;
+  newnode->storageClasses = storageClasses;
+  newnode->bitfieldWidth = maybeClone( bitfieldWidth );
+  newnode->hasEllipsis = hasEllipsis;
+  newnode->initializer = initializer;
+  newnode->next = maybeClone( next );
+  newnode->linkage = linkage;
+  return newnode;
+}
+
+DeclarationNode::DeclarationNode()
+  : type( 0 ), bitfieldWidth( 0 ), initializer( 0 ), hasEllipsis( false ), linkage( ::linkage )
+{
+}
+
+DeclarationNode::~DeclarationNode()
+{
+  delete type;
+  delete bitfieldWidth;
+  delete initializer;
+}
+
+bool
+DeclarationNode::get_hasEllipsis() const
+{
+  return hasEllipsis;
+}
+
+const char *storageClassName[] =
+{
+  // order must correspond with DeclarationNode::StorageClass
+  "static",
+  "auto",
+  "extern",
+  "register",
+  "inline",
+  "fortran",
+};
+
+void
+DeclarationNode::print( std::ostream &os, int indent ) const
+{
+  os << string(indent,  ' ');
+  if( name == "" ) {
+///     os << "An unnamed ";
+  } else {
+    os << name << ": a ";
+  }
+  if( linkage != LinkageSpec::Cforall ) {
+    os << LinkageSpec::toString( linkage ) << " ";
+  }
+  printEnums( storageClasses.begin(), storageClasses.end(), storageClassName, os );
+  if( type ) {
+    type->print( os, indent );
+  } else {
+    os << "untyped entity ";
+  }
+  if( bitfieldWidth ) {
+    os << endl << string(indent+2,  ' ') << "with bitfield width ";
+    bitfieldWidth->printOneLine( os );
+  }
+
+  if( initializer != 0 ) {
+    os << endl << string(indent+2,  ' ') << "with initializer ";
+    initializer->printOneLine( os );
+  }
+
+  os << endl;
+}
+
+void
+DeclarationNode::printList( std::ostream &os, int indent ) const
+{
+  ParseNode::printList( os, indent );
+  if( hasEllipsis ) {
+    os << string( indent, ' ' )  << "and a variable number of other arguments" << endl;
+  }
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newFunction( std::string* name, DeclarationNode *ret, DeclarationNode *param, StatementNode *body, bool newStyle )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->name = assign_strptr( name );
+
+  newnode->type = new TypeData( TypeData::Function );
+  newnode->type->function->params = param;
+  newnode->type->function->newStyle = newStyle;
+  newnode->type->function->body = body;
+  if( body ) {
+    newnode->type->function->hasBody = true;
+  }
+
+  if( ret ) {
+    newnode->type->base = ret->type;
+    ret->type = 0;
+    delete ret;
+  }
+
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newQualifier( Qualifier q )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->type = new TypeData();
+  newnode->type->qualifiers.push_back( q );
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newStorageClass( StorageClass sc )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->storageClasses.push_back( sc );
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newBasicType( BasicType bt )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->type = new TypeData( TypeData::Basic );
+  newnode->type->basic->typeSpec.push_back( bt );
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newModifier( Modifier mod )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->type = new TypeData( TypeData::Basic );
+  newnode->type->basic->modifiers.push_back( mod );
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newForall( DeclarationNode* forall )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->type = new TypeData( TypeData::Unknown );
+  newnode->type->forall = forall;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newFromTypedef( std::string* name )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->type = new TypeData( TypeData::SymbolicInst );
+  newnode->type->symbolic->name = assign_strptr( name );
+  newnode->type->symbolic->isTypedef = true;
+  newnode->type->symbolic->params = 0;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newAggregate( TyCon kind, std::string* name, DeclarationNode *formals, ExpressionNode *actuals, DeclarationNode *fields )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->type = new TypeData( TypeData::Aggregate );
+  newnode->type->aggregate->kind = kind;
+  newnode->type->aggregate->name = assign_strptr( name );
+  if( newnode->type->aggregate->name == "" ) {
+    newnode->type->aggregate->name = DeclarationNode::anonymous.newName();
+  }
+  newnode->type->aggregate->params = formals;
+  newnode->type->aggregate->actuals = actuals;
+  newnode->type->aggregate->members = fields;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newEnum( std::string *name, DeclarationNode *constants )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->name = assign_strptr( name );
+  newnode->type = new TypeData( TypeData::Enum );
+  newnode->type->enumeration->name = newnode->name;
+  if( newnode->type->enumeration->name == "" ) {
+    newnode->type->enumeration->name = DeclarationNode::anonymous.newName();
+  }
+  newnode->type->enumeration->constants = constants;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newEnumConstant( std::string* name, ExpressionNode *constant )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->name = assign_strptr( name );
+  // do something with the constant
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newName( std::string* name )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->name = assign_strptr( name );
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newFromTypeGen( std::string* name, ExpressionNode *params )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->type = new TypeData( TypeData::SymbolicInst );
+  newnode->type->symbolic->name = assign_strptr( name );
+  newnode->type->symbolic->isTypedef = false;
+  newnode->type->symbolic->actuals = params;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newTypeParam( TypeClass tc, std::string* name )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->name = assign_strptr( name );
+  newnode->type = new TypeData( TypeData::Variable );
+  newnode->type->variable->tyClass = tc;
+  newnode->type->variable->name = newnode->name;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newContext( std::string *name, DeclarationNode *params, DeclarationNode *asserts )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->type = new TypeData( TypeData::Aggregate );
+  newnode->type->aggregate->kind = Context;
+  newnode->type->aggregate->params = params;
+  newnode->type->aggregate->members = asserts;
+  newnode->type->aggregate->name = assign_strptr( name );
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newContextUse( std::string *name, ExpressionNode *params )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->type = new TypeData( TypeData::AggregateInst );
+  newnode->type->aggInst->aggregate = new TypeData( TypeData::Aggregate );
+  newnode->type->aggInst->aggregate->aggregate->kind = Context;
+  newnode->type->aggInst->aggregate->aggregate->name = assign_strptr( name );
+  newnode->type->aggInst->params = params;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newTypeDecl( std::string *name, DeclarationNode *typeParams )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->name = assign_strptr( name );
+  newnode->type = new TypeData( TypeData::Symbolic );
+  newnode->type->symbolic->isTypedef = false;
+  newnode->type->symbolic->params = typeParams;
+  newnode->type->symbolic->name = newnode->name;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newPointer( DeclarationNode *qualifiers )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->type = new TypeData( TypeData::Pointer );
+  return newnode->addQualifiers( qualifiers );
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newArray( ExpressionNode *size, DeclarationNode *qualifiers, bool isStatic )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->type = new TypeData( TypeData::Array );
+  newnode->type->array->dimension = size;
+  newnode->type->array->isStatic = isStatic;
+  newnode->type->array->isVarLen = false;
+  return newnode->addQualifiers( qualifiers );
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newVarArray( DeclarationNode *qualifiers )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->type = new TypeData( TypeData::Array );
+  newnode->type->array->dimension = 0;
+  newnode->type->array->isStatic = false;
+  newnode->type->array->isVarLen = true;
+  return newnode->addQualifiers( qualifiers );
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newBitfield( ExpressionNode *size )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->bitfieldWidth = size;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newTuple( DeclarationNode *members )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->type = new TypeData( TypeData::Tuple );
+  newnode->type->tuple->members = members;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newTypeof( ExpressionNode *expr )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->type = new TypeData( TypeData::Typeof );
+  newnode->type->typeexpr->expr = expr;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newAttr( std::string *name, ExpressionNode *expr )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->type = new TypeData( TypeData::Attr );
+  newnode->type->attr->name = assign_strptr( name );
+  newnode->type->attr->expr = expr;
+  return newnode;
+}
+
+/* static class method */
+DeclarationNode *
+DeclarationNode::newAttr( std::string *name, DeclarationNode *type )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->type = new TypeData( TypeData::Attr );
+  newnode->type->attr->name = assign_strptr( name );
+  newnode->type->attr->type = type;
+  return newnode;
+}
+
+static void
+addQualifiersToType( TypeData *&src, TypeData *dst )
+{
+  if( src && dst ) {
+    if( src->forall && dst->kind == TypeData::Function ) {
+      if( dst->forall ) {
+	dst->forall->appendList( src->forall );
+      } else {
+	dst->forall = src->forall;
+      }
+      src->forall = 0;
+    }
+    if( dst->base ) {
+      addQualifiersToType( src, dst->base );
+    } else if( dst->kind == TypeData::Function ) {
+      dst->base = src;
+      src = 0;
+    } else {
+      dst->qualifiers.splice( dst->qualifiers.end(), src->qualifiers );
+    }
+  }
+}
+      
+DeclarationNode *
+DeclarationNode::addQualifiers( DeclarationNode *q )
+{
+  if( q ) {
+    storageClasses.splice( storageClasses.end(), q->storageClasses );
+    if( q->type ) {
+      if( !type ) {
+	type = new TypeData;
+      }
+      addQualifiersToType( q->type, type );
+      if( q->type && q->type->forall ) {
+        if( type->forall ) {
+          type->forall->appendList( q->type->forall );
+        } else {
+          type->forall = q->type->forall;
+        }
+        q->type->forall = 0;
+      }
+    }
+  }
+  delete q;
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::copyStorageClasses( DeclarationNode *q )
+{
+  storageClasses = q->storageClasses;
+  return this;
+}
+
+static void
+addTypeToType( TypeData *&src, TypeData *&dst )
+{
+  if( src && dst ) {
+    if( src->forall && dst->kind == TypeData::Function ) {
+      if( dst->forall ) {
+        dst->forall->appendList( src->forall );
+      } else {
+        dst->forall = src->forall;
+      }
+      src->forall = 0;
+    }
+    if( dst->base ) {
+      addTypeToType( src, dst->base );
+    } else {
+      switch( dst->kind ) {
+      case TypeData::Unknown:
+	src->qualifiers.splice( src->qualifiers.end(), dst->qualifiers );
+	dst = src;
+	src = 0;
+	break;
+
+      case TypeData::Basic:
+	dst->qualifiers.splice( dst->qualifiers.end(), src->qualifiers );
+        if( src->kind != TypeData::Unknown ) {
+	  assert( src->kind == TypeData::Basic );
+	  dst->basic->modifiers.splice( dst->basic->modifiers.end(), src->basic->modifiers );
+	  dst->basic->typeSpec.splice( dst->basic->typeSpec.end(), src->basic->typeSpec );
+	}
+	break;
+
+      default:
+        switch( src->kind ) {
+        case TypeData::Aggregate:
+        case TypeData::Enum:
+          dst->base = new TypeData( TypeData::AggregateInst );
+          dst->base->aggInst->aggregate = src;
+          if( src->kind == TypeData::Aggregate ) {
+            dst->base->aggInst->params = maybeClone( src->aggregate->actuals );
+          }
+          dst->base->qualifiers.splice( dst->base->qualifiers.end(), src->qualifiers );
+          src = 0;
+          break;
+          
+        default:
+          if( dst->forall ) {
+            dst->forall->appendList( src->forall );
+          } else {
+            dst->forall = src->forall;
+          }
+          src->forall = 0;
+          dst->base = src;
+          src = 0;
+        }
+      }
+    }
+  }
+}
+
+DeclarationNode *
+DeclarationNode::addType( DeclarationNode *o )
+{
+  if( o ) {
+    storageClasses.splice( storageClasses.end(), o->storageClasses );
+    if ( o->type ) {
+      if( !type ) {
+        if( o->type->kind == TypeData::Aggregate || o->type->kind == TypeData::Enum ) {
+	  type = new TypeData( TypeData::AggregateInst );
+	  type->aggInst->aggregate = o->type;
+	  if( o->type->kind == TypeData::Aggregate ) {
+	    type->aggInst->params = maybeClone( o->type->aggregate->actuals );
+          }
+          type->qualifiers.splice( type->qualifiers.end(), o->type->qualifiers );
+	} else {
+	  type = o->type;
+	}
+	o->type = 0;
+      } else {
+	addTypeToType( o->type, type );
+      }
+    }
+    if( o->bitfieldWidth ) {
+      bitfieldWidth = o->bitfieldWidth;
+    }
+  }
+  delete o;
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::addTypedef()
+{
+  TypeData *newtype = new TypeData( TypeData::Symbolic );
+  newtype->symbolic->params = 0;
+  newtype->symbolic->isTypedef = true;
+  newtype->symbolic->name = name;
+  newtype->base = type;
+  type = newtype;
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::addAssertions( DeclarationNode* assertions )
+{
+  assert( type );
+  switch( type->kind ) {
+  case TypeData::Symbolic:
+    if( type->symbolic->assertions ) {
+      type->symbolic->assertions->appendList( assertions );
+    } else {
+      type->symbolic->assertions = assertions;
+    }
+    break;
+    
+  case TypeData::Variable:
+    if( type->variable->assertions ) {
+      type->variable->assertions->appendList( assertions );
+    } else {
+      type->variable->assertions = assertions;
+    }
+    break;
+    
+  default:
+    assert( false );
+  }
+    
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::addName( std::string* newname )
+{
+  name = assign_strptr( newname );
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::addBitfield( ExpressionNode *size )
+{
+  bitfieldWidth = size;
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::addVarArgs()
+{
+  assert( type );
+  hasEllipsis = true;
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::addFunctionBody( StatementNode *body )
+{
+  assert( type );
+  assert( type->kind == TypeData::Function );
+  assert( type->function->body == 0 );
+  type->function->body = body;
+  type->function->hasBody = true;
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::addOldDeclList( DeclarationNode *list )
+{
+  assert( type );
+  assert( type->kind == TypeData::Function );
+  assert( type->function->oldDeclList == 0 );
+  type->function->oldDeclList = list;
+  return this;
+}
+
+static void
+setBase( TypeData *&type, TypeData *newType )
+{
+  if( type ) {
+    TypeData *prevBase = type;
+    TypeData *curBase = type->base;
+    while( curBase != 0 ) {
+      prevBase = curBase;
+      curBase = curBase->base;
+    }
+    prevBase->base = newType;
+  } else {
+    type = newType;
+  }
+}
+
+DeclarationNode *
+DeclarationNode::addPointer( DeclarationNode *p )
+{
+  if( p ) {
+    assert( p->type->kind == TypeData::Pointer );
+    setBase( type, p->type );
+    p->type = 0;
+    delete p;
+  }
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::addArray( DeclarationNode *a )
+{
+  if( a ) {
+    assert( a->type->kind == TypeData::Array );
+    setBase( type, a->type );
+    a->type = 0;
+    delete a;
+  }
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::addNewPointer( DeclarationNode *p )
+{
+  if( p ) {
+    assert( p->type->kind == TypeData::Pointer );
+    if( type ) {
+      switch( type->kind ) {
+      case TypeData::Aggregate:
+      case TypeData::Enum:
+        p->type->base = new TypeData( TypeData::AggregateInst );
+        p->type->base->aggInst->aggregate = type;
+       	if( type->kind == TypeData::Aggregate ) {
+       	  p->type->base->aggInst->params = maybeClone( type->aggregate->actuals );
+       	}
+        p->type->base->qualifiers.splice( p->type->base->qualifiers.end(), type->qualifiers );
+        break;
+        
+      default:
+        p->type->base = type;
+      }
+      type = 0;
+    }
+    delete this;
+    return p;
+  } else {
+    return this;
+  }
+}
+
+static TypeData *
+findLast( TypeData *a )
+{
+  assert( a );
+  TypeData *cur = a;
+  while( cur->base ) {
+    cur = cur->base;
+  }
+  return cur;
+}
+
+DeclarationNode *
+DeclarationNode::addNewArray( DeclarationNode *a )
+{
+  if( a ) {
+    assert( a->type->kind == TypeData::Array );
+    TypeData *lastArray = findLast( a->type );
+    if( type ) {  
+      switch( type->kind ) {
+      case TypeData::Aggregate:
+      case TypeData::Enum:
+        lastArray->base = new TypeData( TypeData::AggregateInst );
+        lastArray->base->aggInst->aggregate = type;
+        if( type->kind == TypeData::Aggregate ) {
+          lastArray->base->aggInst->params = maybeClone( type->aggregate->actuals );
+        }
+        lastArray->base->qualifiers.splice( lastArray->base->qualifiers.end(), type->qualifiers );
+        break;
+        
+      default:
+        lastArray->base = type;
+      }
+      type = 0;
+    }
+    delete this;
+    return a;
+  } else {
+    return this;
+  }
+}
+
+DeclarationNode *
+DeclarationNode::addParamList( DeclarationNode *params )
+{
+  TypeData *ftype = new TypeData( TypeData::Function );
+  ftype->function->params = params;
+  setBase( type, ftype );
+  return this;
+}
+
+static TypeData*
+addIdListToType( TypeData *type, DeclarationNode *ids )
+{
+  if( type ) {
+    if( type->kind != TypeData::Function ) {
+      type->base = addIdListToType( type->base, ids );
+    } else {
+      type->function->idList = ids;
+    }
+    return type;
+  } else {
+    TypeData *newtype = new TypeData( TypeData::Function );
+    newtype->function->idList = ids;
+    return newtype;
+  }
+}
+    
+DeclarationNode *
+DeclarationNode::addIdList( DeclarationNode *ids )
+{
+  type = addIdListToType( type, ids );
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::addInitializer( InitializerNode *init )
+{
+  //assert
+  initializer = init;
+  return this;
+}
+
+DeclarationNode *
+DeclarationNode::cloneBaseType( string *newName )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  TypeData *srcType = type;
+  while( srcType->base ) {
+    srcType = srcType->base;
+  }
+  newnode->type = maybeClone( srcType );
+  if( newnode->type->kind == TypeData::AggregateInst ) {
+    // don't duplicate members
+    if( newnode->type->aggInst->aggregate->kind == TypeData::Enum ) {
+      delete newnode->type->aggInst->aggregate->enumeration->constants;
+      newnode->type->aggInst->aggregate->enumeration->constants = 0;
+    } else {
+      assert( newnode->type->aggInst->aggregate->kind == TypeData::Aggregate );
+      delete newnode->type->aggInst->aggregate->aggregate->members;
+      newnode->type->aggInst->aggregate->aggregate->members = 0;
+    }
+  }
+  newnode->type->forall = maybeClone( type->forall );
+  newnode->storageClasses = storageClasses;
+  newnode->name = assign_strptr( newName );
+  return newnode;
+}
+
+DeclarationNode *
+DeclarationNode::cloneBaseType( DeclarationNode *o )
+{
+  if( o ) {
+    o->storageClasses.insert( o->storageClasses.end(), storageClasses.begin(), storageClasses.end() );
+    if ( type ) {
+      TypeData *srcType = type;
+      while( srcType->base ) {
+	srcType = srcType->base;
+      }
+      TypeData *newType = srcType->clone();
+      if( newType->kind == TypeData::AggregateInst ) {
+        // don't duplicate members
+        if( newType->aggInst->aggregate->kind == TypeData::Enum ) {
+          delete newType->aggInst->aggregate->enumeration->constants;
+          newType->aggInst->aggregate->enumeration->constants = 0;
+        } else {
+          assert( newType->aggInst->aggregate->kind == TypeData::Aggregate );
+          delete newType->aggInst->aggregate->aggregate->members;
+          newType->aggInst->aggregate->aggregate->members = 0;
+        }
+      }
+      newType->forall = maybeClone( type->forall );
+      if( !o->type ) {
+	o->type = newType;
+      } else {
+	addTypeToType( newType, o->type );
+	delete newType;
+      }
+    }
+  }
+  return o;
+}
+
+DeclarationNode *
+DeclarationNode::cloneType( string *newName )
+{
+  DeclarationNode *newnode = new DeclarationNode;
+  newnode->type = maybeClone( type );
+  newnode->storageClasses = storageClasses;
+  newnode->name = assign_strptr( newName );
+  return newnode;
+}
+
+DeclarationNode *
+DeclarationNode::cloneType( DeclarationNode *o )
+{
+  if( o ) {
+    o->storageClasses.insert( o->storageClasses.end(), storageClasses.begin(), storageClasses.end() );
+    if ( type ) {
+      TypeData *newType = type->clone();
+      if( !o->type ) {
+	o->type = newType;
+      } else {
+	addTypeToType( newType, o->type );
+	delete newType;
+      }
+    }
+  }
+  return o;
+}
+
+DeclarationNode *
+DeclarationNode::appendList( DeclarationNode *node )
+{
+  if( node != 0 ) {
+    set_link( node );
+  }
+  return this;
+}
+
+DeclarationNode*
+DeclarationNode::extractAggregate() const
+{
+  if( type ) {
+    TypeData *ret = type->extractAggregate();
+    if( ret ) {
+      DeclarationNode *newnode = new DeclarationNode;
+      newnode->type = ret;
+      return newnode;
+    } else {
+      return 0;
+    }
+  } else {
+    return 0;
+  }
+}
+
+void buildList( const DeclarationNode *firstNode, std::list< Declaration* > &outputList )
+{
+  SemanticError errors;
+  std::back_insert_iterator< std::list< Declaration* > > out( outputList );
+  const DeclarationNode *cur = firstNode;
+  while( cur ) {
+    try {
+      if( DeclarationNode *extr = cur->extractAggregate() ) {
+	// handle the case where a structure declaration is contained within an object or type
+	// declaration
+	Declaration *decl = extr->build();
+	if( decl ) {
+	  *out++ = decl;
+	}
+      }
+      Declaration *decl = cur->build();
+      if( decl ) {
+        *out++ = decl;
+      }
+    } catch( SemanticError &e ) {
+      errors.append( e );
+    }
+    cur = dynamic_cast< DeclarationNode* >( cur->get_link() );
+  }
+  if( !errors.isEmpty() ) {
+    throw errors;
+  }
+}
+
+void buildList( const DeclarationNode *firstNode, std::list< DeclarationWithType* > &outputList )
+{
+  SemanticError errors;
+  std::back_insert_iterator< std::list< DeclarationWithType* > > out( outputList );
+  const DeclarationNode *cur = firstNode;
+  while( cur ) {
+    try {
+///       if( DeclarationNode *extr = cur->extractAggregate() ) {
+/// 	// handle the case where a structure declaration is contained within an object or type
+/// 	// declaration
+/// 	Declaration *decl = extr->build();
+/// 	if( decl ) {
+///           *out++ = decl;
+/// 	}
+///       }
+      Declaration *decl = cur->build();
+      if( decl ) {
+        if( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
+          *out++ = dwt;
+        } else if( StructDecl *agg = dynamic_cast< StructDecl* >( decl ) ) {
+          StructInstType *inst = new StructInstType( Type::Qualifiers(), agg->get_name() );
+          *out++ = new ObjectDecl( "", Declaration::NoStorageClass, linkage, 0, inst, 0 );
+          delete agg;
+        } else if( UnionDecl *agg = dynamic_cast< UnionDecl* >( decl ) ) {
+          UnionInstType *inst = new UnionInstType( Type::Qualifiers(), agg->get_name() );
+          *out++ = new ObjectDecl( "", Declaration::NoStorageClass, linkage, 0, inst, 0 );
+        }
+      }
+    } catch( SemanticError &e ) {
+      errors.append( e );
+    }
+    cur = dynamic_cast< DeclarationNode* >( cur->get_link() );
+  }
+  if( !errors.isEmpty() ) {
+    throw errors;
+  }
+}
+
+void buildTypeList( const DeclarationNode *firstNode, std::list< Type* > &outputList )
+{
+  SemanticError errors;
+  std::back_insert_iterator< std::list< Type* > > out( outputList );
+  const DeclarationNode *cur = firstNode;
+  while( cur ) {
+    try {
+      *out++ = cur->buildType();
+    } catch( SemanticError &e ) {
+      errors.append( e );
+    }
+    cur = dynamic_cast< DeclarationNode* >( cur->get_link() );
+  }
+  if( !errors.isEmpty() ) {
+    throw errors;
+  }
+}
+
+Declaration *
+DeclarationNode::build() const
+{
+
+  if( !type ) {
+    if( buildInline() ) {
+      throw SemanticError( "invalid inline specification in declaration of ", this );
+    } else {
+      return new ObjectDecl( name, buildStorageClass(), linkage, maybeBuild< Expression >( bitfieldWidth ), 0, maybeBuild< Initializer >( initializer ) );
+    }
+  } else {
+    Declaration *newDecl = type->buildDecl( name, buildStorageClass(), maybeBuild< Expression >( bitfieldWidth ), buildInline(), linkage, maybeBuild< Initializer >(initializer) );
+    return newDecl;
+  }
+  // we should never get here
+  assert( false );
+  return 0;
+}
+
+Type *
+DeclarationNode::buildType() const
+{
+
+  assert( type );
+  
+  switch( type->kind ) {
+  case TypeData::Enum:
+    return new EnumInstType( type->buildQualifiers(), type->enumeration->name );
+    
+  case TypeData::Aggregate: {
+    ReferenceToType *ret;
+    switch( type->aggregate->kind ) {
+    case DeclarationNode::Struct:
+      ret = new StructInstType( type->buildQualifiers(), type->aggregate->name );
+      break;
+
+    case DeclarationNode::Union:
+      ret = new UnionInstType( type->buildQualifiers(), type->aggregate->name );
+      break;
+
+    case DeclarationNode::Context:
+      ret = new ContextInstType( type->buildQualifiers(), type->aggregate->name );
+      break;
+
+    default:
+      assert( false );
+    }
+    buildList( type->aggregate->actuals, ret->get_parameters() );
+    return ret;
+  }
+  
+  case TypeData::Symbolic: {
+    TypeInstType *ret = new TypeInstType( type->buildQualifiers(), type->symbolic->name, false );
+    buildList( type->symbolic->actuals, ret->get_parameters() );
+    return ret;
+  }
+  
+  default:
+    return type->build();
+  }
+}
+
+Declaration::StorageClass 
+DeclarationNode::buildStorageClass() const
+{
+  static const Declaration::StorageClass scMap[] = {  
+    Declaration::Static,
+    Declaration::Auto,
+    Declaration::Extern,
+    Declaration::Register,
+    Declaration::NoStorageClass, // inline
+    Declaration::Fortran
+  };  
+  
+  Declaration::StorageClass ret = Declaration::NoStorageClass;
+  for( std::list< StorageClass >::const_iterator i = storageClasses.begin(); i != storageClasses.end(); ++i ) {
+    assert( unsigned( *i ) < sizeof( scMap ) / sizeof( scMap[0] ) );
+    if( *i == Inline ) continue;
+    if( ret == Declaration::NoStorageClass ) {
+      ret = scMap[ *i ];
+    } else {
+      throw SemanticError( "invalid combination of storage classes in declaration of ", this );
+    }
+  }
+  return ret;
+}
+
+bool 
+DeclarationNode::buildInline() const
+{
+  std::list< StorageClass >::const_iterator first = std::find( storageClasses.begin(), storageClasses.end(), Inline );
+  if( first == storageClasses.end() ) {
+    return false;
+  } else {
+    std::list< StorageClass >::const_iterator next = std::find( ++first, storageClasses.end(), Inline );
+    if( next == storageClasses.end() ) {
+      return true;
+    } else {
+      throw SemanticError( "duplicate inline specification in declaration of ", this );
+    }
+  }
+  // we should never get here
+  return false;
+}
Index: translator/Parser/ExpressionNode.cc
===================================================================
--- translator/Parser/ExpressionNode.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser/ExpressionNode.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,804 @@
+/* -*- C++ -*- */
+#include <cassert>
+#include <cctype>
+#include <algorithm>
+
+#include "ParseNode.h"
+#include "SynTree/Type.h"
+#include "SynTree/Constant.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Declaration.h"
+#include "UnimplementedError.h"
+#include "parseutility.h"
+#include "utility.h"
+
+using namespace std;
+
+ExpressionNode::ExpressionNode() : ParseNode(), argName( 0 ) {
+}
+
+ExpressionNode::ExpressionNode(string *name_) : ParseNode( *name_ ), argName( 0 ) {
+  delete name_;
+}
+
+ExpressionNode::ExpressionNode( const ExpressionNode &other )
+  : ParseNode( other.name )
+{
+  if( other.argName ) {
+    argName = other.argName->clone();
+  } else {
+    argName = 0;
+  }
+}
+
+ExpressionNode * ExpressionNode::set_asArgName( std::string *aName ) {
+  argName = new VarRefNode(aName);
+  return this;
+}
+
+ExpressionNode * ExpressionNode::set_asArgName( ExpressionNode *aDesignator ) {
+  argName = aDesignator;
+  return this;
+}
+
+void ExpressionNode::printDesignation( std::ostream &os, int indent ) const {
+  if( argName ) {
+    os << string(' ', indent) << "(designated by:  ";
+    argName->printOneLine(os, indent );
+    os << ")" << std::endl;
+  }
+}
+
+NullExprNode::NullExprNode()
+{
+}
+
+NullExprNode *
+NullExprNode::clone() const
+{
+  return new NullExprNode();
+}
+
+void
+NullExprNode::print(std::ostream & os, int indent) const
+{
+  printDesignation(os);
+  os << "null expression";
+}
+
+void
+NullExprNode::printOneLine(std::ostream & os, int indent) const
+{
+  printDesignation(os);
+  os << "null";
+}
+
+Expression *
+NullExprNode::build() const
+{
+  return 0;
+}
+
+CommaExprNode *ExpressionNode::add_to_list(ExpressionNode *exp){
+  return new CommaExprNode(this, exp );
+}
+
+//  enum ConstantNode::Type =  { Integer, Float, Character, String, Range }
+
+ConstantNode::ConstantNode(void) :
+  ExpressionNode(), sign(true), longs(0), size(0)
+{}
+
+ConstantNode::ConstantNode(string *name_) :
+  ExpressionNode(name_), sign(true), longs(0), size(0)
+{}
+
+ConstantNode::ConstantNode(Type t, string *inVal) :
+  type(t), sign(true), longs(0), size(0)
+{
+  if( inVal ) {
+    value = *inVal;
+    delete inVal;
+  } else {
+    value = "";
+  }
+
+  classify(value);
+}
+
+ConstantNode::ConstantNode( const ConstantNode &other )
+  : ExpressionNode( other ), type( other.type ), value( other.value ), sign( other.sign ), base( other.base ), longs( other.longs ), size( other.size )
+{
+}
+
+// for some reason, std::tolower doesn't work as an argument to std::transform in g++ 3.1
+inline char
+tolower_hack( char c )
+{
+  return std::tolower( c );
+}
+
+void ConstantNode::classify(std::string &str){
+  switch(type){
+    case Integer:
+    case Float:
+      {
+	std::string sfx("");
+	char c;
+	int i = str.length() - 1;
+
+	while( i >= 0 && !isxdigit(c = str.at(i--)) )
+	  sfx += c;
+
+	value = str.substr( 0, i + 2 );
+
+	// get rid of underscores
+	value.erase(remove(value.begin(), value.end(), '_'), value.end());
+
+	std::transform(sfx.begin(), sfx.end(), sfx.begin(), tolower_hack);
+
+	if( sfx.find("ll") != string::npos ){
+	  longs = 2;
+	} else if (sfx.find("l") != string::npos ){
+	  longs = 1;
+	}
+
+	assert((longs >= 0) && (longs <= 2));
+
+	if( sfx.find("u") != string::npos )
+	  sign = false;
+
+	break;
+      }
+    case Character:
+      {
+	// remove underscores from hex and oct escapes
+	if(str.substr(1,2) == "\\x")
+	  value.erase(remove(value.begin(), value.end(), '_'), value.end());
+
+	break;
+      }
+  default:
+    // shouldn't be here
+    ;
+  }
+}
+
+ConstantNode::Type ConstantNode::get_type(void) const {
+  return type;
+}
+
+ConstantNode*
+ConstantNode::append( std::string *newValue )
+{
+  if( newValue ) {
+    if (type == String){
+      std::string temp = *newValue;
+      value.resize( value.size() - 1 );
+      value += newValue->substr(1, newValue->size());
+    } else
+      value += *newValue;
+
+    delete newValue;
+  }
+  return this;
+}
+
+void ConstantNode::printOneLine(std::ostream &os, int indent ) const
+{
+  os << string(indent, ' ');
+  printDesignation(os);
+
+  switch( type ) {
+    /* integers */
+  case Integer:
+      os << value ;
+      break;
+  case Float:
+    os << value ;
+    break;
+
+  case Character:
+    os << "'" << value << "'";
+    break;
+
+  case String:
+    os << '"' << value << '"';
+    break;
+  }
+
+  os << ' ';
+}
+
+void ConstantNode::print(std::ostream &os, int indent ) const
+{
+  printOneLine( os, indent );
+  os << endl;
+}
+
+Expression *ConstantNode::build() const {
+  ::Type::Qualifiers q;
+  BasicType *bt;
+
+  switch(get_type()){
+  case Integer:
+    /* Cfr. standard 6.4.4.1 */
+    //bt.set_kind(BasicType::SignedInt);
+    bt = new BasicType(q, BasicType::SignedInt);
+    break;
+
+  case Float:
+    bt = new BasicType(q, BasicType::Float);
+    break;
+
+  case Character:
+    bt = new BasicType(q, BasicType::Char);
+    break;
+
+  case String:
+    // string should probably be a primitive type
+    ArrayType *at;
+    std::string value = get_value();
+    at = new ArrayType(q, new BasicType(q, BasicType::Char),
+				new ConstantExpr( Constant( new BasicType(q, BasicType::SignedInt),
+									      toString( value.size() - 1 ) ) ),  // account for '\0'
+				false, false );
+
+    return new ConstantExpr( Constant(at, value), maybeBuild< Expression >( get_argName() ) );
+  }
+
+  return new ConstantExpr(  Constant(bt, get_value()),  maybeBuild< Expression >( get_argName() ) );
+}
+
+
+VarRefNode::VarRefNode() : isLabel(false) {}
+
+VarRefNode::VarRefNode(string *name_, bool labelp) :
+  ExpressionNode(name_), isLabel(labelp) {}
+
+VarRefNode::VarRefNode( const VarRefNode &other )
+  : ExpressionNode( other ), isLabel( other.isLabel )
+{
+}
+
+Expression *VarRefNode::build() const {
+  return new NameExpr( get_name(), maybeBuild< Expression >( get_argName() ) );
+}
+
+void VarRefNode::printOneLine(std::ostream &os, int indent ) const {
+  printDesignation(os);
+  os << get_name() << ' ';
+}
+
+void VarRefNode::print(std::ostream &os, int indent ) const {
+  printDesignation(os);
+  os << '\r' << string(indent, ' ') << "Referencing: ";
+
+  os << "Variable: " << get_name();
+
+  os << endl;
+}
+
+
+OperatorNode::OperatorNode(Type t):type(t) {}
+
+OperatorNode::OperatorNode( const OperatorNode &other )
+  : ExpressionNode( other ), type( other.type )
+{
+}
+
+OperatorNode::~OperatorNode() {}
+
+OperatorNode::Type OperatorNode::get_type(void) const{
+  return type;
+}
+
+void OperatorNode::printOneLine( std::ostream &os, int indent ) const
+{
+  printDesignation(os);
+  os << OpName[ type ] << ' ';
+}
+
+void OperatorNode::print( std::ostream &os, int indent ) const{
+  printDesignation(os);
+  os << '\r' << string(indent, ' ') << "Operator: " << OpName[type] << endl;
+
+  return;
+}
+
+std::string OperatorNode::get_typename(void) const{
+  return string(OpName[ type ]);
+}
+
+const char *OperatorNode::OpName[] =
+  { "TupleC",  "Comma", "TupleFieldSel",// "TuplePFieldSel", //n-adic
+    // triadic
+    "Cond",   "NCond",
+    // diadic
+    "SizeOf",      "AlignOf", "Attr", "CompLit", "Plus",    "Minus",   "Mul",     "Div",     "Mod",      "Or",
+      "And",       "BitOr",   "BitAnd",  "Xor",     "Cast",    "LShift",  "RShift",  "LThan",   "GThan",
+      "LEThan",    "GEThan", "Eq",      "Neq",     "Assign",  "MulAssn", "DivAssn", "ModAssn", "PlusAssn",
+      "MinusAssn", "LSAssn", "RSAssn",  "AndAssn", "ERAssn",  "OrAssn",  "Index",   "FieldSel","PFieldSel",
+      "Range",
+    // monadic
+    "UnPlus", "UnMinus", "AddressOf", "PointTo", "Neg", "BitNeg", "Incr", "IncrPost", "Decr", "DecrPost", "LabelAddress"
+  };
+
+CompositeExprNode::CompositeExprNode(void) : ExpressionNode(), function( 0 ), arguments( 0 ) {
+}
+
+CompositeExprNode::CompositeExprNode(string *name_) : ExpressionNode(name_), function( 0 ), arguments( 0 )
+{
+}
+
+CompositeExprNode::CompositeExprNode(ExpressionNode *f, ExpressionNode *args):
+  function(f), arguments(args) {
+}
+
+CompositeExprNode::CompositeExprNode(ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2):
+  function(f), arguments(arg1) {
+  arguments->set_link(arg2);
+}
+
+CompositeExprNode::CompositeExprNode( const CompositeExprNode &other )
+  : ExpressionNode( other ), function( maybeClone( other.function ) )
+{
+  ParseNode *cur = other.arguments;
+  while( cur ) {
+    if( arguments ) {
+      arguments->set_link( cur->clone() );
+    } else {
+      arguments = (ExpressionNode*)cur->clone();
+    }
+    cur = cur->get_link();
+  }
+}
+
+CompositeExprNode::~CompositeExprNode()
+{
+  delete function;
+  delete arguments;
+}
+
+// the names that users use to define operator functions
+static const char *opFuncName[] =
+  { "",  "", "",
+    "",   "",
+    // diadic
+    "",   "", "", "", "?+?",    "?-?",   "?*?",     "?/?",     "?%?",     "",       "",
+      "?|?",  "?&?",  "?^?",     "",    "?<<?",  "?>>?",  "?<?",   "?>?",    "?<=?",
+      "?>=?", "?==?",      "?!=?",     "?=?",  "?*=?", "?/=?", "?%=?", "?+=?", "?-=?",
+      "?<<=?", "?>>=?",  "?&=?", "?^=?",  "?|=?",  "?[?]",   "","","Range",
+    // monadic
+    "+?", "-?", "", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "LabAddress"
+  };
+
+#include "utility.h"
+Expression *CompositeExprNode::build() const {
+  OperatorNode *op;
+  std::list<Expression *> args;
+
+  buildList(get_args(), args);
+
+  if (!( op = dynamic_cast<OperatorNode *>(function)) ){
+    // a function as opposed to an operator
+    return new UntypedExpr(function->build(), args, maybeBuild< Expression >( get_argName() ));
+
+  } else {
+
+    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:
+      // 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(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:
+    case OperatorNode::PointTo:
+    case OperatorNode::Neg:
+    case OperatorNode::BitNeg:
+    case OperatorNode::LabelAddress:
+      return new UntypedExpr( new NameExpr( opFuncName[ 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( expr_node->build(), maybeBuild< Expression >( get_argName() ) );
+        } else {
+          return new CastExpr(expr_node->build(),targetType, maybeBuild< Expression >( get_argName() ) );
+        }
+      }
+
+    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::AlignOf:
+    case OperatorNode::SizeOf:
+      {
+/// 	bool isSizeOf = (op->get_type() == OperatorNode::SizeOf);
+
+	if( TypeValueNode * arg = dynamic_cast<TypeValueNode *>(get_args()) ) {
+          return new SizeofExpr(arg->get_decl()->buildType());
+        } else {
+	  return new SizeofExpr(args.front());
+        }
+      }
+    
+    case OperatorNode::Attr:
+      {
+        VarRefNode *var = dynamic_cast<VarRefNode *>(get_args());
+        assert( var );
+        if( !get_args()->get_link() ) {
+          return new AttrExpr(var->build(), (Expression*)0);
+	} else if( TypeValueNode * arg = dynamic_cast<TypeValueNode *>(get_args()->get_link()) ) {
+          return new AttrExpr(var->build(), arg->get_decl()->buildType());
+        } else {
+	  return new AttrExpr(var->build(), args.back());
+        }
+      }
+    
+
+    case OperatorNode::CompLit:
+      throw UnimplementedError( "C99 compound literals" );
+
+      // the short-circuited operators
+    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:
+      {
+        assert(args.size() == 3);
+        std::list< Expression* >::const_iterator i = args.begin();
+        Expression *arg1 = notZeroExpr( *i++ );
+        Expression *arg2 = *i++;
+        Expression *arg3 = *i++;
+        return new ConditionalExpr( arg1, arg2, arg3 );
+      }
+
+    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:
+      {
+        TupleExpr *ret = new TupleExpr();
+        std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) );
+        return ret;
+      }
+
+    default:
+      // shouldn't happen
+      return 0;
+    }
+  }
+}
+
+void CompositeExprNode::printOneLine(std::ostream &os, int indent) const
+{
+  printDesignation(os);
+  os << "( ";
+  function->printOneLine( os, indent );
+  for( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
+    cur->printOneLine( os, indent );
+  }
+  os << ") ";
+}
+
+void CompositeExprNode::print(std::ostream &os, int indent) const
+{
+  printDesignation(os);
+  os << '\r' << string(indent, ' ') << "Application of: " << endl;
+  function->print( os, indent + ParseNode::indent_by );
+
+  os << '\r' << string(indent, ' ') ;
+  if( arguments ) {
+    os << "... on arguments: " << endl;
+    arguments->printList(os, indent + ParseNode::indent_by);
+  } else
+    os << "... on no arguments: " << endl;
+}
+
+void CompositeExprNode::set_function(ExpressionNode *f){
+  function = f;
+}
+
+void CompositeExprNode::set_args(ExpressionNode *args){
+  arguments = args;
+}
+
+ExpressionNode *CompositeExprNode::get_function(void) const {
+  return function;
+}
+
+ExpressionNode *CompositeExprNode::get_args(void) const {
+  return arguments;
+}
+
+void CompositeExprNode::add_arg(ExpressionNode *arg){
+  if(arguments)
+    arguments->set_link(arg);
+  else
+    set_args(arg);
+}
+
+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 )
+{
+}
+
+ValofExprNode::ValofExprNode(StatementNode *s): body(s) {}
+
+ValofExprNode::ValofExprNode( const ValofExprNode &other )
+  : ExpressionNode( other ), body( maybeClone( body ) )
+{
+}
+
+ValofExprNode::~ValofExprNode() {
+  delete body;
+}
+
+void ValofExprNode::print( std::ostream &os, int indent ) const {
+  printDesignation(os);
+  os << string(indent, ' ') << "Valof Expression:" << std::endl;
+  get_body()->print(os, indent + 4);
+}
+
+void ValofExprNode::printOneLine( std::ostream &, int indent ) const
+{
+  assert( false );
+}
+
+Expression *ValofExprNode::build() const {
+  return new UntypedValofExpr ( get_body()->build(), maybeBuild< Expression >( get_argName() ) );
+}
+
+ForCtlExprNode::ForCtlExprNode(ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr)
+  throw (SemanticError)
+  : condition(cond), change(incr)
+{
+  if(init_ == 0)
+    init = 0;
+  else {
+    DeclarationNode *decl;
+    ExpressionNode *exp;
+
+    if((decl = dynamic_cast<DeclarationNode *>(init_)) != 0)
+      init = new StatementNode(decl);
+    else if((exp = dynamic_cast<ExpressionNode *>(init_)) != 0)
+      init = new StatementNode(StatementNode::Exp, exp);
+    else
+      throw SemanticError("Error in for control expression");
+  }
+}
+
+ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
+  : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) )
+{
+}
+
+ForCtlExprNode::~ForCtlExprNode(){
+  delete init;
+  delete condition;
+  delete change;
+}
+
+Expression *ForCtlExprNode::build() const {
+  // this shouldn't be used!
+  assert( false );
+  return 0;
+}
+
+void ForCtlExprNode::print( std::ostream &os, int indent ) const{
+  os << string(indent,' ') << "For Control Expression -- : " << endl;
+
+  os << "\r" << string(indent + 2,' ') << "initialization: ";
+  if(init != 0)
+    init->print(os, indent + 4);
+
+  os << "\n\r" << string(indent + 2,' ') << "condition: ";
+  if(condition != 0)
+    condition->print(os, indent + 4);
+  os << "\n\r" << string(indent + 2,' ') << "increment: ";
+  if(change != 0)
+    change->print(os, indent + 4);
+}
+
+void
+ForCtlExprNode::printOneLine( std::ostream &, int indent ) const
+{
+  assert( false );
+}
+
+TypeValueNode::TypeValueNode(DeclarationNode *decl)
+  : decl( decl )
+{
+}
+
+TypeValueNode::TypeValueNode( const TypeValueNode &other )
+  : ExpressionNode( other ), decl( maybeClone( other.decl ) )
+{
+}
+
+Expression *
+TypeValueNode::build() const
+{
+  return new TypeExpr( decl->buildType() );
+}
+
+void
+TypeValueNode::print(std::ostream &os, int indent) const
+{
+  os << std::string( indent, ' ' ) << "Type:";
+  get_decl()->print(os, indent + 2);
+}
+
+void
+TypeValueNode::printOneLine(std::ostream &os, int indent) const
+{
+  os << "Type:";
+  get_decl()->print(os, indent + 2);
+}
+
+ExpressionNode *flattenCommas( ExpressionNode *list )
+{
+  if( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) )
+    {
+      OperatorNode *op;
+           if ( (op = dynamic_cast< OperatorNode * >( composite->get_function() )) && (op->get_type() == OperatorNode::Comma) )
+	     {
+	         if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
+		   composite->add_arg( next );
+		 return flattenCommas( composite->get_args() );
+	     }
+    }
+
+  if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
+    list->set_next( flattenCommas( next ) );
+
+  return list;
+}
+
+ExpressionNode *tupleContents( ExpressionNode *tuple )
+{
+  if( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( tuple ) ) {
+    OperatorNode *op = 0;
+    if ( (op = dynamic_cast< OperatorNode * >( composite->get_function() )) && (op->get_type() == OperatorNode::TupleC) )
+      return composite->get_args();
+  }
+  return tuple;
+}
Index: translator/Parser/InitializerNode.cc
===================================================================
--- translator/Parser/InitializerNode.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser/InitializerNode.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,103 @@
+#include "ParseNode.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Initializer.h"
+#include "utility.h"
+#include "SemanticError.h"
+// #include <cstdlib> // for strtol
+#include <cassert>
+
+
+InitializerNode::InitializerNode( ExpressionNode *_expr, bool aggrp, ExpressionNode *des )
+  : expr( _expr ), aggregate( aggrp ), designator( des ), kids( 0 )
+{
+  if ( aggrp )
+    kids = dynamic_cast< InitializerNode *>( get_link() );
+
+  if ( kids != 0 )
+    set_link( 0 );
+}
+
+InitializerNode::InitializerNode( InitializerNode *init, bool aggrp, ExpressionNode *des )
+  : aggregate( aggrp ), designator( des ), kids( 0 )
+{
+  if (init != 0)
+    set_link(init);
+
+  if ( aggrp )
+      kids = dynamic_cast< InitializerNode *>( get_link() );
+
+  if ( kids != 0 )
+    set_next( 0 );
+}
+
+InitializerNode::~InitializerNode() {
+  delete expr;
+}
+
+void InitializerNode::print( std::ostream &os, int indent ) const {
+  os << std::string(indent, ' ') << "Initializer expression" << std::endl;
+}
+
+void InitializerNode::printOneLine( std::ostream &os ) const {
+  if (!aggregate)
+    {
+
+      if ( designator != 0 )
+	{
+	  os << "designated by: (";
+	  ExpressionNode  *curdes = designator;
+	  while( curdes != 0){
+	    curdes->printOneLine(os);
+	    curdes = (ExpressionNode *)(curdes->get_link());
+	    if(curdes) os << ", ";
+	  }
+	  os << ")";
+	}
+
+      if (expr) expr->printOneLine(os);
+    }
+  else  // It's an aggregate
+    {
+      os << "[--";
+      if( next_init() != 0 )
+	next_init()->printOneLine(os);
+
+      if (aggregate) os << "--]";
+    }
+
+  InitializerNode * moreInit;
+  if  ( get_link() != 0 && ((moreInit = dynamic_cast< InitializerNode * >( get_link() ) ) != 0) )
+    moreInit->printOneLine( os );
+}
+
+Initializer *InitializerNode::build() const {
+  // if ( get_expression() == 0 ) return 0;  // XXX (?)
+
+  if ( aggregate )
+    {
+      assert( next_init() != 0 );
+
+      std::list< Initializer *> initlist;
+      buildList<Initializer, InitializerNode>( next_init(), initlist );
+
+      std::list< Expression *> designlist;
+      if ( designator != 0 )
+	buildList<Expression, ExpressionNode>( designator, designlist );
+
+      return new ListInit( initlist, designlist );
+    }
+  else
+    {
+      std::list< Expression *> designators;
+
+      if ( designator != 0 )
+	buildList<Expression, ExpressionNode>( designator, designators );
+
+      if ( get_expression() != 0)
+	return new SingleInit( get_expression()->build(), designators );
+    }
+
+  return 0;
+}
+
+
Index: translator/Parser/LinkageSpec.cc
===================================================================
--- translator/Parser/LinkageSpec.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser/LinkageSpec.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,111 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: LinkageSpec.cc,v 1.3 2003/01/29 14:55:08 rcbilson Exp $
+ *
+ */
+
+#include <string>
+#include <cassert>
+
+#include "LinkageSpec.h"
+#include "SemanticError.h"
+
+/* static class method */
+LinkageSpec::Type 
+LinkageSpec::fromString( const std::string &stringSpec )
+{
+  if( stringSpec == "\"Cforall\"" ) {
+    return Cforall;
+  } else if( stringSpec == "\"C\"" ) {
+    return C;
+  } else {
+    throw SemanticError( "Invalid linkage specifier " + stringSpec );
+  }
+}
+
+/* static class method */
+std::string 
+LinkageSpec::toString( LinkageSpec::Type linkage )
+{
+  switch( linkage ) {
+  case Intrinsic:
+    return "intrinsic";
+    
+  case Cforall:
+    return "Cforall";
+    
+  case C:
+    return "C";
+    
+  case AutoGen:
+    return "automatically generated";
+    
+  case Compiler:
+    return "compiler built-in";
+  }
+  assert( false );
+  return "";
+}
+
+/* static class method */
+bool 
+LinkageSpec::isDecoratable( Type t )
+{
+  switch( t ) {
+  case Intrinsic:
+  case Cforall:
+  case AutoGen:
+    return true;
+    
+  case C:
+  case Compiler:
+    return false;
+  }
+  assert( false );
+  return false;
+}
+
+/* static class method */
+bool 
+LinkageSpec::isGeneratable( Type t )
+{
+  switch( t ) {
+  case Intrinsic:
+  case Cforall:
+  case AutoGen:
+  case C:
+    return true;
+    
+  case Compiler:
+    return false;
+  }
+  assert( false );
+  return false;
+}
+
+/* static class method */
+bool 
+LinkageSpec::isOverloadable( Type t )
+{
+  return isDecoratable( t );
+}
+
+/* static class method */
+bool 
+LinkageSpec::isBuiltin( Type t )
+{
+  switch( t ) {
+  case Cforall:
+  case AutoGen:
+  case C:
+    return false;
+    
+  case Intrinsic:
+  case Compiler:
+    return true;
+  }
+  assert( false );
+  return false;
+}
+
Index: translator/Parser/LinkageSpec.h
===================================================================
--- translator/Parser/LinkageSpec.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser/LinkageSpec.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,33 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: LinkageSpec.h,v 1.3 2003/01/29 14:55:08 rcbilson Exp $
+ *
+ */
+
+#ifndef LINKAGESPEC_H
+#define LINKAGESPEC_H
+
+#include <string>
+
+struct LinkageSpec
+{
+  enum Type
+  {
+    Intrinsic,		// C built-in defined in prelude
+    Cforall,		// ordinary
+    C,			// not overloadable, not mangled
+    AutoGen,		// built by translator (struct assignment)
+    Compiler		// gcc internal
+  };
+  
+  static Type fromString( const std::string& );
+  static std::string toString( Type );
+  
+  static bool isDecoratable( Type );
+  static bool isGeneratable( Type );
+  static bool isOverloadable( Type );
+  static bool isBuiltin( Type );
+};
+
+#endif /* #ifndef LINKAGESPEC_H */
Index: translator/Parser/ParseNode.cc
===================================================================
--- translator/Parser/ParseNode.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser/ParseNode.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,94 @@
+/* -*- C++ -*- */
+#include "ParseNode.h"
+using namespace std;
+
+// Builder
+int ParseNode::indent_by = 4;
+
+ParseNode::ParseNode(void): next( 0 ) {};
+ParseNode::ParseNode (string _name) : name(_name), next( 0 ) {}
+
+ParseNode *ParseNode::set_name (string _name) {
+  name = _name;
+
+  return this;
+}
+
+ParseNode *ParseNode::set_name (string *_name) {
+  name = *_name; // deep copy
+  delete _name;
+
+  return this;
+}
+
+ParseNode::~ParseNode(void){
+  delete next;
+};
+
+string ParseNode::get_name(void) {
+  return name;
+}
+
+ParseNode *ParseNode::get_link(void) const {
+  return next;
+}
+
+ParseNode *ParseNode::get_last(void) {
+  ParseNode * current = this;
+
+  while(current->get_link() != 0)
+    current = current->get_link();
+
+  return current;
+}
+
+ParseNode *ParseNode::set_link(ParseNode *_next){
+  ParseNode *follow;
+
+  if(_next == 0) return this;
+
+  for(follow = this; follow->next != 0; follow = follow->next);
+  follow->next = _next;
+
+  return this;
+}
+
+const string ParseNode::get_name(void) const {
+  return name;
+}
+
+void ParseNode::print(std::ostream &os, int indent) const
+{
+}
+
+
+void ParseNode::printList(std::ostream &os, int indent) const
+{
+  print( os, indent );
+
+  if( next ) {
+    next->printList( os, indent );
+  }
+}
+
+ParseNode &ParseNode::operator,(ParseNode &p){
+  set_link(&p);
+
+  return *this;
+}
+
+ParseNode *mkList(ParseNode &pn){
+  /* it just relies on `operator,' to take care of the "arguments" and provides
+     a nice interface to an awful-looking address-of, rendering, for example
+         (StatementNode *)(&(*$5 + *$7)) into (StatementNode *)mkList(($5, $7))
+     (although "nice"  is probably not the word)
+  */
+
+  return &pn;
+}
+
+
+// Local Variables: //
+// mode: C++                //
+// compile-command: "gmake" //
+// End: //
Index: translator/Parser/ParseNode.h
===================================================================
--- translator/Parser/ParseNode.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser/ParseNode.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,516 @@
+#ifndef PARSENODE_H
+#define PARSENODE_H
+
+#include <iostream>
+#include <string>
+#include <list>
+#include <iterator>
+
+#include "utility.h"
+#include "SynTree/SynTree.h"
+#include "SynTree/Declaration.h"
+#include "SemanticError.h"
+#include "UniqueName.h"
+
+class ExpressionNode;
+class CompositeExprNode;
+class CommaExprNode;
+class StatementNode;
+class CompoundStmtNode;
+class DeclarationNode;
+class InitializerNode;
+
+// Builder
+class ParseNode {
+public:
+  ParseNode(void);
+  ParseNode (std::string);
+  virtual ~ParseNode(void);
+
+  ParseNode *set_name (std::string) ;
+  ParseNode *set_name (std::string *) ;
+
+  std::string get_name(void);
+
+  ParseNode *get_link(void) const;
+  ParseNode *get_last(void);
+  ParseNode *set_link(ParseNode *);
+  void set_next( ParseNode *newlink ) { next = newlink; }
+
+  virtual ParseNode *clone() const { return 0; };
+
+  const std::string get_name(void) const;
+  virtual void print( std::ostream &, int indent = 0 ) const;
+  virtual void printList( std::ostream &, int indent = 0 ) const;
+
+  ParseNode &operator,(ParseNode &);
+
+protected:
+  std::string name;
+  ParseNode *next;
+  static int indent_by;
+};
+
+ParseNode *mkList(ParseNode &);
+
+class ExpressionNode : public ParseNode {
+public:
+  ExpressionNode();
+  ExpressionNode(std::string *);
+  ExpressionNode( const ExpressionNode &other );
+  virtual ~ExpressionNode() { /* can't delete asArgName because it might be referenced elsewhere */ };
+
+  virtual ExpressionNode *clone() const = 0;
+
+  virtual CommaExprNode *add_to_list(ExpressionNode *);
+
+  ExpressionNode *get_argName() const { return argName; }
+  ExpressionNode *set_asArgName( std::string *aName );
+  ExpressionNode *set_asArgName( ExpressionNode *aDesignator );
+
+  virtual void print(std::ostream &, int indent = 0) const = 0;
+  virtual void printOneLine(std::ostream &, int indent = 0) const = 0;
+
+  virtual Expression *build() const = 0;
+protected:
+  void printDesignation (std::ostream &, int indent = 0) const;
+
+private:
+  ExpressionNode *argName;
+};
+
+// NullExprNode is used in tuples as a place-holder where a tuple component is omitted
+// e.g., [ 2, , 3 ]
+class NullExprNode : public ExpressionNode
+{
+public:
+  NullExprNode();
+
+  virtual NullExprNode *clone() const;
+
+  virtual void print(std::ostream &, int indent = 0) const;
+  virtual void printOneLine(std::ostream &, int indent = 0) const;
+
+  virtual Expression *build() const;
+};
+
+class ConstantNode : public ExpressionNode {
+public:
+  enum Type {
+    Integer, Float, Character, String /* , Range, EnumConstant  */
+  };
+
+  ConstantNode(void);
+  ConstantNode(std::string *);
+  ConstantNode(Type, std::string *);
+  ConstantNode( const ConstantNode &other );
+
+  virtual ConstantNode *clone() const { return new ConstantNode( *this ); }
+
+  Type get_type(void) const ;
+  virtual void print(std::ostream &, int indent = 0) const;
+  virtual void printOneLine(std::ostream &, int indent = 0) const;
+
+  std::string get_value() const { return value; }
+  ConstantNode *append( std::string *newValue );
+
+  Expression *build() const;
+
+private:
+  void classify(std::string &);
+  Type type;
+  std::string value;
+  bool sign;
+  short base;
+  int longs, size;
+};
+
+class VarRefNode : public ExpressionNode {
+public:
+  VarRefNode();
+  VarRefNode(std::string *, bool isLabel = false );
+  VarRefNode( const VarRefNode &other );
+
+  virtual Expression *build() const ;
+
+  virtual VarRefNode *clone() const { return new VarRefNode( *this ); }
+
+  virtual void print(std::ostream &, int indent = 0) const;
+  virtual void printOneLine(std::ostream &, int indent = 0) const;
+private:
+  bool isLabel;
+};
+
+class TypeValueNode : public ExpressionNode
+{
+public:
+  TypeValueNode(DeclarationNode *);
+  TypeValueNode( const TypeValueNode &other );
+
+  DeclarationNode *get_decl() const { return decl; }
+
+  virtual Expression *build() const ;
+
+  virtual TypeValueNode *clone() const { return new TypeValueNode( *this ); }
+
+  virtual void print(std::ostream &, int indent = 0) const;
+  virtual void printOneLine(std::ostream &, int indent = 0) const;
+private:
+  DeclarationNode *decl;
+};
+
+class OperatorNode : public ExpressionNode {
+public:
+  enum Type { TupleC, Comma, TupleFieldSel,
+              Cond, NCond, 
+	      SizeOf, AlignOf, Attr, CompLit, Plus, Minus, Mul, Div, Mod, Or, And, 
+	        BitOr, BitAnd, Xor, Cast, LShift, RShift, LThan, GThan, LEThan, GEThan, Eq, Neq, 
+	        Assign, MulAssn, DivAssn, ModAssn, PlusAssn, MinusAssn, LSAssn, RSAssn, AndAssn, 
+	        ERAssn, OrAssn, Index, FieldSel, PFieldSel, Range,
+              UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, LabelAddress
+            };
+
+  OperatorNode(Type t);
+  OperatorNode( const OperatorNode &other );
+  virtual ~OperatorNode();
+
+  virtual OperatorNode *clone() const { return new OperatorNode( *this ); }
+
+  Type get_type(void) const;
+  std::string get_typename(void) const;
+
+  virtual void print(std::ostream &, int indent = 0) const;
+  virtual void printOneLine(std::ostream &, int indent = 0) const;
+
+  virtual Expression *build() const { return 0; }
+  
+private:
+  Type type;
+  static const char *OpName[];
+};
+
+
+class CompositeExprNode : public ExpressionNode {
+public:
+  CompositeExprNode(void);
+  CompositeExprNode(std::string *);
+  CompositeExprNode(ExpressionNode *f, ExpressionNode *args = 0);
+  CompositeExprNode(ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2);
+  CompositeExprNode( const CompositeExprNode &other );
+  virtual ~CompositeExprNode();
+
+  virtual CompositeExprNode *clone() const { return new CompositeExprNode( *this ); }
+  virtual Expression *build() const;
+
+  virtual void print(std::ostream &, int indent = 0) const;
+  virtual void printOneLine(std::ostream &, int indent = 0) const;
+
+  void set_function(ExpressionNode *);
+  void set_args(ExpressionNode *);
+
+  void add_arg(ExpressionNode *);
+
+  ExpressionNode *get_function() const;
+  ExpressionNode *get_args() const;
+
+private:
+  ExpressionNode *function;
+  ExpressionNode *arguments;
+};
+
+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 ); }
+};
+
+class ForCtlExprNode : public ExpressionNode {
+public:
+  ForCtlExprNode(ParseNode *, ExpressionNode *, ExpressionNode *) throw (SemanticError);
+  ForCtlExprNode( const ForCtlExprNode &other );
+  ~ForCtlExprNode();
+
+  StatementNode *get_init() const { return init; }
+  ExpressionNode *get_condition() const { return condition; }
+  ExpressionNode *get_change() const { return change; }
+
+  virtual ForCtlExprNode *clone() const { return new ForCtlExprNode( *this ); }
+  virtual Expression *build() const;
+
+  virtual void print( std::ostream &, int indent = 0 ) const;
+  virtual void printOneLine( std::ostream &, int indent = 0 ) const;
+private:
+  StatementNode *init;
+  ExpressionNode *condition;
+  ExpressionNode *change;
+};
+
+class ValofExprNode : public ExpressionNode {
+public:
+  ValofExprNode();
+  ValofExprNode( StatementNode *s = 0 );
+  ValofExprNode( const ValofExprNode &other );
+  ~ValofExprNode();
+  
+  virtual ValofExprNode *clone() const { return new ValofExprNode( *this ); }
+
+  StatementNode *get_body() const { return body; }
+  void print( std::ostream &, int indent = 0 ) const;
+  void printOneLine( std::ostream &, int indent = 0 ) const;
+  Expression *build() const;
+
+private:
+  StatementNode *body;
+};
+
+class TypeData;
+
+class DeclarationNode : public ParseNode
+{
+public:
+  enum Qualifier { Const, Restrict, Volatile, Lvalue };
+  enum StorageClass { Static, Auto, Extern, Register, Inline, Fortran };
+  enum BasicType { Char, Int, Float, Double, Void, Bool, Complex, Imaginary };
+  enum Modifier { Signed, Unsigned, Short, Long };
+  enum TyCon { Struct, Union, Context };
+  enum TypeClass { Type, Dtype, Ftype };
+
+  static const char *qualifierName[];
+  static const char *basicTypeName[];
+  static const char *modifierName[];
+  static const char *tyConName[];
+  static const char *typeClassName[];
+
+  static DeclarationNode *newFunction( std::string* name, DeclarationNode *ret, DeclarationNode *param,
+				       StatementNode *body, bool newStyle = false );
+  static DeclarationNode *newQualifier( Qualifier );
+  static DeclarationNode *newStorageClass( StorageClass );
+  static DeclarationNode *newBasicType( BasicType );
+  static DeclarationNode *newModifier( Modifier );
+  static DeclarationNode *newForall( DeclarationNode* );
+  static DeclarationNode *newFromTypedef( std::string* );
+  static DeclarationNode *newAggregate( TyCon kind, std::string* name, DeclarationNode *formals, ExpressionNode *actuals, DeclarationNode *fields );
+  static DeclarationNode *newEnum( std::string *name, DeclarationNode *constants );
+  static DeclarationNode *newEnumConstant( std::string* name, ExpressionNode *constant );
+  static DeclarationNode *newName( std::string* );
+  static DeclarationNode *newFromTypeGen( std::string*, ExpressionNode *params );
+  static DeclarationNode *newTypeParam( TypeClass, std::string* );
+  static DeclarationNode *newContext( std::string *name, DeclarationNode *params, DeclarationNode *asserts );
+  static DeclarationNode *newContextUse( std::string *name, ExpressionNode *params );
+  static DeclarationNode *newTypeDecl( std::string *name, DeclarationNode *typeParams );
+  static DeclarationNode *newPointer( DeclarationNode *qualifiers );
+  static DeclarationNode *newArray( ExpressionNode *size, DeclarationNode *qualifiers, bool isStatic );
+  static DeclarationNode *newVarArray( DeclarationNode *qualifiers );
+  static DeclarationNode *newBitfield( ExpressionNode *size );
+  static DeclarationNode *newTuple( DeclarationNode *members );
+  static DeclarationNode *newTypeof( ExpressionNode *expr );
+  static DeclarationNode *newAttr( std::string*, ExpressionNode *expr );
+  static DeclarationNode *newAttr( std::string*, DeclarationNode *type );
+
+  DeclarationNode *addQualifiers( DeclarationNode* );
+  DeclarationNode *copyStorageClasses( DeclarationNode* );
+  DeclarationNode *addType( DeclarationNode* );
+  DeclarationNode *addTypedef();
+  DeclarationNode *addAssertions( DeclarationNode* );
+  DeclarationNode *addName( std::string* );
+  DeclarationNode *addBitfield( ExpressionNode *size );
+  DeclarationNode *addVarArgs();
+  DeclarationNode *addFunctionBody( StatementNode *body );
+  DeclarationNode *addOldDeclList( DeclarationNode *list );
+  DeclarationNode *addPointer( DeclarationNode *qualifiers );
+  DeclarationNode *addArray( DeclarationNode *array );
+  DeclarationNode *addNewPointer( DeclarationNode *pointer );
+  DeclarationNode *addNewArray( DeclarationNode *array );
+  DeclarationNode *addParamList( DeclarationNode *list );
+  DeclarationNode *addIdList( DeclarationNode *list );       // old-style functions
+  DeclarationNode *addInitializer( InitializerNode *init );
+
+  DeclarationNode *cloneType( std::string *newName );
+  DeclarationNode *cloneType( DeclarationNode *existing );
+  DeclarationNode *cloneType( int ) { return cloneType( (std::string*)0 ); }
+  DeclarationNode *cloneBaseType( std::string *newName );
+  DeclarationNode *cloneBaseType( DeclarationNode *newdecl );
+
+  DeclarationNode *appendList( DeclarationNode * );
+
+  DeclarationNode *clone() const;
+  void print( std::ostream &, int indent = 0 ) const;
+  void printList( std::ostream &, int indent = 0 ) const;
+
+  Declaration *build() const;
+  ::Type *buildType() const;
+
+  bool get_hasEllipsis() const;
+  std::string get_name() const { return name; }
+  LinkageSpec::Type get_linkage() const { return linkage; }
+  DeclarationNode *extractAggregate() const;
+
+  DeclarationNode();
+  ~DeclarationNode();
+private:
+  Declaration::StorageClass buildStorageClass() const;
+  bool buildInline() const;
+
+  TypeData *type;
+  std::string name;
+  std::list< StorageClass > storageClasses;
+  ExpressionNode *bitfieldWidth;
+  InitializerNode *initializer;
+  bool hasEllipsis;
+  LinkageSpec::Type linkage;
+
+  static UniqueName anonymous;
+};
+
+class StatementNode : public ParseNode {
+public:
+  enum Type { Exp,   If,        Switch,  Case,    Default,  Choose,   Fallthru, 
+              While, Do,        For,
+              Goto,  Continue,  Break,   Return,  Throw,
+              Try,   Catch,     Finally, Asm,
+	      Decl
+            };
+
+  StatementNode( void );
+  StatementNode( std::string );
+  StatementNode( Type, ExpressionNode *e = 0, StatementNode *s = 0 );
+  StatementNode( Type, std::string *target );
+  StatementNode( DeclarationNode *decl );
+
+
+  ~StatementNode(void);
+
+  static StatementNode * newCatchStmt(DeclarationNode *d = 0, StatementNode *s = 0, bool catchRestP = false );
+
+  void set_control(ExpressionNode *);
+  StatementNode * set_block(StatementNode *);
+
+  ExpressionNode *get_control() const ;
+  StatementNode *get_block() const;
+  StatementNode::Type get_type(void) const;
+
+  StatementNode *add_label(std::string *);
+  std::list<std::string> *get_labels() const;
+
+  void addDeclaration( DeclarationNode *newDecl ) { decl = newDecl; }
+  void setCatchRest( bool newVal ) { isCatchRest = newVal; }
+
+  std::string get_target() const;
+
+  StatementNode *add_controlexp(ExpressionNode *);
+  StatementNode *append_block(StatementNode *);
+  StatementNode *append_last_case(StatementNode *);
+
+  void print( std::ostream &, int indent = 0) const;
+
+  virtual StatementNode *clone() const;
+
+  virtual Statement *build() const;
+
+private:
+  static const char *StType[];
+  Type type;
+  ExpressionNode *control;
+  StatementNode *block;
+  std::list<std::string> *labels;
+  std::string *target; // target label for jump statements
+  DeclarationNode *decl;
+
+  bool isCatchRest;
+};
+
+class CompoundStmtNode : public StatementNode {
+public:
+  CompoundStmtNode(void);
+  CompoundStmtNode(std::string *);
+  CompoundStmtNode(StatementNode *);
+  ~CompoundStmtNode();
+
+  void add_statement(StatementNode *);
+
+  void print( std::ostream &, int indent = 0 ) const;
+
+  virtual Statement *build() const;
+
+private:
+  StatementNode *first, *last;
+};
+
+class NullStmtNode : public CompoundStmtNode {
+public:
+  Statement *build() const;
+  void print(std::ostream &, int indent = 0) const;
+};
+
+class InitializerNode : public ParseNode {
+public:
+  InitializerNode( ExpressionNode *, bool aggrp = false,  ExpressionNode *des = 0 );
+  InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode *des = 0 );
+  ~InitializerNode();
+
+  ExpressionNode *get_expression() const { return expr; }
+
+  InitializerNode *set_designators( ExpressionNode *des ) { designator = des;  return this; }
+  ExpressionNode *get_designators() const { return designator; }
+
+  InitializerNode *next_init() const { return kids; }
+
+  void print( std::ostream &, int indent = 0 ) const;
+  void printOneLine( std::ostream & ) const;
+
+  virtual Initializer *build() const;
+
+private:
+  ExpressionNode *expr;
+  bool aggregate;
+  ExpressionNode *designator; // may be list
+  InitializerNode *kids;
+};
+
+
+
+template< typename SynTreeType, typename NodeType >
+void
+buildList( const NodeType *firstNode, std::list< SynTreeType* > &outputList )
+{
+  SemanticError errors;
+  std::back_insert_iterator< std::list< SynTreeType* > > out( outputList );
+  const NodeType *cur = firstNode;
+
+  while( cur ) {
+    try {
+      SynTreeType *result = dynamic_cast< SynTreeType* >( cur->build() );
+      if( result ) {
+        *out++ = result;
+      } else {
+      }
+    } catch( SemanticError &e ) {
+      errors.append( e );
+    }
+    cur = dynamic_cast< NodeType* >( cur->get_link() );
+  }
+  if( !errors.isEmpty() ) {
+    throw errors;
+  }
+}
+
+// in DeclarationNode.cc
+void buildList( const DeclarationNode *firstNode, std::list< Declaration* > &outputList );
+void buildList( const DeclarationNode *firstNode, std::list< DeclarationWithType* > &outputList );
+void buildTypeList( const DeclarationNode *firstNode, std::list< Type* > &outputList );
+
+// in ExpressionNode.cc
+ExpressionNode *flattenCommas( ExpressionNode *list );
+ExpressionNode *tupleContents( ExpressionNode *tuple );
+
+#endif /* #ifndef PARSENODE_H */
+
+// Local Variables: //
+// mode: C++ //
+// compile-command: "gmake" //
+// End: //
Index: translator/Parser/Parser.cc
===================================================================
--- translator/Parser/Parser.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser/Parser.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Parser.cc,v 1.6 2002/11/15 20:07:18 rcbilson Exp $
+ *
+ */
+
+#include "Parser.h"
+#include "TypedefTable.h"
+#include "lex.h"
+#include "cfa.tab.h"
+
+/* global variables in cfa.y */
+extern int yyparse(void);
+
+extern int yydebug;
+extern LinkageSpec::Type linkage;
+
+extern TypedefTable typedefTable;
+extern DeclarationNode *theTree;
+/* end of globals */
+
+Parser *Parser::theParser = 0;
+
+Parser::Parser(): parseTree( 0 ), parseStatus( 1 ) {}
+
+Parser::~Parser()
+{
+  delete parseTree;
+}
+
+/* static class method */
+Parser &
+Parser::get_parser()
+{
+  if( theParser == 0 ) {
+    theParser = new Parser;
+  }
+  return *theParser;
+}
+
+void 
+Parser::parse( FILE *input )
+{
+  extern FILE *yyin;
+  yyin = input;
+  extern int yylineno;
+  yylineno = 1;
+  typedefTable.enterScope();
+  parseStatus = yyparse();
+  parseTree = theTree;
+}
+
+void
+Parser::set_debug( bool debug )
+{
+  yydebug = debug;
+}
+
+void 
+Parser::set_linkage( LinkageSpec::Type linkage )
+{
+  ::linkage = linkage;
+}
+
+
+void 
+Parser::freeTree()
+{
+  delete parseTree;
+  parseTree = 0;
+}
+
Index: translator/Parser/Parser.h
===================================================================
--- translator/Parser/Parser.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser/Parser.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * A singleton class to encapsulate the bison-generated parser
+ *
+ * $Id: Parser.h,v 1.4 2002/09/09 16:47:14 rcbilson Exp $
+ *
+ */
+
+#ifndef PARSER_H
+#define PARSER_H
+
+#include <cstdio>
+
+#include "Parser/ParseNode.h"
+#include "LinkageSpec.h"
+
+class Parser
+{
+public:
+  static Parser &get_parser();
+
+  /* do the actual parse */
+  void parse( FILE *input );
+
+  /* accessors to return the result of the parse */
+  DeclarationNode *get_parseTree() const { return parseTree; }
+  int get_parseStatus() const { return parseStatus; }
+
+  /* mutators to control parse options */
+  void set_debug( bool debug );
+  void set_linkage( LinkageSpec::Type linkage );
+
+  /* free the parse tree without actually destroying the parser */
+  void freeTree();
+
+  ~Parser();
+
+private:
+  Parser();
+  static Parser *theParser;
+  DeclarationNode *parseTree;
+  int parseStatus;
+};
+
+#endif /* #ifndef PARSER_H */
Index: translator/Parser/StatementNode.cc
===================================================================
--- translator/Parser/StatementNode.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser/StatementNode.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,437 @@
+/* -*- C++ -*- */
+#include <list>
+#include <algorithm>
+#include <cassert>
+
+#include "ParseNode.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Expression.h"
+#include "parseutility.h"
+#include "utility.h"
+
+using namespace std;
+
+const char *StatementNode::StType[] =
+  { "Exp",   "If",       "Switch", "Case",    "Default",  "Choose",   "Fallthru", 
+    "While", "Do",       "For", 
+    "Goto",  "Continue", "Break",  "Return",  "Throw",
+    "Try",   "Catch",    "Finally", "Asm",
+    "Decl"
+  };
+
+StatementNode::StatementNode(void) : 
+  ParseNode(), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), decl( 0 ), isCatchRest ( false ) {}
+
+StatementNode::StatementNode(string name_) : 
+  ParseNode(name_), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), decl( 0 ), isCatchRest ( false ) {}
+
+StatementNode::StatementNode( DeclarationNode *decl ) :
+  type( Decl ), control( 0 ), block( 0 ), labels( 0 ), target( 0 ), isCatchRest ( false )
+{
+  if( decl ) {
+    if( DeclarationNode *agg = decl->extractAggregate() ) {
+      this->decl = agg;
+      StatementNode *nextStmt = new StatementNode;
+      nextStmt->type = Decl;
+      nextStmt->decl = decl;
+      next = nextStmt;
+      if( decl->get_link() ) {
+        next->set_next( new StatementNode( dynamic_cast< DeclarationNode* >( decl->get_link() ) ) );
+        decl->set_next( 0 );
+      }
+    } else {
+      if( decl->get_link() ) {
+        next = new StatementNode( dynamic_cast< DeclarationNode* >( decl->get_link() ) );
+        decl->set_next( 0 );
+      }
+      this->decl = decl;
+    }
+  }
+}
+
+StatementNode::StatementNode(Type t, ExpressionNode *ctrl_label, StatementNode *block_ ) :
+  type(t), control(ctrl_label), block(block_), labels( 0 ), target( 0 ), decl( 0 ), isCatchRest ( false )
+{
+  if (t == Default)
+    control = 0;
+} 
+
+StatementNode::StatementNode(Type t, string *_target) :
+  type(t), control(0), block(0),   labels( 0 ), target(_target), decl( 0 ), isCatchRest ( false ) {}
+
+StatementNode::~StatementNode(void){
+  delete control;
+  delete block;
+  delete labels;
+  delete target;
+  delete decl;
+}
+
+StatementNode * StatementNode::newCatchStmt(DeclarationNode *d, StatementNode *s, bool catchRestP ) {
+  StatementNode *ret = new StatementNode( StatementNode::Catch, 0, s ); 
+  ret->addDeclaration( d );
+  ret->setCatchRest( catchRestP );
+
+  return ret;
+}
+
+std::string StatementNode::get_target() const{
+  if(target)
+    return *target;
+
+  return string("");
+}
+
+StatementNode *
+StatementNode::clone() const
+{
+  StatementNode *newnode = new StatementNode( type, maybeClone( control ), maybeClone( block ) );
+  if( target ) {
+    newnode->target = new string( *target );
+  } else {
+    newnode->target = 0;
+  }
+  newnode->decl = maybeClone( decl );
+  return newnode;
+}
+
+void StatementNode::set_control(ExpressionNode *c){
+  control = c;
+}
+
+StatementNode * StatementNode::set_block(StatementNode *b){
+  block = b;
+
+  return this;
+}
+
+ExpressionNode *StatementNode::get_control(void) const {
+  return control;
+}
+
+StatementNode *StatementNode::get_block(void) const {
+  return block;
+}
+
+StatementNode::Type StatementNode::get_type(void) const {
+  return type;
+}
+
+StatementNode *StatementNode::add_label(std::string *l){
+  if(l != 0){
+    if(labels == 0)
+      labels = new std::list<std::string>();
+
+    labels->push_front(*l); 
+    delete l;
+  }
+
+  return this;
+}
+
+std::list<std::string> *StatementNode::get_labels() const
+{  return labels; }
+
+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){
+  if( stmt != 0) {
+    if( block == 0 )
+      block = stmt;
+    else
+      block->set_link(stmt);
+  }
+  return this;
+}
+
+
+StatementNode *StatementNode::append_last_case(StatementNode *stmt){
+  if( stmt != 0 ) {
+    StatementNode *next = (StatementNode *)get_link();
+    if ( next && ( next->get_type() == StatementNode::Case || next->get_type() == StatementNode::Default) )
+      next->append_last_case ( stmt );
+    else
+      if( block == 0 )
+	block = stmt;
+      else
+	block->set_link(stmt);
+  }
+
+  return this;
+}
+
+void StatementNode::print( std::ostream &os, int indent ) const {
+
+  if(labels != 0)
+    if(!labels->empty()){
+      std::list<std::string>::const_iterator i;
+
+      os << '\r' << string(indent, ' ');
+      for( i = labels->begin(); i != labels->end(); i++ )
+	os << *i << ":";
+      os << endl;
+    }
+
+  switch( type ) {
+  case Decl:
+    decl->print( os, indent );
+    break;
+  
+  case Exp:
+    if( control ) {
+      os << string( indent, ' ' );
+      control->print( os, indent );
+      os << endl;
+    } else 
+      os << string( indent, ' ' ) << "Null Statement" << endl;
+    break;
+
+  default:
+    os << '\r' << string(indent, ' ') << StatementNode::StType[type] << endl;
+
+    if   ( type == Catch ) {
+      if( decl ){
+	os << '\r' << string( indent + ParseNode::indent_by, ' ' ) << "Declaration: " << endl;
+	decl->print( os, indent + 2*ParseNode::indent_by);
+      } else if ( isCatchRest ) {
+	os << '\r' << string( indent + ParseNode::indent_by, ' ' ) << "Catches the rest " << endl;
+      } else {
+	; // should never reach here
+      }
+    }
+
+    if( control ){
+      os << '\r' << string( indent + ParseNode::indent_by, ' ' ) << "Expression: " << endl;
+      control->printList( os, indent + 2*ParseNode::indent_by);
+    }
+
+    if( block ){
+      os << '\r' << string( indent + ParseNode::indent_by, ' ' ) << "Branches of execution: " << endl;
+      block->printList( os, indent + 2*ParseNode::indent_by);  
+    }
+
+    if( target ){
+      os << '\r' << string( indent + ParseNode::indent_by, ' ' ) << "Target: " << get_target() << endl;
+    }
+
+    break;
+  }
+}
+
+Statement *StatementNode::build() const {
+
+  std::list<Statement *> branches;
+  std::list<Expression *> exps;
+  std::list<Label> labs;
+
+  if(labels != 0){
+    std::back_insert_iterator< std::list<Label> > lab_it(labs);
+    copy(labels->begin(), labels->end(), lab_it);
+  }
+
+  // try {
+  buildList<Statement, StatementNode>(get_block(), branches);
+  
+  switch( type ) {
+  case Decl:
+    return new DeclStmt( labs, maybeBuild< Declaration >( decl ) );
+
+  case Exp:
+    {
+      Expression *e = maybeBuild< Expression >( get_control() );
+
+      if(e)
+        return new ExprStmt( labs, e );
+      else
+        return new NullStmt( labs );
+    }
+
+  case If:
+    {
+      Statement *thenb = 0, *elseb = 0;
+
+      assert( branches.size() >= 1 );
+
+      thenb = branches.front();  branches.pop_front();
+      if(!branches.empty())
+	{ elseb = branches.front();  branches.pop_front(); }
+
+      return new IfStmt( labs, notZeroExpr( get_control()->build() ), thenb, elseb);
+    }
+
+  case While:
+    assert(branches.size() == 1);
+    return new WhileStmt( labs, notZeroExpr( get_control()->build() ), branches.front() );
+
+  case Do:
+    assert(branches.size() == 1);
+    return new WhileStmt( labs, notZeroExpr( get_control()->build() ), branches.front(), true );
+    
+  case For:
+    {
+      assert(branches.size() == 1);
+
+      ForCtlExprNode *ctl = dynamic_cast<ForCtlExprNode *>(get_control());
+      assert(ctl != 0);
+
+      Statement *stmt = 0;
+      if(ctl->get_init() != 0)
+	stmt = ctl->get_init()->build();
+
+      Expression *cond = 0;
+      if(ctl->get_condition() != 0)
+	cond = notZeroExpr( ctl->get_condition()->build() );
+
+      Expression *incr = 0;
+      if(ctl->get_change() != 0)
+	incr = ctl->get_change()->build();
+
+      return new ForStmt( labs, stmt, cond, incr, branches.front() );
+    }
+
+  case Switch:
+    // try{
+    return new SwitchStmt( labs, get_control()->build(), branches );
+
+  case Choose:
+    return new ChooseStmt( labs, get_control()->build(), branches );
+
+  case Fallthru:
+    return new FallthruStmt( labs );
+
+  case Case: 
+    return new CaseStmt( labs, get_control()->build(), branches);
+
+  case Default:
+    return new CaseStmt( labs, 0, branches, true);
+
+  case Goto:
+    {
+      if (get_target() == "")  { // computed goto
+	assert( get_control() != 0 );
+	return new BranchStmt( labs, get_control()->build(), BranchStmt::Goto );
+      }
+
+      return new BranchStmt( labs, get_target(), BranchStmt::Goto);
+    }
+
+  case Break:
+    return new BranchStmt( labs, get_target(), BranchStmt::Break);
+
+  case Continue:
+    return new BranchStmt( labs, get_target(), BranchStmt::Continue);
+
+  case Return:
+  case Throw :
+    buildList( get_control(), exps );
+    if( exps.size() ==0 )
+      return new ReturnStmt( labs, 0, type == Throw );
+    if( exps.size() > 0 )
+      return new ReturnStmt( labs, exps.back(), type == Throw );
+
+  case Try:
+    {
+      assert( branches.size() >= 0 );
+      CompoundStmt *tryBlock = dynamic_cast<CompoundStmt *>(branches.front());
+      branches.pop_front();
+      FinallyStmt *finallyBlock = 0;
+      if( (finallyBlock = dynamic_cast<FinallyStmt *>(branches.back())) ) {
+	branches.pop_back();
+      }
+      return new TryStmt( labs, tryBlock, branches, finallyBlock );
+    }
+
+  case Catch:
+    {
+      assert( branches.size() == 1 );
+
+      return new CatchStmt( labs, maybeBuild< Declaration >( decl ), branches.front(), isCatchRest );
+    }
+
+  case Finally:
+    {
+      assert( branches.size() == 1 );
+      CompoundStmt *block = dynamic_cast<CompoundStmt *>( branches.front() );
+      assert( block != 0 );
+
+      return new FinallyStmt( labs, block );
+    }
+
+  default:
+    // shouldn't be here
+    return 0;
+  }
+
+  // shouldn't be here
+}
+
+CompoundStmtNode::CompoundStmtNode(void)
+  : first( 0 ), last( 0 )
+{
+}
+
+CompoundStmtNode::CompoundStmtNode(string *name_)
+  : StatementNode(*name_), first( 0 ), last( 0 )
+{
+}
+
+CompoundStmtNode::CompoundStmtNode(StatementNode *stmt): first(stmt)
+{
+  if( first ) {
+    last = (StatementNode *)(stmt->get_last());
+  } else {
+    last = 0;
+  }
+}
+
+CompoundStmtNode::~CompoundStmtNode()
+{
+  delete first;
+}
+
+void CompoundStmtNode::add_statement(StatementNode *stmt) {
+  if(stmt != 0){
+    last->set_link(stmt);
+    last = (StatementNode *)(stmt->get_link());
+  }
+}
+
+void CompoundStmtNode::print(ostream &os, int indent) const {
+  if( first ) {
+    first->printList( os, indent+2 );
+  }
+}
+
+Statement *CompoundStmtNode::build() const {
+
+  std::list<Label> labs;
+  std::list<std::string> *labels = get_labels();
+
+  if(labels != 0){
+    std::back_insert_iterator< std::list<Label> > lab_it(labs);
+    copy(labels->begin(), labels->end(), lab_it);
+  }
+
+  CompoundStmt *cs = new CompoundStmt( labs );
+  buildList( first, cs->get_kids() );
+  return cs;
+}
+
+void NullStmtNode::print(ostream &os, int indent) const {
+  os << "\r" << string(indent, ' ') << "Null Statement:" << endl;
+}
+
+Statement *NullStmtNode::build() const { 
+  return new NullStmt;
+}
+
+// Local Variables: //
+// mode: C++                //
+// compile-command: "gmake -f ../Makefile" //
+// End: //
Index: translator/Parser/TypeData.cc
===================================================================
--- translator/Parser/TypeData.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser/TypeData.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,1074 @@
+#include <cassert>
+#include <algorithm>
+#include <iterator>
+#include "utility.h"
+#include "TypeData.h"
+#include "SynTree/Type.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Statement.h"
+
+
+TypeData::TypeData( Kind k )
+  : kind( k ), base( 0 ), forall( 0 )
+{
+  switch( kind ) {
+  case Unknown:
+  case Pointer:
+  case EnumConstant:
+    // nothing else to initialize
+    break;
+
+  case Basic:
+    basic = new Basic_t;
+    break;
+
+  case Array:
+    array = new Array_t;
+    array->dimension = 0;
+    array->isVarLen = false;
+    array->isStatic = false;
+    break;
+
+  case Function:
+    function = new Function_t;
+    function->params = 0;
+    function->idList = 0;
+    function->oldDeclList = 0;
+    function->body = 0;
+    function->hasBody = false;
+    break;
+
+  case Aggregate:
+    aggregate = new Aggregate_t;
+    aggregate->params = 0;
+    aggregate->actuals = 0;
+    aggregate->members = 0;
+    break;
+
+  case AggregateInst:
+    aggInst = new AggInst_t;
+    aggInst->aggregate = 0;
+    aggInst->params = 0;
+    break;
+
+  case Enum:
+    enumeration = new Enumeration_t;
+    enumeration->constants = 0;
+    break;
+
+  case Symbolic:
+  case SymbolicInst:
+    symbolic = new Symbolic_t;
+    symbolic->params = 0;
+    symbolic->actuals = 0;
+    symbolic->assertions = 0;
+    break;
+
+  case Variable:
+    variable = new Variable_t;
+    variable->tyClass = DeclarationNode::Type;
+    variable->assertions = 0;
+    break;
+
+  case Tuple:
+    tuple = new Tuple_t;
+    tuple->members = 0;
+    break;
+  
+  case Typeof:
+    typeexpr = new Typeof_t;
+    typeexpr->expr = 0;
+    break;
+  
+  case Attr:
+    attr = new Attr_t;
+    attr->expr = 0;
+    attr->type = 0;
+    break;
+  }
+}
+
+TypeData::~TypeData()
+{
+  delete base;
+  delete forall;
+
+  switch( kind ) {
+  case Unknown:
+  case Pointer:
+  case EnumConstant:
+    // nothing to destroy
+    break;
+
+  case Basic:
+    delete basic;
+    break;
+
+  case Array:
+    delete array->dimension;
+    delete array;
+    break;
+
+  case Function:
+    delete function->params;
+    delete function->idList;
+    delete function->oldDeclList;
+    delete function->body;
+    delete function;
+    break;
+
+  case Aggregate:
+    delete aggregate->params;
+    delete aggregate->actuals;
+    delete aggregate->members;
+    delete aggregate;
+    break;
+
+  case AggregateInst:
+    delete aggInst->aggregate;
+    delete aggInst->params;
+    delete aggInst;
+    break;
+
+  case Enum:
+    delete enumeration->constants;
+    delete enumeration;
+    break;
+
+  case Symbolic:
+  case SymbolicInst:
+    delete symbolic->params;
+    delete symbolic->actuals;
+    delete symbolic->assertions;
+    delete symbolic;
+    break;
+
+  case Variable:
+    delete variable->assertions;
+    delete variable;
+    break;
+
+  case Tuple:
+    delete tuple->members;
+    delete tuple;
+    break;
+  
+  case Typeof:
+    delete typeexpr->expr;
+    delete typeexpr;
+    break;
+  
+  case Attr:
+    delete attr->expr;
+    delete attr->type;
+    delete attr;
+    break;
+  }
+}
+
+TypeData *
+TypeData::clone() const
+{
+  TypeData *newtype = new TypeData( kind );
+  newtype->qualifiers = qualifiers;
+  newtype->base = maybeClone( base );
+  newtype->forall = maybeClone( forall );
+
+  switch( kind ) {
+  case Unknown:
+  case EnumConstant:
+  case Pointer:
+    // nothing else to copy
+    break;
+
+  case Basic:
+    newtype->basic->typeSpec = basic->typeSpec;
+    newtype->basic->modifiers = basic->modifiers;
+    break;
+
+  case Array:
+    newtype->array->dimension = maybeClone( array->dimension );
+    newtype->array->isVarLen = array->isVarLen;
+    newtype->array->isStatic = array->isStatic;
+    break;
+
+  case Function:
+    newtype->function->params = maybeClone( function->params );
+    newtype->function->idList = maybeClone( function->idList );
+    newtype->function->oldDeclList = maybeClone( function->oldDeclList );
+    newtype->function->body = maybeClone( function->body );
+    newtype->function->hasBody = function->hasBody;
+    newtype->function->newStyle = function->newStyle;
+    break;
+
+  case Aggregate:
+    newtype->aggregate->params = maybeClone( aggregate->params );
+    newtype->aggregate->actuals = maybeClone( aggregate->actuals );
+    newtype->aggregate->members = maybeClone( aggregate->members );
+    newtype->aggregate->name = aggregate->name;
+    newtype->aggregate->kind = aggregate->kind;
+    break;
+
+  case AggregateInst:
+    newtype->aggInst->aggregate = maybeClone( aggInst->aggregate );
+    newtype->aggInst->params = maybeClone( aggInst->params );
+    break;
+
+  case Enum:
+    newtype->enumeration->name = enumeration->name;
+    newtype->enumeration->constants = maybeClone( enumeration->constants );
+    break;
+
+  case Symbolic:
+  case SymbolicInst:
+    newtype->symbolic->params = maybeClone( symbolic->params );
+    newtype->symbolic->actuals = maybeClone( symbolic->actuals );
+    newtype->symbolic->assertions = maybeClone( symbolic->assertions );
+    newtype->symbolic->isTypedef = symbolic->isTypedef;
+    newtype->symbolic->name = symbolic->name;
+    break;
+
+  case Variable:
+    newtype->variable->assertions = maybeClone( variable->assertions );
+    newtype->variable->name = variable->name;
+    newtype->variable->tyClass = variable->tyClass;
+    break;
+
+  case Tuple:
+    newtype->tuple->members = maybeClone( tuple->members );
+    break;
+    
+  case Typeof:
+    newtype->typeexpr->expr = maybeClone( typeexpr->expr );
+    break;
+  
+  case Attr:
+    newtype->attr->expr = maybeClone( attr->expr );
+    newtype->attr->type = maybeClone( attr->type );
+    break;
+  }
+  return newtype;
+}
+
+void 
+TypeData::print( std::ostream &os, int indent ) const
+{
+  using std::endl;
+  using std::string;
+
+  printEnums( qualifiers.begin(), qualifiers.end(), DeclarationNode::qualifierName, os );
+
+  if( forall ) {
+    os << "forall " << endl;
+    forall->printList( os, indent+4 );
+  }
+
+  switch( kind ) {
+  case Unknown:
+    os << "entity of unknown type ";
+    break;
+
+  case Pointer:
+    os << "pointer ";
+    if( base ) {
+      os << "to ";
+      base->print( os, indent );
+    }
+    break;
+
+  case EnumConstant:
+    os << "enumeration constant ";
+    break;
+
+  case Basic:
+    printEnums( basic->modifiers.begin(), basic->modifiers.end(), DeclarationNode::modifierName, os );
+    printEnums( basic->typeSpec.begin(), basic->typeSpec.end(), DeclarationNode::basicTypeName, os );
+    break;
+
+  case Array:
+    if( array->isStatic ) {
+      os << "static ";
+    }
+    if( array->dimension ) {
+      os << "array of ";
+      array->dimension->printOneLine( os, indent );
+    } else if ( array->isVarLen ) {
+      os << "variable-length array of ";
+    } else {
+      os << "open array of ";
+    }
+    if( base ) {
+      base->print( os, indent );
+    }
+    break;
+
+  case Function:
+    os << "function" << endl;
+    if ( function->params ) {
+      os << string( indent+2, ' ' ) << "with parameters " << endl;
+      function->params->printList( os, indent+4 );
+    } else {
+      os << string( indent+2, ' ' ) << "with no parameters " << endl;
+    }
+    if ( function->idList ) {
+      os << string( indent+2, ' ' ) << "with old-style identifier list " << endl;
+      function->idList->printList( os, indent+4 );
+    }
+    if ( function->oldDeclList ) {
+      os << string( indent+2, ' ' ) << "with old-style declaration list " << endl;
+      function->oldDeclList->printList( os, indent+4 );
+    }
+    os << string( indent+2, ' ' ) << "returning ";
+    if ( base ) {
+      base->print( os, indent+4 );
+    } else {
+      os << "nothing ";
+    }
+    os << endl;
+    if ( function->hasBody ) {
+      os << string( indent+2, ' ' ) << "with body " << endl;
+    }
+    if ( function->body ) {
+      function->body->printList( os, indent+2 );
+    }
+    break;
+
+  case Aggregate:
+    os << DeclarationNode::tyConName[ aggregate->kind ] << ' ' << aggregate->name << endl;
+    if( aggregate->params ) {
+      os << string( indent+2, ' ' ) << "with type parameters " << endl;
+      aggregate->params->printList( os, indent+4 );
+    }
+    if( aggregate->actuals ) {
+      os << string( indent+2, ' ' ) << "instantiated with actual parameters " << endl;
+      aggregate->actuals->printList( os, indent+4 );
+    }
+    if( aggregate->members ) {
+      os << string( indent+2, ' ' ) << "with members " << endl;
+      aggregate->members->printList( os, indent+4 );
+///     } else {
+///       os << string( indent+2, ' ' ) << "with no members " << endl;
+    }
+    break;
+
+  case AggregateInst:
+    if( aggInst->aggregate ) {
+      os << "instance of " ;
+      aggInst->aggregate->print( os, indent );
+    } else {
+      os << "instance of an unspecified aggregate ";
+    }
+    if( aggInst->params ) {
+      os << string( indent+2, ' ' ) << "with parameters " << endl;
+      aggInst->params->printList( os, indent+2 );
+    }
+    break;
+
+  case Enum:
+    os << "enumeration ";
+    if( enumeration->constants ) {
+      os << "with constants" << endl;
+      enumeration->constants->printList( os, indent+2 );
+    }
+    break;
+
+  case SymbolicInst:
+    os << "instance of type " << symbolic->name;
+    if( symbolic->actuals ) {
+      os << " with parameters" << endl;
+      symbolic->actuals->printList( os, indent + 2 );
+    }
+    break;
+
+  case Symbolic:
+    if( symbolic->isTypedef ) {
+      os << "typedef definition ";
+    } else {
+      os << "type definition ";
+    }
+    if( symbolic->params ) {
+      os << endl << string( indent+2, ' ' ) << "with parameters" << endl;
+      symbolic->params->printList( os, indent + 2 );
+    }
+    if( symbolic->assertions ) {
+      os << endl << string( indent+2, ' ' ) << "with assertions" << endl;
+      symbolic->assertions->printList( os, indent + 4 );
+      os << string( indent+2, ' ' );
+    }
+    if( base ) {
+      os << "for ";
+      base->print( os, indent + 2 );
+    }
+    break;
+
+  case Variable:
+    os << DeclarationNode::typeClassName[ variable->tyClass ] << " variable ";
+    if( variable->assertions ) {
+      os << endl << string( indent+2, ' ' ) << "with assertions" << endl;
+      variable->assertions->printList( os, indent + 4 );
+      os << string( indent+2, ' ' );
+    }
+    break;
+
+  case Tuple:
+    os << "tuple ";
+    if( tuple->members ) {
+      os << "with members " << endl;
+      tuple->members->printList( os, indent + 2 );
+    }
+    break;
+    
+  case Typeof:
+    os << "type-of expression ";
+    if( typeexpr->expr ) {
+      typeexpr->expr->print( os, indent + 2 );
+    }
+    break;
+    
+  case Attr:
+    os << "attribute type decl " << attr->name << " applied to ";
+    if( attr->expr ) {
+      attr->expr->print( os, indent + 2 );
+    }
+    if( attr->type ) {
+      attr->type->print( os, indent + 2 );
+    }
+    break;
+  }
+}
+
+TypeData *
+TypeData::extractAggregate( bool toplevel ) const
+{
+  TypeData *ret = 0;
+
+  switch( kind ) {
+  case Aggregate:
+    if( !toplevel && aggregate->members ) {
+      ret = clone();
+      ret->qualifiers.clear();
+    }
+    break;
+
+  case Enum:
+    if( !toplevel && enumeration->constants ) {
+      ret = clone();
+      ret->qualifiers.clear();
+    }
+    break;
+
+  case AggregateInst:
+    if( aggInst->aggregate ) {
+      ret = aggInst->aggregate->extractAggregate( false );
+    }
+    break;
+
+  default:
+    if( base ) {
+      ret = base->extractAggregate( false );
+    }
+  }
+  return ret;
+}
+
+void
+buildForall( const DeclarationNode *firstNode, std::list< TypeDecl* > &outputList )
+{
+  
+  buildList( firstNode, outputList );
+  for( std::list< TypeDecl* >::iterator i = outputList.begin(); i != outputList.end(); ++i ) {
+    if( (*i)->get_kind() == TypeDecl::Any ) {
+      FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
+      assignType->get_parameters().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
+      assignType->get_parameters().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
+      assignType->get_returnVals().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
+      (*i)->get_assertions().push_front( new FunctionDecl( "?=?", Declaration::NoStorageClass, LinkageSpec::Cforall,  assignType, 0, false ) );
+    }
+  }
+}
+
+Declaration *
+TypeData::buildDecl( std::string name, Declaration::StorageClass sc, Expression *bitfieldWidth, bool isInline, LinkageSpec::Type linkage, Initializer *init ) const
+{
+
+  if ( kind == TypeData::Function ) {
+    FunctionDecl *decl;
+    if( function->hasBody ) {
+      if( function->body ) {
+        Statement *stmt = function->body->build();
+        CompoundStmt *body = dynamic_cast< CompoundStmt* >( stmt );
+        assert( body );
+        decl = new FunctionDecl( name, sc, linkage, buildFunction(), body, isInline );
+      } else {
+	// std::list<Label> ls;
+        decl = new FunctionDecl( name, sc, linkage, buildFunction(), new CompoundStmt( std::list<Label>() ), isInline );
+      }
+    } else {
+      decl = new FunctionDecl( name, sc, linkage, buildFunction(), 0, isInline );
+    }
+    for( DeclarationNode *cur = function->idList; cur != 0; cur = dynamic_cast< DeclarationNode* >( cur->get_link() ) ) {
+      if( cur->get_name() != "" ) {
+        decl->get_oldIdents().insert( decl->get_oldIdents().end(), cur->get_name() );
+      }
+    }
+    buildList( function->oldDeclList, decl->get_oldDecls() );
+    return decl;
+  } else if ( kind == TypeData::Aggregate ) {
+    return buildAggregate();
+  } else if ( kind == TypeData::Enum ) {
+    return buildEnum();
+  } else if ( kind == TypeData::Symbolic ) {
+    return buildSymbolic( name, sc );
+  } else if ( kind == TypeData::Variable ) {
+    return buildVariable();
+  } else {
+    if( isInline ) {
+      throw SemanticError( "invalid inline specification in declaration of ", this );
+    } else {
+      return new ObjectDecl( name, sc, linkage, bitfieldWidth, build(), init );
+    }
+  }
+  return 0;
+}
+
+Type *
+TypeData::build() const
+{
+
+  switch( kind ) {
+  case Unknown:
+    // fill in implicit int
+    return new BasicType( buildQualifiers(), BasicType::SignedInt );
+
+  case Basic:
+    return buildBasicType();
+
+  case Pointer:
+    return buildPointer();
+
+  case Array:
+    return buildArray();
+
+  case Function:
+    return buildFunction();
+
+  case AggregateInst:
+    return buildAggInst();
+
+  case EnumConstant:
+    // the name gets filled in later -- by SymTab::Validate
+    return new EnumInstType( buildQualifiers(), "" );
+
+  case SymbolicInst:
+    return buildSymbolicInst();;
+
+  case Tuple:
+    return buildTuple();
+  
+  case Typeof:
+    return buildTypeof();
+
+  case Attr:
+    return buildAttr();
+
+  case Symbolic:
+  case Enum:
+  case Aggregate:
+  case Variable:
+    assert( false );
+  }
+
+  return 0;
+}
+
+Type::Qualifiers
+TypeData::buildQualifiers() const
+{
+  Type::Qualifiers q;
+  for( std::list< DeclarationNode::Qualifier >::const_iterator i = qualifiers.begin(); i != qualifiers.end(); ++i ) {
+    switch( *i ) {
+    case DeclarationNode::Const:
+      q.isConst = true;
+      break;
+
+    case DeclarationNode::Volatile:
+      q.isVolatile = true;
+      break;
+
+    case DeclarationNode::Restrict:
+      q.isRestrict = true;
+      break;
+
+    case DeclarationNode::Lvalue:
+      q.isLvalue = true;
+      break;
+    }
+  }
+  return q;
+}
+
+Type*
+TypeData::buildBasicType() const
+{
+
+  static const BasicType::Kind kindMap[] = { BasicType::Char, BasicType::SignedInt, BasicType::Float, BasicType::Double,
+                                             BasicType::Char /* void */, BasicType::Bool, BasicType::DoubleComplex,
+					     BasicType::DoubleImaginary };
+
+  bool init = false;
+  bool sawDouble = false;
+  bool sawSigned = false;
+  BasicType::Kind ret;
+
+  for( std::list< DeclarationNode::BasicType >::const_iterator i = basic->typeSpec.begin(); i != basic->typeSpec.end(); ++i ) {
+    if( !init ) {
+      init = true;
+      if( *i == DeclarationNode::Void ) {
+        if( basic->typeSpec.size() != 1 || !basic->modifiers.empty() ) {
+	  throw SemanticError( "invalid type specifier \"void\" in type ", this );
+	} else {
+	  return new VoidType( buildQualifiers() );
+	}
+      } else {
+        ret = kindMap[ *i ];
+      }
+    } else {
+      switch( *i ) {
+      case DeclarationNode::Float:
+	if( sawDouble ) {
+	  throw SemanticError( "invalid type specifier \"float\" in type ", this );
+	} else {
+	  switch( ret ) {
+	  case BasicType::DoubleComplex:
+	    ret = BasicType::FloatComplex;
+	    break;
+
+	  case BasicType::DoubleImaginary:
+	    ret = BasicType::FloatImaginary;
+	    break;
+
+	  default:
+	    throw SemanticError( "invalid type specifier \"float\" in type ", this );
+	  }
+	}
+	break;
+
+      case DeclarationNode::Double:
+	if( sawDouble ) {
+	  throw SemanticError( "duplicate type specifier \"double\" in type ", this );
+	} else {
+	  switch( ret ) {
+	  case BasicType::DoubleComplex:
+	  case BasicType::DoubleImaginary:
+	    break;
+
+	  default:
+	    throw SemanticError( "invalid type specifier \"double\" in type ", this );
+	  }
+	}
+	break;
+	
+      case DeclarationNode::Complex:
+        switch( ret ) {
+        case BasicType::Float:
+          ret = BasicType::FloatComplex;
+          break;
+          
+        case BasicType::Double:
+          ret = BasicType::DoubleComplex;
+          break;
+
+	default:
+	  throw SemanticError( "invalid type specifier \"complex\" in type ", this );
+        }
+	break;
+        
+      case DeclarationNode::Imaginary:
+        switch( ret ) {
+        case BasicType::Float:
+          ret = BasicType::FloatImaginary;
+          break;
+          
+        case BasicType::Double:
+          ret = BasicType::DoubleImaginary;
+          break;
+
+	default:
+	  throw SemanticError( "invalid type specifier \"imaginary\" in type ", this );
+        }
+	break;
+        
+      default:
+	throw SemanticError( std::string( "invalid type specifier \"" ) + DeclarationNode::basicTypeName[ *i ] + "\" in type ", this );
+      }
+    }
+    if( *i == DeclarationNode::Double ) {
+      sawDouble = true;
+    }
+  }
+
+  for( std::list< DeclarationNode::Modifier >::const_iterator i = basic->modifiers.begin(); i != basic->modifiers.end(); ++i ) {
+    switch( *i ) {
+    case DeclarationNode::Long:
+      if( !init ) {
+	init = true;
+	ret = BasicType::LongSignedInt;
+      } else {
+	switch( ret ) {
+	case BasicType::SignedInt:
+	  ret = BasicType::LongSignedInt;
+	  break;
+
+	case BasicType::UnsignedInt:
+	  ret = BasicType::LongUnsignedInt;
+	  break;
+
+	case BasicType::LongSignedInt:
+	  ret = BasicType::LongLongSignedInt;
+	  break;
+
+	case BasicType::LongUnsignedInt:
+	  ret = BasicType::LongLongUnsignedInt;
+	  break;
+
+	case BasicType::Double:
+	  ret = BasicType::LongDouble;
+	  break;
+
+	case BasicType::DoubleComplex:
+	  ret = BasicType::LongDoubleComplex;
+	  break;
+
+	case BasicType::DoubleImaginary:
+	  ret = BasicType::LongDoubleImaginary;
+	  break;
+
+	default:
+	  throw SemanticError( "invalid type modifier \"long\" in type ", this );
+	}
+      }
+      break;
+
+    case DeclarationNode::Short:
+      if( !init ) {
+	init = true;
+	ret = BasicType::ShortSignedInt;
+      } else {
+	switch( ret ) {
+	case BasicType::SignedInt:
+	  ret = BasicType::ShortSignedInt;
+	  break;
+
+	case BasicType::UnsignedInt:
+	  ret = BasicType::ShortUnsignedInt;
+	  break;
+
+	default:
+	  throw SemanticError( "invalid type modifier \"short\" in type ", this );
+	}
+      }
+      break;
+
+    case DeclarationNode::Signed:
+      if( !init ) {
+	init = true;
+	ret = BasicType::SignedInt;
+      } else if( sawSigned ) {
+	throw SemanticError( "duplicate type modifer \"signed\" in type ", this );
+      } else {
+	switch( ret ) {
+	case BasicType::SignedInt:
+	case BasicType::ShortSignedInt:
+	  break;
+
+	case BasicType::Char:
+	  ret = BasicType::SignedChar;
+	  break;
+
+	default:
+	  throw SemanticError( "invalid type modifer \"signed\" in type ", this );
+	}
+      }
+      break;
+
+    case DeclarationNode::Unsigned:
+      if( !init ) {
+	init = true;
+	ret = BasicType::UnsignedInt;
+      } else if( sawSigned ) {
+	throw SemanticError( "invalid type modifer \"unsigned\" in type ", this );
+      } else {
+	switch( ret ) {
+	case BasicType::LongSignedInt:
+	  ret = BasicType::LongUnsignedInt;
+	  break;
+
+	case BasicType::SignedInt:
+	  ret = BasicType::UnsignedInt;
+	  break;
+
+	case BasicType::ShortSignedInt:
+	  ret = BasicType::ShortUnsignedInt;
+	  break;
+
+	case BasicType::Char:
+	  ret = BasicType::UnsignedChar;
+	  break;
+
+	default:
+	  throw SemanticError( "invalid type modifer \"unsigned\" in type ", this );
+	}
+      }
+      break;
+    }
+
+    if( *i == DeclarationNode::Signed ) {
+      sawSigned = true;
+    }
+  }
+
+  BasicType *bt;
+  if( !init ) {
+    bt = new BasicType( buildQualifiers(), BasicType::SignedInt );
+  } else {
+    bt = new BasicType( buildQualifiers(), ret );
+  }
+  buildForall( forall, bt->get_forall() );
+  return bt;
+}
+
+
+PointerType * 
+TypeData::buildPointer() const
+{
+  
+  PointerType *pt;
+  if( base ) {
+    pt = new PointerType( buildQualifiers(), base->build() );
+  } else {
+    pt = new PointerType( buildQualifiers(), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
+  }
+  buildForall( forall, pt->get_forall() );
+  return pt;
+}
+
+ArrayType * 
+TypeData::buildArray() const
+{
+  
+  ArrayType *at;
+  if( base ) {
+    at = new ArrayType( buildQualifiers(), base->build(), maybeBuild< Expression >( array->dimension ),
+	                  array->isVarLen, array->isStatic );
+  } else {
+    at = new ArrayType( buildQualifiers(), new BasicType( Type::Qualifiers(), BasicType::SignedInt ),
+	                  maybeBuild< Expression >( array->dimension ), array->isVarLen, array->isStatic );
+  }
+  buildForall( forall, at->get_forall() );
+  return at;
+}
+
+FunctionType *
+TypeData::buildFunction() const
+{
+  assert( kind == Function );
+
+
+  bool hasEllipsis = function->params ? function->params->get_hasEllipsis() : true;
+  if( !function->params ) hasEllipsis = !function->newStyle;
+  FunctionType *ft = new FunctionType( buildQualifiers(), hasEllipsis );
+  buildList( function->params, ft->get_parameters() );
+  buildForall( forall, ft->get_forall() );
+  if( base ) {
+    switch( base->kind ) {
+    case Tuple:
+      buildList( base->tuple->members, ft->get_returnVals() );
+      break;
+
+    default:
+      ft->get_returnVals().push_back( dynamic_cast< DeclarationWithType* >( base->buildDecl( "", Declaration::NoStorageClass, 0, false, LinkageSpec::Cforall ) ) );
+    }
+  } else {
+    ft->get_returnVals().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 ) );
+  }
+  return ft;
+}
+
+AggregateDecl *
+TypeData::buildAggregate() const
+{
+  assert( kind == Aggregate );
+
+
+  AggregateDecl *at;
+  switch( aggregate->kind ) {
+  case DeclarationNode::Struct:
+    at = new StructDecl( aggregate->name );
+    break;
+    
+  case DeclarationNode::Union:
+    at = new UnionDecl( aggregate->name );
+    break;
+    
+  case DeclarationNode::Context:
+    at = new ContextDecl( aggregate->name );
+    break;
+    
+  default:
+    assert( false );
+  }
+  
+  buildList( aggregate->params, at->get_parameters() );
+  buildList( aggregate->members, at->get_members() );
+
+  return at;
+}
+
+/// namespace {
+/// Type*
+/// makeType( Declaration* decl )
+/// {
+///   if( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
+///     return dwt->get_type()->clone();
+///   } else {
+///     return 0;
+///   }
+/// }
+/// }
+
+ReferenceToType *
+TypeData::buildAggInst() const
+{
+  assert( kind == AggregateInst );
+
+
+  std::string name;
+
+  ReferenceToType *ret;
+  if( aggInst->aggregate->kind == Enum ) {
+    ret = new EnumInstType( buildQualifiers(), aggInst->aggregate->enumeration->name );
+  } else {
+    assert( aggInst->aggregate->kind == Aggregate );
+    switch( aggInst->aggregate->aggregate->kind ) {
+    case DeclarationNode::Struct:
+      ret = new StructInstType( buildQualifiers(), aggInst->aggregate->aggregate->name );
+      break;
+
+    case DeclarationNode::Union:
+      ret = new UnionInstType( buildQualifiers(), aggInst->aggregate->aggregate->name );
+      break;
+
+    case DeclarationNode::Context:
+      ret = new ContextInstType( buildQualifiers(), aggInst->aggregate->aggregate->name );
+      break;
+
+    default:
+      assert( false );
+    }
+  }
+  buildList( aggInst->params, ret->get_parameters() );
+  buildForall( forall, ret->get_forall() );
+  return ret;
+}
+
+NamedTypeDecl*
+TypeData::buildSymbolic( const std::string &name, Declaration::StorageClass sc ) const
+{
+  assert( kind == Symbolic );
+
+
+  NamedTypeDecl *ret;
+  if( symbolic->isTypedef ) {
+    ret = new TypedefDecl( name, sc, maybeBuild< Type >( base ) );
+  } else {
+    ret = new TypeDecl( name, sc, maybeBuild< Type >( base ), TypeDecl::Any );
+  }
+  buildList( symbolic->params, ret->get_parameters() );
+  buildList( symbolic->assertions, ret->get_assertions() );
+  return ret;
+}
+
+TypeDecl*
+TypeData::buildVariable() const
+{
+  assert( kind == Variable );
+
+
+  static const TypeDecl::Kind kindMap[] = { TypeDecl::Any, TypeDecl::Ftype, TypeDecl::Dtype };
+
+  TypeDecl *ret = new TypeDecl( variable->name, Declaration::NoStorageClass, 0, kindMap[ variable->tyClass ] );
+  buildList( variable->assertions, ret->get_assertions() );
+    
+  return ret;
+}
+
+EnumDecl* 
+TypeData::buildEnum() const
+{
+  assert( kind == Enum );
+
+
+  EnumDecl *ret = new EnumDecl( enumeration->name );
+  buildList( enumeration->constants, ret->get_members() );
+
+  return ret;
+}
+
+TypeInstType * 
+TypeData::buildSymbolicInst() const
+{
+  assert( kind == SymbolicInst );
+
+
+  TypeInstType *ret = new TypeInstType( buildQualifiers(), symbolic->name, false );
+  buildList( symbolic->actuals, ret->get_parameters() );
+  buildForall( forall, ret->get_forall() );
+
+  return ret;
+}
+
+TupleType * 
+TypeData::buildTuple() const
+{
+  assert( kind == Tuple );
+
+
+  TupleType *ret = new TupleType( buildQualifiers() );
+  buildTypeList( tuple->members, ret->get_types() );
+  buildForall( forall, ret->get_forall() );
+
+  return ret;
+}
+
+TypeofType * 
+TypeData::buildTypeof() const
+{
+  assert( kind == Typeof );
+
+
+  assert( typeexpr );
+  assert( typeexpr->expr );
+  TypeofType *ret = new TypeofType( buildQualifiers(), typeexpr->expr->build() );
+
+  return ret;
+}
+
+AttrType * 
+TypeData::buildAttr() const
+{
+  assert( kind == Attr );
+
+
+  assert( attr );
+  AttrType *ret;
+  if( attr->expr ) {
+    ret = new AttrType( buildQualifiers(), attr->name, attr->expr->build() );
+  } else {
+    assert( attr->type );
+    ret = new AttrType( buildQualifiers(), attr->name, attr->type->buildType() );
+  }
+
+  return ret;
+}
+
Index: translator/Parser/TypeData.h
===================================================================
--- translator/Parser/TypeData.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser/TypeData.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,128 @@
+#ifndef TYPEDATA_H
+#define TYPEDATA_H
+
+#include <list>
+#include "ParseNode.h"
+#include "SynTree/SynTree.h"
+#include "SynTree/Type.h"
+#include "SynTree/Declaration.h"
+#include "SemanticError.h"
+#include "LinkageSpec.h"
+
+struct TypeData
+{
+  enum Kind { Unknown, Basic, Pointer, Array, Function, Aggregate, AggregateInst,
+	      Enum, EnumConstant, Symbolic, SymbolicInst, Variable, Tuple, Typeof, Attr } kind;
+
+  TypeData( Kind k = Unknown );
+  ~TypeData();
+  void print( std::ostream &, int indent = 0 ) const;
+  TypeData *clone() const;
+
+  Type *build() const;
+  FunctionType *buildFunction() const;
+
+  TypeData *base;
+  std::list< DeclarationNode::Qualifier > qualifiers;
+  DeclarationNode *forall;
+
+  struct Basic_t {
+    std::list< DeclarationNode::BasicType > typeSpec;
+    std::list< DeclarationNode::Modifier > modifiers;
+  };
+
+  struct Aggregate_t {
+    DeclarationNode::TyCon kind;
+    std::string name;
+    DeclarationNode *params;
+    ExpressionNode *actuals;	// holds actual parameters that will later be applied to AggInst
+    DeclarationNode *members;
+  };
+
+  struct AggInst_t {
+    TypeData *aggregate;
+    ExpressionNode *params;
+  };
+
+  struct Array_t {
+    ExpressionNode *dimension;
+    bool isVarLen;
+    bool isStatic;
+  };
+
+  struct Enumeration_t {
+    std::string name;
+    DeclarationNode *constants;
+  };
+
+  struct Function_t {
+    DeclarationNode *params;
+    DeclarationNode *idList; // old-style
+    DeclarationNode *oldDeclList;
+    StatementNode *body;
+    bool hasBody;
+    bool newStyle;
+  };
+
+  struct Symbolic_t {
+    std::string name;
+    bool isTypedef;
+    DeclarationNode *params;
+    ExpressionNode *actuals;
+    DeclarationNode *assertions;
+  };
+
+  struct Variable_t {
+    DeclarationNode::TypeClass tyClass;
+    std::string name;
+    DeclarationNode *assertions;
+  };
+
+  struct Tuple_t {
+    DeclarationNode *members;
+  };
+  
+  struct Typeof_t {
+    ExpressionNode *expr;
+  };
+
+  struct Attr_t {
+    std::string name;
+    ExpressionNode *expr;
+    DeclarationNode *type;
+  };
+
+  union {
+    Basic_t *basic;
+    Aggregate_t *aggregate;
+    AggInst_t *aggInst;
+    Array_t *array;
+    Enumeration_t *enumeration;
+    Function_t *function;
+    Symbolic_t *symbolic;
+    Variable_t *variable;
+    Tuple_t *tuple;
+    Typeof_t *typeexpr;
+    Attr_t *attr;
+  };
+
+  TypeData *extractAggregate( bool toplevel = true ) const;
+  /* helper function for DeclNodeImpl::build */
+  Declaration * buildDecl( std::string name, Declaration::StorageClass sc, Expression *bitfieldWidth, bool isInline, LinkageSpec::Type linkage, Initializer *init = 0 ) const;
+  /* helper functions for build() */
+  Type::Qualifiers buildQualifiers() const;
+  Type *buildBasicType() const;
+  PointerType * buildPointer() const;
+  ArrayType * buildArray() const;
+  AggregateDecl * buildAggregate() const;
+  ReferenceToType * buildAggInst() const;
+  NamedTypeDecl * buildSymbolic( const std::string &name, Declaration::StorageClass sc ) const;
+  TypeDecl* buildVariable() const;
+  EnumDecl* buildEnum() const;
+  TypeInstType * buildSymbolicInst() const;
+  TupleType * buildTuple() const;
+  TypeofType * buildTypeof() const;
+  AttrType * buildAttr() const;
+};
+
+#endif /* #ifndef TYPEDATA_H */
Index: translator/Parser/TypedefTable.cc
===================================================================
--- translator/Parser/TypedefTable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser/TypedefTable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,190 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: TypedefTable.cc,v 1.7 2004/09/14 17:21:12 rcbilson Exp $
+ *
+ */
+
+#include <map>
+#include <list>
+#include "TypedefTable.h"
+#include <cassert>
+using namespace std;
+
+#if 0
+#include <iostream>
+#  define debugPrint(x) cerr << x
+#else
+#  define debugPrint(x)
+#endif
+
+TypedefTable::TypedefTable()
+    : currentScope(0)
+{
+}
+
+bool
+TypedefTable::isKind(string identifier, kind_t kind) const
+{
+    tableType::const_iterator id_pos = table.find(identifier);
+    if (id_pos == table.end()) {
+	return true;
+    } else {
+	return (*((*id_pos).second.begin())).kind == kind;
+    }
+}
+
+bool
+TypedefTable::isIdentifier(string identifier) const
+{
+    return isKind(identifier, ID);
+}
+
+bool
+TypedefTable::isTypedef(string identifier) const
+{
+    return isKind(identifier, TD);
+}
+
+bool
+TypedefTable::isTypegen(string identifier) const
+{
+    return isKind(identifier, TG);
+}
+
+void
+TypedefTable::addToScope(const std::string &identifier, kind_t kind, int scope)
+{
+  if( currentContext != "" && scope == contextScope ) {
+    DeferredEntry entry = { identifier, kind };
+    contexts[currentContext].push_back( entry );
+  } else {
+    debugPrint( "Adding " << identifier << " as type " << kind << " scope " << scope << " from scope " << currentScope << endl );
+    Entry newEntry = { scope, kind };
+    tableType::iterator curPos = table.find(identifier);
+    if (curPos == table.end()) {
+      list<Entry> newList;
+      newList.push_front(newEntry);
+      table[identifier] = newList;
+    } else {
+      list<Entry>::iterator listPos = (*curPos).second.begin();
+      while( listPos != (*curPos).second.end() && listPos->scope > scope ) {
+        listPos++;
+      }
+      (*curPos).second.insert(listPos, newEntry);
+    }
+  }
+}
+
+void
+TypedefTable::addToCurrentScope(const std::string &identifier, kind_t kind)
+{
+  addToScope( identifier, kind, currentScope );
+}
+
+void
+TypedefTable::addToCurrentScope(kind_t kind)
+{
+  addToCurrentScope( nextIdentifiers.top(), kind );
+}
+
+void
+TypedefTable::addToEnclosingScope(const std::string &identifier, kind_t kind)
+{
+  assert( currentScope >= 1 );
+  addToScope( identifier, kind, currentScope - 1 );
+}
+
+void
+TypedefTable::addToEnclosingScope(kind_t kind)
+{
+  addToEnclosingScope( nextIdentifiers.top(), kind );
+}
+
+void
+TypedefTable::addToEnclosingScope2(const std::string &identifier, kind_t kind)
+{
+  assert( currentScope >= 2 );
+  addToScope( identifier, kind, currentScope - 2 );
+}
+
+void
+TypedefTable::addToEnclosingScope2(kind_t kind)
+{
+  addToEnclosingScope2( nextIdentifiers.top(), kind );
+}
+
+void
+TypedefTable::setNextIdentifier( const std::string &identifier )
+{
+  nextIdentifiers.top() = identifier;
+}
+
+void
+TypedefTable::openContext( std::string contextName )
+{
+  map< string, deferListType >::iterator i = contexts.find( contextName );
+  if( i != contexts.end() ) {
+    deferListType &entries = i->second;
+    for (deferListType::iterator i = entries.begin(); i != entries.end(); i++) {
+      addToEnclosingScope( i->identifier, i->kind );
+    }
+  }
+}
+
+void
+TypedefTable::enterScope(void)
+{
+    currentScope += 1;
+    deferListStack.push( deferListType() );
+    nextIdentifiers.push( "" );
+    debugPrint( "Entering scope " << currentScope << ", nextIdentifiers size is " << nextIdentifiers.size() << endl );
+}
+
+void
+TypedefTable::leaveScope(void)
+{
+    debugPrint( "Leaving scope " << currentScope << endl );
+    for (tableType::iterator i = table.begin(); i != table.end(); i++) {
+	list<Entry> &declList = (*i).second;
+	while (!declList.empty() && declList.front().scope == currentScope) {
+	    declList.pop_front();
+	}
+	if( declList.empty() ) {
+	  table.erase( i );
+	}
+    }
+    currentScope -= 1;
+    for (deferListType::iterator i = deferListStack.top().begin(); i != deferListStack.top().end(); i++) {
+      addToCurrentScope( i->identifier, i->kind );
+    }
+    deferListStack.pop();
+    debugPrint( "nextIdentifiers size is " << nextIdentifiers.size() << " top is " << nextIdentifiers.top() << endl );
+    nextIdentifiers.pop();
+}
+
+void
+TypedefTable::enterContext( std::string contextName )
+{
+  currentContext = contextName;
+  contextScope = currentScope;
+}
+
+void
+TypedefTable::leaveContext(void)
+{
+  currentContext = "";
+}
+
+void
+TypedefTable::print(void) const
+{
+    for (tableType::const_iterator i = table.begin(); i != table.end(); i++) {
+	debugPrint( (*i).first << ": " );
+	list<Entry> declList = (*i).second;
+	for (list<Entry>::const_iterator j = declList.begin(); j != declList.end(); j++) {
+	    debugPrint( "(" << (*j).scope << " " << (*j).kind << ") " );
+	}
+	debugPrint( endl );
+    }
+}
Index: translator/Parser/TypedefTable.h
===================================================================
--- translator/Parser/TypedefTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser/TypedefTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,86 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: TypedefTable.h,v 1.5 2003/05/11 15:24:05 rcbilson Exp $
+ *
+ */
+
+#ifndef TYPEDEFTABLE_H
+#define TYPEDEFTABLE_H
+
+#include <map>
+#include <list>
+#include <string>
+#include <stack>
+
+class TypedefTable
+{
+  public:
+    enum kind_t { ID, TD, TG };
+  private:
+    struct Entry
+    {
+	int scope;
+	kind_t kind;
+    };
+    
+    struct DeferredEntry
+    {
+      std::string identifier;
+      kind_t kind;
+    };
+
+    typedef std::map<std::string, std::list<Entry> > tableType;
+    tableType table;
+
+    int currentScope;
+    std::string currentContext;
+    int contextScope;
+    
+    typedef std::list< DeferredEntry > deferListType;
+    std::stack< deferListType > deferListStack;
+    std::map< std::string, deferListType > contexts;
+    
+    std::stack< std::string > nextIdentifiers;
+
+    bool isKind(std::string identifier, kind_t kind) const;
+    void addToScope(const std::string &identifier, kind_t kind, int scope);
+  public:
+    TypedefTable();
+
+    bool isIdentifier(std::string identifier) const;
+    bool isTypedef(std::string identifier) const;
+    bool isTypegen(std::string identifier) const;
+    
+    // "addToCurrentScope" adds the identifier/type pair to the current scope This does less
+    // than you think it does, since each declaration is within its own scope.  Mostly useful for
+    // type parameters.
+    void addToCurrentScope(const std::string &identifier, kind_t kind);
+    void addToCurrentScope(kind_t kind);   // use nextIdentifiers.top()
+
+    // "addToEnclosingScope" adds the identifier/type pair to the scope that encloses the current
+    // one.  This is the right way to handle type and typedef names
+    void addToEnclosingScope(const std::string &identifier, kind_t kind);
+    void addToEnclosingScope(kind_t kind); // use nextIdentifiers.top()
+    
+    // "addToEnclosingScope2" adds the identifier/type pair to the scope that encloses the scope
+    // enclosing the the current one.  This is the right way to handle assertion names
+    void addToEnclosingScope2(const std::string &identifier, kind_t kind);
+    void addToEnclosingScope2(kind_t kind); // use nextIdentifiers.top()
+    
+    // set the next identifier to be used by an "add" operation without an identifier parameter
+    // within the current scope
+    void setNextIdentifier( const std::string &identifier );
+    
+    // dump the definitions from a pre-defined context into the current scope
+    void openContext( std::string contextName );
+    
+    void enterScope(void);
+    void leaveScope(void);
+    void enterContext( std::string contextName );
+    void leaveContext(void);
+
+    void print(void) const;
+};
+
+#endif /* ifndef TYPEDEFTABLE_H */
Index: translator/Parser/cfa.y
===================================================================
--- translator/Parser/cfa.y	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser/cfa.y	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,2746 @@
+/*                               -*- Mode: C -*-
+ *
+ * CForall Grammar Version 1.0, Copyright (C) Peter A. Buhr 2001 -- Permission is granted to copy this
+ *	grammar and to use it within software systems.  THIS GRAMMAR IS PROVIDED "AS IS" AND WITHOUT
+ *	ANY EXPRESS OR IMPLIED WARRANTIES.
+ *
+ * cfa.y --
+ *
+ * Author           : Peter A. Buhr
+ * Created On       : Sat Sep  1 20:22:55 2001
+ * Last Modified By : Peter A. Buhr
+ * Last Modified On : Mon Nov  3 11:21:43 2003
+ * Update Count     : 856
+ */
+
+/* This grammar is based on the ANSI99 C grammar, specifically parts of EXPRESSION and STATEMENTS, and on the
+   C grammar by James A. Roskind, specifically parts of DECLARATIONS and EXTERNAL DEFINITIONS.  While parts
+   have been copied, important changes have been made in all sections; these changes are sufficient to
+   constitute a new grammar.  In particular, this grammar attempts to be more syntactically precise, i.e., it
+   parses less incorrect language syntax that must be subsequently rejected by semantic checks.  Nevertheless,
+   there are still several semantic checks required and many are noted in the grammar. Finally, the grammar
+   is extended with GCC and CFA language extensions. */
+
+/* Acknowledgments to Richard Bilson, Glen Ditchfield, and Rodolfo Gabriel Esteves who all helped when I got
+   stuck with the grammar. */
+
+/* The root language for this grammar is ANSI99 C. All of ANSI99 is parsed, except for:
+
+   1. designation with '=' (use ':' instead)
+
+   Most of the syntactic extensions from ANSI90 to ANSI99 C are marked with the comment "ANSI99". This grammar
+   also has two levels of extensions. The first extensions cover most of the GCC C extensions, except for:
+
+   1. nested functions
+   2. generalized lvalues
+   3. designation with and without '=' (use ':' instead)
+   4. attributes not allowed in parenthesis of declarator
+
+   All of the syntactic extensions for GCC C are marked with the comment "GCC". The second extensions are for
+   Cforall (CFA), which fixes several of C's outstanding problems and extends C with many modern language
+   concepts. All of the syntactic extensions for CFA C are marked with the comment "CFA". As noted above,
+   there is one unreconcileable parsing problem between ANSI99 and CFA with respect to designators; this is
+   discussed in detail before the "designation" grammar rule. */
+
+%{
+#define YYDEBUG_LEXER_TEXT (yylval)			/* lexer loads this up each time */
+#define YYDEBUG 1					/* get the pretty debugging code to compile*/
+
+#undef __GNUC_MINOR__
+
+#include <cstdio>
+#include <stack>
+#include "TypedefTable.h"
+#include "lex.h"
+#include "ParseNode.h"
+#include "LinkageSpec.h"
+
+DeclarationNode *theTree = 0;				/* the resulting parse tree */
+LinkageSpec::Type linkage = LinkageSpec::Cforall;
+std::stack< LinkageSpec::Type > linkageStack;
+TypedefTable typedefTable;
+%}
+
+/************************* TERMINAL TOKENS ********************************/
+
+/* keywords */
+%token TYPEDEF
+%token AUTO EXTERN REGISTER STATIC
+%token INLINE						/* ANSI99 */
+%token FORTRAN						/* ANSI99, extension ISO/IEC 9899:1999 Section J.5.9(1) */
+%token CONST VOLATILE
+%token RESTRICT						/* ANSI99 */
+%token FORALL LVALUE					/* CFA */
+%token VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED
+%token BOOL COMPLEX IMAGINARY				/* ANSI99 */
+%token TYPEOF LABEL					/* GCC */
+%token ENUM STRUCT UNION
+%token TYPE FTYPE DTYPE CONTEXT				/* CFA */
+%token SIZEOF
+%token ALIGNOF ATTRIBUTE EXTENSION			/* GCC */
+%token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN
+%token CHOOSE FALLTHRU TRY CATCH FINALLY THROW		/* CFA */
+%token ASM						/* ANSI99, extension ISO/IEC 9899:1999 Section J.5.10(1) */
+
+/* names and constants: lexer differentiates between identifier and typedef names */
+%token<tok> IDENTIFIER		TYPEDEFname		TYPEGENname
+%token<tok> ATTR_IDENTIFIER	ATTR_TYPEDEFname	ATTR_TYPEGENname
+%token<tok> INTEGERconstant	FLOATINGconstant	CHARACTERconstant       STRINGliteral
+%token<tok> ZERO		ONE			/* CFA */
+
+/* multi-character operators */
+%token ARROW			/* ->				*/
+%token ICR DECR			/* ++	--			*/
+%token LS RS			/* <<	>>			*/
+%token LE GE EQ NE		/* <=	>=	==	!=	*/
+%token ANDAND OROR		/* &&	||			*/
+%token ELLIPSIS			/* ...				*/
+
+%token MULTassign	DIVassign	MODassign	/* *=	/=	%=	*/
+%token PLUSassign	MINUSassign			/* +=	-=		*/
+%token LSassign		RSassign			/* <<=	>>=		*/
+%token ANDassign	ERassign	ORassign	/* &=	^=	|=	*/
+
+/* Types declaration */
+%union
+{
+  Token tok;
+  ParseNode *pn;
+  ExpressionNode *en;
+  DeclarationNode *decl;
+  DeclarationNode::TyCon aggKey;
+  DeclarationNode::TypeClass tclass;
+  StatementNode *sn;
+  ConstantNode *constant;
+  InitializerNode *in;
+}
+
+%type<tok> zero_one  identifier  no_attr_identifier  no_01_identifier
+%type<tok> identifier_or_typedef_name  no_attr_identifier_or_typedef_name  no_01_identifier_or_typedef_name
+%type<constant> string_literal_list
+
+/* expressions */
+%type<constant> constant
+%type<en> tuple				tuple_expression_list
+%type<en> unary_operator                assignment_operator
+%type<en> primary_expression		postfix_expression		unary_expression
+%type<en> cast_expression		multiplicative_expression	additive_expression	shift_expression
+%type<en> relational_expression		equality_expression		AND_expression		exclusive_OR_expression
+%type<en> inclusive_OR_expression	logical_AND_expression		logical_OR_expression	conditional_expression
+%type<en> constant_expression		assignment_expression		assignment_expression_opt
+%type<en> comma_expression		comma_expression_opt
+%type<en> argument_expression_list	argument_expression		for_control_expression	assignment_opt
+%type<en> subrange
+
+/* statements */
+%type<sn> labeled_statement	compound_statement      expression_statement	selection_statement
+%type<sn> iteration_statement	jump_statement		exception_statement	asm_statement
+%type<sn> fall_through_opt	fall_through
+%type<sn> statement		statement_list
+%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<sn> switch_clause_list_opt switch_clause_list	choose_clause_list_opt	choose_clause_list
+%type<pn> handler_list		handler_clause		finally_clause
+
+/* declarations */
+%type<decl> abstract_array abstract_declarator abstract_function abstract_parameter_array
+%type<decl> abstract_parameter_declaration abstract_parameter_declarator abstract_parameter_function
+%type<decl> abstract_parameter_ptr abstract_ptr
+
+%type<aggKey> aggregate_key
+%type<decl>  aggregate_name
+
+%type<decl> array_dimension array_parameter_1st_dimension array_parameter_dimension multi_array_dimension
+
+%type<decl> assertion assertion_list_opt
+
+%type<en>   bit_subrange_size_opt bit_subrange_size
+
+%type<decl> basic_declaration_specifier basic_type_name basic_type_specifier direct_type_name indirect_type_name
+
+%type<decl> context_declaration context_declaration_list context_declaring_list context_specifier
+
+%type<decl> declaration declaration_list declaration_list_opt declaration_qualifier_list
+%type<decl> declaration_specifier declarator declaring_list
+
+%type<decl> elaborated_type_name
+
+%type<decl> enumerator_list enum_name
+%type<en> enumerator_value_opt
+
+%type<decl> exception_declaration external_definition external_definition_list external_definition_list_opt
+
+%type<decl> field_declaration field_declaration_list field_declarator field_declaring_list
+%type<en> field field_list
+
+%type<decl> function_array function_declarator function_definition function_no_ptr function_ptr
+
+%type<decl> identifier_parameter_array identifier_parameter_declarator identifier_parameter_function
+%type<decl> identifier_parameter_ptr identifier_list
+
+%type<decl> new_abstract_array new_abstract_declarator_no_tuple new_abstract_declarator_tuple
+%type<decl> new_abstract_function new_abstract_parameter_declaration new_abstract_parameter_list
+%type<decl> new_abstract_ptr new_abstract_tuple
+
+%type<decl> new_array_parameter_1st_dimension
+
+%type<decl> new_context_declaring_list new_declaration new_field_declaring_list
+%type<decl> new_function_declaration new_function_return new_function_specifier
+
+%type<decl> new_identifier_parameter_array new_identifier_parameter_declarator_no_tuple
+%type<decl> new_identifier_parameter_declarator_tuple new_identifier_parameter_ptr
+
+%type<decl> new_parameter_declaration new_parameter_list new_parameter_type_list new_parameter_type_list_opt
+
+%type<decl> new_typedef_declaration new_variable_declaration new_variable_specifier
+
+%type<decl> old_declaration old_declaration_list old_declaration_list_opt old_function_array
+%type<decl> old_function_declarator old_function_no_ptr old_function_ptr
+
+%type<decl> parameter_declaration parameter_list parameter_type_list
+%type<decl> parameter_type_list_opt
+
+%type<decl> paren_identifier paren_typedef
+
+%type<decl> storage_class storage_class_name storage_class_list
+
+%type<decl> sue_declaration_specifier sue_type_specifier
+
+%type<tclass> type_class
+%type<decl> type_declarator type_declarator_name type_declaring_list
+
+%type<decl> typedef typedef_array typedef_declaration typedef_declaration_specifier typedef_expression
+%type<decl> typedef_function typedef_parameter_array typedef_parameter_function typedef_parameter_ptr
+%type<decl> typedef_parameter_redeclarator typedef_ptr typedef_redeclarator typedef_type_specifier
+%type<decl> typegen_declaration_specifier typegen_type_specifier
+
+%type<decl> type_name type_name_no_function
+%type<decl> type_parameter type_parameter_list
+
+%type<en> type_name_list
+
+%type<decl> type_qualifier type_qualifier_name type_qualifier_list type_qualifier_list_opt type_specifier
+
+%type<decl> variable_abstract_array variable_abstract_declarator variable_abstract_function
+%type<decl> variable_abstract_ptr variable_array variable_declarator variable_function variable_ptr
+
+/* initializers */
+%type<in>  initializer initializer_list initializer_opt
+
+/* designators */
+%type<en>  designator designator_list designation
+
+
+/* Handle single shift/reduce conflict for dangling else by shifting the ELSE token. For example, this string
+   is ambiguous:
+   .---------.			matches IF '(' comma_expression ')' statement
+   if ( C ) S1 else S2
+   `-----------------'	matches IF '(' comma_expression ')' statement ELSE statement */
+
+%nonassoc THEN	/* rule precedence for IF '(' comma_expression ')' statement */
+%nonassoc ELSE	/* token precedence for start of else clause in IF statement */
+
+%start translation_unit					/* parse-tree root */
+
+%%
+/************************* Namespace Management ********************************/
+
+/* The grammar in the ANSI C standard is not strictly context-free, since it relies upon the distinct terminal
+   symbols "identifier" and "TYPEDEFname" that are lexically identical.  While it is possible to write a
+   purely context-free grammar, such a grammar would obscure the relationship between syntactic and semantic
+   constructs.  Hence, this grammar uses the ANSI style.
+
+   Cforall compounds this problem by introducing type names local to the scope of a declaration (for instance,
+   those introduced through "forall" qualifiers), and by introducing "type generators" -- parametrized types.
+   This latter type name creates a third class of identifiers that must be distinguished by the scanner.
+
+   Since the scanner cannot distinguish among the different classes of identifiers without some context
+   information, it accesses a data structure (the TypedefTable) to allow classification of an identifier that
+   it has just read.  Semantic actions during the parser update this data structure when the class of
+   identifiers change.
+
+   Because the Cforall language is block-scoped, there is the possibility that an identifier can change its
+   class in a local scope; it must revert to its original class at the end of the block.  Since type names can
+   be local to a particular declaration, each declaration is itself a scope.  This requires distinguishing
+   between type names that are local to the current declaration scope and those that persist past the end of
+   the declaration (i.e., names defined in "typedef" or "type" declarations).
+
+   The non-terminals "push" and "pop" derive the empty string; their only use is to denote the opening and
+   closing of scopes.  Every push must have a matching pop, although it is regrettable the matching pairs do
+   not always occur within the same rule.  These non-terminals may appear in more contexts than strictly
+   necessary from a semantic point of view.  Unfortunately, these extra rules are necessary to prevent parsing
+   conflicts -- the parser may not have enough context and look-ahead information to decide whether a new
+   scope is necessary, so the effect of these extra rules is to open a new scope unconditionally.  As the
+   grammar evolves, it may be neccesary to add or move around "push" and "pop" nonterminals to resolve
+   conflicts of this sort.  */
+
+push:
+		{
+		    typedefTable.enterScope();
+		}
+	;
+
+pop:
+		{
+		    typedefTable.leaveScope();
+		}
+	;
+
+/************************* CONSTANTS ********************************/
+
+constant:
+		/* ENUMERATIONconstant is not included here; it is treated as a variable with type
+		   "enumeration constant". */
+	INTEGERconstant		{ $$ = new ConstantNode(ConstantNode::Integer,   $1); }
+	| FLOATINGconstant	{ $$ = new ConstantNode(ConstantNode::Float,     $1); }
+	| CHARACTERconstant	{ $$ = new ConstantNode(ConstantNode::Character, $1); }
+	;
+
+identifier:
+	IDENTIFIER
+	| ATTR_IDENTIFIER				/* CFA */
+	| zero_one					/* CFA */
+	;
+
+no_01_identifier:
+	IDENTIFIER
+	| ATTR_IDENTIFIER				/* CFA */
+	;
+
+no_attr_identifier:
+	IDENTIFIER
+	;
+
+zero_one:						/* CFA */
+	ZERO
+	| ONE
+	;
+
+string_literal_list:					/* juxtaposed strings are concatenated */
+	STRINGliteral				{ $$ = new ConstantNode(ConstantNode::String, $1); }
+	| string_literal_list STRINGliteral	{ $$ = $1->append( $2 ); }
+	;
+
+/************************* EXPRESSIONS ********************************/
+
+primary_expression:
+	IDENTIFIER					/* typedef name cannot be used as a variable name */
+		{ $$ = new VarRefNode($1); }
+	| zero_one
+		{ $$ = new VarRefNode($1); }
+	| constant
+		{ $$ = $1; }
+	| string_literal_list
+		{ $$ = $1; }
+	| '(' comma_expression ')'
+		{ $$ = $2; }
+	| '(' compound_statement ')'			/* GCC, lambda expression */
+		{ $$ = new ValofExprNode($2); }
+	;
+
+postfix_expression:
+	primary_expression
+	| postfix_expression '[' push assignment_expression pop ']'
+		 /* CFA, comma_expression disallowed in the context because it results in a commom user error:
+		    subscripting a matrix with x[i,j] instead of x[i][j]. While this change is not backwards
+		    compatible, there seems to be 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); }
+	| postfix_expression '(' argument_expression_list ')'
+		{ $$ = new CompositeExprNode($1, $3); }
+	| postfix_expression '.' no_attr_identifier
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::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)); }
+	| postfix_expression ARROW '[' push field_list pop ']' /* CFA, tuple field selector */
+	| postfix_expression ICR
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::IncrPost), $1); }
+	| postfix_expression DECR
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::DecrPost), $1); }
+		/* GCC has priority: cast_expression */
+	| '(' type_name_no_function ')' '{' initializer_list comma_opt '}' /* ANSI99 */
+		{ $$ = 0; }
+	;
+
+argument_expression_list:
+	argument_expression
+	| argument_expression_list ',' argument_expression
+						{ $$ = (ExpressionNode *)($1->set_link($3)); }
+	;
+
+argument_expression:
+	/* empty */					/* use default argument */
+		{ $$ = 0; }
+	| assignment_expression
+	| no_attr_identifier ':' assignment_expression
+                                                { $$ = $3->set_asArgName($1); }
+		/* Only a list of no_attr_identifier_or_typedef_name is allowed in this context. However, there
+		   is insufficient look ahead to distinguish between this list of parameter names and a tuple,
+		   so the tuple form must be used with an appropriate semantic check. */
+	| '[' push assignment_expression pop ']' ':' assignment_expression
+						{ $$ = $7->set_asArgName($3); }
+	| '[' push assignment_expression ',' tuple_expression_list pop ']' ':' assignment_expression
+						{ $$ = $9->set_asArgName(new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)$3->set_link( flattenCommas( $5 )))); }
+	;
+
+field_list:						/* CFA, tuple field selector */
+	field
+	| field_list ',' field                  { $$ = (ExpressionNode *)$1->set_link( $3 ); }
+	;
+
+field:							/* CFA, tuple field selector */
+	no_attr_identifier
+						{ $$ = new VarRefNode( $1 ); }
+	| no_attr_identifier '.' field
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel), new VarRefNode( $1 ), $3); }
+	| no_attr_identifier '.' '[' push field_list pop ']'
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel), new VarRefNode( $1 ), $5); }
+	| no_attr_identifier ARROW field
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel), new VarRefNode( $1 ), $3); }
+	| no_attr_identifier ARROW '[' push field_list pop ']'
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel), new VarRefNode( $1 ), $5); }
+	;
+
+unary_expression:
+	postfix_expression
+	| ICR unary_expression
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Incr), $2); }
+	| DECR unary_expression
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Decr), $2); }
+	| EXTENSION cast_expression			/* GCC */
+		{ $$ = $2; }
+	| unary_operator cast_expression
+		{ $$ = new CompositeExprNode($1, $2); }
+	| '!' cast_expression
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Neg), $2); }
+	| '*' cast_expression				/* CFA */
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PointTo), $2); }
+		/* '*' is is separated from unary_operator because of shift/reduce conflict in:
+			{ * X; } // dereference X
+			{ * int X; } // CFA declaration of pointer to int
+		   '&' must be moved here if C++ reference variables are supported. */
+	| SIZEOF unary_expression
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::SizeOf), $2); }
+	| SIZEOF '(' type_name_no_function ')'
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::SizeOf), new TypeValueNode($3)); }
+	| ATTR_IDENTIFIER
+		{ $$ = 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)); }
+	| 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); }
+	| ALIGNOF '(' type_name_no_function ')'		/* GCC, type alignment */
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::AlignOf), new TypeValueNode($3)); }
+	| ANDAND no_attr_identifier			/* GCC, address of label */
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LabelAddress),
+					     new VarRefNode($2, true)); }
+	;
+
+unary_operator:
+	'&'                               { $$ = new OperatorNode(OperatorNode::AddressOf); }
+	| '+'                             { $$ = new OperatorNode(OperatorNode::UnPlus); }
+	| '-'                             { $$ = new OperatorNode(OperatorNode::UnMinus); }
+	| '~'                             { $$ = new OperatorNode(OperatorNode::BitNeg); }
+	;
+
+cast_expression:
+	unary_expression
+	| '(' type_name_no_function ')' cast_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cast),
+								       new TypeValueNode($2), $4); }
+	| '(' type_name_no_function ')' tuple
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cast),
+								       new TypeValueNode($2), $4); }
+	;
+
+multiplicative_expression:
+	cast_expression
+	| multiplicative_expression '*' cast_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Mul),$1,$3); }
+	| multiplicative_expression '/' cast_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Div),$1,$3); }
+	| multiplicative_expression '%' cast_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Mod),$1,$3); }
+	;
+
+additive_expression:
+	multiplicative_expression
+	| additive_expression '+' multiplicative_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Plus),$1,$3); }
+	| additive_expression '-' multiplicative_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Minus),$1,$3); }
+	;
+
+shift_expression:
+	additive_expression
+	| shift_expression LS additive_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LShift),$1,$3); }
+	| shift_expression RS additive_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::RShift),$1,$3); }
+	;
+
+relational_expression:
+	shift_expression
+	| relational_expression '<' shift_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LThan),$1,$3); }
+	| relational_expression '>' shift_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::GThan),$1,$3); }
+	| relational_expression LE shift_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LEThan),$1,$3); }
+	| relational_expression GE shift_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::GEThan),$1,$3); }
+	;
+
+equality_expression:
+	relational_expression
+	| equality_expression EQ relational_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Eq), $1, $3); }
+	| equality_expression NE relational_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Neq), $1, $3); }
+	;
+
+AND_expression:
+	equality_expression
+	| AND_expression '&' equality_expression
+						{ $$ =new CompositeExprNode(new OperatorNode(OperatorNode::BitAnd), $1, $3); }
+	;
+
+exclusive_OR_expression:
+	AND_expression
+	| exclusive_OR_expression '^' AND_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Xor), $1, $3); }
+	;
+
+inclusive_OR_expression:
+	exclusive_OR_expression
+	| inclusive_OR_expression '|' exclusive_OR_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::BitOr), $1, $3); }
+	;
+
+logical_AND_expression:
+	inclusive_OR_expression
+	| logical_AND_expression ANDAND inclusive_OR_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::And), $1, $3); }
+	;
+
+logical_OR_expression:
+	logical_AND_expression
+	| logical_OR_expression OROR logical_AND_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Or), $1, $3); }
+	;
+
+conditional_expression:
+	logical_OR_expression
+	| logical_OR_expression '?' comma_expression ':' conditional_expression
+						{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cond),
+								       (ExpressionNode *)mkList((*$1,*$3,*$5))); }
+	| logical_OR_expression '?' /* empty */ ':' conditional_expression /* GCC, omitted first operand */
+						{ $$=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 ))); }
+	;
+
+constant_expression:
+	conditional_expression
+	;
+
+assignment_expression:
+		/* CFA, assignment is separated from assignment_operator to ensure no assignment operations
+		   for tuples */
+	conditional_expression
+	| unary_expression '=' assignment_expression
+						{ $$ =new CompositeExprNode(new OperatorNode(OperatorNode::Assign), $1, $3); }
+	| unary_expression assignment_operator assignment_expression
+						{ $$ =new CompositeExprNode($2, $1, $3); }
+	| tuple assignment_opt				/* CFA, tuple expression */
+		{
+		  if( $2 == 0 ) {
+		    $$ = $1;
+		  } else {
+		    $$ = new CompositeExprNode( new OperatorNode( OperatorNode::Assign ), $1, $2 );
+		  }
+		}
+	;
+
+assignment_expression_opt:
+	/* empty */
+		{ $$ = new NullExprNode; }
+	| assignment_expression
+	;
+
+tuple:							/* CFA, tuple */
+		/* CFA, one assignment_expression is factored out of comma_expression to eliminate a
+		   shift/reduce conflict with comma_expression in new_identifier_parameter_array and
+		   new_abstract_array */
+	'[' push pop ']'
+		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ) ); }
+	| '[' push assignment_expression pop ']'
+		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), $3 ); }
+	| '[' push ',' tuple_expression_list pop ']'
+		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)(new NullExprNode)->set_link( $4 ) ); }
+	| '[' push assignment_expression ',' tuple_expression_list pop ']'
+		{ $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)$3->set_link( flattenCommas( $5 ) ) ); }
+	;
+
+tuple_expression_list:
+	assignment_expression_opt
+	| tuple_expression_list ',' assignment_expression_opt
+		{ $$ = (ExpressionNode *)$1->set_link( $3 ); }
+	;
+
+assignment_operator:
+	MULTassign					{ $$ = new OperatorNode(OperatorNode::MulAssn);   }
+	| DIVassign					{ $$ = new OperatorNode(OperatorNode::DivAssn);   }
+	| MODassign					{ $$ = new OperatorNode(OperatorNode::ModAssn);   }
+	| PLUSassign					{ $$ = new OperatorNode(OperatorNode::PlusAssn);  }
+	| MINUSassign					{ $$ = new OperatorNode(OperatorNode::MinusAssn); }
+	| LSassign					{ $$ = new OperatorNode(OperatorNode::LSAssn);    }
+	| RSassign					{ $$ = new OperatorNode(OperatorNode::RSAssn);    }
+	| ANDassign					{ $$ = new OperatorNode(OperatorNode::AndAssn);   }
+	| ERassign					{ $$ = new OperatorNode(OperatorNode::ERAssn);    }
+	| ORassign					{ $$ = new OperatorNode(OperatorNode::OrAssn);    }
+	;
+
+comma_expression:
+	assignment_expression
+	| comma_expression ',' assignment_expression	/* { $$ = (ExpressionNode *)$1->add_to_list($3); } */
+			       { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Comma),$1,$3); }
+	;
+
+comma_expression_opt:
+	/* empty */                                     { $$ = 0; }
+	| comma_expression
+	;
+
+/*************************** STATEMENTS *******************************/
+
+statement:
+	labeled_statement
+	| compound_statement
+	| expression_statement                          { $$ = $1; }
+	| selection_statement
+	| iteration_statement
+	| jump_statement
+	| exception_statement
+	| asm_statement
+	;
+
+labeled_statement:
+	no_attr_identifier ':' attribute_list_opt statement
+		{ $$ = $4->add_label($1);}
+	;
+
+compound_statement:
+	'{' '}'
+		{ $$ = new CompoundStmtNode( (StatementNode *)0 ); }
+	| '{'
+		/* Two scopes are necessary because the block itself has a scope, but every declaration within
+		   the block also requires its own scope */
+	  push push
+	  label_declaration_opt				/* GCC, local labels */
+	  block_item_list pop '}'			/* ANSI99, intermix declarations and statements */
+		{ $$ = new CompoundStmtNode( $5 ); }
+	;
+
+block_item_list:					/* ANSI99 */
+	block_item
+	| block_item_list push block_item
+		{ if($1 != 0) { $1->set_link($3); $$ = $1; } }
+	;
+
+block_item:
+	declaration					/* CFA, new & old style declarations */
+		{ $$ = new StatementNode( $1 ); }
+	| EXTENSION declaration				/* GCC */
+		{ $$ = new StatementNode( $2 ); }
+	| statement pop
+	;
+
+statement_list:
+	statement
+	| statement_list statement
+		{ if($1 != 0) { $1->set_link($2); $$ = $1; } }
+	;
+
+expression_statement:
+	comma_expression_opt ';'
+		{ $$ = new StatementNode(StatementNode::Exp, $1, 0); }
+	;
+
+selection_statement:
+	IF '(' comma_expression ')' statement		%prec THEN
+		/* explicitly deal with the shift/reduce conflict on if/else */
+		{ $$ = new StatementNode(StatementNode::If, $3, $5); }
+	| IF '(' comma_expression ')' statement ELSE statement
+		{ $$ = new StatementNode(StatementNode::If, $3, (StatementNode *)mkList((*$5, *$7)) ); }
+	| SWITCH '(' comma_expression ')' case_clause	/* CFA */
+		{ $$ = new StatementNode(StatementNode::Switch, $3, $5); }
+	| SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' /* CFA */
+		{ $$ = new StatementNode(StatementNode::Switch, $3, $8); /* xxx */ }
+		/* The semantics of the declaration list is changed to include any associated initialization,
+		   which is performed *before* the transfer to the appropriate case clause.  Statements after
+		   the initial declaration list can never be executed, and therefore, are removed from the
+		   grammar even though C allows it. */
+	| CHOOSE '(' comma_expression ')' case_clause	/* CFA */
+		{ $$ = new StatementNode(StatementNode::Choose, $3, $5); }
+	| CHOOSE '(' comma_expression ')' '{' push declaration_list_opt choose_clause_list_opt '}' /* CFA */
+		{ $$ = new StatementNode(StatementNode::Choose, $3, $8); }
+	;
+
+/* CASE and DEFAULT clauses are only allowed in the SWITCH statement, precluding Duff's device. In addition, a
+   case clause allows a list of values and subranges. */
+
+case_value:						/* CFA */
+	constant_expression			{ $$ = $1; }
+	| constant_expression ELLIPSIS constant_expression /* GCC, subrange */
+		{ $$ = new CompositeExprNode(new OperatorNode(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_label:						/* CFA */
+	CASE case_value_list ':'		{  $$ = new StatementNode(StatementNode::Case, $2, 0); }
+	| DEFAULT ':'			        {  $$ = new StatementNode(StatementNode::Default);     }
+		/* A semantic check is required to ensure only one default clause per switch/choose
+		   statement. */
+	;
+
+case_label_list:					/* CFA */
+	case_label
+	| case_label_list case_label            { $$ = (StatementNode *)($1->set_link($2)); }
+	;
+
+case_clause:						/* CFA */
+	case_label_list statement		{  $$ = $1->append_last_case($2); }
+	;
+
+switch_clause_list_opt:					/* CFA */
+	/* empty */				{ $$ = 0; }
+	| switch_clause_list
+	;
+
+switch_clause_list:					/* CFA */
+	case_label_list statement_list
+						{ $$ = $1->append_last_case($2); }
+	| switch_clause_list case_label_list statement_list
+						{ $$ = (StatementNode *)($1->set_link($2->append_last_case($3))); }
+	;
+
+choose_clause_list_opt:					/* CFA */
+	/* empty */				{ $$ = 0; }
+	| choose_clause_list
+	;
+
+choose_clause_list:					/* CFA */
+	case_label_list fall_through
+		  { $$ = $1->append_last_case($2); }
+	| case_label_list statement_list fall_through_opt
+		  { $$ = $1->append_last_case((StatementNode *)mkList((*$2,*$3))); }
+	| choose_clause_list case_label_list fall_through
+		  { $$ = (StatementNode *)($1->set_link($2->append_last_case($3))); }
+	| choose_clause_list case_label_list statement_list fall_through_opt
+		  { $$ = (StatementNode *)($1->set_link($2->append_last_case((StatementNode *)mkList((*$3,*$4))))); }
+	;
+
+fall_through_opt:					/* CFA */
+	/* empty */				{ $$ = 0; }
+	| fall_through
+	;
+
+fall_through:						/* CFA */
+	FALLTHRU				{ $$ = new StatementNode(StatementNode::Fallthru, 0, 0); }
+	| FALLTHRU ';'			        { $$ = new StatementNode(StatementNode::Fallthru, 0, 0); }
+	;
+
+iteration_statement:
+	WHILE '(' comma_expression ')' statement
+						{ $$ = new StatementNode(StatementNode::While, $3, $5); }
+	| DO statement WHILE '(' comma_expression ')' ';'
+						{ $$ = new StatementNode(StatementNode::Do, $5, $2); }
+	| FOR '(' push for_control_expression ')' statement
+						{ $$ = new StatementNode(StatementNode::For, $4, $6); }
+	;
+
+for_control_expression:
+	comma_expression_opt pop ';' comma_expression_opt ';' comma_expression_opt
+						{ $$ = new ForCtlExprNode($1, $4, $6); }
+	| declaration comma_expression_opt ';' comma_expression_opt /* ANSI99 */
+		/* Like C++, the loop index can be declared local to the loop. */
+						{ $$ = new ForCtlExprNode($1, $2, $4); }
+	;
+
+jump_statement:
+	GOTO no_attr_identifier ';'
+						{ $$ = new StatementNode(StatementNode::Goto, $2); }
+	| GOTO '*' comma_expression ';'		/* GCC, computed goto */
+		/* The syntax for the GCC computed goto violates normal expression precedence, e.g.,
+		   goto *i+3; => goto *(i+3); whereas normal operator precedence yields goto (*i)+3; */
+						{ $$ = new StatementNode(StatementNode::Goto, $3); }
+	| CONTINUE ';'
+		/* A semantic check is required to ensure this statement appears only in the body of an
+		   iteration statement. */
+						{ $$ = new StatementNode(StatementNode::Continue, 0, 0); }
+	| CONTINUE no_attr_identifier ';'	/* CFA, multi-level continue */
+		/* A semantic check is required to ensure this statement appears only in the body of an
+		   iteration statement, and the target of the transfer appears only at the start of an
+		   iteration statement. */
+						{ $$ = new StatementNode(StatementNode::Continue, $2); }
+	| BREAK ';'
+		/* A semantic check is required to ensure this statement appears only in the body of an
+		   iteration statement. */
+						{ $$ = new StatementNode(StatementNode::Break, 0, 0); }
+	| BREAK no_attr_identifier ';'	/* CFA, multi-level exit */
+		/* A semantic check is required to ensure this statement appears only in the body of an
+		   iteration statement, and the target of the transfer appears only at the start of an
+		   iteration statement. */
+						{ $$ = new StatementNode(StatementNode::Break, $2 ); }
+	| RETURN comma_expression_opt ';'
+						{ $$ = new StatementNode(StatementNode::Return, $2, 0); }
+	| THROW assignment_expression ';'
+						{ $$ = new StatementNode(StatementNode::Throw, $2, 0); }
+	| THROW ';'
+                                                { $$ = new StatementNode(StatementNode::Throw, 0, 0); }
+	;
+
+exception_statement:
+	TRY compound_statement handler_list
+			     { $$ = new StatementNode(StatementNode::Try, 0,(StatementNode *)(mkList((*$2,*$3)))); }
+	| TRY compound_statement finally_clause
+			     { $$ = new StatementNode(StatementNode::Try, 0,(StatementNode *)(mkList((*$2,*$3)))); }
+	| TRY compound_statement handler_list finally_clause
+                             { 
+			       $3->set_link($4);
+			       $$ = new StatementNode(StatementNode::Try, 0,(StatementNode *)(mkList((*$2,*$3))));
+			     }
+	;
+
+handler_list:
+		/* There must be at least one catch clause */
+	handler_clause
+		/* ISO/IEC 9899:1999 Section 15.3(6) If present, a "..." handler shall be the last handler for
+		   its try block. */
+	| CATCH '(' ELLIPSIS ')' compound_statement
+						{ $$ = StatementNode::newCatchStmt( 0, $5, true ); }
+	| handler_clause CATCH '(' ELLIPSIS ')' compound_statement
+						{ $$ = $1->set_link( StatementNode::newCatchStmt( 0, $6, true ) ); }
+	;
+
+handler_clause:
+	CATCH '(' push push exception_declaration pop ')' compound_statement pop
+						{ $$ = StatementNode::newCatchStmt($5, $8); }
+	| handler_clause CATCH '(' push push exception_declaration pop ')' compound_statement pop
+						{ $$ = $1->set_link( StatementNode::newCatchStmt($6, $9) );   }
+	;
+
+finally_clause:
+	FINALLY compound_statement
+                                                { $$ = new StatementNode(StatementNode::Finally, 0, $2);
+						  std::cout << "Just created a finally node" << std::endl;
+						}
+	;
+
+exception_declaration:
+		/* A semantic check is required to ensure type_specifier does not create a new type, e.g.:
+
+			catch ( struct { int i; } x ) ...
+
+		   This new type cannot catch any thrown type because of name equivalence among types. */
+	type_specifier
+	| type_specifier declarator
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    $$ = $2->addType( $1 );
+		}
+	| type_specifier variable_abstract_declarator
+		{   $$ = $2->addType( $1 ); }
+	| new_abstract_declarator_tuple no_attr_identifier /* CFA */
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    $$ = $1->addName( $2 );
+		}
+	| new_abstract_declarator_tuple			/* CFA */
+	;
+
+asm_statement:
+	ASM type_qualifier_list_opt '(' constant_expression ')' ';'
+						{ $$ = new StatementNode(StatementNode::Asm, 0, 0); }
+	| ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ')' ';' /* remaining GCC */
+						{ $$ = new StatementNode(StatementNode::Asm, 0, 0); }
+	| ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ':' asm_operands_opt ')' ';'
+						{ $$ = new StatementNode(StatementNode::Asm, 0, 0); }
+	| ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ':' asm_operands_opt ':'
+			asm_clobbers_list ')' ';'
+						{ $$ = new StatementNode(StatementNode::Asm, 0, 0); }
+	;
+
+asm_operands_opt:					/* GCC */
+	/* empty */
+	| asm_operands_list
+	;
+
+asm_operands_list:					/* GCC */
+	asm_operand
+	| asm_operands_list ',' asm_operand
+	;
+
+asm_operand:						/* GCC */
+	STRINGliteral '(' constant_expression ')'	{}
+	;
+
+asm_clobbers_list:					/* GCC */
+	STRINGliteral				{}
+	| asm_clobbers_list ',' STRINGliteral
+	;
+
+/******************************* DECLARATIONS *********************************/
+
+declaration_list_opt:					/* used at beginning of switch statement */
+	pop
+		{ $$ = 0; }
+	| declaration_list
+	;
+
+declaration_list:
+	declaration
+	| declaration_list push declaration
+		{ $$ = $1->appendList( $3 ); }
+	;
+
+old_declaration_list_opt:				/* used to declare parameter types in K&R style functions */
+	pop
+		{ $$ = 0; }
+	| old_declaration_list
+	;
+
+old_declaration_list:
+	old_declaration
+	| old_declaration_list push old_declaration
+		{ $$ = $1->appendList( $3 ); }
+	;
+
+label_declaration_opt:					/* GCC, local label */
+	/* empty */
+	| label_declaration_list
+	;
+
+label_declaration_list:					/* GCC, local label */
+	LABEL label_list ';'
+	| label_declaration_list LABEL label_list ';'
+	;
+
+label_list:						/* GCC, local label */
+	no_attr_identifier_or_typedef_name		{}
+	| label_list ',' no_attr_identifier_or_typedef_name {}
+	;
+
+declaration:						/* CFA, new & old style declarations */
+	new_declaration
+	| old_declaration
+	;
+
+/* C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and
+   function declarations. CFA declarations use the same declaration tokens as in C; however, CFA places
+   declaration modifiers to the left of the base type, while C declarations place modifiers to the right of
+   the base type. CFA declaration modifiers are interpreted from left to right and the entire type
+   specification is distributed across all variables in the declaration list (as in Pascal).  ANSI C and the
+   new CFA declarations may appear together in the same program block, but cannot be mixed within a specific
+   declaration.
+
+	    CFA	    	    C
+	[10] int x;	int x[10];	// array of 10 integers
+	[10] * char y;	char *y[10];	// array of 10 pointers to char
+   */
+
+new_declaration:					/* CFA */
+	new_variable_declaration pop ';'
+	| new_typedef_declaration pop ';'
+	| new_function_declaration pop ';'
+	| type_declaring_list pop ';'
+	| context_specifier pop ';'
+	;
+
+new_variable_declaration:				/* CFA */
+	new_variable_specifier initializer_opt
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::ID);
+			$$ = $1;
+		}
+	| declaration_qualifier_list new_variable_specifier initializer_opt
+		/* declaration_qualifier_list also includes type_qualifier_list, so a semantic check is
+		   necessary to preclude them as a type_qualifier cannot appear in that context. */
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::ID);
+			$$ = $2->addQualifiers( $1 );
+		}
+	| new_variable_declaration pop ',' push identifier_or_typedef_name initializer_opt
+		{
+			typedefTable.addToEnclosingScope( *$5, TypedefTable::ID);
+			$$ = $1->appendList( $1->cloneType( $5 ) );
+		}
+	;
+
+new_variable_specifier:					/* CFA */
+		/* A semantic check is required to ensure asm_name only appears on declarations with implicit
+		   or explicit static storage-class */
+	new_abstract_declarator_no_tuple identifier_or_typedef_name asm_name_opt
+		{
+			typedefTable.setNextIdentifier( *$2 );
+			$$ = $1->addName( $2 );
+		}
+	| new_abstract_tuple identifier_or_typedef_name asm_name_opt
+		{
+			typedefTable.setNextIdentifier( *$2 );
+			$$ = $1->addName( $2 );
+		}
+	| type_qualifier_list new_abstract_tuple identifier_or_typedef_name asm_name_opt
+		{
+			typedefTable.setNextIdentifier( *$3 );
+			$$ = $2->addQualifiers( $1 )->addName( $3 );
+		}
+	;
+
+new_function_declaration:				/* CFA */
+	new_function_specifier
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::ID);
+			$$ = $1;
+		}
+	| declaration_qualifier_list new_function_specifier
+		/* declaration_qualifier_list also includes type_qualifier_list, so a semantic check is
+		   necessary to preclude them as a type_qualifier cannot appear in this context. */
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::ID);
+			$$ = $2->addQualifiers( $1 );
+		}
+	| new_function_declaration pop ',' push identifier_or_typedef_name
+		{
+			typedefTable.addToEnclosingScope( *$5, TypedefTable::ID);
+			$$ = $1->appendList( $1->cloneType( $5 ) );
+		}
+	;
+
+new_function_specifier:					/* CFA */
+	'[' push pop ']' identifier '(' push new_parameter_type_list_opt pop ')'
+		{
+			typedefTable.setNextIdentifier( *($5) );
+			$$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
+		}
+	| '[' push pop ']' TYPEDEFname '(' push new_parameter_type_list_opt pop ')'
+		{
+			typedefTable.setNextIdentifier( *($5) );
+			$$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
+		}
+		/* identifier_or_typedef_name must be broken apart because of the sequence:
+
+		   '[' ']' identifier_or_typedef_name '(' new_parameter_type_list_opt ')'
+		   '[' ']' type_specifier
+
+		   type_specifier can resolve to just TYPEDEFname (e.g. typedef int T; int f( T );). Therefore
+		   this must be flattened to allow lookahead to the '(' without having to reduce
+		   identifier_or_typedef_name. */
+	| new_abstract_tuple identifier_or_typedef_name '(' push new_parameter_type_list_opt pop ')'
+		/* To obtain LR(1), this rule must be factored out from function return type (see
+		   new_abstract_declarator). */
+		{
+			$$ = DeclarationNode::newFunction( $2, $1, $5, 0, true );
+		}
+	| new_function_return identifier_or_typedef_name '(' push new_parameter_type_list_opt pop ')'
+		{
+			$$ = DeclarationNode::newFunction( $2, $1, $5, 0, true );
+		}
+	;
+
+new_function_return:					/* CFA */
+	'[' push new_parameter_list pop ']'
+		{ $$ = DeclarationNode::newTuple( $3 ); }
+	| '[' push new_parameter_list pop ',' push new_abstract_parameter_list pop ']'
+		/* To obtain LR(1), the last new_abstract_parameter_list is added into this flattened rule to
+		   lookahead to the ']'. */
+		{ $$ = DeclarationNode::newTuple( $3->appendList( $7 ) ); }
+	;
+
+new_typedef_declaration:				/* CFA */
+	TYPEDEF new_variable_specifier
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::TD);
+			$$ = $2->addTypedef();
+		}
+	| TYPEDEF new_function_specifier
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::TD);
+			$$ = $2->addTypedef();
+		}
+	| new_typedef_declaration pop ',' push no_attr_identifier
+		{
+			typedefTable.addToEnclosingScope( *$5, TypedefTable::TD);
+			$$ = $1->appendList( $1->cloneType( $5 ) );
+		}
+	;
+
+/* Traditionally typedef is part of storage-class specifier for syntactic convenience only. Here, it is
+   factored out as a separate form of declaration, which syntactically precludes storage-class specifiers and
+   initialization. */
+
+typedef_declaration:
+	TYPEDEF type_specifier declarator
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::TD);
+			$$ = $3->addType( $2 )->addTypedef();
+		}
+	| typedef_declaration pop ',' push declarator
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::TD);
+			$$ = $1->appendList( $1->cloneBaseType( $5 )->addTypedef() );
+		}
+	| type_qualifier_list TYPEDEF type_specifier declarator /* remaining OBSOLESCENT (see 2) */
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::TD);
+			$$ = $4->addType( $3 )->addQualifiers( $1 )->addTypedef();
+		}
+	| type_specifier TYPEDEF declarator
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::TD);
+			$$ = $3->addType( $1 )->addTypedef();
+		}
+	| type_specifier TYPEDEF type_qualifier_list declarator
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::TD);
+			$$ = $4->addQualifiers($1)->addTypedef()->addType($1);
+		}
+	;
+
+typedef_expression:					/* GCC, naming expression type */
+	TYPEDEF no_attr_identifier '=' assignment_expression
+		{
+			typedefTable.addToEnclosingScope(*($2), TypedefTable::TD);
+			$$ = DeclarationNode::newName( 0 ); // XXX
+		}
+	| typedef_expression pop ',' push no_attr_identifier '=' assignment_expression
+		{
+			typedefTable.addToEnclosingScope(*($5), TypedefTable::TD);
+			$$ = DeclarationNode::newName( 0 ); // XXX
+		}
+	;
+
+old_declaration:
+	declaring_list pop ';'
+	| typedef_declaration pop ';'
+	| typedef_expression pop ';'			/* GCC, naming expression type */
+	| sue_declaration_specifier pop ';'
+	;
+
+declaring_list:
+		/* A semantic check is required to ensure asm_name only appears on declarations with implicit
+		   or explicit static storage-class */
+	declaration_specifier declarator asm_name_opt initializer_opt
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::ID);
+			$$ = ($2->addType( $1 ))->addInitializer($4);
+		}
+	| declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt
+		{
+			typedefTable.addToEnclosingScope( TypedefTable::ID);
+			$$ = $1->appendList( $1->cloneBaseType( $4->addInitializer($6) ) );
+		}
+	;
+
+declaration_specifier:					/* type specifier + storage class */
+	basic_declaration_specifier
+	| sue_declaration_specifier
+	| typedef_declaration_specifier
+	| typegen_declaration_specifier
+	;
+
+type_specifier:						/* declaration specifier - storage class */
+	basic_type_specifier
+	| sue_type_specifier
+	| typedef_type_specifier
+	| typegen_type_specifier
+	;
+
+type_qualifier_list_opt:				/* GCC, used in asm_statement */
+	/* empty */
+		{ $$ = 0; }
+	| type_qualifier_list
+	;
+
+type_qualifier_list:
+		/* A semantic check is necessary to ensure a type qualifier is appropriate for the kind of
+		   declaration.
+
+		   ISO/IEC 9899:1999 Section 6.7.3(4) : If the same qualifier appears more than once in the
+		   same specifier-qualifier-list, either directly or via one or more typedefs, the behavior is
+		   the same as if it appeared only once. */
+	type_qualifier
+	| type_qualifier_list type_qualifier
+		{ $$ = $1->addQualifiers( $2 ); }
+	;
+
+type_qualifier:
+	type_qualifier_name
+	| attribute
+		{ $$ = DeclarationNode::newQualifier( DeclarationNode::Const ); }
+	;
+
+type_qualifier_name:
+	CONST
+		{ $$ = DeclarationNode::newQualifier( DeclarationNode::Const ); }
+	| RESTRICT
+		{ $$ = DeclarationNode::newQualifier( DeclarationNode::Restrict ); }
+	| VOLATILE
+		{ $$ = DeclarationNode::newQualifier( DeclarationNode::Volatile ); }
+	| LVALUE					/* CFA */
+		{ $$ = DeclarationNode::newQualifier( DeclarationNode::Lvalue ); }
+	| FORALL '(' 
+		{
+			typedefTable.enterScope();
+		}
+	  type_parameter_list ')'		/* CFA */
+		{
+			typedefTable.leaveScope();
+			$$ = DeclarationNode::newForall( $4 );
+		}
+	;
+
+declaration_qualifier_list:
+	storage_class_list
+	| type_qualifier_list storage_class_list	/* remaining OBSOLESCENT (see 2) */
+		{ $$ = $1->addQualifiers( $2 ); }
+	| declaration_qualifier_list type_qualifier_list storage_class_list
+		{ $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
+	;
+
+storage_class_list:
+		/* A semantic check is necessary to ensure a storage class is appropriate for the kind of
+		   declaration and that only one of each is specified, except for inline, which can appear
+		   with the others.
+
+		   ISO/IEC 9899:1999 Section 6.7.1(2) : At most, one storage-class specifier may be given in
+		   the declaration specifiers in a declaration. */
+	storage_class
+	| storage_class_list storage_class
+		{ $$ = $1->addQualifiers( $2 ); }
+	;
+
+storage_class:
+	storage_class_name
+	;
+
+storage_class_name:
+	AUTO
+		{ $$ = DeclarationNode::newStorageClass( DeclarationNode::Auto ); }
+	| EXTERN
+		{ $$ = DeclarationNode::newStorageClass( DeclarationNode::Extern ); }
+	| REGISTER
+		{ $$ = DeclarationNode::newStorageClass( DeclarationNode::Register ); }
+	| STATIC
+		{ $$ = DeclarationNode::newStorageClass( DeclarationNode::Static ); }
+	| INLINE					/* ANSI99 */
+		/* INLINE is essentially a storage class specifier for functions, and hence, belongs here. */
+		{ $$ = DeclarationNode::newStorageClass( DeclarationNode::Inline ); }
+	| FORTRAN					/* ANSI99 */
+		{ $$ = DeclarationNode::newStorageClass( DeclarationNode::Fortran ); }
+	;
+
+basic_type_name:
+	CHAR
+		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Char ); }
+	| DOUBLE
+		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Double ); }
+	| FLOAT
+		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Float ); }
+	| INT
+		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Int ); }
+	| LONG
+		{ $$ = DeclarationNode::newModifier( DeclarationNode::Long ); }
+	| SHORT
+		{ $$ = DeclarationNode::newModifier( DeclarationNode::Short ); }
+	| SIGNED
+		{ $$ = DeclarationNode::newModifier( DeclarationNode::Signed ); }
+	| UNSIGNED
+		{ $$ = DeclarationNode::newModifier( DeclarationNode::Unsigned ); }
+	| VOID
+		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Void ); }
+	| BOOL						/* ANSI99 */
+		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Bool ); }
+	| COMPLEX					/* ANSI99 */
+		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Complex ); }
+	| IMAGINARY					/* ANSI99 */
+		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Imaginary ); }
+	;
+
+basic_declaration_specifier:
+		/* A semantic check is necessary for conflicting storage classes. */
+	basic_type_specifier
+	| declaration_qualifier_list basic_type_specifier
+		{ $$ = $2->addQualifiers( $1 ); }
+	| basic_declaration_specifier storage_class	/* remaining OBSOLESCENT (see 2) */
+		{ $$ = $1->addQualifiers( $2 ); }
+	| basic_declaration_specifier storage_class type_qualifier_list
+		{ $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
+	| basic_declaration_specifier storage_class basic_type_specifier
+		{ $$ = $3->addQualifiers( $2 )->addType( $1 ); }
+	;
+
+basic_type_specifier:
+	direct_type_name
+	| type_qualifier_list_opt indirect_type_name type_qualifier_list_opt
+		{ $$ = $2->addQualifiers( $1 )->addQualifiers( $3 ); }
+	;
+
+direct_type_name:
+		/* A semantic check is necessary for conflicting type qualifiers. */
+	basic_type_name
+	| type_qualifier_list basic_type_name
+		{ $$ = $2->addQualifiers( $1 ); }
+	| direct_type_name type_qualifier
+		{ $$ = $1->addQualifiers( $2 ); }
+	| direct_type_name basic_type_name
+		{ $$ = $1->addType( $2 ); }
+	;
+
+indirect_type_name:
+	TYPEOF '(' type_name ')'			/* GCC: typeof(x) y; */
+		{ $$ = $3; }
+	| TYPEOF '(' comma_expression ')'		/* GCC: typeof(a+b) y; */
+		{ $$ = DeclarationNode::newTypeof( $3 ); }
+	| ATTR_TYPEGENname '(' type_name ')'		/* CFA: e.g., @type(x) y; */
+		{ $$ = DeclarationNode::newAttr( $1, $3 ); }
+	| ATTR_TYPEGENname '(' comma_expression ')' 	/* CFA: e.g., @type(a+b) y; */
+		{ $$ = DeclarationNode::newAttr( $1, $3 ); }
+	;
+
+sue_declaration_specifier:
+	sue_type_specifier
+	| declaration_qualifier_list sue_type_specifier
+		{ $$ = $2->addQualifiers( $1 ); }
+	| sue_declaration_specifier storage_class	/* remaining OBSOLESCENT (see 2) */
+		{ $$ = $1->addQualifiers( $2 ); }
+	| sue_declaration_specifier storage_class type_qualifier_list
+		{ $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
+	;
+
+sue_type_specifier:
+	elaborated_type_name				/* struct, union, enum */
+	| type_qualifier_list elaborated_type_name
+		{ $$ = $2->addQualifiers( $1 ); }
+	| sue_type_specifier type_qualifier
+		{ $$ = $1->addQualifiers( $2 ); }
+	;
+
+typedef_declaration_specifier:
+	typedef_type_specifier
+	| declaration_qualifier_list typedef_type_specifier
+		{ $$ = $2->addQualifiers( $1 ); }
+	| typedef_declaration_specifier storage_class	/* remaining OBSOLESCENT (see 2) */
+		{ $$ = $1->addQualifiers( $2 ); }
+	| typedef_declaration_specifier storage_class type_qualifier_list
+		{ $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
+	;
+
+typedef_type_specifier:					/* typedef types */
+	TYPEDEFname
+		{ $$ = DeclarationNode::newFromTypedef( $1 ); }
+	| type_qualifier_list TYPEDEFname
+		{ $$ = DeclarationNode::newFromTypedef( $2 )->addQualifiers( $1 ); }
+	| typedef_type_specifier type_qualifier
+		{ $$ = $1->addQualifiers( $2 ); }
+	;
+
+elaborated_type_name:
+	aggregate_name
+	| enum_name
+	;
+
+aggregate_name:
+	aggregate_key '{' field_declaration_list '}'
+		{ $$ = DeclarationNode::newAggregate( $1, 0, 0, 0, $3 ); }
+	| aggregate_key no_attr_identifier_or_typedef_name
+		{ $$ = DeclarationNode::newAggregate( $1, $2, 0, 0, 0 ); }
+	| aggregate_key no_attr_identifier_or_typedef_name '{' field_declaration_list '}'
+		{ $$ = DeclarationNode::newAggregate( $1, $2, 0, 0, $4 ); }
+	| aggregate_key '(' push type_parameter_list pop ')' '{' field_declaration_list '}' /* CFA */
+		{ $$ = DeclarationNode::newAggregate( $1, 0, $4, 0, $8 ); }
+	| aggregate_key '(' push type_parameter_list pop ')' no_attr_identifier_or_typedef_name /* CFA */
+		{ $$ = DeclarationNode::newAggregate( $1, $7, $4, 0, 0 ); }
+	| aggregate_key '(' push type_parameter_list pop ')' no_attr_identifier_or_typedef_name '{' field_declaration_list '}' /* CFA */
+		{ $$ = DeclarationNode::newAggregate( $1, $7, $4, 0, $9 ); }
+	| aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' '{' field_declaration_list '}' /* CFA */
+		{ $$ = DeclarationNode::newAggregate( $1, 0, $4, $8, $11 ); }
+	| aggregate_key '(' push type_name_list pop ')' no_attr_identifier_or_typedef_name /* CFA */
+		/* push and pop are only to prevent S/R conflicts */
+		{ $$ = DeclarationNode::newAggregate( $1, $7, 0, $4, 0 ); }
+	| aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' no_attr_identifier_or_typedef_name '{' field_declaration_list '}' /* CFA */
+		{ $$ = DeclarationNode::newAggregate( $1, $10, $4, $8, $12 ); }
+	;
+
+aggregate_key:
+	STRUCT attribute_list_opt
+		{ $$ = DeclarationNode::Struct; }
+	| UNION attribute_list_opt
+		{ $$ = DeclarationNode::Union; }
+	;
+
+field_declaration_list:
+	field_declaration
+		{ $$ = $1; }
+	| field_declaration_list field_declaration
+		{ $$ = $1->appendList( $2 ); }
+	;
+
+field_declaration:
+	new_field_declaring_list ';'			/* CFA, new style field declaration */
+	| EXTENSION new_field_declaring_list ';'	/* GCC */
+		{ $$ = $2; }
+	| field_declaring_list ';'
+	| EXTENSION field_declaring_list ';'		/* GCC */
+		{ $$ = $2; }
+	;
+
+new_field_declaring_list:				/* CFA, new style field declaration */
+	new_abstract_declarator_tuple			/* CFA, no field name */
+	| new_abstract_declarator_tuple no_attr_identifier_or_typedef_name
+		{ $$ = $1->addName( $2 ); }
+	| new_field_declaring_list ',' no_attr_identifier_or_typedef_name
+		{ $$ = $1->appendList( $1->cloneType( $3 ) ); }
+	| new_field_declaring_list ','			/* CFA, no field name */
+		{ $$ = $1->appendList( $1->cloneType( 0 ) ); }
+	;
+
+field_declaring_list:
+	type_specifier field_declarator
+		{ $$ = $2->addType( $1 ); }
+	| field_declaring_list ',' attribute_list_opt field_declarator
+		{ $$ = $1->appendList( $1->cloneBaseType( $4 ) ); }
+	;
+
+field_declarator:
+	/* empty */					/* CFA, no field name */
+		{ $$ = DeclarationNode::newName( 0 ); /* XXX */ }
+	| bit_subrange_size				/* no field name */
+		{ $$ = DeclarationNode::newBitfield( $1 ); }
+	| variable_declarator bit_subrange_size_opt
+		/* A semantic check is required to ensure bit_subrange only appears on base type int. */
+		{ $$ = $1->addBitfield( $2 ); }
+	| typedef_redeclarator bit_subrange_size_opt
+		/* A semantic check is required to ensure bit_subrange only appears on base type int. */
+		{ $$ = $1->addBitfield( $2 ); }
+	| variable_abstract_declarator			/* CFA, no field name */
+	;
+
+bit_subrange_size_opt:
+	/* empty */
+		{ $$ = 0; }
+	| bit_subrange_size
+		{ $$ = $1; }
+	;
+
+bit_subrange_size:
+	':' constant_expression
+		{ $$ = $2; }
+	;
+
+enum_key:
+	ENUM attribute_list_opt
+	;
+
+enum_name:
+	enum_key '{' enumerator_list comma_opt '}'
+		{ $$ = DeclarationNode::newEnum( 0, $3 ); }
+	| enum_key no_attr_identifier_or_typedef_name '{' enumerator_list comma_opt '}'
+		{ $$ = DeclarationNode::newEnum( $2, $4 ); }
+	| enum_key no_attr_identifier_or_typedef_name
+		{ $$ = DeclarationNode::newEnum( $2, 0 ); }
+	;
+
+enumerator_list:
+	no_attr_identifier_or_typedef_name enumerator_value_opt
+		{ $$ = DeclarationNode::newEnumConstant( $1, $2 ); }
+	| enumerator_list ',' no_attr_identifier_or_typedef_name enumerator_value_opt
+		{ $$ = $1->appendList( DeclarationNode::newEnumConstant( $3, $4 ) ); }
+	;
+
+enumerator_value_opt:
+	/* empty */
+		{ $$ = 0; }
+	| '=' constant_expression
+		{ $$ = $2; }
+	;
+
+/* Minimum of one parameter after which ellipsis is allowed only at the end. */
+
+new_parameter_type_list_opt:				/* CFA */
+	/* empty */
+		{ $$ = 0; }
+	| new_parameter_type_list
+	;
+
+new_parameter_type_list:				/* CFA, abstract + real */
+	new_abstract_parameter_list
+	| new_parameter_list
+	| new_parameter_list pop ',' push new_abstract_parameter_list
+		{ $$ = $1->appendList( $5 ); }
+	| new_abstract_parameter_list pop ',' push ELLIPSIS
+		{ $$ = $1->addVarArgs(); }
+	| new_parameter_list pop ',' push ELLIPSIS
+		{ $$ = $1->addVarArgs(); }
+	;
+
+new_parameter_list:					/* CFA */
+		/* To obtain LR(1) between new_parameter_list and new_abstract_tuple, the last
+		   new_abstract_parameter_list is factored out from new_parameter_list, flattening the rules
+		   to get lookahead to the ']'. */
+	new_parameter_declaration
+	| new_abstract_parameter_list pop ',' push new_parameter_declaration
+		{ $$ = $1->appendList( $5 ); }
+	| new_parameter_list pop ',' push new_parameter_declaration
+		{ $$ = $1->appendList( $5 ); }
+	| new_parameter_list pop ',' push new_abstract_parameter_list pop ',' push new_parameter_declaration
+		{ $$ = $1->appendList( $5 )->appendList( $9 ); }
+	;
+
+new_abstract_parameter_list:				/* CFA, new & old style abstract */
+	new_abstract_parameter_declaration
+	| new_abstract_parameter_list pop ',' push new_abstract_parameter_declaration
+		{ $$ = $1->appendList( $5 ); }
+	;
+
+parameter_type_list_opt:
+	/* empty */
+		{ $$ = 0; }
+	| parameter_type_list
+	;
+
+parameter_type_list:
+	parameter_list
+	| parameter_list pop ',' push ELLIPSIS
+		{ $$ = $1->addVarArgs(); }
+	;
+
+parameter_list:						/* abstract + real */
+	abstract_parameter_declaration
+	| parameter_declaration
+	| parameter_list pop ',' push abstract_parameter_declaration
+		{ $$ = $1->appendList( $5 ); }
+	| parameter_list pop ',' push parameter_declaration
+		{ $$ = $1->appendList( $5 ); }
+	;
+
+/* Provides optional identifier names (abstract_declarator/variable_declarator), no initialization, different
+   semantics for typedef name by using typedef_parameter_redeclarator instead of typedef_redeclarator, and
+   function prototypes. */
+
+new_parameter_declaration:				/* CFA, new & old style parameter declaration */
+	parameter_declaration
+	| new_identifier_parameter_declarator_no_tuple identifier_or_typedef_name assignment_opt
+		{ $$ = $1->addName( $2 ); }
+	| new_abstract_tuple identifier_or_typedef_name assignment_opt
+		/* To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator). */
+		{ $$ = $1->addName( $2 ); }
+	| type_qualifier_list new_abstract_tuple identifier_or_typedef_name assignment_opt
+		{ $$ = $2->addName( $3 )->addQualifiers( $1 ); }
+	| new_function_specifier
+	;
+
+new_abstract_parameter_declaration:			/* CFA, new & old style parameter declaration */
+	abstract_parameter_declaration
+	| new_identifier_parameter_declarator_no_tuple
+	| new_abstract_tuple
+		/* To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator). */
+	| type_qualifier_list new_abstract_tuple
+		{ $$ = $2->addQualifiers( $1 ); }
+	| new_abstract_function
+	;
+
+parameter_declaration:
+	declaration_specifier identifier_parameter_declarator assignment_opt
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID);
+		    $$ = $2->addType( $1 )->addInitializer( new InitializerNode($3) );
+		}
+	| declaration_specifier typedef_parameter_redeclarator assignment_opt
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID);
+		    $$ = $2->addType( $1 )->addInitializer( new InitializerNode($3) );
+		}
+	;
+
+abstract_parameter_declaration:
+	declaration_specifier
+	| declaration_specifier abstract_parameter_declarator
+		{ $$ = $2->addType( $1 ); }
+	;
+
+/* ISO/IEC 9899:1999 Section 6.9.1(6) : "An identifier declared as a typedef name shall not be redeclared as a
+   parameter." Because the scope of the K&R-style parameter-list sees the typedef first, the following is
+   based only on identifiers.  The ANSI-style parameter-list can redefine a typedef name. */
+
+identifier_list:					/* K&R-style parameter list => no types */
+	no_attr_identifier
+		{ $$ = DeclarationNode::newName( $1 ); }
+	| identifier_list ',' no_attr_identifier
+		{ $$ = $1->appendList( DeclarationNode::newName( $3 ) ); }
+	;
+
+identifier_or_typedef_name:
+	identifier
+	| TYPEDEFname
+	| TYPEGENname
+	;
+
+no_01_identifier_or_typedef_name:
+	no_01_identifier
+	| TYPEDEFname
+	| TYPEGENname
+	;
+
+no_attr_identifier_or_typedef_name:
+	no_attr_identifier
+	| TYPEDEFname
+	| TYPEGENname
+	;
+
+type_name_no_function:					/* sizeof, alignof, cast (constructor) */
+	new_abstract_declarator_tuple			/* CFA */
+	| type_specifier
+	| type_specifier variable_abstract_declarator
+		{ $$ = $2->addType( $1 ); }
+	;
+
+type_name:						/* typeof, assertion */
+	new_abstract_declarator_tuple			/* CFA */
+	| new_abstract_function				/* CFA */
+	| type_specifier
+	| type_specifier abstract_declarator
+		{ $$ = $2->addType( $1 ); }
+	;
+
+initializer_opt:
+	/* empty */                             { $$ = 0; }
+	| '=' initializer                       { $$ = $2; }
+	;
+
+initializer:
+	assignment_expression			{ $$ = new InitializerNode($1); }
+	| '{' initializer_list comma_opt '}'    { $$ = new InitializerNode($2, true); }
+	;
+
+initializer_list:
+	initializer
+	| designation initializer                            { $$ = $2->set_designators( $1 ); }
+	| initializer_list ',' initializer                   { $$ = (InitializerNode *)( $1->set_link($3) ); }
+	| initializer_list ',' designation initializer
+					   { $$ = (InitializerNode *)( $1->set_link( $4->set_designators($3) ) ); }
+	;
+
+/* There is an unreconcileable parsing problem between ANSI99 and CFA with respect to designators. The problem
+   is use of '=' to separator the designator from the initializer value, as in:
+
+	int x[10] = { [1] = 3 };
+
+   The string "[1] = 3" can be parsed as a designator assignment or a tuple assignment.  To disambiguate this
+   case, CFA changes the syntax from "=" to ":" as the separator between the designator and initializer. GCC
+   does uses ":" for field selection. The optional use of the "=" in GCC, or in this case ":", cannot be
+   supported either due to shift/reduce conflicts */
+
+designation:
+	designator_list ':'				/* ANSI99, CFA uses ":" instead of "=" */
+	| no_attr_identifier_or_typedef_name ':'		/* GCC, field name */
+						       { $$ = new VarRefNode( $1 ); }
+	;
+
+designator_list:					/* ANSI99 */
+	designator
+	| designator_list designator                   { $$ = (ExpressionNode *)($1->set_link( $2 )); }
+	;
+
+designator:
+	'.' no_attr_identifier_or_typedef_name		/* ANSI99, field name */
+						       { $$ = new VarRefNode( $2 ); }
+	| '[' push assignment_expression pop ']'	/* ANSI99, single array element */
+		/* assignment_expression used instead of constant_expression because of shift/reduce conflicts
+		   with tuple. */
+						       { $$ = $3; }
+	| '[' push subrange pop ']'			/* CFA, multiple array elements */
+						       { $$ = $3; }
+	| '[' push constant_expression ELLIPSIS constant_expression pop ']' /* GCC, multiple array elements */
+						       { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range), $3, $5); }
+	| '.' '[' push field_list pop ']'		/* CFA, tuple field selector */
+						       { $$ = $4; }
+	;
+
+/* The CFA type system is based on parametric polymorphism, the ability to declare functions with type
+   parameters, rather than an object-oriented type system. This required four groups of extensions:
+
+   Overloading: function, data, and operator identifiers may be overloaded.
+
+   Type declarations: "type" is used to generate new types for declaring objects. Similarly, "dtype" is used
+       for object and incomplete types, and "ftype" is used for function types. Type declarations with
+       initializers provide definitions of new types. Type declarations with storage class "extern" provide
+       opaque types.
+
+   Polymorphic functions: A forall clause declares a type parameter. The corresponding argument is inferred at
+       the call site. A polymorphic function is not a template; it is a function, with an address and a type.
+
+   Specifications and Assertions: Specifications are collections of declarations parameterized by one or more
+       types. They serve many of the purposes of abstract classes, and specification hierarchies resemble
+       subclass hierarchies. Unlike classes, they can define relationships between types.  Assertions declare
+       that a type or types provide the operations declared by a specification.  Assertions are normally used
+       to declare requirements on type arguments of polymorphic functions.  */
+
+typegen_declaration_specifier:				/* CFA */
+	typegen_type_specifier
+	| declaration_qualifier_list typegen_type_specifier
+		{ $$ = $2->addQualifiers( $1 ); }
+	| typegen_declaration_specifier storage_class	/* remaining OBSOLESCENT (see 2) */
+		{ $$ = $1->addQualifiers( $2 ); }
+	| typegen_declaration_specifier storage_class type_qualifier_list
+		{ $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
+	;
+
+typegen_type_specifier:					/* CFA */
+	TYPEGENname '(' type_name_list ')'
+		{ $$ = DeclarationNode::newFromTypeGen( $1, $3 ); }
+	| type_qualifier_list TYPEGENname '(' type_name_list ')'
+		{ $$ = DeclarationNode::newFromTypeGen( $2, $4 )->addQualifiers( $1 ); }
+	| typegen_type_specifier type_qualifier
+		{ $$ = $1->addQualifiers( $2 ); }
+	;
+
+type_parameter_list:					/* CFA */
+	type_parameter assignment_opt
+	| type_parameter_list ',' type_parameter assignment_opt
+		{ $$ = $1->appendList( $3 ); }
+	;
+
+type_parameter:						/* CFA */
+	type_class no_attr_identifier_or_typedef_name
+		{ typedefTable.addToEnclosingScope(*($2), TypedefTable::TD); }
+	  assertion_list_opt
+		{ $$ = DeclarationNode::newTypeParam( $1, $2 )->addAssertions( $4 ); }
+	| type_specifier identifier_parameter_declarator
+	;
+
+type_class:						/* CFA */
+	TYPE
+		{ $$ = DeclarationNode::Type; }
+	| DTYPE
+		{ $$ = DeclarationNode::Ftype; }
+	| FTYPE
+		{ $$ = DeclarationNode::Dtype; }
+	;
+
+assertion_list_opt:					/* CFA */
+	/* empty */
+		{ $$ = 0; }
+	| assertion_list_opt assertion
+		{ $$ = $1 == 0 ? $2 : $1->appendList( $2 ); }
+	;
+
+assertion:						/* CFA */
+	'|' no_attr_identifier_or_typedef_name '(' type_name_list ')'
+		{
+		    typedefTable.openContext( *($2) );
+		    $$ = DeclarationNode::newContextUse( $2, $4 );
+		}
+	| '|' '{' push context_declaration_list '}'
+		{ $$ = $4; }
+	| '|' '(' push type_parameter_list pop ')' '{' push context_declaration_list '}' '(' type_name_list ')'
+		{ $$ = 0; }
+	;
+
+type_name_list:						/* CFA */
+	type_name
+		{ $$ = new TypeValueNode( $1 ); }
+	| assignment_expression
+	| type_name_list ',' type_name
+		{ $$ = (ExpressionNode *)($1->set_link(new TypeValueNode( $3 ))); }
+	| type_name_list ',' assignment_expression
+		{ $$ = (ExpressionNode *)($1->set_link($3)); }
+	;
+
+type_declaring_list:					/* CFA */
+	TYPE type_declarator
+		{ $$ = $2; }
+	| storage_class_list TYPE type_declarator
+		{ $$ = $3->addQualifiers( $1 ); }
+	| type_declaring_list ',' type_declarator
+		{ $$ = $1->appendList( $3->copyStorageClasses( $1 ) ); }
+	;
+
+type_declarator:					/* CFA */
+	type_declarator_name assertion_list_opt
+		{ $$ = $1->addAssertions( $2 ); }
+	| type_declarator_name assertion_list_opt '=' type_name
+		{ $$ = $1->addAssertions( $2 )->addType( $4 ); }
+	;
+
+type_declarator_name:					/* CFA */
+	no_attr_identifier_or_typedef_name
+		{
+		    typedefTable.addToEnclosingScope(*($1), TypedefTable::TD);
+		    $$ = DeclarationNode::newTypeDecl( $1, 0 );
+		}
+	| no_01_identifier_or_typedef_name '(' push type_parameter_list pop ')'
+		{
+		    typedefTable.addToEnclosingScope(*($1), TypedefTable::TG);
+		    $$ = DeclarationNode::newTypeDecl( $1, $4 );
+		}
+	;
+
+context_specifier:					/* CFA */
+	CONTEXT no_attr_identifier_or_typedef_name '(' push type_parameter_list pop ')' '{' '}'
+		{
+		    typedefTable.addToEnclosingScope(*($2), TypedefTable::ID);
+		    $$ = DeclarationNode::newContext( $2, $5, 0 );
+		}
+	| CONTEXT no_attr_identifier_or_typedef_name '(' push type_parameter_list pop ')' '{'
+		{
+		    typedefTable.enterContext( *($2) );
+		    typedefTable.enterScope();
+		}
+	  context_declaration_list '}'
+		{
+		    typedefTable.leaveContext();
+		    typedefTable.addToEnclosingScope(*($2), TypedefTable::ID);
+		    $$ = DeclarationNode::newContext( $2, $5, $10 );
+		}
+	;
+
+context_declaration_list:				/* CFA */
+	context_declaration
+	| context_declaration_list push context_declaration
+		{ $$ = $1->appendList( $3 ); }
+	;
+
+context_declaration:					/* CFA */
+	new_context_declaring_list pop ';'
+	| context_declaring_list pop ';'
+	;
+
+new_context_declaring_list:				/* CFA */
+	new_variable_specifier
+		{
+		    typedefTable.addToEnclosingScope2( TypedefTable::ID );
+		    $$ = $1;
+		}
+	| new_function_specifier
+		{
+		    typedefTable.addToEnclosingScope2( TypedefTable::ID );
+		    $$ = $1;
+		}
+	| new_context_declaring_list pop ',' push identifier_or_typedef_name
+		{
+		    typedefTable.addToEnclosingScope2( *($5), TypedefTable::ID );
+		    $$ = $1->appendList( $1->cloneType( $5 ) );
+		}
+	;
+
+context_declaring_list:					/* CFA */
+	type_specifier declarator
+		{
+		    typedefTable.addToEnclosingScope2( TypedefTable::ID);
+		    $$ = $2->addType( $1 );
+		}
+	| context_declaring_list pop ',' push declarator
+		{
+		    typedefTable.addToEnclosingScope2( TypedefTable::ID);
+		    $$ = $1->appendList( $1->cloneBaseType( $5 ) );
+		}
+	;
+
+/***************************** EXTERNAL DEFINITIONS *****************************/
+
+translation_unit:
+	/* empty */					/* empty input file */
+		{}
+	| external_definition_list
+		{
+		  if( theTree ) {
+		    theTree->appendList( $1 );
+		  } else {
+		    theTree = $1;
+		  }
+		}
+	;
+
+external_definition_list:
+	external_definition
+	| external_definition_list push external_definition
+		{
+		  if( $1 ) {
+		    $$ = $1->appendList( $3 );
+		  } else {
+		    $$ = $3;
+		  }
+		}
+	;
+
+external_definition_list_opt:
+	/* empty */
+		{
+		  $$ = 0;
+		}
+	| external_definition_list
+	;
+
+external_definition:
+	declaration
+	| function_definition
+	| asm_statement					/* GCC, global assembler statement */
+		{}
+	| EXTERN STRINGliteral
+		{
+		  linkageStack.push( linkage );
+		  linkage = LinkageSpec::fromString( *$2 );
+		}
+	  '{' external_definition_list_opt '}'		/* C++-style linkage specifier */
+		{
+		  linkage = linkageStack.top();
+		  linkageStack.pop();
+		  $$ = $5;
+		}
+	| EXTENSION external_definition
+		{ $$ = $2; }
+	;
+
+function_definition:
+	new_function_specifier compound_statement	/* CFA */
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $1->addFunctionBody( $2 );
+		}
+	| declaration_qualifier_list new_function_specifier compound_statement /* CFA */
+		/* declaration_qualifier_list also includes type_qualifier_list, so a semantic check is
+		   necessary to preclude them as a type_qualifier cannot appear in this context. */
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 );
+		}
+
+	| declaration_specifier function_declarator compound_statement
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $2->addFunctionBody( $3 )->addType( $1 );
+		}
+
+		/* These rules are a concession to the "implicit int" type_specifier because there is a
+		   significant amount of code with functions missing a type-specifier on the return type.
+		   Parsing is possible because function_definition does not appear in the context of an
+		   expression (nested functions would preclude this concession). A function prototype
+		   declaration must still have a type_specifier. OBSOLESCENT (see 1) */
+	| function_declarator compound_statement
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $1->addFunctionBody( $2 );
+		}
+	| type_qualifier_list function_declarator compound_statement
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 );
+		}
+	| declaration_qualifier_list function_declarator compound_statement
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $2->addFunctionBody( $3 )->addQualifiers( $1 );
+		}
+	| declaration_qualifier_list type_qualifier_list function_declarator compound_statement
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $3->addFunctionBody( $4 )->addQualifiers( $2 )->addQualifiers( $1 );
+		}
+
+		/* Old-style K&R function definition, OBSOLESCENT (see 4) */
+	| declaration_specifier old_function_declarator push old_declaration_list_opt compound_statement
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addType( $1 );
+		}
+	| old_function_declarator push old_declaration_list_opt compound_statement
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $1->addOldDeclList( $3 )->addFunctionBody( $4 );
+		}
+	| type_qualifier_list old_function_declarator push old_declaration_list_opt compound_statement
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addQualifiers( $1 );
+		}
+
+		/* Old-style K&R function definition with "implicit int" type_specifier, OBSOLESCENT (see 4) */
+	| declaration_qualifier_list old_function_declarator push old_declaration_list_opt compound_statement
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $2->addOldDeclList( $4 )->addFunctionBody( $5 )->addQualifiers( $1 );
+		}
+	| declaration_qualifier_list type_qualifier_list old_function_declarator push old_declaration_list_opt
+			compound_statement
+		{
+		    typedefTable.addToEnclosingScope( TypedefTable::ID );
+		    typedefTable.leaveScope();
+		    $$ = $3->addOldDeclList( $5 )->addFunctionBody( $6 )->addQualifiers( $2 )->addQualifiers( $1 );
+		}
+	;
+
+declarator:
+	variable_declarator
+	| function_declarator
+	| typedef_redeclarator
+	;
+
+subrange:
+	constant_expression '~' constant_expression	/* CFA, integer subrange */
+		{ $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range), $1, $3); }
+	;
+
+asm_name_opt:						/* GCC */
+	/* empty */
+	| ASM '(' string_literal_list ')' attribute_list_opt
+	;
+
+attribute_list_opt:					/* GCC */
+	/* empty */
+	| attribute_list
+	;
+
+attribute_list:						/* GCC */
+	attribute
+	| attribute_list attribute
+	;
+
+attribute:						/* GCC */
+	ATTRIBUTE '(' '(' attribute_parameter_list ')' ')'
+	;
+
+attribute_parameter_list:				/* GCC */
+	attrib
+	| attribute_parameter_list ',' attrib
+	;
+
+attrib:							/* GCC */
+	/* empty */
+	| any_word
+	| any_word '(' comma_expression_opt ')'
+	;
+
+any_word:						/* GCC */
+	identifier_or_typedef_name {}
+	| storage_class_name {}
+	| basic_type_name {}
+	| type_qualifier {}
+	;
+
+/* ============================================================================
+   The following sections are a series of grammar patterns used to parse declarators. Multiple patterns are
+   necessary because the type of an identifier in wrapped around the identifier in the same form as its usage
+   in an expression, as in:
+
+	int (*f())[10] { ... };
+	... (*f())[3] += 1;	// definition mimics usage
+
+   Because these patterns are highly recursive, changes at a lower level in the recursion require copying some
+   or all of the pattern. Each of these patterns has some subtle variation to ensure correct syntax in a
+   particular context.
+   ============================================================================ */
+
+/* ----------------------------------------------------------------------------
+   The set of valid declarators before a compound statement for defining a function is less than the set of
+   declarators to define a variable or function prototype, e.g.:
+
+	valid declaration	invalid definition
+	-----------------	------------------
+	int f;			int f {}
+	int *f;			int *f {}
+	int f[10];		int f[10] {}
+	int (*f)(int);		int (*f)(int) {}
+
+   To preclude this syntactic anomaly requires separating the grammar rules for variable and function
+   declarators, hence variable_declarator and function_declarator.
+   ---------------------------------------------------------------------------- */
+
+/* This pattern parses a declaration of a variable that is not redefining a typedef name. The pattern
+   precludes declaring an array of functions versus a pointer to an array of functions. */
+
+variable_declarator:
+	paren_identifier attribute_list_opt
+	| variable_ptr
+	| variable_array attribute_list_opt
+	| variable_function attribute_list_opt
+	;
+
+paren_identifier:
+	identifier
+		{
+		    typedefTable.setNextIdentifier( *($1) );
+		    $$ = DeclarationNode::newName( $1 );
+		}
+	| '(' paren_identifier ')'			/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+variable_ptr:
+	'*' variable_declarator
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
+	| '*' type_qualifier_list variable_declarator
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
+	| '(' variable_ptr ')'
+		{ $$ = $2; }
+	;
+
+variable_array:
+	paren_identifier array_dimension
+		{ $$ = $1->addArray( $2 ); }
+	| '(' variable_ptr ')' array_dimension
+		{ $$ = $2->addArray( $4 ); }
+	| '(' variable_array ')' multi_array_dimension	/* redundant parenthesis */
+		{ $$ = $2->addArray( $4 ); }
+	| '(' variable_array ')'			/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+variable_function:
+	'(' variable_ptr ')' '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $2->addParamList( $6 ); }
+	| '(' variable_function ')'			/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+/* This pattern parses a function declarator that is not redefining a typedef name. Because functions cannot
+   be nested, there is no context where a function definition can redefine a typedef name. To allow nested
+   functions requires further separation of variable and function declarators in typedef_redeclarator.  The
+   pattern precludes returning arrays and functions versus pointers to arrays and functions. */
+
+function_declarator:
+	function_no_ptr attribute_list_opt
+	| function_ptr
+	| function_array attribute_list_opt
+	;
+
+function_no_ptr:
+	paren_identifier '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $1->addParamList( $4 ); }
+	| '(' function_ptr ')' '(' push parameter_type_list_opt pop ')'
+		{ $$ = $2->addParamList( $6 ); }
+	| '(' function_no_ptr ')'			/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+function_ptr:
+	'*' function_declarator
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
+	| '*' type_qualifier_list function_declarator
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
+	| '(' function_ptr ')'
+		{ $$ = $2; }
+	;
+
+function_array:
+	'(' function_ptr ')' array_dimension
+		{ $$ = $2->addArray( $4 ); }
+	| '(' function_array ')' multi_array_dimension	/* redundant parenthesis */
+		{ $$ = $2->addArray( $4 ); }
+	| '(' function_array ')'			/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+/* This pattern parses an old-style K&R function declarator (OBSOLESCENT, see 4) that is not redefining a
+   typedef name (see function_declarator for additional comments). The pattern precludes returning arrays and
+   functions versus pointers to arrays and functions. */
+
+old_function_declarator:
+	old_function_no_ptr
+	| old_function_ptr
+	| old_function_array
+	;
+
+old_function_no_ptr:
+	paren_identifier '(' identifier_list ')'	/* function_declarator handles empty parameter */
+		{ $$ = $1->addIdList( $3 ); }
+	| '(' old_function_ptr ')' '(' identifier_list ')'
+		{ $$ = $2->addIdList( $5 ); }
+	| '(' old_function_no_ptr ')'			/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+old_function_ptr:
+	'*' old_function_declarator
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
+	| '*' type_qualifier_list old_function_declarator
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
+	| '(' old_function_ptr ')'
+		{ $$ = $2; }
+	;
+
+old_function_array:
+	'(' old_function_ptr ')' array_dimension
+		{ $$ = $2->addArray( $4 ); }
+	| '(' old_function_array ')' multi_array_dimension /* redundant parenthesis */
+		{ $$ = $2->addArray( $4 ); }
+	| '(' old_function_array ')'			/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+/* This pattern parses a declaration for a variable or function prototype that redefines a typedef name, e.g.:
+
+	typedef int foo;
+	{
+	   int foo; // redefine typedef name in new scope
+	}
+
+   The pattern precludes declaring an array of functions versus a pointer to an array of functions, and
+   returning arrays and functions versus pointers to arrays and functions. */
+
+typedef_redeclarator:
+	paren_typedef attribute_list_opt
+	| typedef_ptr
+	| typedef_array attribute_list_opt
+	| typedef_function attribute_list_opt
+	;
+
+paren_typedef:
+	TYPEDEFname
+		{
+		typedefTable.setNextIdentifier( *($1) );
+		$$ = DeclarationNode::newName( $1 );
+		}
+	| '(' paren_typedef ')'
+		{ $$ = $2; }
+	;
+
+typedef_ptr:
+	'*' typedef_redeclarator
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
+	| '*' type_qualifier_list typedef_redeclarator
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
+	| '(' typedef_ptr ')'
+		{ $$ = $2; }
+	;
+
+typedef_array:
+	paren_typedef array_dimension
+		{ $$ = $1->addArray( $2 ); }
+	| '(' typedef_ptr ')' array_dimension
+		{ $$ = $2->addArray( $4 ); }
+	| '(' typedef_array ')' multi_array_dimension	/* redundant parenthesis */
+		{ $$ = $2->addArray( $4 ); }
+	| '(' typedef_array ')'				/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+typedef_function:
+	paren_typedef '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $1->addParamList( $4 ); }
+	| '(' typedef_ptr ')' '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $2->addParamList( $6 ); }
+	| '(' typedef_function ')'			/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+/* This pattern parses a declaration for a parameter variable or function prototype that is not redefining a
+   typedef name and allows the ANSI99 array options, which can only appear in a parameter list.  The pattern
+   precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays
+   and functions versus pointers to arrays and functions. */
+
+identifier_parameter_declarator:
+	paren_identifier attribute_list_opt
+	| identifier_parameter_ptr
+	| identifier_parameter_array attribute_list_opt
+	| identifier_parameter_function attribute_list_opt
+	;
+
+identifier_parameter_ptr:
+	'*' identifier_parameter_declarator
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
+	| '*' type_qualifier_list identifier_parameter_declarator
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
+	| '(' identifier_parameter_ptr ')'
+		{ $$ = $2; }
+	;
+
+identifier_parameter_array:
+	paren_identifier array_parameter_dimension
+		{ $$ = $1->addArray( $2 ); }
+	| '(' identifier_parameter_ptr ')' array_dimension
+		{ $$ = $2->addArray( $4 ); }
+	| '(' identifier_parameter_array ')' multi_array_dimension /* redundant parenthesis */
+		{ $$ = $2->addArray( $4 ); }
+	| '(' identifier_parameter_array ')'		/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+identifier_parameter_function:
+	paren_identifier '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $1->addParamList( $4 ); }
+	| '(' identifier_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $2->addParamList( $6 ); }
+	| '(' identifier_parameter_function ')'		/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+/* This pattern parses a declaration for a parameter variable or function prototype that is redefining a
+   typedef name, e.g.:
+
+	typedef int foo;
+	int f( int foo ); // redefine typedef name in new scope
+
+   and allows the ANSI99 array options, which can only appear in a parameter list.  In addition, the pattern
+   handles the special meaning of parenthesis around a typedef name:
+
+	ISO/IEC 9899:1999 Section 6.7.5.3(11) : "In a parameter declaration, a single typedef name in
+	parentheses is taken to be an abstract declarator that specifies a function with a single parameter,
+	not as redundant parentheses around the identifier."
+
+   which precludes the following cases:
+
+	typedef float T;
+	int f( int ( T [5] ) );			// see abstract_parameter_declarator
+	int g( int ( T ( int ) ) );		// see abstract_parameter_declarator
+	int f( int f1( T a[5] ) );		// see identifier_parameter_declarator
+	int g( int g1( T g2( int p ) ) );	// see identifier_parameter_declarator
+
+   In essence, a '(' immediately to the left of typedef name, T, is interpreted as starting a parameter type
+   list, and not as redundant parentheses around a redeclaration of T. Finally, the pattern also precludes
+   declaring an array of functions versus a pointer to an array of functions, and returning arrays and
+   functions versus pointers to arrays and functions. */
+
+typedef_parameter_redeclarator:
+	typedef attribute_list_opt
+	| typedef_parameter_ptr
+	| typedef_parameter_array attribute_list_opt
+	| typedef_parameter_function attribute_list_opt
+	;
+
+typedef:
+	TYPEDEFname
+		{
+		    typedefTable.setNextIdentifier( *($1) );
+		    $$ = DeclarationNode::newName( $1 );
+		}
+	;
+
+typedef_parameter_ptr:
+	'*' typedef_parameter_redeclarator
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
+	| '*' type_qualifier_list typedef_parameter_redeclarator
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
+	| '(' typedef_parameter_ptr ')'
+		{ $$ = $2; }
+	;
+
+typedef_parameter_array:
+	typedef array_parameter_dimension
+		{ $$ = $1->addArray( $2 ); }
+	| '(' typedef_parameter_ptr ')' array_parameter_dimension
+		{ $$ = $2->addArray( $4 ); }
+	;
+
+typedef_parameter_function:
+	typedef '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $1->addParamList( $4 ); }
+	| '(' typedef_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $2->addParamList( $6 ); }
+	;
+
+/* This pattern parses a declaration of an abstract variable or function prototype, i.e., there is no
+   identifier to which the type applies, e.g.:
+
+	sizeof( int );
+	sizeof( int [10] );
+
+   The pattern precludes declaring an array of functions versus a pointer to an array of functions, and
+   returning arrays and functions versus pointers to arrays and functions. */
+
+abstract_declarator:
+	abstract_ptr
+	| abstract_array attribute_list_opt
+	| abstract_function attribute_list_opt
+	;
+
+abstract_ptr:
+	'*'
+		{ $$ = DeclarationNode::newPointer( 0 ); }
+	| '*' type_qualifier_list
+		{ $$ = DeclarationNode::newPointer( $2 ); }
+	| '*' abstract_declarator
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
+	| '*' type_qualifier_list abstract_declarator
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
+	| '(' abstract_ptr ')'
+		{ $$ = $2; }
+	;
+
+abstract_array:
+	array_dimension
+	| '(' abstract_ptr ')' array_dimension
+		{ $$ = $2->addArray( $4 ); }
+	| '(' abstract_array ')' multi_array_dimension	/* redundant parenthesis */
+		{ $$ = $2->addArray( $4 ); }
+	| '(' abstract_array ')'			/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+abstract_function:
+	'(' push parameter_type_list_opt pop ')'	/* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = DeclarationNode::newFunction( 0, 0, $3, 0 ); }
+	| '(' abstract_ptr ')' '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $2->addParamList( $6 ); }
+	| '(' abstract_function ')'			/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+array_dimension:
+		/* Only the first dimension can be empty. */
+	'[' push pop ']'
+		{ $$ = DeclarationNode::newArray( 0, 0, false ); }
+	| '[' push pop ']' multi_array_dimension
+		{ $$ = DeclarationNode::newArray( 0, 0, false )->addArray( $5 ); }
+	| multi_array_dimension
+	;
+
+multi_array_dimension:
+	'[' push assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $3, 0, false ); }
+	| '[' push '*' pop ']'				/* ANSI99 */
+		{ $$ = DeclarationNode::newVarArray( 0 ); }
+	| multi_array_dimension '[' push assignment_expression pop ']'
+		{ $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); }
+	| multi_array_dimension '[' push '*' pop ']'	/* ANSI99 */
+		{ $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); }
+	;
+
+/* This pattern parses a declaration of a parameter abstract variable or function prototype, i.e., there is no
+   identifier to which the type applies, e.g.:
+
+	int f( int );		// abstract variable parameter; no parameter name specified
+	int f( int (int) );	// abstract function-prototype parameter; no parameter name specified
+
+   The pattern precludes declaring an array of functions versus a pointer to an array of functions, and
+   returning arrays and functions versus pointers to arrays and functions. */
+
+abstract_parameter_declarator:
+	abstract_parameter_ptr
+	| abstract_parameter_array attribute_list_opt
+	| abstract_parameter_function attribute_list_opt
+	;
+
+abstract_parameter_ptr:
+	'*'
+		{ $$ = DeclarationNode::newPointer( 0 ); }
+	| '*' type_qualifier_list
+		{ $$ = DeclarationNode::newPointer( $2 ); }
+	| '*' abstract_parameter_declarator
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
+	| '*' type_qualifier_list abstract_parameter_declarator
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
+	| '(' abstract_parameter_ptr ')'
+		{ $$ = $2; }
+	;
+
+abstract_parameter_array:
+	array_parameter_dimension
+	| '(' abstract_parameter_ptr ')' array_parameter_dimension
+		{ $$ = $2->addArray( $4 ); }
+	| '(' abstract_parameter_array ')' multi_array_dimension /* redundant parenthesis */
+		{ $$ = $2->addArray( $4 ); }
+	| '(' abstract_parameter_array ')'		/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+abstract_parameter_function:
+	'(' push parameter_type_list_opt pop ')'	/* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = DeclarationNode::newFunction( 0, 0, $3, 0 ); }
+	| '(' abstract_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $2->addParamList( $6 ); }
+	| '(' abstract_parameter_function ')'		/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+array_parameter_dimension:
+		/* Only the first dimension can be empty or have qualifiers. */
+	array_parameter_1st_dimension
+	| array_parameter_1st_dimension multi_array_dimension
+		{ $$ = $1->addArray( $2 ); }
+	| multi_array_dimension
+	;
+
+/* The declaration of an array parameter has additional syntax over arrays in normal variable declarations:
+
+	ISO/IEC 9899:1999 Section 6.7.5.2(1) : "The optional type qualifiers and the keyword static shall
+	appear only in a declaration of a function parameter with an array type, and then only in the
+	outermost array type derivation."
+   */
+
+array_parameter_1st_dimension:
+	'[' push pop ']'
+		{ $$ = DeclarationNode::newArray( 0, 0, false ); }
+	| '[' push type_qualifier_list '*' pop ']'	/* remaining ANSI99 */
+		{ $$ = DeclarationNode::newVarArray( $3 ); }
+	| '[' push type_qualifier_list assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $4, $3, false ); }
+	| '[' push STATIC assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $4, 0, true ); }
+	| '[' push STATIC type_qualifier_list assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $5, $4, true ); }
+	;
+
+/* This pattern parses a declaration of an abstract variable, i.e., there is no identifier to which the type
+   applies, e.g.:
+
+	sizeof( int ); // abstract variable; no identifier name specified
+
+   The pattern precludes declaring an array of functions versus a pointer to an array of functions, and
+   returning arrays and functions versus pointers to arrays and functions. */
+
+variable_abstract_declarator:
+	variable_abstract_ptr
+	| variable_abstract_array attribute_list_opt
+	| variable_abstract_function attribute_list_opt
+	;
+
+variable_abstract_ptr:
+	'*'
+		{ $$ = DeclarationNode::newPointer( 0 ); }
+	| '*' type_qualifier_list
+		{ $$ = DeclarationNode::newPointer( $2 ); }
+	| '*' variable_abstract_declarator
+		{ $$ = $2->addPointer( DeclarationNode::newPointer( 0 ) ); }
+	| '*' type_qualifier_list variable_abstract_declarator
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( $2 ) ); }
+	| '(' variable_abstract_ptr ')'
+		{ $$ = $2; }
+	;
+
+variable_abstract_array:
+	array_dimension
+	| '(' variable_abstract_ptr ')' array_dimension
+		{ $$ = $2->addArray( $4 ); }
+	| '(' variable_abstract_array ')' multi_array_dimension /* redundant parenthesis */
+		{ $$ = $2->addArray( $4 ); }
+	| '(' variable_abstract_array ')'		/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+variable_abstract_function:
+	'(' variable_abstract_ptr ')' '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */
+		{ $$ = $2->addParamList( $6 ); }
+	| '(' variable_abstract_function ')'		/* redundant parenthesis */
+		{ $$ = $2; }
+	;
+
+/* This pattern parses a new-style declaration for a parameter variable or function prototype that is either
+   an identifier or typedef name and allows the ANSI99 array options, which can only appear in a parameter
+   list. */
+
+new_identifier_parameter_declarator_tuple:		/* CFA */
+	new_identifier_parameter_declarator_no_tuple
+	| new_abstract_tuple
+	| type_qualifier_list new_abstract_tuple
+		{ $$ = $2->addQualifiers( $1 ); }
+	;
+
+new_identifier_parameter_declarator_no_tuple:		/* CFA */
+	new_identifier_parameter_ptr
+	| new_identifier_parameter_array
+	;
+
+new_identifier_parameter_ptr:				/* CFA */
+	'*' type_specifier
+		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
+	| type_qualifier_list '*' type_specifier
+		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
+	| '*' new_abstract_function
+		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
+	| type_qualifier_list '*' new_abstract_function
+		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
+	| '*' new_identifier_parameter_declarator_tuple
+		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
+	| type_qualifier_list '*' new_identifier_parameter_declarator_tuple
+		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
+	;
+
+new_identifier_parameter_array:				/* CFA */
+		/* Only the first dimension can be empty or have qualifiers. Empty dimension must be factored
+		   out due to shift/reduce conflict with new-style empty (void) function return type. */
+	'[' push pop ']' type_specifier
+		{ $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
+	| new_array_parameter_1st_dimension type_specifier
+		{ $$ = $2->addNewArray( $1 ); }
+	| '[' push pop ']' multi_array_dimension type_specifier
+		{ $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
+	| new_array_parameter_1st_dimension multi_array_dimension type_specifier
+		{ $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
+	| multi_array_dimension type_specifier
+		{ $$ = $2->addNewArray( $1 ); }
+	| '[' push pop ']' new_identifier_parameter_ptr
+		{ $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
+	| new_array_parameter_1st_dimension new_identifier_parameter_ptr
+		{ $$ = $2->addNewArray( $1 ); }
+	| '[' push pop ']' multi_array_dimension new_identifier_parameter_ptr
+		{ $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
+	| new_array_parameter_1st_dimension multi_array_dimension new_identifier_parameter_ptr
+		{ $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
+	| multi_array_dimension new_identifier_parameter_ptr
+		{ $$ = $2->addNewArray( $1 ); }
+	;
+
+new_array_parameter_1st_dimension:
+	'[' push type_qualifier_list '*' pop ']'	/* remaining ANSI99 */
+		{ $$ = DeclarationNode::newVarArray( $3 ); }
+	| '[' push type_qualifier_list assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $4, $3, false ); }
+	| '[' push declaration_qualifier_list assignment_expression pop ']'
+		/* declaration_qualifier_list must be used because of shift/reduce conflict with
+		   assignment_expression, so a semantic check is necessary to preclude them as a
+		   type_qualifier cannot appear in this context. */
+		{ $$ = DeclarationNode::newArray( $4, $3, true ); }
+	| '[' push declaration_qualifier_list type_qualifier_list assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $5, $4->addQualifiers( $3 ), true ); }
+	;
+
+/* This pattern parses a new-style declaration of an abstract variable or function prototype, i.e., there is
+   no identifier to which the type applies, e.g.:
+
+	[int] f( int );		// abstract variable parameter; no parameter name specified
+	[int] f( [int] (int) );	// abstract function-prototype parameter; no parameter name specified
+
+   These rules need LR(3):
+
+	new_abstract_tuple identifier_or_typedef_name
+	'[' new_parameter_list ']' identifier_or_typedef_name '(' new_parameter_type_list_opt ')'
+
+   since a function return type can be syntactically identical to a tuple type:
+
+	[int, int] t;
+	[int, int] f( int );
+
+   Therefore, it is necessary to look at the token after identifier_or_typedef_name to know when to reduce
+   new_abstract_tuple. To make this LR(1), several rules have to be flattened (lengthened) to allow
+   the necessary lookahead. To accomplish this, new_abstract_declarator has an entry point without tuple, and
+   tuple declarations are duplicated when appearing with new_function_specifier. */
+
+new_abstract_declarator_tuple:				/* CFA */
+	new_abstract_tuple
+	| type_qualifier_list new_abstract_tuple
+		{ $$ = $2->addQualifiers( $1 ); }
+	| new_abstract_declarator_no_tuple
+	;
+
+new_abstract_declarator_no_tuple:			/* CFA */
+	new_abstract_ptr
+	| new_abstract_array
+	;
+
+new_abstract_ptr:					/* CFA */
+	'*' type_specifier
+		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
+	| type_qualifier_list '*' type_specifier
+		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
+	| '*' new_abstract_function
+		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
+	| type_qualifier_list '*' new_abstract_function
+		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
+	| '*' new_abstract_declarator_tuple
+		{ $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
+	| type_qualifier_list '*' new_abstract_declarator_tuple
+		{ $$ = $3->addNewPointer( DeclarationNode::newPointer( $1 ) ); }
+	;
+
+new_abstract_array:					/* CFA */
+		/* Only the first dimension can be empty. Empty dimension must be factored out due to
+		   shift/reduce conflict with empty (void) function return type. */
+	'[' push pop ']' type_specifier
+		{ $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
+	| '[' push pop ']' multi_array_dimension type_specifier
+		{ $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
+	| multi_array_dimension type_specifier
+		{ $$ = $2->addNewArray( $1 ); }
+	| '[' push pop ']' new_abstract_ptr
+		{ $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
+	| '[' push pop ']' multi_array_dimension new_abstract_ptr
+		{ $$ = $6->addNewArray( $5 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
+	| multi_array_dimension new_abstract_ptr
+		{ $$ = $2->addNewArray( $1 ); }
+	;
+
+new_abstract_tuple:					/* CFA */
+	'[' push new_abstract_parameter_list pop ']'
+		{ $$ = DeclarationNode::newTuple( $3 ); }
+	;
+
+new_abstract_function:					/* CFA */
+	'[' push pop ']' '(' new_parameter_type_list_opt ')'
+		{ $$ = DeclarationNode::newFunction( 0, DeclarationNode::newTuple( 0 ), $6, 0 ); }
+	| new_abstract_tuple '(' push new_parameter_type_list_opt pop ')'
+		{ $$ = DeclarationNode::newFunction( 0, $1, $4, 0 ); }
+	| new_function_return '(' push new_parameter_type_list_opt pop ')'
+		{ $$ = DeclarationNode::newFunction( 0, $1, $4, 0 ); }
+	;
+
+/* 1) ISO/IEC 9899:1999 Section 6.7.2(2) : "At least one type specifier shall be given in the declaration
+      specifiers in each declaration, and in the specifier-qualifier list in each structure declaration and
+      type name."
+
+   2) ISO/IEC 9899:1999 Section 6.11.5(1) : "The placement of a storage-class specifier other than at the
+      beginning of the declaration specifiers in a declaration is an obsolescent feature."
+
+   3) ISO/IEC 9899:1999 Section 6.11.6(1) : "The use of function declarators with empty parentheses (not
+      prototype-format parameter type declarators) is an obsolescent feature."
+
+   4) ISO/IEC 9899:1999 Section 6.11.7(1) : "The use of function definitions with separate parameter
+      identifier and declaration lists (not prototype-format parameter type and identifier declarators) is
+      an obsolescent feature."  */
+
+/************************* MISCELLANEOUS ********************************/
+
+comma_opt:						/* redundant comma */
+	/* empty */
+	| ','
+	;
+
+assignment_opt:
+	/* empty */
+		{ $$ = 0; }
+	| '=' assignment_expression
+		{ $$ = $2; }
+	;
+
+%%
+/* ----end of grammar----*/
+
+void yyerror(char *string) {
+    using std::cout;
+    using std::endl;
+    if( yyfilename ) {
+      cout << yyfilename << ":" << endl;
+    }
+    cout << yylineno << ": syntax error reading token " << *(yylval.tok.str) << endl;
+}
+
+/* Local Variables: */
+/* fill-column: 110 */
+/* compile-command: "gmake" */
+/* End: */
Index: translator/Parser/lex.h
===================================================================
--- translator/Parser/lex.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser/lex.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,43 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: lex.h,v 1.2 2003/11/07 19:45:31 rcbilson Exp $
+ *
+ * Prototypes that enable Roskind's c5.y to compile with g++
+ * Richard Bilson       5 Jan 2001
+ *
+ */
+
+#ifndef PARSER_LEX_H
+#define PARSER_LEX_H
+
+int yylex();
+void yyerror(char *);
+extern "C" {
+#include <malloc.h>
+}
+
+/* External declarations for information sharing between lexer and scanner */
+#include "TypedefTable.h"
+extern TypedefTable typedefTable;
+
+/* current location in the input */
+extern int yylineno;
+extern char *yyfilename;
+
+struct Location
+{
+  char *file;
+  int line;
+};
+
+class Token
+{
+public:
+  std::string *str;
+  Location loc;
+
+  operator std::string *() { return str; }
+};
+
+#endif // ifndef PARSER_LEX_H
Index: translator/Parser/lex.l
===================================================================
--- translator/Parser/lex.l	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser/lex.l	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,372 @@
+/*                               -*- Mode: C -*- 
+ * 
+ * CForall Lexer Version 1.0, Copyright (C) Peter A. Buhr 2001 -- Permission is granted to copy this
+ *	grammar and to use it within software systems.  THIS GRAMMAR IS PROVIDED "AS IS" AND WITHOUT
+ *	ANY EXPRESS OR IMPLIED WARRANTIES.
+ * 
+ * lex.l -- 
+ * 
+ * Author           : Peter A. Buhr
+ * Created On       : Sat Sep 22 08:58:10 2001
+ * Last Modified By : Peter A. Buhr
+ * Last Modified On : Sat Nov  1 18:09:47 2003
+ * Update Count     : 197
+ */
+
+%option yylineno
+
+%{
+/* This lexer assumes the program has been preprocessed by cpp. Hence, all user level preprocessor
+   directive have been performed and removed from the source. The only exceptions are preprocessor
+   directives passed to the compiler (e.g., line-number directives) and C/C++ style comments, which
+   are ignored. */
+
+/*************** Includes and Defines *****************************/
+
+#include <string>
+
+#include "lex.h"
+#include "ParseNode.h"
+#include "cfa.tab.h" /* YACC generated definitions based on C++ grammar */
+
+char *yyfilename;
+
+#define WHITE_RETURN(x)		/* do nothing */
+#define NEWLINE_RETURN()	WHITE_RETURN('\n')
+#define RETURN_VAL(x)		yylval.tok.str = new std::string(yytext); \
+                                yylval.tok.loc.file = yyfilename; \
+                                yylval.tok.loc.line = yylineno; \
+                                return(x)
+
+#define KEYWORD_RETURN(x)	RETURN_VAL(x)		/* keyword */
+#define IDENTIFIER_RETURN()	RETURN_VAL((typedefTable.isIdentifier(yytext) ? IDENTIFIER : typedefTable.isTypedef(yytext) ? TYPEDEFname : TYPEGENname))
+#define ATTRIBUTE_RETURN()	RETURN_VAL((typedefTable.isIdentifier(yytext) ? ATTR_IDENTIFIER : typedefTable.isTypedef(yytext) ? ATTR_TYPEDEFname : ATTR_TYPEGENname))
+
+#define ASCIIOP_RETURN()	RETURN_VAL((int)yytext[0]) /* single character operator */
+#define NAMEDOP_RETURN(x)	RETURN_VAL(x)		/* multichar operator, with a name */
+
+#define NUMERIC_RETURN(x)	rm_underscore(); RETURN_VAL(x) /* numeric constant */
+
+void rm_underscore() {					/* remove underscores in constant or escape sequence */
+    int j = 0;
+    for ( int i = 0; i < yyleng; i += 1 ) {
+	if ( yytext[i] != '_' ) {
+	    yytext[j] = yytext[i];
+	    j += 1;
+	} // if
+    } // for
+    yyleng = j;
+    yytext[yyleng] = '\0';
+}
+
+%}
+
+octal [0-7]
+nonzero [1-9]
+decimal [0-9]
+hex [0-9a-fA-F]
+universal_char "\\"((u{hex_quad})|(U{hex_quad}{2}))
+
+	/* identifier, GCC: $ in identifier */
+identifier ([a-zA-Z_$]|{universal_char})([0-9a-zA-Z_$]|{universal_char})*
+
+	/* attribute identifier, GCC: $ in identifier */
+attr_identifier "@"{identifier}
+
+	/*  numeric constants, CFA: '_' in constant */
+hex_quad {hex}{4}
+integer_suffix "_"?(([uU][lL]?)|([uU]("ll"|"LL")?)|([lL][uU]?)|("ll"|"LL")[uU]?)
+
+octal_digits ({octal})|({octal}({octal}|"_")*{octal})
+octal_prefix "0""_"?
+octal_constant (("0")|({octal_prefix}{octal_digits})){integer_suffix}?
+
+nonzero_digits ({nonzero})|({nonzero}({decimal}|"_")*{decimal})
+decimal_constant {nonzero_digits}{integer_suffix}?
+
+hex_digits ({hex})|({hex}({hex}|"_")*{hex})
+hex_prefix "0"[xX]"_"?
+hex_constant {hex_prefix}{hex_digits}{integer_suffix}?
+
+decimal_digits ({decimal})|({decimal}({decimal}|"_")*{decimal})
+fractional_constant ({decimal_digits}?"."{decimal_digits})|({decimal_digits}".")
+exponent "_"?[eE]"_"?[+-]?{decimal_digits}
+floating_suffix "_"?[flFL]
+floating_constant (({fractional_constant}{exponent}?)|({decimal_digits}{exponent})){floating_suffix}?
+
+binary_exponent "_"?[pP]"_"?[+-]?{decimal_digits}
+hex_fractional_constant ({hex_digits}?"."{hex_digits})|({hex_digits}".")
+hex_floating_constant {hex_prefix}(({hex_fractional_constant}{binary_exponent})|({hex_digits}{binary_exponent})){floating_suffix}?
+
+	/* character escape sequence, GCC: \e => esc character */
+simple_escape "\\"[abefnrtv'"?\\]
+octal_escape "\\"{octal}{1,3}
+hex_escape "\\""x"{hex}+
+escape_seq {simple_escape}|{octal_escape}|{hex_escape}|{universal_char}
+
+	/* display/white-space characters */
+h_tab [\011]
+form_feed [\014]
+v_tab [\013]
+c_return [\015]
+h_white [ ]|{h_tab}
+
+	/* operators */
+op_unary_only "~"|"!"
+op_unary_binary "+"|"-"|"*"
+op_unary_pre_post "++"|"--"
+op_unary {op_unary_only}|{op_unary_binary}|{op_unary_pre_post}
+
+op_binary_only "/"|"%"|"^"|"&"|"|"|"<"|">"|"="|"=="|"!="|"<<"|">>"|"<="|">="|"+="|"-="|"*="|"/="|"%="|"&="|"|="|"^="|"<<="|">>="
+op_binary_over {op_unary_binary}|{op_binary_only}
+op_binary_not_over "?"|"->"|"&&"|"||"
+operator {op_unary_pre_post}|{op_binary_over}|{op_binary_not_over}
+
+%x COMMENT
+
+%%
+	/* line directives */
+^{h_white}*"#"{h_white}*[0-9]+{h_white}*["][^"\n]+["][^\n]*"\n" {
+	char *end_num;
+	char *begin_string, *end_string;
+	char *filename;
+	long lineno, length;
+	lineno = strtol( yytext + 1, &end_num, 0 );
+	begin_string = strchr( end_num, '"' );
+	if( begin_string ) {
+	  end_string = strchr( begin_string + 1, '"' );
+	  if( end_string ) {
+	    length = end_string - begin_string - 1;
+	    filename = new char[ length + 1 ];
+	    memcpy( filename, begin_string + 1, length );
+	    filename[ length ] = '\0';
+	    //std::cout << "file " << filename << " line " << lineno << std::endl;
+	    yylineno = lineno;
+	    yyfilename = filename;
+	  }
+	}
+}
+
+	/* ignore preprocessor directives (for now) */
+^{h_white}*"#"[^\n]*"\n" ;
+
+	/* ignore C style comments */
+"/*"			{BEGIN COMMENT;}
+<COMMENT>.|\n		;
+<COMMENT>"*/"		{BEGIN 0;}
+
+	/* ignore C++ style comments */
+"//"[^\n]*"\n"		;
+
+	/* ignore whitespace */
+{h_white}+		{WHITE_RETURN(' ');}
+({v_tab}|{c_return}|{form_feed})+ {WHITE_RETURN(' ');}
+({h_white}|{v_tab}|{c_return}|{form_feed})*"\n" {NEWLINE_RETURN();}
+
+	/* keywords */
+__alignof		{KEYWORD_RETURN(ALIGNOF);}	/* GCC */
+__alignof__		{KEYWORD_RETURN(ALIGNOF);}	/* GCC */
+asm			{KEYWORD_RETURN(ASM);}
+__asm			{KEYWORD_RETURN(ASM);}		/* GCC */
+__asm__			{KEYWORD_RETURN(ASM);}		/* GCC */
+__attribute		{KEYWORD_RETURN(ATTRIBUTE);}	/* GCC */
+__attribute__		{KEYWORD_RETURN(ATTRIBUTE);}	/* GCC */
+auto			{KEYWORD_RETURN(AUTO);}
+_Bool			{KEYWORD_RETURN(BOOL);}		/* ANSI99 */
+break			{KEYWORD_RETURN(BREAK);}
+case			{KEYWORD_RETURN(CASE);}
+catch			{KEYWORD_RETURN(CATCH);}	/* CFA */
+char			{KEYWORD_RETURN(CHAR);}
+choose			{KEYWORD_RETURN(CHOOSE);}
+_Complex		{KEYWORD_RETURN(COMPLEX);}	/* ANSI99 */
+__complex		{KEYWORD_RETURN(COMPLEX);}	/* GCC */
+__complex__		{KEYWORD_RETURN(COMPLEX);}	/* GCC */
+const			{KEYWORD_RETURN(CONST);}
+__const			{KEYWORD_RETURN(CONST);}	/* GCC */
+__const__		{KEYWORD_RETURN(CONST);}	/* GCC */
+context			{KEYWORD_RETURN(CONTEXT);}
+continue		{KEYWORD_RETURN(CONTINUE);}
+default			{KEYWORD_RETURN(DEFAULT);}
+do			{KEYWORD_RETURN(DO);}
+double			{KEYWORD_RETURN(DOUBLE);}
+dtype			{KEYWORD_RETURN(DTYPE);}
+else			{KEYWORD_RETURN(ELSE);}
+enum			{KEYWORD_RETURN(ENUM);}
+__extension__		{KEYWORD_RETURN(EXTENSION);}	/* GCC */
+extern			{KEYWORD_RETURN(EXTERN);}
+fallthru		{KEYWORD_RETURN(FALLTHRU);}
+finally			{KEYWORD_RETURN(FINALLY);}	/* CFA */
+float			{KEYWORD_RETURN(FLOAT);}
+for			{KEYWORD_RETURN(FOR);}
+forall			{KEYWORD_RETURN(FORALL);}
+fortran			{KEYWORD_RETURN(FORTRAN);}
+ftype			{KEYWORD_RETURN(FTYPE);}
+goto			{KEYWORD_RETURN(GOTO);}
+if			{KEYWORD_RETURN(IF);}
+_Imaginary		{KEYWORD_RETURN(IMAGINARY);}	/* ANSI99 */
+__imag			{KEYWORD_RETURN(IMAGINARY);}	/* GCC */
+__imag__		{KEYWORD_RETURN(IMAGINARY);}	/* GCC */
+inline			{KEYWORD_RETURN(INLINE);}	/* ANSI99 */
+__inline		{KEYWORD_RETURN(INLINE);}	/* GCC */
+__inline__		{KEYWORD_RETURN(INLINE);}	/* GCC */
+int			{KEYWORD_RETURN(INT);}
+__label__		{KEYWORD_RETURN(LABEL);}	/* GCC */
+long			{KEYWORD_RETURN(LONG);}
+lvalue			{KEYWORD_RETURN(LVALUE);}
+register		{KEYWORD_RETURN(REGISTER);}
+restrict		{KEYWORD_RETURN(RESTRICT);}	/* ANSI99 */
+__restrict		{KEYWORD_RETURN(RESTRICT);}	/* GCC */
+__restrict__		{KEYWORD_RETURN(RESTRICT);}	/* GCC */
+return			{KEYWORD_RETURN(RETURN);}
+short			{KEYWORD_RETURN(SHORT);}
+signed			{KEYWORD_RETURN(SIGNED);}
+__signed		{KEYWORD_RETURN(SIGNED);}	/* GCC */
+__signed__		{KEYWORD_RETURN(SIGNED);}	/* GCC */
+sizeof			{KEYWORD_RETURN(SIZEOF);}
+static			{KEYWORD_RETURN(STATIC);}
+struct			{KEYWORD_RETURN(STRUCT);}
+switch			{KEYWORD_RETURN(SWITCH);}
+throw			{KEYWORD_RETURN(THROW);}	/* CFA */
+try			{KEYWORD_RETURN(TRY);}		/* CFA */
+type			{KEYWORD_RETURN(TYPE);}
+typedef			{KEYWORD_RETURN(TYPEDEF);}
+typeof			{KEYWORD_RETURN(TYPEOF);}	/* GCC */
+__typeof		{KEYWORD_RETURN(TYPEOF);}	/* GCC */
+__typeof__		{KEYWORD_RETURN(TYPEOF);}	/* GCC */
+union			{KEYWORD_RETURN(UNION);}
+unsigned		{KEYWORD_RETURN(UNSIGNED);}
+void			{KEYWORD_RETURN(VOID);}
+volatile		{KEYWORD_RETURN(VOLATILE);}
+__volatile		{KEYWORD_RETURN(VOLATILE);}	/* GCC */
+__volatile__		{KEYWORD_RETURN(VOLATILE);}	/* GCC */
+while			{KEYWORD_RETURN(WHILE);}
+
+	/* identifier */
+{identifier}		{IDENTIFIER_RETURN();}
+{attr_identifier}	{ATTRIBUTE_RETURN();}
+
+	/* numeric constants */
+"0"			{NUMERIC_RETURN(ZERO);}		/* CFA */
+"1"			{NUMERIC_RETURN(ONE);}		/* CFA */
+{decimal_constant}	{NUMERIC_RETURN(INTEGERconstant);}
+{octal_constant}	{NUMERIC_RETURN(INTEGERconstant);}
+{hex_constant}		{NUMERIC_RETURN(INTEGERconstant);}
+{floating_constant}	{NUMERIC_RETURN(FLOATINGconstant);}
+{hex_floating_constant}	{NUMERIC_RETURN(FLOATINGconstant);}
+
+	/* character constant, allows empty value */
+"L"?[']([^'\\\n]|{escape_seq})*['] {RETURN_VAL(CHARACTERconstant);}
+
+	/* string constant */
+"L"?["]([^"\\\n]|{escape_seq})*["] {RETURN_VAL(STRINGliteral);}
+
+	/* punctuation */
+"["			{ASCIIOP_RETURN();}
+"]"			{ASCIIOP_RETURN();}
+"("			{ASCIIOP_RETURN();}
+")"			{ASCIIOP_RETURN();}
+"{"			{ASCIIOP_RETURN();}
+"}"			{ASCIIOP_RETURN();}
+","			{ASCIIOP_RETURN();}		/* also operator */
+":"			{ASCIIOP_RETURN();}
+";"			{ASCIIOP_RETURN();}
+"."			{ASCIIOP_RETURN();}		/* also operator */
+"..."			{NAMEDOP_RETURN(ELLIPSIS);}
+
+	/* alternative ANSI99 brackets, "<:" & "<:<:" handled by preprocessor */
+"<:"			{RETURN_VAL('[');}
+":>"			{RETURN_VAL(']');}
+"<%"			{RETURN_VAL('{');}
+"%>"			{RETURN_VAL('}');}
+
+	/* operators */
+"!"			{ASCIIOP_RETURN();}
+"+"			{ASCIIOP_RETURN();}
+"-"			{ASCIIOP_RETURN();}
+"*"			{ASCIIOP_RETURN();}
+"/"			{ASCIIOP_RETURN();}
+"%"			{ASCIIOP_RETURN();}
+"^"			{ASCIIOP_RETURN();}
+"~"			{ASCIIOP_RETURN();}
+"&"			{ASCIIOP_RETURN();}
+"|"			{ASCIIOP_RETURN();}
+"<"			{ASCIIOP_RETURN();}
+">"			{ASCIIOP_RETURN();}
+"="			{ASCIIOP_RETURN();}
+"?"			{ASCIIOP_RETURN();}
+
+"++"			{NAMEDOP_RETURN(ICR);}
+"--"			{NAMEDOP_RETURN(DECR);}
+"=="			{NAMEDOP_RETURN(EQ);}
+"!="			{NAMEDOP_RETURN(NE);}
+"<<"			{NAMEDOP_RETURN(LS);}
+">>"			{NAMEDOP_RETURN(RS);}
+"<="			{NAMEDOP_RETURN(LE);}
+">="			{NAMEDOP_RETURN(GE);}
+"&&"			{NAMEDOP_RETURN(ANDAND);}
+"||"			{NAMEDOP_RETURN(OROR);}
+"->"			{NAMEDOP_RETURN(ARROW);}
+"+="			{NAMEDOP_RETURN(PLUSassign);}
+"-="			{NAMEDOP_RETURN(MINUSassign);}
+"*="			{NAMEDOP_RETURN(MULTassign);}
+"/="			{NAMEDOP_RETURN(DIVassign);}
+"%="			{NAMEDOP_RETURN(MODassign);}
+"&="			{NAMEDOP_RETURN(ANDassign);}
+"|="			{NAMEDOP_RETURN(ORassign);}
+"^="			{NAMEDOP_RETURN(ERassign);}
+"<<="			{NAMEDOP_RETURN(LSassign);}
+">>="			{NAMEDOP_RETURN(RSassign);}
+
+	/* CFA, operator identifier */
+{op_unary}"?"		{IDENTIFIER_RETURN();}		/* unary */
+"?"({op_unary_pre_post}|"()"|"[?]") {IDENTIFIER_RETURN();}
+"?"{op_binary_over}"?"	{IDENTIFIER_RETURN();}		/* binary */
+	/*
+	  This rule handles ambiguous cases with operator identifiers, e.g., "int *?*?()", where the
+	  string "*?*?"  can be lexed as "*"/"?*?" or "*?"/"*?". Since it is common practise to put
+	  a unary operator juxtaposed to an identifier, e.g., "*i", users will be annoyed if they
+	  cannot do this with respect to operator identifiers. Even with this special hack, there
+	  are 5 general cases that cannot be handled. The first case is for the function-call
+	  identifier "?()":
+
+	  int * ?()();	// declaration: space required after '*'
+	  * ?()();	// expression: space required after '*'
+
+	  Without the space, the string "*?()" is ambiguous without N character look ahead; it
+	  requires scanning ahead to determine if there is a '(', which is the start of an
+	  argument/parameter list.
+
+	  The 4 remaining cases occur in expressions:
+
+	  i++?i:0;		// space required before '?'
+	  i--?i:0;		// space required before '?'
+	  i?++i:0;		// space required after '?'
+	  i?--i:0;		// space required after '?'
+
+	  In the first two cases, the string "i++?" is ambiguous, where this string can be lexed as
+	  "i"/"++?" or "i++"/"?"; it requires scanning ahead to determine if there is a '(', which
+	  is the start of an argument list.  In the second two cases, the string "?++x" is
+	  ambiguous, where this string can be lexed as "?++"/"x" or "?"/"++x"; it requires scanning
+	  ahead to determine if there is a '(', which is the start of an argument list.
+	*/
+{op_unary}"?"(({op_unary_pre_post}|"[?]")|({op_binary_over}"?")) {
+			    // 1 or 2 character unary operator ?
+			    int i = yytext[1] == '?' ? 1 : 2;
+			    yyless( i );		/* put back characters up to first '?' */
+			    if ( i > 1 ) {
+				NAMEDOP_RETURN( yytext[0] == '+' ? ICR : DECR );
+			    } else {
+				ASCIIOP_RETURN();
+			    } // if
+			}
+
+	/* unknown characters */
+.			{printf("unknown character(s):\"%s\" on line %d\n", yytext, yylineno);}
+
+%%
+
+
+/* Local Variables: */
+/* fill-column: 100 */
+/* compile-command: "gmake" */
+/* End: */
Index: translator/Parser/module.mk
===================================================================
--- translator/Parser/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,44 @@
+###
+### This file is part of the Cforall project
+###
+### $Id: module.mk,v 1.12 2005/08/30 19:11:40 rcbilson Exp $
+###
+
+YACC=bison
+YFLAGS=-d --debug -v
+LEX=flex
+LFLAGS=
+
+SRC += Parser/cfa.y \
+       Parser/lex.l \
+       Parser/TypedefTable.cc \
+       Parser/ParseNode.cc \
+       Parser/DeclarationNode.cc \
+       Parser/ExpressionNode.cc \
+       Parser/StatementNode.cc \
+       Parser/InitializerNode.cc \
+       Parser/TypeData.cc \
+       Parser/LinkageSpec.cc \
+       Parser/parseutility.cc \
+       Parser/Parser.cc
+
+EXTRA_OUTPUT += Parser/cfa.tab.cc \
+                Parser/cfa.tab.h \
+		Parser/lex.yy.cc \
+		Parser/cfa.output
+
+LIBS += -lfl
+
+Parser/Parser.cc: Parser/cfa.tab.h
+
+Parser/cfa.tab.cc: Parser/cfa.y
+	$(YACC) $(YFLAGS) $< --file-prefix=Parser/cfa
+	-mv Parser/cfa.tab.c Parser/cfa.tab.cc
+
+Parser/cfa.tab.h: Parser/cfa.tab.cc
+
+Parser/lex.yy.cc: Parser/lex.l Parser/cfa.tab.h Parser/TypedefTable.h
+	$(LEX) $(LFLAGS) -o$@ $< 
+
+Parser/lex.yy.o: Parser/lex.yy.cc Parser/ParseNode.h
+	$(CXX) $(CXXFLAGS) -Wno-unused -c -o $@ $<
Index: translator/Parser/parseutility.cc
===================================================================
--- translator/Parser/parseutility.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser/parseutility.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,20 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: parseutility.cc,v 1.2 2005/08/29 20:14:15 rcbilson Exp $
+ *
+ */
+
+#include "parseutility.h"
+#include "SynTree/Type.h"
+#include "SynTree/Expression.h"
+
+
+Expression *
+notZeroExpr( Expression *orig )
+{
+      UntypedExpr *comparison = new UntypedExpr( new NameExpr( "?!=?" ) );
+      comparison->get_args().push_back( orig );
+      comparison->get_args().push_back( new NameExpr( "0" ) );
+      return new CastExpr( comparison, new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
+}
Index: translator/Parser/parseutility.h
===================================================================
--- translator/Parser/parseutility.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Parser/parseutility.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,15 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: parseutility.h,v 1.2 2005/08/29 20:14:15 rcbilson Exp $
+ *
+ */
+
+#ifndef PARSER_PARSEUTILITY_H
+#define PARSER_PARSEUTILITY_H
+
+#include "SynTree/SynTree.h"
+
+Expression *notZeroExpr( Expression *orig );
+
+#endif /* #ifndef PARSER_PARSEUTILITY_H */
Index: translator/ResolvExpr/AdjustExprType.cc
===================================================================
--- translator/ResolvExpr/AdjustExprType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/AdjustExprType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,136 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: AdjustExprType.cc,v 1.3 2005/08/29 20:14:15 rcbilson Exp $
+ *
+ */
+
+#include "typeops.h"
+#include "SynTree/Type.h"
+#include "TypeEnvironment.h"
+#include "SymTab/Indexer.h"
+
+namespace ResolvExpr {
+
+class AdjustExprType : public Mutator
+{
+  typedef Mutator Parent;
+
+public:
+  AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer );
+
+private:
+  virtual Type* mutate(VoidType *voidType);
+  virtual Type* mutate(BasicType *basicType);
+  virtual Type* mutate(PointerType *pointerType);
+  virtual Type* mutate(ArrayType *arrayType);
+  virtual Type* mutate(FunctionType *functionType);
+  virtual Type* mutate(StructInstType *aggregateUseType);
+  virtual Type* mutate(UnionInstType *aggregateUseType);
+  virtual Type* mutate(EnumInstType *aggregateUseType);
+  virtual Type* mutate(ContextInstType *aggregateUseType);
+  virtual Type* mutate(TypeInstType *aggregateUseType);
+  virtual Type* mutate(TupleType *tupleType);
+  
+  const TypeEnvironment &env;
+  const SymTab::Indexer &indexer;
+};
+
+void
+adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer )
+{
+  AdjustExprType adjuster( env, indexer );
+  Type *newType = type->acceptMutator( adjuster );
+  type = newType;
+}
+
+AdjustExprType::AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer )
+  : env( env ), indexer( indexer )
+{
+}
+
+Type* 
+AdjustExprType::mutate(VoidType *voidType)
+{
+  return voidType;
+}
+
+Type* 
+AdjustExprType::mutate(BasicType *basicType)
+{
+  return basicType;
+}
+
+Type* 
+AdjustExprType::mutate(PointerType *pointerType)
+{
+  return pointerType;
+}
+
+Type* 
+AdjustExprType::mutate(ArrayType *arrayType)
+{
+  PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->get_base()->clone() );
+  delete arrayType;
+  return pointerType;
+}
+
+Type* 
+AdjustExprType::mutate(FunctionType *functionType)
+{
+  PointerType *pointerType = new PointerType( Type::Qualifiers(), functionType );
+  return pointerType;
+}
+
+Type* 
+AdjustExprType::mutate(StructInstType *aggregateUseType)
+{
+  return aggregateUseType;
+}
+
+Type* 
+AdjustExprType::mutate(UnionInstType *aggregateUseType)
+{
+  return aggregateUseType;
+}
+
+Type* 
+AdjustExprType::mutate(EnumInstType *aggregateUseType)
+{
+  return aggregateUseType;
+}
+
+Type* 
+AdjustExprType::mutate(ContextInstType *aggregateUseType)
+{
+  return aggregateUseType;
+}
+
+Type* 
+AdjustExprType::mutate(TypeInstType *typeInst)
+{
+  EqvClass eqvClass;
+  if( env.lookup( typeInst->get_name(), eqvClass ) ) {
+    if( eqvClass.kind == TypeDecl::Ftype ) {
+      PointerType *pointerType = new PointerType( Type::Qualifiers(), typeInst );
+      return pointerType;
+    }
+  } else if( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
+    if( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
+      if( tyDecl->get_kind() == TypeDecl::Ftype ) {
+        PointerType *pointerType = new PointerType( Type::Qualifiers(), typeInst );
+        return pointerType;
+      }
+    }
+  }
+  return typeInst;
+}
+
+Type* 
+AdjustExprType::mutate(TupleType *tupleType)
+{
+  return tupleType;
+}
+
+
+} // namespace ResolvExpr
Index: translator/ResolvExpr/Alternative.cc
===================================================================
--- translator/ResolvExpr/Alternative.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/Alternative.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,75 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Alternative.cc,v 1.6 2005/08/29 20:14:15 rcbilson Exp $
+ *
+ */
+
+#include "Alternative.h"
+#include "SynTree/Type.h"
+#include "SynTree/Expression.h"
+#include "utility.h"
+
+namespace ResolvExpr {
+
+Alternative::Alternative()
+  : expr( 0 )
+{
+}
+
+Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost )
+  : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( env )
+{
+}
+
+Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost, const Cost &cvtCost )
+  : cost( cost ), cvtCost( cvtCost ), expr( expr ), env( env )
+{
+}
+
+Alternative::Alternative( const Alternative &other )
+{
+  initialize( other, *this );
+}
+
+Alternative &
+Alternative::operator=( const Alternative &other )
+{
+  if( &other == this ) return *this;
+  initialize( other, *this );
+  return *this;
+}
+
+void 
+Alternative::initialize( const Alternative &src, Alternative &dest )
+{
+  dest.cost = src.cost;
+  dest.cvtCost = src.cvtCost;
+  dest.expr = maybeClone( src.expr );
+  dest.env = src.env;
+}
+
+Alternative::~Alternative()
+{
+  delete expr;
+}
+
+void 
+Alternative::print( std::ostream &os, int indent ) const
+{
+  os << std::string( indent, ' ' ) << "Cost " << cost << ": ";
+  if( expr ) {
+    expr->print( os, indent );
+    os << "(types:" << std::endl;
+    printAll( expr->get_results(), os, indent + 4 );
+    os << ")" << std::endl;
+  } else {
+    os << "Null expression!" << std::endl;
+  }
+  os << std::string( indent, ' ' ) << "Environment: ";
+  env.print( os, indent+2 );
+  os << std::endl;
+}
+
+
+} // namespace ResolvExpr
Index: translator/ResolvExpr/Alternative.h
===================================================================
--- translator/ResolvExpr/Alternative.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/Alternative.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,43 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Alternative.h,v 1.9 2005/08/29 20:14:15 rcbilson Exp $
+ *
+ */
+
+#ifndef RESOLVEXPR_ALTERNATIVE_H
+#define RESOLVEXPR_ALTERNATIVE_H
+
+#include <list>
+#include "SynTree/SynTree.h"
+#include "Cost.h"
+#include "TypeEnvironment.h"
+
+namespace ResolvExpr {
+
+struct Alternative;
+typedef std::list< Alternative > AltList;
+
+struct Alternative
+{
+  Alternative();
+  Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost );
+  Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost, const Cost &cvtCost );
+  Alternative( const Alternative &other );
+  Alternative &operator=( const Alternative &other );
+  ~Alternative();
+  
+  void initialize( const Alternative &src, Alternative &dest );
+  
+  void print( std::ostream &os, int indent = 0 ) const;
+  
+  Cost cost;
+  Cost cvtCost;
+  Expression *expr;
+  TypeEnvironment env;
+};
+
+
+} // namespace ResolvExpr
+
+#endif /* #ifndef RESOLVEXPR_ALTERNATIVE_H */
Index: translator/ResolvExpr/AlternativeFinder.cc
===================================================================
--- translator/ResolvExpr/AlternativeFinder.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/AlternativeFinder.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,928 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: AlternativeFinder.cc,v 1.36 2005/08/29 20:14:15 rcbilson Exp $
+ *
+ */
+
+#include <list>
+#include <iterator>
+#include <algorithm>
+#include <functional>
+#include <cassert>
+
+#include "AlternativeFinder.h"
+#include "Alternative.h"
+#include "Cost.h"
+#include "typeops.h"
+#include "Unify.h"
+#include "RenameVars.h"
+#include "SynTree/Type.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Initializer.h"
+#include "SynTree/Visitor.h"
+#include "SymTab/Indexer.h"
+#include "SymTab/Mangler.h"
+#include "SynTree/TypeSubstitution.h"
+#include "SymTab/Validate.h"
+#include "Designators/Processor.h"
+#include "Tuples/TupleAssignment.h"
+#include "Tuples/NameMatcher.h"
+#include "utility.h"
+
+
+//#define DEBUG_COST
+
+namespace ResolvExpr {
+
+Expression *
+resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env )
+{
+  CastExpr *castToVoid = new CastExpr( expr );
+
+  AlternativeFinder finder( indexer, env );
+  finder.findWithAdjustment( castToVoid );
+
+  // it's a property of the language that a cast expression has either 1 or 0 interpretations;
+  // if it has 0 interpretations, an exception has already been thrown.
+  assert( finder.get_alternatives().size() == 1 );
+  CastExpr *newExpr = dynamic_cast< CastExpr* >( finder.get_alternatives().front().expr );
+  assert( newExpr );
+  env = finder.get_alternatives().front().env;
+  return newExpr->get_arg()->clone();
+}
+
+namespace {
+
+  void
+  printAlts( const AltList &list, std::ostream &os, int indent = 0 )
+  {
+    for( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {
+      i->print( os, indent );
+      os << std::endl;
+    }
+  }
+
+  void
+  makeExprList( const AltList &in, std::list< Expression* > &out )
+  {
+    for( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
+      out.push_back( i->expr->clone() );
+    }
+  }
+
+  Cost
+  sumCost( const AltList &in )
+  {
+    Cost total;
+    for( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
+      total += i->cost;
+    }
+    return total;
+  }
+
+  struct PruneStruct
+  {
+    bool isAmbiguous;
+    AltList::iterator candidate;
+    PruneStruct() {}
+    PruneStruct( AltList::iterator candidate ): isAmbiguous( false ), candidate( candidate ) {}
+  };
+
+  template< typename InputIterator, typename OutputIterator >
+  void
+  pruneAlternatives( InputIterator begin, InputIterator end, OutputIterator out, const SymTab::Indexer &indexer )
+  {
+    // select the alternatives that have the minimum conversion cost for a particular set of result types
+    std::map< std::string, PruneStruct > selected;
+    for( AltList::iterator candidate = begin; candidate != end; ++candidate ) {
+      PruneStruct current( candidate );
+      std::string mangleName;
+      for( std::list< Type* >::const_iterator retType = candidate->expr->get_results().begin(); retType != candidate->expr->get_results().end(); ++retType ) {
+        Type *newType = (*retType)->clone();
+        candidate->env.apply( newType );
+        mangleName += SymTab::Mangler::mangle( newType );
+        delete newType;
+      }
+      std::map< std::string, PruneStruct >::iterator mapPlace = selected.find( mangleName );
+      if( mapPlace != selected.end() ) {
+        if( candidate->cost < mapPlace->second.candidate->cost ) {
+///           std::cout << "cost " << candidate->cost << " beats " << target->second.cost << std::endl;
+          selected[ mangleName ] = current;
+        } else if( candidate->cost == mapPlace->second.candidate->cost ) {
+///           std::cout << "marking ambiguous" << std::endl;
+          mapPlace->second.isAmbiguous = true;
+        }
+      } else {
+        selected[ mangleName ] = current;
+      }
+    }
+
+///     std::cout << "there are " << selected.size() << " alternatives before elimination" << std::endl;
+
+    // accept the alternatives that were unambiguous
+    for( std::map< std::string, PruneStruct >::iterator target = selected.begin(); target != selected.end(); ++target) {
+      if( !target->second.isAmbiguous ) {
+        Alternative &alt = *target->second.candidate;
+        for( std::list< Type* >::iterator result = alt.expr->get_results().begin(); result != alt.expr->get_results().end(); ++result ) {
+          alt.env.applyFree( *result );
+        }
+        *out++ = alt;
+      }
+    }
+
+  }
+
+  template< typename InputIterator, typename OutputIterator >
+  void
+  findMinCost( InputIterator begin, InputIterator end, OutputIterator out )
+  {
+    AltList alternatives;
+
+    // select the alternatives that have the minimum parameter cost
+    Cost minCost = Cost::infinity;
+    for( AltList::iterator i = begin; i != end; ++i ) {
+      if( i->cost < minCost ) {
+        minCost = i->cost;
+        i->cost = i->cvtCost;
+        alternatives.clear();
+        alternatives.push_back( *i );
+      } else if( i->cost == minCost ) {
+        i->cost = i->cvtCost;
+        alternatives.push_back( *i );
+      }
+    }
+    std::copy( alternatives.begin(), alternatives.end(), out );
+  }
+
+  template< typename InputIterator >
+  void
+  simpleCombineEnvironments( InputIterator begin, InputIterator end, TypeEnvironment &result )
+  {
+    while( begin != end ) {
+      result.simpleCombine( (*begin++).env );
+    }
+  }
+
+  void
+  renameTypes( Expression *expr )
+  {
+    for( std::list< Type* >::iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) {
+      (*i)->accept( global_renamer );
+    }
+  }
+}
+
+template< typename InputIterator, typename OutputIterator >
+void
+AlternativeFinder::findSubExprs( InputIterator begin, InputIterator end, OutputIterator out )
+{
+  while( begin != end ) {
+    AlternativeFinder finder( indexer, env );
+    finder.findWithAdjustment( *begin );
+    // XXX  either this
+    //Designators::fixDesignations( finder, (*begin++)->get_argName() );
+    // or XXX this
+    begin++;
+///     std::cout << "findSubExprs" << std::endl;
+///     printAlts( finder.alternatives, std::cout );
+    *out++ = finder;
+  }
+}
+
+AlternativeFinder::AlternativeFinder( const SymTab::Indexer &indexer, const TypeEnvironment &env )
+  : indexer( indexer ), env( env )
+{
+}
+
+void
+AlternativeFinder::find( Expression *expr, bool adjust )
+{
+  expr->accept( *this );
+  if( alternatives.empty() ) {
+    throw SemanticError( "No reasonable alternatives for expression ", expr );
+  }
+  for( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) {
+    if( adjust ) {
+      adjustExprTypeList( i->expr->get_results().begin(), i->expr->get_results().end(), i->env, indexer );
+    }
+  }
+///   std::cout << "alternatives before prune:" << std::endl;
+///   printAlts( alternatives, std::cout );
+  AltList::iterator oldBegin = alternatives.begin();
+  pruneAlternatives( alternatives.begin(), alternatives.end(), front_inserter( alternatives ), indexer );
+  if( alternatives.begin() == oldBegin ) {
+    std::ostrstream stream;
+    stream << "Can't choose between alternatives for expression ";
+    expr->print( stream );
+    stream << "Alternatives are:";
+    AltList winners;
+    findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) );
+    printAlts( winners, stream, 8 );
+    throw SemanticError( std::string( stream.str(), stream.pcount() ) );
+  }
+  alternatives.erase( oldBegin, alternatives.end() );
+///   std::cout << "there are " << alternatives.size() << " alternatives after elimination" << std::endl;
+}
+
+void
+AlternativeFinder::findWithAdjustment( Expression *expr )
+{
+  find( expr, true );
+}
+
+template< typename StructOrUnionType >
+void
+AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const std::string &name )
+{
+  std::list< Declaration* > members;
+  aggInst->lookup( name, members );
+  for( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
+    if( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
+      alternatives.push_back( Alternative( new MemberExpr( dwt->clone(), expr->clone() ), env, newCost ) );
+      renameTypes( alternatives.back().expr );
+    } else {
+      assert( false );
+    }
+  }
+}
+
+void
+AlternativeFinder::visit(ApplicationExpr *applicationExpr)
+{
+  alternatives.push_back( Alternative( applicationExpr->clone(), env, Cost::zero ) );
+}
+
+Cost
+computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer )
+{
+  ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( alt.expr );
+  assert( appExpr );
+  PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
+  assert( pointer );
+  FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
+  assert( function );
+
+  Cost convCost( 0, 0, 0 );
+  std::list< DeclarationWithType* >& formals = function->get_parameters();
+  std::list< DeclarationWithType* >::iterator formal = formals.begin();
+  std::list< Expression* >& actuals = appExpr->get_args();
+  for( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
+///     std::cout << "actual expression:" << std::endl;
+///     (*actualExpr)->print( std::cout, 8 );
+///     std::cout << "--- results are" << std::endl;
+///     printAll( (*actualExpr)->get_results(), std::cout, 8 );
+    std::list< DeclarationWithType* >::iterator startFormal = formal;
+    Cost actualCost;
+    for( std::list< Type* >::iterator actual = (*actualExpr)->get_results().begin(); actual != (*actualExpr)->get_results().end(); ++actual ) {
+      if( formal == formals.end() ) {
+        if( function->get_isVarArgs() ) {
+          convCost += Cost( 1, 0, 0 );
+          break;
+        } else {
+          return Cost::infinity;
+        }
+      }
+///       std::cout << std::endl << "converting ";
+///       (*actual)->print( std::cout, 8 );
+///       std::cout << std::endl << " to ";
+///       (*formal)->get_type()->print( std::cout, 8 );
+      Cost newCost = conversionCost( *actual, (*formal)->get_type(), indexer, alt.env );
+///       std::cout << std::endl << "cost is" << newCost << std::endl;
+
+      if( newCost == Cost::infinity ) {
+        return newCost;
+      }
+      convCost += newCost;
+      actualCost += newCost;
+
+      convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actual, alt.env, indexer), 0 );
+
+      formal++;
+    }
+    if( actualCost != Cost( 0, 0, 0 ) ) {
+      std::list< DeclarationWithType* >::iterator startFormalPlusOne = startFormal;
+      startFormalPlusOne++;
+      if( formal == startFormalPlusOne ) {
+        // not a tuple type
+        Type *newType = (*startFormal)->get_type()->clone();
+        alt.env.apply( newType );
+        *actualExpr = new CastExpr( *actualExpr, newType );
+      } else {
+        TupleType *newType = new TupleType( Type::Qualifiers() );
+        for( std::list< DeclarationWithType* >::iterator i = startFormal; i != formal; ++i ) {
+          newType->get_types().push_back( (*i)->get_type()->clone() );
+        }
+        alt.env.apply( newType );
+        *actualExpr = new CastExpr( *actualExpr, newType );
+      }
+    }
+
+  }
+  if( formal != formals.end() ) {
+    return Cost::infinity;
+  }
+
+  for( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) {
+///     std::cout << std::endl << "converting ";
+///     assert->second.actualType->print( std::cout, 8 );
+///     std::cout << std::endl << " to ";
+///     assert->second.formalType->print( std::cout, 8 );
+    Cost newCost = conversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env );
+///     std::cout << std::endl << "cost of conversion is " << newCost << std::endl;
+    if( newCost == Cost::infinity ) {
+      return newCost;
+    }
+    convCost += newCost;
+
+    convCost += Cost( 0, polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer), 0 );
+  }
+
+  return convCost;
+}
+
+void
+makeUnifiableVars( Type *type, OpenVarSet &unifiableVars, AssertionSet &needAssertions )
+{
+  for( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
+    unifiableVars[ (*tyvar)->get_name() ] = (*tyvar)->get_kind();
+    for( std::list< DeclarationWithType* >::iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) {
+      needAssertions[ *assert ] = true;
+    }
+///     needAssertions.insert( needAssertions.end(), (*tyvar)->get_assertions().begin(), (*tyvar)->get_assertions().end() );
+  }
+}
+
+bool
+AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave )
+{
+  std::list< TypeEnvironment > toBeDone;
+  simpleCombineEnvironments( actuals.begin(), actuals.end(), resultEnv );
+  // make sure we don't widen any existing bindings
+  for( TypeEnvironment::iterator i = resultEnv.begin(); i != resultEnv.end(); ++i ) {
+    i->allowWidening  = false;
+  }
+  resultEnv.extractOpenVars( openVars );
+
+  /*
+  Tuples::NameMatcher matcher( formals );
+  try {
+    matcher.match( actuals );
+  } catch ( Tuples::NoMatch &e ) {
+    std::cerr << "Alternative doesn't match: " << e.message << std::endl;
+  }
+  */
+  std::list< DeclarationWithType* >::iterator formal = formals.begin();
+  for( AltList::const_iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
+    for( std::list< Type* >::iterator actual = actualExpr->expr->get_results().begin(); actual != actualExpr->expr->get_results().end(); ++actual ) {
+      if( formal == formals.end() ) {
+        return isVarArgs;
+      }
+///       std::cerr << "formal type is ";
+///       (*formal)->get_type()->print( std::cerr );
+///       std::cerr << std::endl << "actual type is ";
+///       (*actual)->print( std::cerr );
+///       std::cerr << std::endl;
+      if( !unify( (*formal)->get_type(), *actual, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
+        return false;
+      }
+      formal++;
+    }
+  }
+  // Handling of default values
+  while( formal != formals.end() ) {
+    if( ObjectDecl *od = dynamic_cast<ObjectDecl *>( *formal ) )
+      if( SingleInit *si = dynamic_cast<SingleInit *>( od->get_init() ))
+	// so far, only constant expressions are accepted as default values
+	if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>(si->get_value()) )
+	  if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) )
+	    if( unify( (*formal)->get_type(), cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
+	      // XXX Don't know if this is right
+	      actuals.push_back( Alternative( cnstexpr->clone(), env, Cost::zero ) );
+	      formal++;
+	      if (formal == formals.end()) break;
+	    }
+    return false;
+  }
+  return true;
+}
+
+static const int recursionLimit = 10;
+
+void
+addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer )
+{
+  for( AssertionSet::iterator i = assertSet.begin(); i != assertSet.end(); ++i ) {
+    if( i->second == true ) {
+      i->first->accept( indexer );
+    }
+  }
+}
+
+template< typename ForwardIterator, typename OutputIterator >
+void
+inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, int level, const SymTab::Indexer &indexer, OutputIterator out )
+{
+  if( begin == end ) {
+    if( newNeed.empty() ) {
+      *out++ = newAlt;
+      return;
+    } else if( level >= recursionLimit ) {
+      throw SemanticError( "Too many recursive assertions" );
+    } else {
+      AssertionSet newerNeed;
+///       std::cerr << "recursing with new set:" << std::endl;
+///       printAssertionSet( newNeed, std::cerr, 8 );
+      inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, level+1, indexer, out );
+      return;
+    }
+  }
+
+  ForwardIterator cur = begin++;
+  if( !cur->second ) {
+    inferRecursive( begin, end, newAlt, openVars, decls, newNeed, level, indexer, out );
+  }
+  DeclarationWithType *curDecl = cur->first;
+///   std::cerr << "inferRecursive: assertion is ";
+///   curDecl->print( std::cerr );
+///   std::cerr << std::endl;
+  std::list< DeclarationWithType* > candidates;
+  decls.lookupId( curDecl->get_name(), candidates );
+///   if( candidates.empty() ) { std::cout << "no candidates!" << std::endl; }
+  for( std::list< DeclarationWithType* >::const_iterator candidate = candidates.begin(); candidate != candidates.end(); ++candidate ) {
+///     std::cout << "inferRecursive: candidate is ";
+///     (*candidate)->print( std::cout );
+///     std::cout << std::endl;
+    AssertionSet newHave, newerNeed( newNeed );
+    TypeEnvironment newEnv( newAlt.env );
+    OpenVarSet newOpenVars( openVars );
+    Type *adjType = (*candidate)->get_type()->clone();
+    adjustExprType( adjType, newEnv, indexer );
+    adjType->accept( global_renamer );
+///     std::cerr << "unifying ";
+///     curDecl->get_type()->print( std::cerr );
+///     std::cerr << " with ";
+///     adjType->print( std::cerr );
+///     std::cerr << std::endl;
+    if( unify( curDecl->get_type(), adjType, newEnv, newerNeed, newHave, newOpenVars, indexer ) ) {
+///       std::cerr << "success!" << std::endl;
+      SymTab::Indexer newDecls( decls );
+      addToIndexer( newHave, newDecls );
+      Alternative newerAlt( newAlt );
+      newerAlt.env = newEnv;
+      assert( (*candidate)->get_uniqueId() );
+      Expression *varExpr = new VariableExpr( static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) ) );
+      deleteAll( varExpr->get_results() );
+      varExpr->get_results().clear();
+      varExpr->get_results().push_front( adjType->clone() );
+///       std::cout << "satisfying assertion " << curDecl->get_uniqueId() << " ";
+///       curDecl->print( std::cout );
+///       std::cout << " with declaration " << (*candidate)->get_uniqueId() << " ";
+///       (*candidate)->print( std::cout );
+///       std::cout << std::endl;
+      ApplicationExpr *appExpr = static_cast< ApplicationExpr* >( newerAlt.expr );
+      // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
+      appExpr->get_inferParams()[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
+      inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out );
+    } else {
+      delete adjType;
+    }
+  }
+}
+
+template< typename OutputIterator >
+void
+AlternativeFinder::inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out )
+{
+///   std::cout << "inferParameters: assertions needed are" << std::endl;
+///   printAll( need, std::cout, 8 );
+  SymTab::Indexer decls( indexer );
+///   std::cout << "============= original indexer" << std::endl;
+///   indexer.print( std::cout );
+///   std::cout << "============= new indexer" << std::endl;
+///   decls.print( std::cout );
+  addToIndexer( have, decls );
+  AssertionSet newNeed;
+  inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out );
+///   std::cout << "declaration 14 is ";
+///   Declaration::declFromId
+///    *out++ = newAlt;
+}
+
+template< typename OutputIterator >
+void
+AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out )
+{
+  OpenVarSet openVars;
+  AssertionSet resultNeed, resultHave;
+  TypeEnvironment resultEnv;
+  makeUnifiableVars( funcType, openVars, resultNeed );
+  if( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave ) ) {
+    ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() );
+    Alternative newAlt( appExpr, resultEnv, sumCost( actualAlt ) );
+    makeExprList( actualAlt, appExpr->get_args() );
+///     std::cout << "need assertions:" << std::endl;
+///     printAssertionSet( resultNeed, std::cout, 8 );
+    inferParameters( resultNeed, resultHave, newAlt, openVars, out );
+  }
+}
+
+void
+AlternativeFinder::visit(UntypedExpr *untypedExpr)
+{
+  bool doneInit = false;
+  AlternativeFinder funcOpFinder( indexer, env );
+
+  AlternativeFinder funcFinder( indexer, env );
+  {
+    NameExpr *fname;
+    if ( (fname = dynamic_cast<NameExpr *>(untypedExpr->get_function()))
+	 && ( fname->get_name() == std::string("LabAddress")) ) {
+	alternatives.push_back( Alternative(untypedExpr, env, Cost()) );
+	return;
+      }
+  }
+
+  funcFinder.findWithAdjustment( untypedExpr->get_function() );
+  std::list< AlternativeFinder > argAlternatives;
+  findSubExprs( untypedExpr->begin_args(), untypedExpr->end_args(), back_inserter( argAlternatives ) );
+
+  std::list< AltList > possibilities;
+  combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) );
+
+  Tuples::TupleAssignSpotter tassign(this);
+  if ( tassign.isTupleAssignment(untypedExpr, possibilities) ) {
+    // take care of possible tuple assignments, or discard expression
+    return;
+  } // else ...
+
+  AltList candidates;
+
+  for( AltList::const_iterator func = funcFinder.alternatives.begin(); func != funcFinder.alternatives.end(); ++func ) {
+///     std::cout << "working on alternative: " << std::endl;
+///     func->print( std::cout, 8 );
+    // check if the type is pointer to function
+    PointerType *pointer;
+    if( func->expr->get_results().size() == 1 && ( pointer = dynamic_cast< PointerType* >( func->expr->get_results().front() ) ) ) {
+      if( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
+        for( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
+	  // XXX
+          //Designators::check_alternative( function, *actualAlt );
+          makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
+        }
+      } else if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( pointer->get_base() ) ) {
+        EqvClass eqvClass;
+        if( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
+          if( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
+            for( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
+              makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
+            }
+          }
+        }
+      }
+    } else {
+      // seek a function operator that's compatible
+      if( !doneInit ) {
+        doneInit = true;
+        NameExpr *opExpr = new NameExpr( "?()" );
+        try {
+          funcOpFinder.findWithAdjustment( opExpr );
+        } catch( SemanticError &e ) {
+          // it's ok if there aren't any defined function ops
+        }
+///         std::cout << "known function ops:" << std::endl;
+///         printAlts( funcOpFinder.alternatives, std::cout, 8 );
+      }
+
+      for( AltList::const_iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) {
+        // check if the type is pointer to function
+        PointerType *pointer;
+        if( funcOp->expr->get_results().size() == 1
+        	&& ( pointer = dynamic_cast< PointerType* >( funcOp->expr->get_results().front() ) ) ) {
+          if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
+            for( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
+              AltList currentAlt;
+              currentAlt.push_back( *func );
+              currentAlt.insert( currentAlt.end(), actualAlt->begin(), actualAlt->end() );
+              makeFunctionAlternatives( *funcOp, function, currentAlt, std::back_inserter( candidates ) );
+            }
+          }
+        }
+      }
+    }
+  }
+
+  for( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) {
+    Cost cvtCost = computeConversionCost( *withFunc, indexer );
+
+#ifdef DEBUG_COST
+    ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( withFunc->expr );
+    assert( appExpr );
+    PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
+    assert( pointer );
+    FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
+    assert( function );
+    std::cout << "Case +++++++++++++" << std::endl;
+    std::cout << "formals are:" << std::endl;
+    printAll( function->get_parameters(), std::cout, 8 );
+    std::cout << "actuals are:" << std::endl;
+    printAll( appExpr->get_args(), std::cout, 8 );
+    std::cout << "bindings are:" << std::endl;
+    withFunc->env.print( std::cout, 8 );
+    std::cout << "cost of conversion is:" << cvtCost << std::endl;
+#endif
+
+    if( cvtCost != Cost::infinity ) {
+      withFunc->cvtCost = cvtCost;
+      alternatives.push_back( *withFunc );
+    }
+  }
+  candidates.clear();
+  candidates.splice( candidates.end(), alternatives );
+
+  findMinCost( candidates.begin(), candidates.end(), std::back_inserter( alternatives ) );
+}
+
+bool
+isLvalue( Expression *expr ) {
+  for( std::list< Type* >::const_iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) {
+    if( !(*i)->get_isLvalue() ) return false;
+  }
+  return true;
+}
+
+void
+AlternativeFinder::visit(AddressExpr *addressExpr)
+{
+  AlternativeFinder finder( indexer, env );
+  finder.find( addressExpr->get_arg() );
+  for( std::list< Alternative >::iterator i = finder.alternatives.begin(); i != finder.alternatives.end(); ++i ) {
+    if( isLvalue( i->expr ) ) {
+      alternatives.push_back( Alternative( new AddressExpr( i->expr->clone() ), i->env, i->cost ) );
+    }
+  }
+}
+
+void
+AlternativeFinder::visit(CastExpr *castExpr)
+{
+  for( std::list< Type* >::iterator i = castExpr->get_results().begin(); i != castExpr->get_results().end(); ++i ) {
+    SymTab::validateType( *i, &indexer );
+    adjustExprType( *i, env, indexer );
+  }
+
+  AlternativeFinder finder( indexer, env );
+  finder.findWithAdjustment( castExpr->get_arg() );
+
+  AltList candidates;
+  for( std::list< Alternative >::iterator i = finder.alternatives.begin(); i != finder.alternatives.end(); ++i ) {
+    AssertionSet needAssertions, haveAssertions;
+    OpenVarSet openVars;
+
+    // It's possible that a cast can throw away some values in a multiply-valued expression.
+    // (An example is a cast-to-void, which casts from one value to zero.)
+    // Figure out the prefix of the subexpression results that are cast directly.
+    // The candidate is invalid if it has fewer results than there are types to cast to.
+    int discardedValues = (*i).expr->get_results().size() - castExpr->get_results().size();
+    if( discardedValues < 0 ) continue;
+    std::list< Type* >::iterator candidate_end = (*i).expr->get_results().begin();
+    std::advance( candidate_end, castExpr->get_results().size() );
+    if( !unifyList( (*i).expr->get_results().begin(), candidate_end,
+    	castExpr->get_results().begin(), castExpr->get_results().end(), i->env, needAssertions, haveAssertions, openVars, indexer ) ) continue;
+    Cost thisCost = castCostList( (*i).expr->get_results().begin(), candidate_end,
+    	castExpr->get_results().begin(), castExpr->get_results().end(), indexer, i->env );
+    if( thisCost != Cost::infinity ) {
+      // count one safe conversion for each value that is thrown away
+      thisCost += Cost( 0, 0, discardedValues );
+      CastExpr *newExpr = castExpr->clone();
+      newExpr->set_arg( i->expr->clone() );
+      candidates.push_back( Alternative( newExpr, i->env, i->cost, thisCost ) );
+    }
+  }
+
+  // findMinCost selects the alternatives with the lowest "cost" members, but has the side effect
+  // of copying the cvtCost member to the cost member (since the old cost is now irrelevant).
+  // Thus, calling findMinCost twice selects first based on argument cost, then on conversion cost.
+  AltList minArgCost;
+  findMinCost( candidates.begin(), candidates.end(), std::back_inserter( minArgCost ) );
+  findMinCost( minArgCost.begin(), minArgCost.end(), std::back_inserter( alternatives ) );
+}
+
+void
+AlternativeFinder::visit(UntypedMemberExpr *memberExpr)
+{
+  AlternativeFinder funcFinder( indexer, env );
+  funcFinder.findWithAdjustment( memberExpr->get_aggregate() );
+
+  for( AltList::const_iterator agg = funcFinder.alternatives.begin(); agg != funcFinder.alternatives.end(); ++agg ) {
+    if( agg->expr->get_results().size() == 1 ) {
+      if( StructInstType *structInst = dynamic_cast< StructInstType* >( agg->expr->get_results().front() ) ) {
+        addAggMembers( structInst, agg->expr, agg->cost, memberExpr->get_member() );
+      } else if( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( agg->expr->get_results().front() ) ) {
+        addAggMembers( unionInst, agg->expr, agg->cost, memberExpr->get_member() );
+      }
+    }
+  }
+}
+
+void
+AlternativeFinder::visit(MemberExpr *memberExpr)
+{
+  alternatives.push_back( Alternative( memberExpr->clone(), env, Cost::zero ) );
+}
+
+void
+AlternativeFinder::visit(NameExpr *nameExpr)
+{
+  std::list< DeclarationWithType* > declList;
+  indexer.lookupId( nameExpr->get_name(), declList );
+///     std::cerr << "nameExpr is " << nameExpr->get_name() << std::endl;
+  for( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) {
+    VariableExpr newExpr( *i, nameExpr->get_argName() );
+    alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) );
+///     std::cerr << "decl is ";
+///     (*i)->print( std::cerr );
+///     std::cerr << std::endl;
+///     std::cerr << "newExpr is ";
+///     newExpr.print( std::cerr );
+///     std::cerr << std::endl;
+    renameTypes( alternatives.back().expr );
+    if( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) {
+      addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), "" );
+    } else if( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) {
+      addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), "" );
+    }
+  }
+}
+
+void
+AlternativeFinder::visit(VariableExpr *variableExpr)
+{
+  alternatives.push_back( Alternative( variableExpr->clone(), env, Cost::zero ) );
+}
+
+void
+AlternativeFinder::visit(ConstantExpr *constantExpr)
+{
+  alternatives.push_back( Alternative( constantExpr->clone(), env, Cost::zero ) );
+}
+
+void
+AlternativeFinder::visit(SizeofExpr *sizeofExpr)
+{
+  if( sizeofExpr->get_isType() ) {
+    alternatives.push_back( Alternative( sizeofExpr->clone(), env, Cost::zero ) );
+  } else {
+    AlternativeFinder finder( indexer, env );
+    finder.find( sizeofExpr->get_expr() );
+    if( finder.alternatives.size() != 1 ) {
+      throw SemanticError( "Ambiguous expression in sizeof operand: ", sizeofExpr->get_expr() );
+    }
+    Alternative &choice = finder.alternatives.front();
+    alternatives.push_back( Alternative( new SizeofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
+  }
+}
+
+void
+AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env )
+{
+  // assume no polymorphism
+  // assume no implicit conversions
+  assert( function->get_parameters().size() == 1 );
+///   std::cout << "resolvAttr: funcDecl is ";
+///   funcDecl->print( std::cout );
+///   std::cout << " argType is ";
+///   argType->print( std::cout );
+///   std::cout << std::endl;
+  if( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) {
+    alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) );
+    for( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) {
+      alternatives.back().expr->get_results().push_back( (*i)->get_type()->clone() );
+    }
+  }
+}
+
+void
+AlternativeFinder::visit(AttrExpr *attrExpr)
+{
+  // assume no 'pointer-to-attribute'
+  NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );
+  assert( nameExpr );
+  std::list< DeclarationWithType* > attrList;
+  indexer.lookupId( nameExpr->get_name(), attrList );
+  if( attrExpr->get_isType() || attrExpr->get_expr() ) {
+    for( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) {
+      // check if the type is function
+      if( FunctionType *function = dynamic_cast< FunctionType* >( (*i)->get_type() ) ) {
+        // assume exactly one parameter
+        if( function->get_parameters().size() == 1 ) {
+          if( attrExpr->get_isType() ) {
+            resolveAttr( *i, function, attrExpr->get_type(), env );
+          } else {
+            AlternativeFinder finder( indexer, env );
+            finder.find( attrExpr->get_expr() );
+            for( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) {
+              if( choice->expr->get_results().size() == 1 ) {
+                resolveAttr(*i, function, choice->expr->get_results().front(), choice->env );
+              }
+            }
+          }
+        }
+      }
+    }
+  } else {
+    for( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) {
+      VariableExpr newExpr( *i );
+      alternatives.push_back( Alternative( newExpr.clone(), env, Cost() ) );
+      renameTypes( alternatives.back().expr );
+    }
+  }
+}
+
+void
+AlternativeFinder::visit(LogicalExpr *logicalExpr)
+{
+  AlternativeFinder firstFinder( indexer, env );
+  firstFinder.findWithAdjustment( logicalExpr->get_arg1() );
+  for( AltList::const_iterator first = firstFinder.alternatives.begin(); first != firstFinder.alternatives.end(); ++first ) {
+    AlternativeFinder secondFinder( indexer, first->env );
+    secondFinder.findWithAdjustment( logicalExpr->get_arg2() );
+    for( AltList::const_iterator second = secondFinder.alternatives.begin(); second != secondFinder.alternatives.end(); ++second ) {
+      LogicalExpr *newExpr = new LogicalExpr( first->expr->clone(), second->expr->clone(), logicalExpr->get_isAnd() );
+      alternatives.push_back( Alternative( newExpr, second->env, first->cost + second->cost ) );
+    }
+  }
+}
+
+void
+AlternativeFinder::visit(ConditionalExpr *conditionalExpr)
+{
+  AlternativeFinder firstFinder( indexer, env );
+  firstFinder.findWithAdjustment( conditionalExpr->get_arg1() );
+  for( AltList::const_iterator first = firstFinder.alternatives.begin(); first != firstFinder.alternatives.end(); ++first ) {
+    AlternativeFinder secondFinder( indexer, first->env );
+    secondFinder.findWithAdjustment( conditionalExpr->get_arg2() );
+    for( AltList::const_iterator second = secondFinder.alternatives.begin(); second != secondFinder.alternatives.end(); ++second ) {
+      AlternativeFinder thirdFinder( indexer, second->env );
+      thirdFinder.findWithAdjustment( conditionalExpr->get_arg3() );
+      for( AltList::const_iterator third = thirdFinder.alternatives.begin(); third != thirdFinder.alternatives.end(); ++third ) {
+        OpenVarSet openVars;
+        AssertionSet needAssertions, haveAssertions;
+        Alternative newAlt( 0, third->env, first->cost + second->cost + third->cost );
+        std::list< Type* > commonTypes;
+        if( unifyList( second->expr->get_results().begin(), second->expr->get_results().end(), third->expr->get_results().begin(), third->expr->get_results().end(), newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) {
+          ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() );
+          std::list< Type* >::const_iterator original = second->expr->get_results().begin();
+          std::list< Type* >::const_iterator commonType = commonTypes.begin();
+          for( ; original != second->expr->get_results().end() && commonType != commonTypes.end(); ++original, ++commonType ) {
+            if( *commonType ) {
+              newExpr->get_results().push_back( *commonType );
+            } else {
+              newExpr->get_results().push_back( (*original)->clone() );
+            }
+          }
+          newAlt.expr = newExpr;
+          inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
+        }
+      }
+    }
+  }
+}
+
+void
+AlternativeFinder::visit(CommaExpr *commaExpr)
+{
+  TypeEnvironment newEnv( env );
+  Expression *newFirstArg = resolveInVoidContext( commaExpr->get_arg1(), indexer, newEnv );
+  AlternativeFinder secondFinder( indexer, newEnv );
+  secondFinder.findWithAdjustment( commaExpr->get_arg2() );
+  for( AltList::const_iterator alt = secondFinder.alternatives.begin(); alt != secondFinder.alternatives.end(); ++alt ) {
+    alternatives.push_back( Alternative( new CommaExpr( newFirstArg->clone(), alt->expr->clone() ), alt->env, alt->cost ) );
+  }
+  delete newFirstArg;
+}
+
+void
+AlternativeFinder::visit(TupleExpr *tupleExpr)
+{
+  std::list< AlternativeFinder > subExprAlternatives;
+  findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), back_inserter( subExprAlternatives ) );
+  std::list< AltList > possibilities;
+  combos( subExprAlternatives.begin(), subExprAlternatives.end(), back_inserter( possibilities ) );
+  for( std::list< AltList >::const_iterator i = possibilities.begin(); i != possibilities.end(); ++i ) {
+    TupleExpr *newExpr = new TupleExpr;
+    makeExprList( *i, newExpr->get_exprs() );
+    for( std::list< Expression* >::const_iterator resultExpr = newExpr->get_exprs().begin(); resultExpr != newExpr->get_exprs().end(); ++resultExpr ) {
+      for( std::list< Type* >::const_iterator resultType = (*resultExpr)->get_results().begin(); resultType != (*resultExpr)->get_results().end(); ++resultType ) {
+        newExpr->get_results().push_back( (*resultType)->clone() );
+      }
+    }
+
+    TypeEnvironment compositeEnv;
+    simpleCombineEnvironments( i->begin(), i->end(), compositeEnv );
+    alternatives.push_back( Alternative( newExpr, compositeEnv, sumCost( *i ) ) );
+  }
+}
+
+} // namespace ResolvExpr
Index: translator/ResolvExpr/AlternativeFinder.h
===================================================================
--- translator/ResolvExpr/AlternativeFinder.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/AlternativeFinder.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,79 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: AlternativeFinder.h,v 1.19 2005/08/29 20:14:15 rcbilson Exp $
+ *
+ */
+
+#ifndef RESOLVEXPR_ALTERNATIVEFINDER_H
+#define RESOLVEXPR_ALTERNATIVEFINDER_H
+
+#include <set>
+
+#include "Alternative.h"
+#include "Unify.h"
+#include "SynTree/SynTree.h"
+#include "SymTab/Indexer.h"
+#include "SynTree/TypeSubstitution.h"
+
+namespace ResolvExpr {
+
+class AlternativeFinder : public Visitor
+{
+public:
+  AlternativeFinder( const SymTab::Indexer &indexer, const TypeEnvironment &env );
+  void find( Expression *expr, bool adjust = false );
+  void findWithAdjustment( Expression *expr );
+  AltList &get_alternatives() { return alternatives; }
+  
+  // make this look like an STL container so that we can apply generic algorithms
+  typedef Alternative value_type;
+  typedef AltList::iterator iterator;
+  typedef AltList::const_iterator const_iterator;
+  AltList::iterator begin() { return alternatives.begin(); }
+  AltList::iterator end() { return alternatives.end(); }
+  AltList::const_iterator begin() const { return alternatives.begin(); }
+  AltList::const_iterator end() const { return alternatives.end(); }
+  
+  const SymTab::Indexer &get_indexer() const { return indexer; }
+  const TypeEnvironment &get_environ() const { return env; }
+private:
+  virtual void visit(ApplicationExpr *applicationExpr);
+  virtual void visit(UntypedExpr *untypedExpr);
+  virtual void visit(AddressExpr *addressExpr);
+  virtual void visit(CastExpr *castExpr);
+  virtual void visit(UntypedMemberExpr *memberExpr);
+  virtual void visit(MemberExpr *memberExpr);
+  virtual void visit(NameExpr *variableExpr);
+  virtual void visit(VariableExpr *variableExpr);
+  virtual void visit(ConstantExpr *constantExpr); 
+  virtual void visit(SizeofExpr *sizeofExpr);
+  virtual void visit(AttrExpr *attrExpr);
+  virtual void visit(LogicalExpr *logicalExpr);
+  virtual void visit(ConditionalExpr *conditionalExpr);
+  virtual void visit(CommaExpr *commaExpr);
+  virtual void visit(TupleExpr *tupleExpr);
+ public:  // xxx - temporary hack - should make Tuples::TupleAssignment a friend
+  template< typename InputIterator, typename OutputIterator >
+  void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out );
+
+ private:
+  template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const std::string &name );
+  bool instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave );
+  template< typename OutputIterator >
+  void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, AltList &actualAlt, OutputIterator out );
+  template< typename OutputIterator >
+  void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out );
+  void resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env );
+
+  const SymTab::Indexer &indexer;
+  AltList alternatives;
+  const TypeEnvironment &env;
+};
+
+Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env )
+;
+
+} // namespace ResolvExpr
+
+#endif /* #ifndef RESOLVEXPR_ALTERNATIVEFINDER_H */
Index: translator/ResolvExpr/AlternativePrinter.cc
===================================================================
--- translator/ResolvExpr/AlternativePrinter.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/AlternativePrinter.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: AlternativePrinter.cc,v 1.5 2005/08/29 20:14:15 rcbilson Exp $
+ *
+ */
+
+#include "AlternativePrinter.h"
+#include "AlternativeFinder.h"
+#include "Alternative.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Type.h"
+#include "SynTree/Expression.h"
+#include "utility.h"
+
+namespace ResolvExpr {
+
+AlternativePrinter::AlternativePrinter( std::ostream &os )
+  : SymTab::Indexer( false ), os( os )
+{
+}
+
+void 
+AlternativePrinter::visit(ExprStmt *exprStmt)
+{
+  TypeEnvironment env;
+  AlternativeFinder finder( *this, env );
+  finder.findWithAdjustment( exprStmt->get_expr() );
+  int count = 1;
+  os << "There are " << finder.get_alternatives().size() << " alternatives" << std::endl;
+  for( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
+    os << "Alternative " << count++ << " ==============" << std::endl;
+    printAll( i->expr->get_results(), os );
+//    i->print( os );
+    os << std::endl;
+  }
+}
+
+} // namespace ResolvExpr
Index: translator/ResolvExpr/AlternativePrinter.h
===================================================================
--- translator/ResolvExpr/AlternativePrinter.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/AlternativePrinter.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,30 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: AlternativePrinter.h,v 1.2 2005/08/29 20:14:15 rcbilson Exp $
+ *
+ */
+
+#ifndef RESOLVEXPR_ALTERNATIVEPRINTER_H
+#define RESOLVEXPR_ALTERNATIVEPRINTER_H
+
+#include <iostream>
+
+#include "Alternative.h"
+#include "SymTab/Indexer.h"
+
+namespace ResolvExpr {
+
+class AlternativePrinter : public SymTab::Indexer
+{
+public:
+  AlternativePrinter( std::ostream &os );
+  virtual void visit(ExprStmt *exprStmt);
+
+private:
+  std::ostream &os;
+};
+
+} // namespace ResolvExpr
+
+#endif /* #ifndef RESOLVEXPR_ALTERNATIVEPRINTER_H */
Index: translator/ResolvExpr/CastCost.cc
===================================================================
--- translator/ResolvExpr/CastCost.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/CastCost.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,105 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: CastCost.cc,v 1.11 2005/08/29 20:14:15 rcbilson Exp $
+ *
+ */
+
+#include "typeops.h"
+#include "Cost.h"
+#include "ConversionCost.h"
+#include "SynTree/Type.h"
+#include "SynTree/Visitor.h"
+#include "SymTab/Indexer.h"
+
+
+namespace ResolvExpr {
+
+class CastCost : public ConversionCost
+{
+public:
+  CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
+  
+  virtual void visit(BasicType *basicType);
+  virtual void visit(PointerType *pointerType);
+};
+
+Cost
+castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env )
+{
+//  std::cout << "casting" << std::endl;
+//  src->print( std::cout, 8 );
+//  std::cout << std::endl << "to" << std::endl;
+//  dest->print( std::cout, 8 );
+  if( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
+    EqvClass eqvClass;
+    NamedTypeDecl *namedType;
+    if( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
+      return castCost( src, eqvClass.type, indexer, env );
+    } else if( ( namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) ) {
+      TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
+      // all typedefs should be gone by this point
+      assert( type );
+      if( type->get_base() ) {
+        return castCost( src, type->get_base(), indexer, env ) + Cost( 0, 0, 1 );
+      }
+    }
+  }
+  if( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) {
+//    std::cout << "types are compatible" << std::endl;
+    return Cost( 0, 0, 0 );
+  } else if( dynamic_cast< VoidType* >( dest ) ) {
+//    std::cout << "destination is void" << std::endl;
+    return Cost( 0, 0, 1 );
+  } else {
+    CastCost converter( dest, indexer, env );
+    src->accept( converter );
+//    std::cout << "cost is " << converter.get_cost() << std::endl;
+    if( converter.get_cost() == Cost::infinity ) {
+      return Cost::infinity;
+    } else {
+      return converter.get_cost() + Cost( 0, 0, 0 );
+    }
+  }
+}
+
+CastCost::CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env )
+  : ConversionCost( dest, indexer, env )
+{
+}
+
+void 
+CastCost::visit(BasicType *basicType)
+{
+  if( dynamic_cast< PointerType* >( dest ) ) {
+    cost = Cost( 1, 0, 0 );
+  } else {
+    ConversionCost::visit( basicType );
+  }
+}
+
+void 
+CastCost::visit(PointerType *pointerType)
+{
+  if( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
+    if( pointerType->get_qualifiers() <= destAsPtr->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) {
+      cost = Cost( 0, 0, 1 );
+    } else if( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
+      if( destAsBasic->isInteger() ) {
+        cost = Cost( 1, 0, 0 );
+      }
+    } else {
+      TypeEnvironment newEnv( env );
+      newEnv.add( pointerType->get_forall() );
+      newEnv.add( pointerType->get_base()->get_forall() );
+      int assignResult = ptrsCastable( pointerType->get_base(), destAsPtr->get_base(), newEnv, indexer );
+      if( assignResult > 0 ) {
+        cost = Cost( 0, 0, 1 );
+      } else if( assignResult < 0 ) {
+        cost = Cost( 1, 0, 0 );
+      }
+    }
+  }
+}
+
+} // namespace ResolvExpr
Index: translator/ResolvExpr/CommonType.cc
===================================================================
--- translator/ResolvExpr/CommonType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/CommonType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,239 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: CommonType.cc,v 1.6 2005/08/29 20:14:15 rcbilson Exp $
+ *
+ */
+
+#include "typeops.h"
+#include "SynTree/Type.h"
+#include "Unify.h"
+
+
+/// #define DEBUG
+
+namespace ResolvExpr {
+
+class CommonType : public Visitor
+{
+public:
+  CommonType( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
+  
+  Type *get_result() const { return result; }
+
+private:
+  virtual void visit( VoidType *voidType );
+  virtual void visit( BasicType *basicType );
+  virtual void visit( PointerType *pointerType );
+  virtual void visit( ArrayType *arrayType );
+  virtual void visit( FunctionType *functionType );
+  virtual void visit( StructInstType *aggregateUseType );
+  virtual void visit( UnionInstType *aggregateUseType );
+  virtual void visit( EnumInstType *aggregateUseType );
+  virtual void visit( ContextInstType *aggregateUseType );
+  virtual void visit( TypeInstType *aggregateUseType );
+  virtual void visit( TupleType *tupleType );
+
+  template< typename RefType > void handleRefType( RefType *inst, Type *other );
+
+  Type *result;
+  Type *type2;				// inherited
+  bool widenFirst, widenSecond;
+  const SymTab::Indexer &indexer;
+  TypeEnvironment &env;
+  const OpenVarSet &openVars;
+};
+
+Type *
+commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )
+{
+  CommonType visitor( type2, widenFirst, widenSecond, indexer, env, openVars );
+  type1->accept( visitor );
+  Type *result = visitor.get_result();
+  if( !result ) {
+    if( widenSecond ) {
+      TypeInstType *inst = dynamic_cast< TypeInstType* >( type2 );
+      if( inst ) {
+        NamedTypeDecl *nt = indexer.lookupType( inst->get_name() );
+        if( nt ) {
+          TypeDecl *type = dynamic_cast< TypeDecl* >( nt );
+          assert( type );
+          if( type->get_base() ) {
+            Type::Qualifiers tq1 = type1->get_qualifiers(), tq2 = type2->get_qualifiers();
+            AssertionSet have, need;
+            OpenVarSet newOpen( openVars );
+            type1->get_qualifiers() = Type::Qualifiers();
+            type->get_base()->get_qualifiers() = tq1;
+            if( unifyExact( type1, type->get_base(), env, have, need, newOpen, indexer ) ) {
+              result = type1->clone();
+              result->get_qualifiers() = tq1 + tq2;
+            }
+            type1->get_qualifiers() = tq1;
+            type->get_base()->get_qualifiers() = Type::Qualifiers();
+          }
+        }
+      }
+    }
+  }
+#ifdef DEBUG
+  std::cout << "============= commonType" << std::endl << "type1 is ";
+  type1->print( std::cout );
+  std::cout << " type2 is ";
+  type2->print( std::cout );
+  if( result ) {
+    std::cout << " common type is ";
+    result->print( std::cout );
+  } else {
+    std::cout << " no common type";
+  }
+  std::cout << std::endl;
+#endif
+  return result;
+}
+
+static const BasicType::Kind combinedType[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] =
+{
+/* 		Bool		Char	SignedChar	UnsignedChar	ShortSignedInt	ShortUnsignedInt	SignedInt	UnsignedInt	LongSignedInt	LongUnsignedInt	LongLongSignedInt	LongLongUnsignedInt	Float	Double	LongDouble	FloatComplex	DoubleComplex	LongDoubleComplex	FloatImaginary	DoubleImaginary	LongDoubleImaginary */
+/* Bool */ 	{ BasicType::Bool,		BasicType::Char,	BasicType::SignedChar,	BasicType::UnsignedChar,	BasicType::ShortSignedInt,	BasicType::ShortUnsignedInt,	BasicType::SignedInt,	BasicType::UnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex },
+/* Char */ 	{ BasicType::Char,		BasicType::Char,	BasicType::UnsignedChar,	BasicType::UnsignedChar,	BasicType::ShortSignedInt,	BasicType::ShortUnsignedInt,	BasicType::SignedInt,	BasicType::UnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex },
+/* SignedChar */ 	{ BasicType::SignedChar,	BasicType::UnsignedChar,	BasicType::SignedChar,	BasicType::UnsignedChar,	BasicType::ShortSignedInt,	BasicType::ShortUnsignedInt,	BasicType::SignedInt,	BasicType::UnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex },
+/* UnsignedChar */ 	{ BasicType::UnsignedChar,	BasicType::UnsignedChar,	BasicType::UnsignedChar,	BasicType::UnsignedChar,	BasicType::ShortSignedInt,	BasicType::ShortUnsignedInt,	BasicType::SignedInt,	BasicType::UnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex },
+/* ShortSignedInt */ 	{ BasicType::ShortSignedInt,	BasicType::ShortSignedInt,	BasicType::ShortSignedInt,	BasicType::ShortSignedInt,	BasicType::ShortSignedInt,	BasicType::ShortUnsignedInt,	BasicType::SignedInt,	BasicType::UnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex },
+/* ShortUnsignedInt */ 	{ BasicType::ShortUnsignedInt,	BasicType::ShortUnsignedInt,	BasicType::ShortUnsignedInt,	BasicType::ShortUnsignedInt,	BasicType::ShortUnsignedInt,	BasicType::ShortUnsignedInt,	BasicType::SignedInt,	BasicType::UnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex },
+/* SignedInt */ 	{ BasicType::SignedInt,		BasicType::SignedInt,	BasicType::SignedInt,	BasicType::SignedInt,	BasicType::SignedInt,	BasicType::SignedInt,	BasicType::SignedInt,	BasicType::UnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex },
+/* UnsignedInt */ 	{ BasicType::UnsignedInt,		BasicType::UnsignedInt,	BasicType::UnsignedInt,	BasicType::UnsignedInt,	BasicType::UnsignedInt,	BasicType::UnsignedInt,	BasicType::UnsignedInt,	BasicType::UnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex },
+/* LongSignedInt */ 	{ BasicType::LongSignedInt,		BasicType::LongSignedInt,	BasicType::LongSignedInt,	BasicType::LongSignedInt,	BasicType::LongSignedInt,	BasicType::LongSignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongSignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex },
+/* LongUnsignedInt */ 	{ BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongUnsignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex },
+/* LongLongSignedInt */ 	{ BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongSignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex },
+/* LongLongUnsignedInt */ 	{ BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::LongLongUnsignedInt,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex },
+/* Float */ 	{ BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Float,	BasicType::Double,	BasicType::LongDouble,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex },
+/* Double */ 	{ BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::Double,	BasicType::LongDouble,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex },
+/* LongDouble */ 	{ BasicType::LongDouble,		BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDouble,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex },
+/* FloatComplex */ 	{ BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex },
+/* DoubleComplex */ 	{ BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex },
+/* LongDoubleComplex */ 	{ BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex },
+/* FloatImaginary */ 	{ BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::FloatImaginary,	BasicType::DoubleImaginary,	BasicType::LongDoubleImaginary },
+/* DoubleImaginary */ 	{ BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::DoubleComplex,	BasicType::DoubleComplex,	BasicType::LongDoubleComplex,	BasicType::DoubleImaginary,	BasicType::DoubleImaginary,	BasicType::LongDoubleImaginary },
+/* LongDoubleImaginary */ 	{ BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleComplex,	BasicType::LongDoubleImaginary,	BasicType::LongDoubleImaginary,	BasicType::LongDoubleImaginary }
+};
+
+CommonType::CommonType( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )
+  : result( 0 ), type2( type2 ), widenFirst( widenFirst ), widenSecond( widenSecond ), indexer( indexer ), env( env ), openVars( openVars )
+{
+}
+
+void 
+CommonType::visit( VoidType *voidType )
+{
+}
+
+void 
+CommonType::visit( BasicType *basicType )
+{
+  if( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) {
+    BasicType::Kind newType = combinedType[ basicType->get_kind() ][ otherBasic->get_kind() ];
+    if( ( ( newType == basicType->get_kind() && basicType->get_qualifiers() >= otherBasic->get_qualifiers() ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->get_qualifiers() <= otherBasic->get_qualifiers() ) || widenSecond ) ) {
+      result = new BasicType( basicType->get_qualifiers() + otherBasic->get_qualifiers(), newType );
+    }
+  }
+}
+
+void 
+CommonType::visit( PointerType *pointerType )
+{
+  if( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) {
+    if( widenFirst && dynamic_cast< VoidType* >( otherPointer->get_base() ) ) {
+      result = otherPointer->clone();
+      result->get_qualifiers() += pointerType->get_qualifiers();
+    } else if( widenSecond && dynamic_cast< VoidType* >( pointerType->get_base() ) ) {
+      result = pointerType->clone();
+      result->get_qualifiers() += otherPointer->get_qualifiers();
+    } else if( ( pointerType->get_base()->get_qualifiers() >= otherPointer->get_base()->get_qualifiers() || widenFirst )
+               && ( pointerType->get_base()->get_qualifiers() <= otherPointer->get_base()->get_qualifiers() || widenSecond ) ) {
+      Type::Qualifiers tq1 = pointerType->get_base()->get_qualifiers(), tq2 = otherPointer->get_base()->get_qualifiers();
+      pointerType->get_base()->get_qualifiers() = Type::Qualifiers();
+      otherPointer->get_base()->get_qualifiers() = Type::Qualifiers();
+      AssertionSet have, need;
+      OpenVarSet newOpen( openVars );
+      if( unifyExact( pointerType->get_base(), otherPointer->get_base(), env, have, need, newOpen, indexer ) ) {
+        if( tq1 < tq2 ) {
+          result = pointerType->clone();
+        } else {
+          result = otherPointer->clone();
+        }
+        result->get_qualifiers() = tq1 + tq2;
+      } else {
+        /// std::cout << "place for ptr-to-type" << std::endl;
+      }
+      pointerType->get_base()->get_qualifiers() = tq1;
+      otherPointer->get_base()->get_qualifiers() = tq2;
+    }
+  }
+}
+
+void 
+CommonType::visit( ArrayType *arrayType )
+{
+}
+
+void 
+CommonType::visit( FunctionType *functionType )
+{
+}
+
+template< typename RefType > void 
+CommonType::handleRefType( RefType *inst, Type *other )
+{
+}
+
+void 
+CommonType::visit( StructInstType *aggregateUseType )
+{
+}
+
+void 
+CommonType::visit( UnionInstType *aggregateUseType )
+{
+}
+
+void 
+CommonType::visit( EnumInstType *aggregateUseType )
+{
+}
+
+void 
+CommonType::visit( ContextInstType *aggregateUseType )
+{
+}
+
+void 
+CommonType::visit( TypeInstType *inst )
+{
+  if( widenFirst ) {
+    NamedTypeDecl *nt = indexer.lookupType( inst->get_name() );
+    if( nt ) {
+      TypeDecl *type = dynamic_cast< TypeDecl* >( nt );
+      assert( type );
+      if( type->get_base() ) {
+        Type::Qualifiers tq1 = inst->get_qualifiers(), tq2 = type2->get_qualifiers();
+        AssertionSet have, need;
+        OpenVarSet newOpen( openVars );
+        type2->get_qualifiers() = Type::Qualifiers();
+        type->get_base()->get_qualifiers() = tq1;
+        if( unifyExact( type->get_base(), type2, env, have, need, newOpen, indexer ) ) {
+          result = type2->clone();
+          result->get_qualifiers() = tq1 + tq2;
+        }
+        type2->get_qualifiers() = tq2;
+        type->get_base()->get_qualifiers() = Type::Qualifiers();
+      }
+    }
+  }
+}
+
+void 
+CommonType::visit( TupleType *tupleType )
+{
+}
+
+} // namespace ResolvExpr
Index: translator/ResolvExpr/ConversionCost.cc
===================================================================
--- translator/ResolvExpr/ConversionCost.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/ConversionCost.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,269 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: ConversionCost.cc,v 1.11 2005/08/29 20:14:15 rcbilson Exp $
+ *
+ */
+
+#include "ConversionCost.h"
+#include "typeops.h"
+#include "SynTree/Type.h"
+#include "SynTree/Visitor.h"
+#include "SymTab/Indexer.h"
+
+
+namespace ResolvExpr {
+
+const Cost Cost::zero = Cost( 0, 0, 0 );
+const Cost Cost::infinity = Cost( -1, -1, -1 );
+
+Cost
+conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env )
+{
+  if( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
+    EqvClass eqvClass;
+    NamedTypeDecl *namedType;
+///     std::cout << "type inst " << destAsTypeInst->get_name();
+    if( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
+      return conversionCost( src, eqvClass.type, indexer, env );
+    } else if( ( namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) ) {
+///       std::cout << " found" << std::endl;
+      TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
+      // all typedefs should be gone by this point
+      assert( type );
+      if( type->get_base() ) {
+        return conversionCost( src, type->get_base(), indexer, env ) + Cost( 0, 0, 1 );
+      }
+    }
+///     std::cout << " not found" << std::endl;
+  }
+///   std::cout << "src is ";
+///   src->print( std::cout );
+///   std::cout << std::endl << "dest is ";
+///   dest->print( std::cout );
+///   std::cout << std::endl << "env is" << std::endl;
+///   env.print( std::cout, 8 );
+  if( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) {
+///     std::cout << "compatible!" << std::endl;
+    return Cost( 0, 0, 0 );
+  } else if( dynamic_cast< VoidType* >( dest ) ) {
+    return Cost( 0, 0, 1 );
+  } else {
+    ConversionCost converter( dest, indexer, env );
+    src->accept( converter );
+    if( converter.get_cost() == Cost::infinity ) {
+      return Cost::infinity;
+    } else {
+      return converter.get_cost() + Cost( 0, 0, 0 );
+    }
+  }
+}
+
+ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env )
+  : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env )
+{
+}
+
+/*
+Old
+===
+                     Double
+                       |
+                     Float
+                       |
+                     ULong
+                     /   \
+                  UInt    Long
+                     \   /
+                      Int
+                       |
+                     Ushort
+                       |
+                     Short
+                       |
+                     Uchar
+                     /   \
+                 Schar   Char
+
+New
+===
+                               +-----LongDoubleComplex--+
+                   LongDouble--+          |             +-LongDoubleImag
+                       |         +---DoubleComplex---+         |
+                     Double------+        |          +----DoubleImag
+                       |           +-FloatComplex-+            |
+                     Float---------+              +-------FloatImag
+                       |
+                   ULongLong
+                       |
+                   LongLong
+                       |
+                     ULong
+                     /   \
+                  UInt    Long
+                     \   /
+                      Int
+                       |
+                     Ushort
+                       |
+                     Short
+                       |
+                     Uchar
+                     /   \
+                 Schar   Char
+                     \   /
+                      Bool
+*/
+
+static const int costMatrix[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] =
+{
+/* Src \ Dest:	Bool	Char	SChar	UChar	Short	UShort	Int	UInt	Long	ULong	LLong	ULLong	Float	Double	LDbl	FCplex	DCplex	LDCplex	FImag	DImag	LDImag */
+/* Bool */ 	{ 0,	1,	1,	2,	3,	4,	5,	6,	6,	7,	8,	9,	10,	11,	12,	11,	12,	13,	-1,	-1,	-1 },
+/* Char */ 	{ -1,	0,	-1,	1,	2,	3,	4,	5,	5,	6,	7,	8,	9,	10,	11,	10,	11,	12,	-1,	-1,	-1 },
+/* SChar */ 	{ -1,	-1,	0,	1,	2,	3,	4,	5,	5,	6,	7,	8,	9,	10,	11,	10,	11,	12,	-1,	-1,	-1 },
+/* UChar */ 	{ -1,	-1,	-1,	0,	1,	2,	3,	4,	4,	5,	6,	7,	8,	9,	10,	9,	10,	11,	-1,	-1,	-1 },
+/* Short */ 	{ -1,	-1,	-1,	-1,	0,	1,	2,	3,	3,	4,	5,	6,	7,	8,	9,	8,	9,	10,	-1,	-1,	-1 },
+/* UShort */ 	{ -1,	-1,	-1,	-1,	-1,	0,	1,	2,	2,	3,	4,	5,	6,	7,	8,	7,	8,	9,	-1,	-1,	-1 },
+/* Int */ 	{ -1,	-1,	-1,	-1,	-1,	-1,	0,	1,	1,	2,	3,	4,	5,	6,	7,	6,	7,	8,	-1,	-1,	-1 },
+/* UInt */ 	{ -1,	-1,	-1,	-1,	-1,	-1,	-1,	0,	-1,	1,	2,	3,	4,	5,	6,	5,	6,	7,	-1,	-1,	-1 },
+/* Long */ 	{ -1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	0,	1,	2,	3,	4,	5,	6,	5,	6,	7,	-1,	-1,	-1 },
+/* ULong */ 	{ -1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	0,	1,	2,	3,	4,	5,	4,	5,	6,	-1,	-1,	-1 },
+/* LLong */ 	{ -1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	0,	1,	2,	3,	4,	3,	4,	5,	-1,	-1,	-1 },
+/* ULLong */ 	{ -1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	0,	1,	2,	3,	2,	3,	4,	-1,	-1,	-1 },
+/* Float */ 	{ -1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	0,	1,	2,	1,	2,	3,	-1,	-1,	-1 },
+/* Double */ 	{ -1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	0,	1,	-1,	1,	2,	-1,	-1,	-1 },
+/* LDbl */ 	{ -1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	0,	-1,	-1,	1,	-1,	-1,	-1 },
+/* FCplex */ 	{ -1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	0,	1,	2,	-1,	-1,	-1 },
+/* DCplex */ 	{ -1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	0,	1,	-1,	-1,	-1 },
+/* LDCplex */ 	{ -1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	0,	-1,	-1,	-1 },
+/* FImag */ 	{ -1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	1,	2,	3,	0,	1,	2 },
+/* DImag */ 	{ -1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	1,	2,	-1,	0,	1 },
+/* LDImag */ 	{ -1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	-1,	1,	-1,	-1,	0 }
+};
+
+void 
+ConversionCost::visit(VoidType *voidType)
+{
+  cost = Cost::infinity;
+}
+
+void 
+ConversionCost::visit(BasicType *basicType)
+{
+  if( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
+    int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
+    if( tableResult == -1 ) {
+      cost = Cost( 1, 0, 0 );
+    } else {
+      cost = Cost( 0, 0, tableResult );
+    }
+  }
+}
+
+void 
+ConversionCost::visit(PointerType *pointerType)
+{
+  if( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
+    if( pointerType->get_base()->get_qualifiers() <= destAsPtr->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) {
+      cost = Cost( 0, 0, 1 );
+    } else {
+      int assignResult = ptrsAssignable( pointerType->get_base(), destAsPtr->get_base(), env );
+      if( assignResult < 0 ) {
+        cost = Cost( 0, 0, 1 );
+      } else if( assignResult > 0 ) {
+        cost = Cost( 1, 0, 0 );
+      }
+    }
+  }
+}
+
+void 
+ConversionCost::visit(ArrayType *arrayType)
+{
+}
+
+void 
+ConversionCost::visit(FunctionType *functionType)
+{
+}
+
+void 
+ConversionCost::visit(StructInstType *inst)
+{
+  if( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
+    if( inst->get_name() == destAsInst->get_name() ) {
+      cost = Cost::zero;
+    }
+  }
+}
+
+void 
+ConversionCost::visit(UnionInstType *inst)
+{
+  if( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
+    if( inst->get_name() == destAsInst->get_name() ) {
+      cost = Cost::zero;
+    }
+  }
+}
+
+void 
+ConversionCost::visit(EnumInstType *inst)
+{
+  static Type::Qualifiers q;
+  static BasicType integer( q, BasicType::SignedInt );
+  integer.accept( *this );
+  if( cost < Cost( 1, 0, 0 ) ) {
+    cost.incSafe();
+  }
+}
+
+void 
+ConversionCost::visit(ContextInstType *inst)
+{
+}
+
+void 
+ConversionCost::visit(TypeInstType *inst)
+{
+  EqvClass eqvClass;
+  NamedTypeDecl *namedType;
+  if( env.lookup( inst->get_name(), eqvClass ) ) {
+    cost = conversionCost( eqvClass.type, dest, indexer, env );
+  } else if( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {
+    if( inst->get_name() == destAsInst->get_name() ) {
+      cost = Cost::zero;
+    }
+  } else if( ( namedType = indexer.lookupType( inst->get_name() ) ) ) {
+    TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
+    // all typedefs should be gone by this point
+    assert( type );
+    if( type->get_base() ) {
+      cost = conversionCost( type->get_base(), dest, indexer, env ) + Cost( 0, 0, 1 );
+    }
+  }
+}
+
+void 
+ConversionCost::visit(TupleType *tupleType)
+{
+  Cost c;
+  if( TupleType *destAsTuple = dynamic_cast< TupleType* >( dest ) ) {
+    std::list< Type* >::const_iterator srcIt = tupleType->get_types().begin();
+    std::list< Type* >::const_iterator destIt = destAsTuple->get_types().begin();
+    while( srcIt != tupleType->get_types().end() ) {
+      Cost newCost = conversionCost( *srcIt++, *destIt++, indexer, env );
+      if( newCost == Cost::infinity ) {
+        return;
+      }
+      c += newCost;
+    }
+    if( destIt != destAsTuple->get_types().end() ) {
+      cost = Cost::infinity;
+    } else {
+      cost = c;
+    }
+  }
+}
+
+} // namespace ResolvExpr
Index: translator/ResolvExpr/ConversionCost.h
===================================================================
--- translator/ResolvExpr/ConversionCost.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/ConversionCost.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: ConversionCost.h,v 1.6 2005/08/29 20:14:16 rcbilson Exp $
+ *
+ */
+
+#ifndef RESOLVEXPR_CONVERSIONCOST_PROTECTED_H
+#define RESOLVEXPR_CONVERSIONCOST_PROTECTED_H
+
+#include "SynTree/Visitor.h"
+#include "SymTab/Indexer.h"
+#include "Cost.h"
+#include "TypeEnvironment.h"
+
+namespace ResolvExpr {
+
+class ConversionCost : public Visitor
+{
+public:
+  ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
+  
+  Cost get_cost() const { return cost; }
+
+  virtual void visit(VoidType *voidType);
+  virtual void visit(BasicType *basicType);
+  virtual void visit(PointerType *pointerType);
+  virtual void visit(ArrayType *arrayType);
+  virtual void visit(FunctionType *functionType);
+  virtual void visit(StructInstType *aggregateUseType);
+  virtual void visit(UnionInstType *aggregateUseType);
+  virtual void visit(EnumInstType *aggregateUseType);
+  virtual void visit(ContextInstType *aggregateUseType);
+  virtual void visit(TypeInstType *aggregateUseType);
+  virtual void visit(TupleType *tupleType);
+
+protected:
+  Type *dest;
+  const SymTab::Indexer &indexer;
+  Cost cost;
+  const TypeEnvironment &env;
+};
+
+} // namespace ResolvExpr
+
+#endif /* #ifndef RESOLVEXPR_CONVERSIONCOST_PROTECTED_H */
Index: translator/ResolvExpr/Cost.h
===================================================================
--- translator/ResolvExpr/Cost.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/Cost.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,140 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Cost.h,v 1.2 2003/01/27 14:46:59 rcbilson Exp $
+ *
+ */
+
+#ifndef RESOLVEXPR_COST_H
+#define RESOLVEXPR_COST_H
+
+#include <iostream>
+
+namespace ResolvExpr {
+
+class Cost
+{
+public:
+  Cost();
+  Cost( int unsafe, int poly, int safe );
+  
+  void incUnsafe( int inc = 1 );
+  void incPoly( int inc = 1 );
+  void incSafe( int inc = 1 );
+  
+  Cost operator+( const Cost &other ) const;
+  Cost operator-( const Cost &other ) const;
+  Cost &operator+=( const Cost &other );
+  bool operator<( const Cost &other ) const;
+  bool operator==( const Cost &other ) const;
+  bool operator!=( const Cost &other ) const;
+  friend std::ostream &operator<<( std::ostream &os, const Cost &cost );
+  
+  static const Cost zero;
+  static const Cost infinity;
+  
+private:
+  int compare( const Cost &other ) const;
+
+  int unsafe;
+  int poly;
+  int safe;
+};
+
+inline
+Cost::Cost()
+  : unsafe( 0 ), poly( 0 ), safe( 0 )
+{
+}
+
+inline
+Cost::Cost( int unsafe, int poly, int safe )
+  : unsafe( unsafe ), poly( poly ), safe( safe )
+{
+}
+
+inline void 
+Cost::incUnsafe( int inc )
+{
+  unsafe += inc;
+}
+
+inline void 
+Cost::incPoly( int inc )
+{
+  unsafe += inc;
+}
+
+inline void 
+Cost::incSafe( int inc )
+{
+  unsafe += inc;
+}
+
+inline Cost 
+Cost::operator+( const Cost &other ) const
+{
+  return Cost( unsafe + other.unsafe, poly + other.poly, safe + other.safe );
+}
+
+inline Cost 
+Cost::operator-( const Cost &other ) const
+{
+  return Cost( unsafe - other.unsafe, poly - other.poly, safe - other.safe );
+}
+
+inline Cost &
+Cost::operator+=( const Cost &other )
+{
+   unsafe += other.unsafe;
+   poly += other.poly;
+   safe += other.safe;
+   return *this;
+}
+
+inline bool 
+Cost::operator<( const Cost &other ) const
+{
+  if( *this == infinity ) return false;
+  if( other == infinity ) return true;
+  if( unsafe > other.unsafe ) {
+    return false;
+  } else if( unsafe < other.unsafe ) {
+    return true;
+  } else if( poly > other.poly ) {
+    return false;
+  } else if( poly < other.poly ) {
+    return true;
+  } else if( safe > other.safe ) {
+    return false;
+  } else if( safe < other.safe ) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+inline bool 
+Cost::operator==( const Cost &other ) const
+{
+  return unsafe == other.unsafe
+         && poly == other.poly
+         && safe == other.safe;
+}
+
+inline bool 
+Cost::operator!=( const Cost &other ) const
+{
+  return !( *this == other );
+}
+
+inline std::ostream &
+operator<<( std::ostream &os, const Cost &cost )
+{
+  os << "( " << cost.unsafe << ", " << cost.poly << ", " << cost.safe << " )";
+  return os;
+}
+
+} // namespace ResolvExpr
+
+#endif /* #ifndef RESOLVEXPR_COST_H */
Index: translator/ResolvExpr/FindOpenVars.cc
===================================================================
--- translator/ResolvExpr/FindOpenVars.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/FindOpenVars.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,105 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: FindOpenVars.cc,v 1.4 2005/08/29 20:14:16 rcbilson Exp $
+ *
+ */
+
+#include "FindOpenVars.h"
+#include "SynTree/Type.h"
+#include "SynTree/Visitor.h"
+
+
+namespace ResolvExpr {
+
+class FindOpenVars : public Visitor
+{
+public:
+  FindOpenVars( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen );
+  
+private:
+  virtual void visit(PointerType *pointerType);
+  virtual void visit(ArrayType *arrayType);
+  virtual void visit(FunctionType *functionType);
+  virtual void visit(TupleType *tupleType);
+  
+  void common_action( Type *type );
+  
+  OpenVarSet &openVars, &closedVars;
+  AssertionSet &needAssertions, &haveAssertions;
+  bool nextIsOpen;
+};
+
+void
+findOpenVars( Type *type, OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen )
+{
+  FindOpenVars finder( openVars, closedVars, needAssertions, haveAssertions, firstIsOpen );
+  type->accept( finder );
+}
+
+FindOpenVars::FindOpenVars( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen )
+  : openVars( openVars ), closedVars( closedVars ), needAssertions( needAssertions ), haveAssertions( haveAssertions ), nextIsOpen( firstIsOpen )
+{
+}
+
+void
+FindOpenVars::common_action( Type *type )
+{
+  if( nextIsOpen ) {
+    for( std::list< TypeDecl* >::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
+      openVars[ (*i)->get_name() ] = (*i)->get_kind();
+      for( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
+        needAssertions[ *assert ] = false;
+      }
+///       cloneAll( (*i)->get_assertions(), needAssertions );
+///       needAssertions.insert( needAssertions.end(), (*i)->get_assertions().begin(), (*i)->get_assertions().end() );
+    }
+  } else {
+    for( std::list< TypeDecl* >::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
+      closedVars[ (*i)->get_name() ] = (*i)->get_kind();
+      for( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
+        haveAssertions[ *assert ] = false;
+      }
+///       cloneAll( (*i)->get_assertions(), haveAssertions );
+///       haveAssertions.insert( haveAssertions.end(), (*i)->get_assertions().begin(), (*i)->get_assertions().end() );
+    }
+  }
+///   std::cout << "type is ";
+///   type->print( std::cout );
+///   std::cout << std::endl << "need is" << std::endl;
+///   printAssertionSet( needAssertions, std::cout );
+///   std::cout << std::endl << "have is" << std::endl;
+///   printAssertionSet( haveAssertions, std::cout );
+}
+
+void 
+FindOpenVars::visit(PointerType *pointerType)
+{
+  common_action( pointerType );
+  Visitor::visit( pointerType );
+}
+
+void 
+FindOpenVars::visit(ArrayType *arrayType)
+{
+  common_action( arrayType );
+  Visitor::visit( arrayType );
+}
+
+void 
+FindOpenVars::visit(FunctionType *functionType)
+{
+  common_action( functionType );
+  nextIsOpen = !nextIsOpen;
+  Visitor::visit( functionType );
+  nextIsOpen = !nextIsOpen;
+}
+
+void 
+FindOpenVars::visit(TupleType *tupleType)
+{
+  common_action( tupleType );
+  Visitor::visit( tupleType );
+}
+
+} // namespace ResolvExpr
Index: translator/ResolvExpr/FindOpenVars.h
===================================================================
--- translator/ResolvExpr/FindOpenVars.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/FindOpenVars.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,20 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: FindOpenVars.h,v 1.3 2005/08/29 20:14:16 rcbilson Exp $
+ *
+ */
+
+#ifndef RESOLVEXPR_FINDOPENVARS_H
+#define RESOLVEXPR_FINDOPENVARS_H
+
+#include "Unify.h"
+#include "SynTree/SynTree.h"
+
+namespace ResolvExpr {
+
+void findOpenVars( Type *type, OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen );
+
+} // namespace ResolvExpr
+
+#endif // #ifndef RESOLVEXPR_FINDOPENVARS_H
Index: translator/ResolvExpr/Occurs.cc
===================================================================
--- translator/ResolvExpr/Occurs.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/Occurs.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Occurs.cc,v 1.2 2005/08/29 20:14:16 rcbilson Exp $
+ *
+ */
+
+#include <set>
+#include <algorithm>
+#include <iterator>
+#include "SynTree/Type.h"
+#include "SynTree/Visitor.h"
+#include "TypeEnvironment.h"
+
+
+namespace ResolvExpr {
+
+class Occurs : public Visitor
+{
+public:
+  Occurs( std::string varName, const TypeEnvironment &env );
+  
+  bool get_result() const { return result; }
+
+  virtual void visit( TypeInstType *typeInst );
+
+private:
+  bool result;
+  std::set< std::string > eqvVars;
+  const TypeEnvironment &env;
+};
+
+bool
+occurs( Type *type, std::string varName, const TypeEnvironment &env )
+{
+  Occurs occur( varName, env );
+  type->accept( occur );
+  return occur.get_result();
+}
+
+Occurs::Occurs( std::string varName, const TypeEnvironment &env )
+  : result( false ), env( env )
+{
+  EqvClass eqvClass;
+  if( env.lookup( varName, eqvClass ) ) {
+    eqvVars = eqvClass.vars;
+  } else {
+    eqvVars.insert( varName );
+  }
+}
+
+void 
+Occurs::visit( TypeInstType *typeInst )
+{
+  EqvClass eqvClass;
+///   std::cout << "searching for vars: ";
+///   std::copy( eqvVars.begin(), eqvVars.end(), std::ostream_iterator< std::string >( std::cout, " " ) );
+///   std::cout << std::endl;
+  if( eqvVars.find( typeInst->get_name() ) != eqvVars.end() ) {
+    result = true;
+  } else if( env.lookup( typeInst->get_name(), eqvClass ) ) {
+    if( eqvClass.type ) {
+///       std::cout << typeInst->get_name() << " is bound to";
+///       eqvClass.type->print( std::cout );
+///       std::cout << std::endl;
+      eqvClass.type->accept( *this );
+    }
+  }
+}
+
+} // namespace ResolvExpr
Index: translator/ResolvExpr/PolyCost.cc
===================================================================
--- translator/ResolvExpr/PolyCost.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/PolyCost.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,62 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: PolyCost.cc,v 1.2 2005/08/29 20:14:16 rcbilson Exp $
+ *
+ */
+
+#include "typeops.h"
+#include "SynTree/Type.h"
+#include "SynTree/Visitor.h"
+#include "SymTab/Indexer.h"
+#include "TypeEnvironment.h"
+
+
+namespace ResolvExpr {
+
+class PolyCost : public Visitor
+{
+public:
+  PolyCost( const TypeEnvironment &env, const SymTab::Indexer &indexer );
+
+  int get_result() const { return result; }
+
+private:
+  virtual void visit(TypeInstType *aggregateUseType);
+  
+  int result;
+  const TypeEnvironment &env;
+  const SymTab::Indexer &indexer;
+};
+
+int
+polyCost( Type *type, const TypeEnvironment &env, const SymTab::Indexer &indexer )
+{
+  PolyCost coster( env, indexer );
+  type->accept( coster );
+  return coster.get_result();
+}
+
+PolyCost::PolyCost( const TypeEnvironment &env, const SymTab::Indexer &indexer )
+  : result( 0 ), env( env ), indexer( indexer )
+{
+}
+
+void 
+PolyCost::visit(TypeInstType *typeInst)
+{
+  EqvClass eqvClass;
+  if( env.lookup( typeInst->get_name(), eqvClass ) ) {
+    if( eqvClass.type ) {
+      if( TypeInstType *otherTypeInst = dynamic_cast< TypeInstType* >( eqvClass.type ) ) {
+        if( indexer.lookupType( otherTypeInst->get_name() ) ) {
+          result += 1;
+        }
+      } else {
+        result += 1;
+      }
+    }
+  }
+}
+
+} // namespace ResolvExpr
Index: translator/ResolvExpr/PtrsAssignable.cc
===================================================================
--- translator/ResolvExpr/PtrsAssignable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/PtrsAssignable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,161 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: PtrsAssignable.cc,v 1.3 2005/08/29 20:14:16 rcbilson Exp $
+ *
+ */
+
+#include "typeops.h"
+#include "SynTree/Type.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Visitor.h"
+
+
+namespace ResolvExpr {
+
+class PtrsAssignable : public Visitor
+{
+public:
+  PtrsAssignable( Type *dest, const TypeEnvironment &env );
+  
+  int get_result() const { return result; }
+
+  virtual void visit(VoidType *voidType);
+  virtual void visit(BasicType *basicType);
+  virtual void visit(PointerType *pointerType);
+  virtual void visit(ArrayType *arrayType);
+  virtual void visit(FunctionType *functionType);
+  virtual void visit(StructInstType *inst);
+  virtual void visit(UnionInstType *inst);
+  virtual void visit(EnumInstType *inst);
+  virtual void visit(ContextInstType *inst);
+  virtual void visit(TypeInstType *inst);
+  virtual void visit(TupleType *tupleType);
+
+private:
+  Type *dest;
+  int result;
+  const TypeEnvironment &env;
+};
+
+int
+ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env )
+{
+  if( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
+    EqvClass eqvClass;
+    if( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
+      return ptrsAssignable( src, eqvClass.type, env );
+    }
+  }
+  if( dynamic_cast< VoidType* >( dest ) ) {
+    return 1;
+  } else {
+    PtrsAssignable ptrs( dest, env );
+    src->accept( ptrs );
+    return ptrs.get_result();
+  }
+}
+
+PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env )
+  : dest( dest ), result( 0 ), env( env )
+{
+}
+
+void 
+PtrsAssignable::visit(VoidType *voidType)
+{
+  if( dynamic_cast< FunctionType* >( dest ) ) {
+    result = 0;
+  } else {
+    result = -1;
+  }
+}
+
+void 
+PtrsAssignable::visit(BasicType *basicType)
+{
+}
+
+void 
+PtrsAssignable::visit(PointerType *pointerType)
+{
+}
+
+void 
+PtrsAssignable::visit(ArrayType *arrayType)
+{
+}
+
+void 
+PtrsAssignable::visit(FunctionType *functionType)
+{
+  result = -1;
+}
+
+void 
+PtrsAssignable::visit(StructInstType *inst)
+{
+  // I don't think we should be doing anything here, but I'm willing to admit that I might be wrong
+}
+
+void 
+PtrsAssignable::visit(UnionInstType *inst)
+{
+  // I don't think we should be doing anything here, but I'm willing to admit that I might be wrong
+}
+
+void 
+PtrsAssignable::visit(EnumInstType *inst)
+{
+  if( dynamic_cast< EnumInstType* >( inst ) ) {
+    result = 1;
+  } else if( BasicType *bt = dynamic_cast< BasicType* >( inst ) ) {
+    result = bt->get_kind() == BasicType::SignedInt;
+  }
+}
+
+void 
+PtrsAssignable::visit(ContextInstType *inst)
+{
+  // I definitely don't think we should be doing anything here
+}
+
+void 
+PtrsAssignable::visit(TypeInstType *inst)
+{
+  EqvClass eqvClass;
+  if( env.lookup( inst->get_name(), eqvClass ) ) {
+    result = ptrsAssignable( eqvClass.type, dest, env );
+  } else {
+    result = 0;
+  }
+}
+
+void 
+PtrsAssignable::visit(TupleType *tupleType)
+{
+///  // This code doesn't belong here, but it might be useful somewhere else
+///   if( TupleType *destAsTuple = dynamic_cast< TupleType* >( dest ) ) {
+///     int ret = 0;
+///     std::list< Type* >::const_iterator srcIt = tupleType->get_types().begin();
+///     std::list< Type* >::const_iterator destIt = destAsTuple->get_types().begin();
+///     while( srcIt != tupleType->get_types().end() && destIt != destAsTuple->get_types().end() ) {
+///       int assignResult = ptrsAssignable( *srcIt++, *destIt++ );
+///       if( assignResult == 0 ) {
+///         result = assignResult;
+///         return;
+///       } else if ( assignResult < 0 ) {
+///         ret = -1;
+///       } else if ( ret > 0 ) {
+///         ret += assignResult;
+///       }
+///     }
+///     if( srcIt == tupleType->get_types().end() && destIt == destAsTuple->get_types().end() ) {
+///       result = ret;
+///     } else {
+///       result = 0;
+///     }
+///   }
+}
+
+} // namespace ResolvExpr
Index: translator/ResolvExpr/PtrsCastable.cc
===================================================================
--- translator/ResolvExpr/PtrsCastable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/PtrsCastable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,164 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: PtrsCastable.cc,v 1.5 2005/08/29 20:14:16 rcbilson Exp $
+ *
+ */
+
+#include "typeops.h"
+#include "SynTree/Type.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Visitor.h"
+#include "SymTab/Indexer.h"
+
+
+namespace ResolvExpr {
+
+class PtrsCastable : public Visitor
+{
+public:
+  PtrsCastable( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
+  
+  int get_result() const { return result; }
+
+  virtual void visit(VoidType *voidType);
+  virtual void visit(BasicType *basicType);
+  virtual void visit(PointerType *pointerType);
+  virtual void visit(ArrayType *arrayType);
+  virtual void visit(FunctionType *functionType);
+  virtual void visit(StructInstType *inst);
+  virtual void visit(UnionInstType *inst);
+  virtual void visit(EnumInstType *inst);
+  virtual void visit(ContextInstType *inst);
+  virtual void visit(TypeInstType *inst);
+  virtual void visit(TupleType *tupleType);
+
+private:
+  Type *dest;
+  int result;
+  const TypeEnvironment &env;
+  const SymTab::Indexer &indexer;
+};
+
+int
+objectCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer )
+{
+  if( dynamic_cast< FunctionType* >( src ) ) {
+    return -1;
+  } else if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( src ) ) {
+    EqvClass eqvClass;
+    if( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
+      if( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
+        if( tyDecl->get_kind() == TypeDecl::Ftype ) {
+          return -1;
+        }
+      }
+    } else if( env.lookup( typeInst->get_name(), eqvClass ) ) {
+      if( eqvClass.kind == TypeDecl::Ftype ) {
+        return -1;
+      }
+    }
+  }
+  return 1;
+}
+
+int
+ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
+{
+  if( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
+    EqvClass eqvClass;
+    if( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
+      return ptrsAssignable( src, eqvClass.type, env );
+    }
+  }
+  if( dynamic_cast< VoidType* >( dest ) ) {
+    return objectCast( src, env, indexer );
+  } else {
+    PtrsCastable ptrs( dest, env, indexer );
+    src->accept( ptrs );
+    return ptrs.get_result();
+  }
+}
+
+PtrsCastable::PtrsCastable( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
+  : dest( dest ), result( 0 ), env( env ), indexer( indexer )
+{
+}
+
+void 
+PtrsCastable::visit(VoidType *voidType)
+{
+  result = objectCast( dest, env, indexer );
+}
+
+void 
+PtrsCastable::visit(BasicType *basicType)
+{
+  result = objectCast( dest, env, indexer );
+}
+
+void 
+PtrsCastable::visit(PointerType *pointerType)
+{
+  result = objectCast( dest, env, indexer );
+}
+
+void 
+PtrsCastable::visit(ArrayType *arrayType)
+{
+  result = objectCast( dest, env, indexer );
+}
+
+void 
+PtrsCastable::visit(FunctionType *functionType)
+{
+  result = -1;
+}
+
+void 
+PtrsCastable::visit(StructInstType *inst)
+{
+  result = objectCast( dest, env, indexer );
+}
+
+void 
+PtrsCastable::visit(UnionInstType *inst)
+{
+  result = objectCast( dest, env, indexer );
+}
+
+void 
+PtrsCastable::visit(EnumInstType *inst)
+{
+  if( dynamic_cast< EnumInstType* >( inst ) ) {
+    result = 1;
+  } else if( BasicType *bt = dynamic_cast< BasicType* >( inst ) ) {
+    if( bt->get_kind() == BasicType::SignedInt ) {
+      result = 0;
+    } else {
+      result = 1;
+    }
+  } else {
+    result = objectCast( dest, env, indexer );
+  }
+}
+
+void 
+PtrsCastable::visit(ContextInstType *inst)
+{
+  // I definitely don't think we should be doing anything here
+}
+
+void 
+PtrsCastable::visit(TypeInstType *inst)
+{
+  result = objectCast( inst, env, indexer ) && objectCast( dest, env, indexer ) ? 1 : -1;
+}
+
+void 
+PtrsCastable::visit(TupleType *tupleType)
+{
+  result = objectCast( dest, env, indexer );
+}
+
+} // namespace ResolvExpr
Index: translator/ResolvExpr/RenameVars.cc
===================================================================
--- translator/ResolvExpr/RenameVars.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/RenameVars.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,162 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: RenameVars.cc,v 1.4 2005/08/29 20:14:16 rcbilson Exp $
+ *
+ */
+
+#include <strstream>
+
+#include "RenameVars.h"
+#include "SynTree/Visitor.h"
+#include "SynTree/Type.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Expression.h"
+
+namespace ResolvExpr {
+
+RenameVars global_renamer;
+
+RenameVars::RenameVars()
+  : level( 0 )
+{
+  mapStack.push_front( std::map< std::string, std::string >() );
+}
+
+void 
+RenameVars::reset()
+{
+  level = 0;
+}
+
+void 
+RenameVars::visit( VoidType *voidType )
+{
+  typeBefore( voidType );
+  typeAfter( voidType );
+}
+
+void 
+RenameVars::visit( BasicType *basicType )
+{
+  typeBefore( basicType );
+  typeAfter( basicType );
+}
+
+void 
+RenameVars::visit( PointerType *pointerType )
+{
+  typeBefore( pointerType );
+///   std::cout << "do pointer" << std::endl;
+  maybeAccept( pointerType->get_base(), *this );
+///   std::cout << "done pointer" << std::endl;
+  typeAfter( pointerType );
+}
+
+void 
+RenameVars::visit( ArrayType *arrayType )
+{
+  typeBefore( arrayType );
+  maybeAccept( arrayType->get_dimension(), *this );
+  maybeAccept( arrayType->get_base(), *this );
+  typeAfter( arrayType );
+}
+
+void 
+RenameVars::visit( FunctionType *functionType )
+{
+  typeBefore( functionType );
+///   std::cout << "return vals" << std::endl;
+  acceptAll( functionType->get_returnVals(), *this );
+///   std::cout << functionType->get_parameters().size() << " parameters" << std::endl;
+  acceptAll( functionType->get_parameters(), *this );
+///   std::cout << "done function" << std::endl;
+  typeAfter( functionType );
+}
+
+void 
+RenameVars::visit( StructInstType *aggregateUseType )
+{
+  typeBefore( aggregateUseType );
+  acceptAll( aggregateUseType->get_parameters(), *this );
+  typeAfter( aggregateUseType );
+}
+
+void 
+RenameVars::visit( UnionInstType *aggregateUseType )
+{
+  typeBefore( aggregateUseType );
+  acceptAll( aggregateUseType->get_parameters(), *this );
+  typeAfter( aggregateUseType );
+}
+
+void 
+RenameVars::visit( EnumInstType *aggregateUseType )
+{
+  typeBefore( aggregateUseType );
+  acceptAll( aggregateUseType->get_parameters(), *this );
+  typeAfter( aggregateUseType );
+}
+
+void 
+RenameVars::visit( ContextInstType *aggregateUseType )
+{
+  typeBefore( aggregateUseType );
+  acceptAll( aggregateUseType->get_parameters(), *this );
+  acceptAll( aggregateUseType->get_members(), *this );
+  typeAfter( aggregateUseType );
+}
+
+void 
+RenameVars::visit( TypeInstType *instType )
+{
+  typeBefore( instType );
+///   std::cout << "instance of type " << instType->get_name() << std::endl;
+  std::map< std::string, std::string >::const_iterator i = mapStack.front().find( instType->get_name() );
+  if( i != mapStack.front().end() ) {
+///     std::cout << "found name " << i->second << std::endl;
+    instType->set_name( i->second );
+  } else {
+///     std::cout << "no name found" << std::endl;
+  }
+  acceptAll( instType->get_parameters(), *this );
+  typeAfter( instType );
+}
+
+void 
+RenameVars::visit( TupleType *tupleType )
+{
+  typeBefore( tupleType );
+  acceptAll( tupleType->get_types(), *this );
+  typeAfter( tupleType );
+}
+
+void 
+RenameVars::typeBefore( Type *type )
+{
+  if( !type->get_forall().empty() ) {
+///     std::cout << "type with forall: ";
+///     type->print( std::cout );
+///     std::cout << std::endl;
+    mapStack.push_front( mapStack.front() );
+    for( std::list< TypeDecl* >::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
+      std::ostrstream output;
+      output << "_" << level << "_" << (*i)->get_name();
+      std::string newname( output.str(), output.pcount() );
+      mapStack.front()[ (*i)->get_name() ] = newname;
+      (*i)->set_name( newname );
+      level++;
+      acceptAll( (*i)->get_assertions(), *this );
+    }
+  }
+}
+
+void 
+RenameVars::typeAfter( Type *type )
+{
+  if( !type->get_forall().empty() ) {
+    mapStack.pop_front();
+  }
+}
+
+} // namespace ResolvExpr
Index: translator/ResolvExpr/RenameVars.h
===================================================================
--- translator/ResolvExpr/RenameVars.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/RenameVars.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,49 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: RenameVars.h,v 1.2 2005/08/29 20:14:16 rcbilson Exp $
+ *
+ */
+
+#ifndef RESOLVEXPR_RENAMEVARS_H
+#define RESOLVEXPR_RENAMEVARS_H
+
+#include <list>
+#include <map>
+#include <string>
+
+#include "SynTree/SynTree.h"
+#include "SynTree/Visitor.h"
+
+namespace ResolvExpr {
+
+class RenameVars : public Visitor
+{
+public:
+  RenameVars();
+  void reset();
+  
+private:
+  virtual void visit( VoidType *basicType );
+  virtual void visit( BasicType *basicType );
+  virtual void visit( PointerType *pointerType );
+  virtual void visit( ArrayType *arrayType );
+  virtual void visit( FunctionType *functionType );
+  virtual void visit( StructInstType *aggregateUseType );
+  virtual void visit( UnionInstType *aggregateUseType );
+  virtual void visit( EnumInstType *aggregateUseType );
+  virtual void visit( ContextInstType *aggregateUseType );
+  virtual void visit( TypeInstType *aggregateUseType );
+  virtual void visit( TupleType *tupleType );
+  
+  void typeBefore( Type *type );
+  void typeAfter( Type *type );
+  int level;
+  std::list< std::map< std::string, std::string > > mapStack;
+};
+
+extern RenameVars global_renamer;
+
+} // namespace ResolvExpr
+
+#endif /* #ifndef RESOLVEXPR_RENAMEVARS_H */
Index: translator/ResolvExpr/ResolveTypeof.cc
===================================================================
--- translator/ResolvExpr/ResolveTypeof.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/ResolveTypeof.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,71 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: ResolveTypeof.cc,v 1.2 2005/08/29 20:14:16 rcbilson Exp $
+ *
+ */
+
+#include "ResolveTypeof.h"
+#include "Alternative.h"
+#include "AlternativeFinder.h"
+#include "Resolver.h"
+#include "TypeEnvironment.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Type.h"
+
+namespace ResolvExpr {
+
+namespace {
+#if 0
+  void
+  printAlts( const AltList &list, std::ostream &os, int indent = 0 )
+  {
+    for( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {
+      i->print( os, indent );
+      os << std::endl;
+    }
+  }
+#endif
+}
+
+class ResolveTypeof : public Mutator
+{
+public:
+  ResolveTypeof( const SymTab::Indexer &indexer ) : indexer( indexer ) {}
+  Type *mutate( TypeofType *typeofType );
+
+private:
+  const SymTab::Indexer &indexer;
+};
+
+Type *
+resolveTypeof( Type *type, const SymTab::Indexer &indexer )
+{
+  ResolveTypeof mutator( indexer );
+  return type->acceptMutator( mutator );
+}
+
+Type *
+ResolveTypeof::mutate( TypeofType *typeofType )
+{
+///   std::cout << "resolving typeof: ";
+///   typeofType->print( std::cout );
+///   std::cout << std::endl;
+  if( typeofType->get_expr() ) {
+    Expression *newExpr = resolveInVoidContext( typeofType->get_expr(), indexer );
+    assert( newExpr->get_results().size() > 0 );
+    Type *newType;
+    if( newExpr->get_results().size() > 1 ) {
+      TupleType *tupleType = new TupleType( Type::Qualifiers() );
+      cloneAll( newExpr->get_results(), tupleType->get_types() );
+      newType = tupleType;
+    } else {
+      newType = newExpr->get_results().front()->clone();
+    }
+    delete typeofType;
+    return newType;
+  }
+  return typeofType;
+}
+
+} // namespace ResolvExpr
Index: translator/ResolvExpr/ResolveTypeof.h
===================================================================
--- translator/ResolvExpr/ResolveTypeof.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/ResolveTypeof.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,20 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: ResolveTypeof.h,v 1.2 2005/08/29 20:14:16 rcbilson Exp $
+ *
+ */
+
+#ifndef RESOLVEXPR_RESOLVETYPEOF_H
+#define RESOLVEXPR_RESOLVETYPEOF_H
+
+#include "SynTree/SynTree.h"
+#include "SymTab/Indexer.h"
+
+namespace ResolvExpr {
+
+Type *resolveTypeof( Type*, const SymTab::Indexer &indexer );
+
+} // namespace ResolvExpr
+
+#endif /* #ifndef RESOLVEXPR_RESOLVETYPEOF_H */
Index: translator/ResolvExpr/Resolver.cc
===================================================================
--- translator/ResolvExpr/Resolver.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/Resolver.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,290 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Resolver.cc,v 1.19 2005/08/29 20:14:16 rcbilson Exp $
+ *
+ */
+
+#include "Resolver.h"
+#include "AlternativeFinder.h"
+#include "Alternative.h"
+#include "RenameVars.h"
+#include "ResolveTypeof.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Type.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Initializer.h"
+#include "SymTab/Indexer.h"
+#include "utility.h"
+
+namespace ResolvExpr {
+
+class Resolver : public SymTab::Indexer
+{
+public:
+  Resolver() : SymTab::Indexer( false ), switchType( 0 ) {}
+  
+  virtual void visit( FunctionDecl *functionDecl );
+  virtual void visit( ObjectDecl *functionDecl );
+  virtual void visit( TypeDecl *typeDecl );
+
+  virtual void visit( ExprStmt *exprStmt );
+  virtual void visit( IfStmt *ifStmt );
+  virtual void visit( WhileStmt *whileStmt );
+  virtual void visit( ForStmt *forStmt );
+  virtual void visit( SwitchStmt *switchStmt );
+  virtual void visit( ChooseStmt *switchStmt );
+  virtual void visit( CaseStmt *caseStmt );
+  virtual void visit( ReturnStmt *returnStmt );
+
+  virtual void visit( SingleInit *singleInit );
+
+private:
+  std::list< Type* > functionReturn;
+  Type* initContext;
+  Type *switchType;
+};
+
+void 
+resolve( std::list< Declaration* > translationUnit )
+{
+  Resolver resolver;
+  acceptAll( translationUnit, resolver );
+///   for( std::list< Declaration* >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
+///     (*i)->print( std::cerr );
+///     (*i)->accept( resolver );
+///   }
+}
+
+Expression *
+resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer )
+{
+  TypeEnvironment env;
+  return resolveInVoidContext( expr, indexer, env );
+}
+
+namespace {
+
+  void
+  finishExpr( Expression *expr, const TypeEnvironment &env )
+  {
+    expr->set_env( new TypeSubstitution );
+    env.makeSubstitution( *expr->get_env() );
+  }
+
+  Expression*
+  findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer )
+  {
+    global_renamer.reset();
+    TypeEnvironment env;
+    Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
+    finishExpr( newExpr, env );
+    return newExpr;
+  }
+  
+  Expression*
+  findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer )
+  {
+    TypeEnvironment env;
+    AlternativeFinder finder( indexer, env );
+    finder.find( untyped );
+///     if( finder.get_alternatives().size() != 1 ) {
+///       std::cout << "untyped expr is ";
+///       untyped->print( std::cout );
+///       std::cout << std::endl << "alternatives are:";
+///       for( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
+///         i->print( std::cout );
+///       }
+///     }
+    assert( finder.get_alternatives().size() == 1 );
+    Alternative &choice = finder.get_alternatives().front();
+    Expression *newExpr = choice.expr->clone();
+    finishExpr( newExpr, choice.env );
+    return newExpr;
+  }
+
+  bool
+  isIntegralType( Type *type )
+  {
+    if( dynamic_cast< EnumInstType* >( type ) ) {
+      return true;
+    } else if( BasicType *bt = dynamic_cast< BasicType* >( type ) ) {
+      return bt->isInteger();
+    } else {
+      return true;
+    }
+  }
+  
+  Expression*
+  findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer )
+  {
+    TypeEnvironment env;
+    AlternativeFinder finder( indexer, env );
+    finder.find( untyped );
+///     if( finder.get_alternatives().size() != 1 ) {
+///       std::cout << "untyped expr is ";
+///       untyped->print( std::cout );
+///       std::cout << std::endl << "alternatives are:";
+///       for( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
+///         i->print( std::cout );
+///       }
+///     }
+    Expression *newExpr = 0;
+    const TypeEnvironment *newEnv = 0;
+    for( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
+      if( i->expr->get_results().size() == 1 && isIntegralType( i->expr->get_results().front() ) ) {
+        if( newExpr ) {
+          throw SemanticError( "Too many interpretations for switch control expression", untyped );
+        } else {
+          newExpr = i->expr->clone();
+          newEnv = &i->env;
+        }
+      }
+    }
+    if( !newExpr ) {
+      throw SemanticError( "Too many interpretations for switch control expression", untyped );
+    }
+    finishExpr( newExpr, *newEnv );
+    return newExpr;
+  }
+  
+}
+  
+void 
+Resolver::visit( ObjectDecl *objectDecl )
+{
+  Type *new_type = resolveTypeof( objectDecl->get_type(), *this );
+  objectDecl->set_type( new_type );
+  initContext = new_type;
+  SymTab::Indexer::visit( objectDecl );
+}
+  
+void 
+Resolver::visit( TypeDecl *typeDecl )
+{
+  if( typeDecl->get_base() ) {
+    Type *new_type = resolveTypeof( typeDecl->get_base(), *this );
+    typeDecl->set_base( new_type );
+  }
+  SymTab::Indexer::visit( typeDecl );
+}
+  
+void 
+Resolver::visit( FunctionDecl *functionDecl )
+{
+///   std::cout << "resolver visiting functiondecl ";
+///   functionDecl->print( std::cout );
+///   std::cout << std::endl;
+  Type *new_type = resolveTypeof( functionDecl->get_type(), *this );
+  functionDecl->set_type( new_type );
+  std::list< Type* > oldFunctionReturn = functionReturn;
+  functionReturn.clear();
+  for( std::list< DeclarationWithType* >::const_iterator i = functionDecl->get_functionType()->get_returnVals().begin(); i != functionDecl->get_functionType()->get_returnVals().end(); ++i ) {
+    functionReturn.push_back( (*i)->get_type() );
+  }
+  SymTab::Indexer::visit( functionDecl );
+  functionReturn = oldFunctionReturn;
+}
+
+void 
+Resolver::visit( ExprStmt *exprStmt )
+{
+  if( exprStmt->get_expr() ) {
+    Expression *newExpr = findVoidExpression( exprStmt->get_expr(), *this );
+    delete exprStmt->get_expr();
+    exprStmt->set_expr( newExpr );
+  }
+}
+
+void 
+Resolver::visit( IfStmt *ifStmt )
+{
+  Expression *newExpr = findSingleExpression( ifStmt->get_condition(), *this );
+  delete ifStmt->get_condition();
+  ifStmt->set_condition( newExpr );
+  Visitor::visit( ifStmt );
+}
+
+void 
+Resolver::visit( WhileStmt *whileStmt )
+{
+  Expression *newExpr = findSingleExpression( whileStmt->get_condition(), *this );
+  delete whileStmt->get_condition();
+  whileStmt->set_condition( newExpr );
+  Visitor::visit( whileStmt );
+}
+
+void 
+Resolver::visit( ForStmt *forStmt )
+{
+  Expression *newExpr;
+  if( forStmt->get_condition() ) {
+    newExpr = findSingleExpression( forStmt->get_condition(), *this );
+    delete forStmt->get_condition();
+    forStmt->set_condition( newExpr );
+  }
+  
+  if( forStmt->get_increment() ) {
+    newExpr = findVoidExpression( forStmt->get_increment(), *this );
+    delete forStmt->get_increment();
+    forStmt->set_increment( newExpr );
+  }
+  
+  Visitor::visit( forStmt );
+}
+
+template< typename SwitchClass >
+void
+handleSwitchStmt( SwitchClass *switchStmt, SymTab::Indexer &visitor )
+{
+  Expression *newExpr;
+  newExpr = findIntegralExpression( switchStmt->get_condition(), visitor );
+  delete switchStmt->get_condition();
+  switchStmt->set_condition( newExpr );
+  
+  visitor.Visitor::visit( switchStmt );
+}
+
+void 
+Resolver::visit( SwitchStmt *switchStmt )
+{
+  handleSwitchStmt( switchStmt, *this );
+}
+
+void 
+Resolver::visit( ChooseStmt *switchStmt )
+{
+  handleSwitchStmt( switchStmt, *this );
+}
+
+void 
+Resolver::visit( CaseStmt *caseStmt )
+{
+  Visitor::visit( caseStmt );
+}
+
+void 
+Resolver::visit( ReturnStmt *returnStmt )
+{
+  if( returnStmt->get_expr() ) {
+    CastExpr *castExpr = new CastExpr( returnStmt->get_expr() );
+    cloneAll( functionReturn, castExpr->get_results() );
+    Expression *newExpr = findSingleExpression( castExpr, *this );
+    delete castExpr;
+    returnStmt->set_expr( newExpr );
+  }
+}
+
+void
+Resolver::visit( SingleInit *singleInit )
+{
+  if( singleInit->get_value() ) {
+    CastExpr *castExpr = new CastExpr( singleInit->get_value(), initContext->clone() );
+    Expression *newExpr = findSingleExpression( castExpr, *this );
+    delete castExpr;
+    singleInit->set_value( newExpr );
+  }
+  singleInit->get_value()->accept( *this );
+}
+
+} // namespace ResolvExpr
Index: translator/ResolvExpr/Resolver.h
===================================================================
--- translator/ResolvExpr/Resolver.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/Resolver.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,21 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Resolver.h,v 1.3 2005/08/29 20:14:16 rcbilson Exp $
+ *
+ */
+
+#ifndef RESOLVEXPR_RESOLVER_H
+#define RESOLVEXPR_RESOLVER_H
+
+#include "SynTree/SynTree.h"
+#include "SymTab/Indexer.h"
+
+namespace ResolvExpr {
+
+void resolve( std::list< Declaration* > translationUnit );
+Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer );
+
+} // namespace ResolvExpr
+
+#endif /* #ifndef RESOLVEXPR_RESOLVER_H */
Index: translator/ResolvExpr/TypeEnvironment.cc
===================================================================
--- translator/ResolvExpr/TypeEnvironment.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/TypeEnvironment.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,223 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: TypeEnvironment.cc,v 1.7 2005/08/29 20:14:16 rcbilson Exp $
+ *
+ */
+
+#include <algorithm>
+#include <iterator>
+
+#include "TypeEnvironment.h"
+#include "SynTree/Type.h"
+#include "SynTree/TypeSubstitution.h"
+#include "utility.h"
+
+namespace ResolvExpr {
+
+void printAssertionSet( const AssertionSet &assertions, std::ostream &os, int indent )
+{
+  for( AssertionSet::const_iterator i = assertions.begin(); i != assertions.end(); ++i ) {
+    i->first->print( os, indent );
+    if( i->second ) {
+      os << "(used)";
+    } else {
+      os << "(not used)";
+    }
+  }
+}
+
+void printOpenVarSet( const OpenVarSet &openVars, std::ostream &os, int indent )
+{
+  os << std::string( indent, ' ' );
+  for( OpenVarSet::const_iterator i = openVars.begin(); i != openVars.end(); ++i ) {
+    os << i->first << "(" << i->second << ") ";
+  }
+}
+
+void
+EqvClass::initialize( const EqvClass &src, EqvClass &dest )
+{
+  dest.vars = src.vars;
+  dest.type = maybeClone( src.type );
+  dest.allowWidening = src.allowWidening;
+  dest.kind = src.kind;
+}
+
+EqvClass::EqvClass() : type( 0 ), allowWidening( true )
+{
+}
+
+EqvClass::EqvClass( const EqvClass &other )
+{
+  initialize( other, *this );
+}
+
+EqvClass &
+EqvClass::operator=( const EqvClass &other )
+{
+  if( this == &other ) return *this;
+  delete type;
+  initialize( other, *this );
+  return *this;
+}
+
+EqvClass::~EqvClass()
+{
+  delete type;
+}
+
+void 
+EqvClass::print( std::ostream &os, int indent ) const
+{
+  os << std::string( indent, ' ' ) << "( ";
+  std::copy( vars.begin(), vars.end(), std::ostream_iterator< std::string >( os, " " ) );
+  os << ")";
+  if( type ) {
+    os << " -> ";
+    type->print( os, indent );
+  }
+  if( !allowWidening ) {
+    os << " (no widening)";
+  }
+  os << std::endl;
+}
+
+bool 
+TypeEnvironment::lookup( const std::string &var, EqvClass &eqvClass ) const
+{
+  for( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) {
+    if( i->vars.find( var ) != i->vars.end() ) {
+///       std::cout << var << " is in class ";
+///       i->print( std::cout );
+      eqvClass = *i;
+      return true;
+    }
+///     std::cout << var << " is not in class ";
+///     i->print( std::cout );
+  }
+  return false;
+}
+
+void 
+TypeEnvironment::add( const EqvClass &eqvClass )
+{
+  std::list< EqvClass >::iterator i = env.begin();
+  while( i != env.end() ) {
+    std::list< EqvClass >::iterator next = i;
+    next++;
+    std::set< std::string > intersection;
+    std::set_intersection( i->vars.begin(), i->vars.end(), eqvClass.vars.begin(), eqvClass.vars.end(), std::inserter( intersection, intersection.begin() ) );
+    if( !intersection.empty() ) {
+      env.erase( i );
+    }
+    i = next;
+  }
+  env.insert( env.end(), eqvClass );
+}
+
+void 
+TypeEnvironment::add( const std::list< TypeDecl* > &tyDecls )
+{
+  for( std::list< TypeDecl* >::const_iterator i = tyDecls.begin(); i != tyDecls.end(); ++i ) {
+    EqvClass newClass;
+    newClass.vars.insert( (*i)->get_name() );
+    newClass.kind = (*i)->get_kind();
+    env.push_back( newClass );
+  }
+}
+
+void 
+TypeEnvironment::makeSubstitution( TypeSubstitution &sub ) const
+{
+  for( std::list< EqvClass >::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) {
+    for( std::set< std::string >::const_iterator theVar = theClass->vars.begin(); theVar != theClass->vars.end(); ++theVar ) {
+///       std::cout << "adding " << *theVar;
+      if( theClass->type ) {
+///         std::cout << " bound to ";
+///         theClass->type->print( std::cout );
+///         std::cout << std::endl;
+        sub.add( *theVar, theClass->type );
+      } else if( theVar != theClass->vars.begin() ) {
+        TypeInstType *newTypeInst = new TypeInstType( Type::Qualifiers(), *theClass->vars.begin(), theClass->kind == TypeDecl::Ftype );
+///         std::cout << " bound to variable " << *theClass->vars.begin() << std::endl;
+        sub.add( *theVar, newTypeInst );
+        delete newTypeInst;
+      }
+    }
+  }
+///   std::cerr << "input env is:" << std::endl;
+///   print( std::cerr, 8 );
+///   std::cerr << "sub is:" << std::endl;
+///   sub.print( std::cerr, 8 );
+  sub.normalize();
+}
+
+void 
+TypeEnvironment::print( std::ostream &os, int indent ) const
+{
+  for( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) {
+    i->print( os, indent );
+  }
+}
+
+std::list< EqvClass >::iterator 
+TypeEnvironment::internal_lookup( const std::string &var )
+{
+  for( std::list< EqvClass >::iterator i = env.begin(); i != env.end(); ++i ) {
+    if( i->vars.find( var ) == i->vars.end() ) {
+      return i;
+    }
+  }
+  return env.end();
+}
+
+void 
+TypeEnvironment::simpleCombine( const TypeEnvironment &second )
+{
+  env.insert( env.end(), second.env.begin(), second.env.end() );
+}
+
+void 
+TypeEnvironment::combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) )
+{
+  TypeEnvironment secondCopy( second );
+  for( std::list< EqvClass >::iterator firstClass = env.begin(); firstClass != env.end(); ++firstClass ) {
+    EqvClass &newClass = *firstClass;
+    std::set< std::string > newVars;
+    for( std::set< std::string >::const_iterator var = firstClass->vars.begin(); var != firstClass->vars.end(); ++var ) {
+      std::list< EqvClass >::iterator secondClass = secondCopy.internal_lookup( *var );
+      if( secondClass != secondCopy.env.end() ) {
+        newVars.insert( secondClass->vars.begin(), secondClass->vars.end() );
+        if( secondClass->type ) {
+          if( newClass.type ) {
+            Type *newType = combineFunc( newClass.type, secondClass->type );
+            delete newClass.type;
+            newClass.type = newType;
+            newClass.allowWidening = newClass.allowWidening && secondClass->allowWidening;
+          } else {
+            newClass.type = secondClass->type->clone();
+            newClass.allowWidening = secondClass->allowWidening;
+          }
+        }
+        secondCopy.env.erase( secondClass );
+      }
+    }
+    newClass.vars.insert( newVars.begin(), newVars.end() );
+  }
+  for( std::list< EqvClass >::iterator secondClass = secondCopy.env.begin(); secondClass != secondCopy.env.end(); ++secondClass ) {
+    env.push_back( *secondClass );
+  }
+}
+
+void 
+TypeEnvironment::extractOpenVars( OpenVarSet &openVars ) const
+{
+  for( std::list< EqvClass >::const_iterator eqvClass = env.begin(); eqvClass != env.end(); ++eqvClass ) {
+    for( std::set< std::string >::const_iterator var = eqvClass->vars.begin(); var != eqvClass->vars.end(); ++var ) {
+      openVars[ *var ] = eqvClass->kind;
+    }
+  }
+}
+
+} // namespace ResolvExpr
Index: translator/ResolvExpr/TypeEnvironment.h
===================================================================
--- translator/ResolvExpr/TypeEnvironment.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/TypeEnvironment.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,92 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: TypeEnvironment.h,v 1.8 2005/08/29 20:14:16 rcbilson Exp $
+ *
+ */
+
+#ifndef RESOLVEXPR_TYPEENVIRONMENT_H
+#define RESOLVEXPR_TYPEENVIRONMENT_H
+
+#include <string>
+#include <set>
+#include <list>
+#include <iostream>
+
+#include "SynTree/SynTree.h"
+#include "SynTree/Type.h"
+#include "SynTree/TypeSubstitution.h"
+#include "SynTree/Declaration.h"
+
+namespace ResolvExpr {
+
+typedef std::map< DeclarationWithType*, bool > AssertionSet;
+typedef std::map< std::string, TypeDecl::Kind > OpenVarSet;
+
+void printAssertionSet( const AssertionSet &, std::ostream &, int indent = 0 );
+void printOpenVarSet( const OpenVarSet &, std::ostream &, int indent = 0 );
+
+struct EqvClass
+{
+  std::set< std::string > vars;
+  Type *type;
+  bool allowWidening;
+  TypeDecl::Kind kind;
+  
+  void initialize( const EqvClass &src, EqvClass &dest );
+  EqvClass();
+  EqvClass( const EqvClass &other );
+  EqvClass &operator=( const EqvClass &other );
+  ~EqvClass();
+  void print( std::ostream &os, int indent = 0 ) const;
+};
+
+class TypeEnvironment
+{
+public:
+  bool lookup( const std::string &var, EqvClass &eqvClass ) const;
+  void add( const EqvClass &eqvClass );
+  void add( const std::list< TypeDecl* > &tyDecls );
+  template< typename SynTreeClass > int apply( SynTreeClass *&type ) const;
+  template< typename SynTreeClass > int applyFree( SynTreeClass *&type ) const;
+  void makeSubstitution( TypeSubstitution &result ) const;
+  bool isEmpty() const { return env.empty(); }
+  void print( std::ostream &os, int indent = 0 ) const;
+  void combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) );
+  void simpleCombine( const TypeEnvironment &second );
+  void extractOpenVars( OpenVarSet &openVars ) const;
+  TypeEnvironment *clone() const { return new TypeEnvironment( *this ); }
+  
+  typedef std::list< EqvClass >::iterator iterator;
+  iterator begin() { return env.begin(); }
+  iterator end() { return env.end(); }
+  typedef std::list< EqvClass >::const_iterator const_iterator;
+  const_iterator begin() const { return env.begin(); }
+  const_iterator end() const { return env.end(); }
+private:
+  std::list< EqvClass > env;
+  
+  std::list< EqvClass >::iterator internal_lookup( const std::string &var );
+};
+
+template< typename SynTreeClass >
+int 
+TypeEnvironment::apply( SynTreeClass *&type ) const
+{
+  TypeSubstitution sub;
+  makeSubstitution( sub );
+  return sub.apply( type );
+}
+
+template< typename SynTreeClass >
+int 
+TypeEnvironment::applyFree( SynTreeClass *&type ) const
+{
+  TypeSubstitution sub;
+  makeSubstitution( sub );
+  return sub.applyFree( type );
+}
+
+} // namespace ResolvExpr
+
+#endif /* #ifndef RESOLVEXPR_TYPEENVIRONMENT_H */
Index: translator/ResolvExpr/Unify.cc
===================================================================
--- translator/ResolvExpr/Unify.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/Unify.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,568 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Unify.cc,v 1.14 2005/08/29 20:14:16 rcbilson Exp $
+ *
+ */
+
+#include <set>
+#include <memory>
+
+#include "Unify.h"
+#include "TypeEnvironment.h"
+#include "typeops.h"
+#include "FindOpenVars.h"
+#include "SynTree/Visitor.h"
+#include "SynTree/Type.h"
+#include "SynTree/Declaration.h"
+#include "SymTab/Indexer.h"
+#include "utility.h"
+
+
+//#define DEBUG
+
+namespace ResolvExpr {
+
+struct WidenMode
+{
+  WidenMode( bool widenFirst, bool widenSecond ): widenFirst( widenFirst ), widenSecond( widenSecond ) {}
+  WidenMode &operator|=( const WidenMode &other ) { widenFirst |= other.widenFirst; widenSecond |= other.widenSecond; return *this; }
+  WidenMode &operator&=( const WidenMode &other ) { widenFirst &= other.widenFirst; widenSecond &= other.widenSecond; return *this; }
+  WidenMode operator|( const WidenMode &other ) { WidenMode newWM( *this ); newWM |= other; return newWM; }
+  WidenMode operator&( const WidenMode &other ) { WidenMode newWM( *this ); newWM &= other; return newWM; }
+  operator bool() { return widenFirst && widenSecond; }
+  
+  bool widenFirst : 1, widenSecond : 1;
+};
+
+class Unify : public Visitor
+{
+public:
+  Unify( Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
+  
+  bool get_result() const { return result; }
+
+private:
+  virtual void visit(VoidType *voidType);
+  virtual void visit(BasicType *basicType);
+  virtual void visit(PointerType *pointerType);
+  virtual void visit(ArrayType *arrayType);
+  virtual void visit(FunctionType *functionType);
+  virtual void visit(StructInstType *aggregateUseType);
+  virtual void visit(UnionInstType *aggregateUseType);
+  virtual void visit(EnumInstType *aggregateUseType);
+  virtual void visit(ContextInstType *aggregateUseType);
+  virtual void visit(TypeInstType *aggregateUseType);
+  virtual void visit(TupleType *tupleType);
+
+  template< typename RefType > void handleRefType( RefType *inst, Type *other );
+
+  bool result;
+  Type *type2;				// inherited
+  TypeEnvironment &env;
+  AssertionSet &needAssertions;
+  AssertionSet &haveAssertions;
+  const OpenVarSet &openVars;
+  WidenMode widenMode;
+  Type *commonType;
+  const SymTab::Indexer &indexer;
+};
+
+bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer, Type *&common );
+bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
+  
+bool
+typesCompatible( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env )
+{
+  TypeEnvironment newEnv;
+  OpenVarSet openVars;
+  AssertionSet needAssertions, haveAssertions;
+  Type *newFirst = first->clone(), *newSecond = second->clone();
+  env.apply( newFirst );
+  env.apply( newSecond );
+  bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+  delete newFirst;
+  delete newSecond;
+  return result;
+}
+
+bool
+typesCompatibleIgnoreQualifiers( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env )
+{
+  TypeEnvironment newEnv;
+  OpenVarSet openVars;
+  AssertionSet needAssertions, haveAssertions;
+  Type *newFirst = first->clone(), *newSecond = second->clone();
+  env.apply( newFirst );
+  env.apply( newSecond );
+  newFirst->get_qualifiers() = Type::Qualifiers();
+  newSecond->get_qualifiers() = Type::Qualifiers();
+///   std::cout << "first is ";
+///   first->print( std::cout );
+///   std::cout << std::endl << "second is ";
+///   second->print( std::cout );
+///   std::cout << std::endl << "newFirst is ";
+///   newFirst->print( std::cout );
+///   std::cout << std::endl << "newSecond is ";
+///   newSecond->print( std::cout );
+///   std::cout << std::endl;
+  bool result = unifyExact( newFirst, newSecond, newEnv, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+  delete newFirst;
+  delete newSecond;
+  return result;
+}
+
+bool
+isFtype( Type *type, const SymTab::Indexer &indexer )
+{
+  if( dynamic_cast< FunctionType* >( type ) ) {
+    return true;
+  } else if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
+    return typeInst->get_isFtype();
+  }
+  return false;
+}
+
+bool
+tyVarCompatible( TypeDecl::Kind kind, Type *type, const SymTab::Indexer &indexer )
+{
+  switch( kind ) {
+  case TypeDecl::Any:
+  case TypeDecl::Dtype:
+    return !isFtype( type, indexer );
+  
+  case TypeDecl::Ftype:
+    return isFtype( type, indexer );
+  }
+  assert( false );
+  return false;
+}
+
+bool
+bindVar( TypeInstType *typeInst, Type *other, TypeDecl::Kind kind, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer )
+{
+  OpenVarSet::const_iterator tyvar = openVars.find( typeInst->get_name() );
+  assert( tyvar != openVars.end() );
+  if( !tyVarCompatible( tyvar->second, other, indexer ) ) {
+    return false;
+  }
+  if( occurs( other, typeInst->get_name(), env ) ) {
+    return false;
+  }
+  EqvClass curClass;
+  if( env.lookup( typeInst->get_name(), curClass ) ) {
+    if( curClass.type ) {
+      Type *common = 0;
+      std::auto_ptr< Type > newType( curClass.type->clone() );
+      if( unifyInexact( newType.get(), other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass.allowWidening, true ), indexer, common ) ) {
+        if( common ) {
+          common->get_qualifiers() = Type::Qualifiers();
+          delete curClass.type;
+          curClass.type = common;
+          env.add( curClass );
+        }
+        return true;
+      } else {
+        return false;
+      }
+    } else {
+      curClass.type = other->clone();
+      curClass.type->get_qualifiers() = Type::Qualifiers();
+      curClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
+      env.add( curClass );
+    }
+  } else {
+    EqvClass newClass;
+    newClass.vars.insert( typeInst->get_name() );
+    newClass.type = other->clone();
+    newClass.type->get_qualifiers() = Type::Qualifiers();
+    newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
+    newClass.kind = kind;
+    env.add( newClass );
+  }
+  return true;
+}
+
+bool
+bindVarToVar( TypeInstType *var1, TypeInstType *var2, TypeDecl::Kind kind, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer )
+{
+  bool result = true;
+  EqvClass class1, class2;
+  bool hasClass1 = false, hasClass2 = false;
+  bool widen1 = false, widen2 = false;
+  Type *type1 = 0, *type2 = 0;
+  
+  if( env.lookup( var1->get_name(), class1 ) ) {
+    hasClass1 = true;
+    if( class1.type ) {
+      if( occurs( class1.type, var2->get_name(), env ) ) {
+        return false;
+      }
+      type1 = class1.type->clone();
+    }
+    widen1 = widenMode.widenFirst && class1.allowWidening;
+  }
+  if( env.lookup( var2->get_name(), class2 ) ) {
+    hasClass2 = true;
+    if( class2.type ) {
+      if( occurs( class2.type, var1->get_name(), env ) ) {
+        return false;
+      }
+      type2 = class2.type->clone();
+    }
+    widen2 = widenMode.widenSecond && class2.allowWidening;
+  }
+  
+  if( type1 && type2 ) {
+//    std::cout << "has type1 && type2" << std::endl;
+    WidenMode newWidenMode ( widen1, widen2 );
+    Type *common = 0;
+    if( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, newWidenMode, indexer, common ) ) {
+      class1.vars.insert( class2.vars.begin(), class2.vars.end() );
+      class1.allowWidening = widen1 && widen2;
+      if( common ) {
+        common->get_qualifiers() = Type::Qualifiers();
+        delete class1.type;
+        class1.type = common;
+      }
+      env.add( class1 );
+    } else {
+      result = false;
+    }
+  } else if( hasClass1 && hasClass2 ) {
+    if( type1 ) {
+      class1.vars.insert( class2.vars.begin(), class2.vars.end() );
+      class1.allowWidening = widen1;
+      env.add( class1 );
+    } else {
+      class2.vars.insert( class1.vars.begin(), class1.vars.end() );
+      class2.allowWidening = widen2;
+      env.add( class2 );
+    }
+  } else if( hasClass1 ) {
+    class1.vars.insert( var2->get_name() );
+    class1.allowWidening = widen1;
+    env.add( class1 );
+  } else if( hasClass2 ) {
+    class2.vars.insert( var1->get_name() );
+    class2.allowWidening = widen2;
+    env.add( class2 );
+  } else {
+    EqvClass newClass;
+    newClass.vars.insert( var1->get_name() );
+    newClass.vars.insert( var2->get_name() );
+    newClass.allowWidening = widen1 && widen2;
+    newClass.kind = kind;
+    env.add( newClass );
+  }
+  delete type1;
+  delete type2;
+  return result;
+}
+
+bool
+unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer )
+{
+  OpenVarSet closedVars;
+  findOpenVars( type1, openVars, closedVars, needAssertions, haveAssertions, false );
+  findOpenVars( type2, openVars, closedVars, needAssertions, haveAssertions, true );
+  Type *commonType = 0;
+  if( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType ) ) {
+    if( commonType ) {
+      delete commonType;
+    }
+    return true;
+  } else {
+    return false;
+  }
+}
+
+bool
+unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType )
+{
+  OpenVarSet closedVars;
+  findOpenVars( type1, openVars, closedVars, needAssertions, haveAssertions, false );
+  findOpenVars( type2, openVars, closedVars, needAssertions, haveAssertions, true );
+  return unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, WidenMode( true, true ), indexer, commonType );
+}
+
+bool
+unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer )
+{
+#ifdef DEBUG
+  TypeEnvironment debugEnv( env );
+#endif
+  bool result;
+  TypeInstType *var1 = dynamic_cast< TypeInstType* >( type1 );
+  TypeInstType *var2 = dynamic_cast< TypeInstType* >( type2 );
+  OpenVarSet::const_iterator entry1, entry2;
+  if( var1 ) {
+    entry1 = openVars.find( var1->get_name() );
+  }
+  if( var2 ) {
+    entry2 = openVars.find( var2->get_name() );
+  }
+  bool isopen1 = var1 && ( entry1 != openVars.end() );
+  bool isopen2 = var2 && ( entry2 != openVars.end() );
+  if( type1->get_qualifiers() != type2->get_qualifiers() ) {
+    return false;
+  } else if( isopen1 && isopen2 && entry1->second == entry2->second ) {
+    result = bindVarToVar( var1, var2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
+  } else if( isopen1 ) {
+    result = bindVar( var1, type2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
+  } else if( isopen2 ) {
+    result = bindVar( var2, type1, entry2->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
+  } else {
+    Unify comparator( type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
+    type1->accept( comparator );
+    result = comparator.get_result();
+  }
+#ifdef DEBUG
+  std::cout << "============ unifyExact" << std::endl;
+  std::cout << "type1 is ";
+  type1->print( std::cout );
+  std::cout << std::endl << "type2 is ";
+  type2->print( std::cout );
+  std::cout << std::endl << "openVars are ";
+  printOpenVarSet( openVars, std::cout, 8 );
+  std::cout << std::endl << "input env is " << std::endl;
+  debugEnv.print( std::cout, 8 );
+  std::cout << std::endl << "result env is " << std::endl;
+  env.print( std::cout, 8 );
+  std::cout << "result is " << result << std::endl;
+#endif
+  return result;
+}
+
+bool
+unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer )
+{
+  return unifyExact( type1, type2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+}
+
+bool
+unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer, Type *&common )
+{
+  Type::Qualifiers tq1 = type1->get_qualifiers(), tq2 = type2->get_qualifiers();
+  type1->get_qualifiers() = Type::Qualifiers();
+  type2->get_qualifiers() = Type::Qualifiers();
+  bool result;
+#ifdef DEBUG
+  std::cout << "unifyInexact type 1 is ";
+  type1->print( std::cout );
+  std::cout << "type 2 is ";
+  type2->print( std::cout );
+  std::cout << std::endl;
+#endif
+  if( !unifyExact( type1, type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer ) ) {
+#ifdef DEBUG
+    std::cout << "unifyInexact: no exact unification found" << std::endl;
+#endif
+    if( ( common = commonType( type1, type2, widenMode.widenFirst, widenMode.widenSecond, indexer, env, openVars ) ) ) {
+      common->get_qualifiers() = tq1 + tq2;
+#ifdef DEBUG
+      std::cout << "unifyInexact: common type is ";
+      common->print( std::cout );
+      std::cout << std::endl;
+#endif
+      result = true;
+    } else {
+#ifdef DEBUG
+      std::cout << "unifyInexact: no common type found" << std::endl;
+#endif
+      result = false;
+    }
+  } else {
+    if( tq1 != tq2 ) {
+      if( ( tq1 > tq2 || widenMode.widenFirst ) && ( tq2 > tq1 || widenMode.widenSecond ) ) {
+        common = type1->clone();
+        common->get_qualifiers() = tq1 + tq2;
+        result = true;
+      } else {
+        result = false;
+      }
+    } else {
+      result = true;
+    }
+  }
+  type1->get_qualifiers() = tq1;
+  type2->get_qualifiers() = tq2;
+  return result;
+}
+
+Unify::Unify( Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer )
+  : result( false ), type2( type2 ), env( env ), needAssertions( needAssertions ), haveAssertions( haveAssertions ), openVars( openVars ), widenMode( widenMode ), indexer( indexer )
+{
+}
+
+void 
+Unify::visit(VoidType *voidType)
+{
+  result = dynamic_cast< VoidType* >( type2 );
+}
+
+void 
+Unify::visit(BasicType *basicType)
+{
+  if( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) {
+    result = basicType->get_kind() == otherBasic->get_kind();
+  }
+}
+
+void
+markAssertionSet( AssertionSet &assertions, DeclarationWithType *assert )
+{
+///   std::cout << "assertion set is" << std::endl;
+///   printAssertionSet( assertions, std::cout, 8 );
+///   std::cout << "looking for ";
+///   assert->print( std::cout );
+///   std::cout << std::endl;
+  AssertionSet::iterator i = assertions.find( assert );
+  if( i != assertions.end() ) {
+///     std::cout << "found it!" << std::endl;
+    i->second = true;
+  }
+}
+
+void
+markAssertions( AssertionSet &assertion1, AssertionSet &assertion2, Type *type )
+{
+  for( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
+    for( std::list< DeclarationWithType* >::const_iterator assert = (*tyvar)->get_assertions().begin(); assert != (*tyvar)->get_assertions().end(); ++assert ) {
+      markAssertionSet( assertion1, *assert );
+      markAssertionSet( assertion2, *assert );
+    }
+  }
+}
+
+void 
+Unify::visit(PointerType *pointerType)
+{
+  if( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) {
+    result = unifyExact( pointerType->get_base(), otherPointer->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+    markAssertions( haveAssertions, needAssertions, pointerType );
+    markAssertions( haveAssertions, needAssertions, otherPointer );
+  }
+}
+
+void 
+Unify::visit(ArrayType *arrayType)
+{
+  // XXX -- compare array dimension
+  ArrayType *otherArray = dynamic_cast< ArrayType* >( type2 );
+  if( otherArray && arrayType->get_isVarLen() == otherArray->get_isVarLen() ) {
+    result = unifyExact( arrayType->get_base(), otherArray->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+  }
+}
+
+template< typename Iterator1, typename Iterator2 >
+bool
+unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
+  for( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
+    if( !unifyExact( (*list1Begin)->get_type(), (*list2Begin)->get_type(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
+      return false;
+    }
+  }
+  if( list1Begin != list1End || list2Begin != list2End ) {
+    return false;
+  } else {
+    return true;
+  }
+}
+
+void 
+Unify::visit(FunctionType *functionType)
+{
+  FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 );
+  if( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) {
+  
+    if( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
+    
+      if( unifyDeclList( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), otherFunction->get_returnVals().begin(), otherFunction->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
+
+        markAssertions( haveAssertions, needAssertions, functionType );
+        markAssertions( haveAssertions, needAssertions, otherFunction );
+
+        result = true;
+      }
+    }
+  }
+}
+
+template< typename RefType >
+void
+Unify::handleRefType( RefType *inst, Type *other )
+{  
+  RefType *otherStruct = dynamic_cast< RefType* >( other );
+  result = otherStruct && inst->get_name() == otherStruct->get_name();
+}  
+
+void 
+Unify::visit(StructInstType *structInst)
+{
+  handleRefType( structInst, type2 );
+}
+
+void 
+Unify::visit(UnionInstType *unionInst)
+{
+  handleRefType( unionInst, type2 );
+}
+
+void 
+Unify::visit(EnumInstType *enumInst)
+{
+  handleRefType( enumInst, type2 );
+}
+
+void 
+Unify::visit(ContextInstType *contextInst)
+{
+  handleRefType( contextInst, type2 );
+}
+
+void 
+Unify::visit(TypeInstType *typeInst)
+{
+  assert( openVars.find( typeInst->get_name() ) == openVars.end() );
+  TypeInstType *otherInst = dynamic_cast< TypeInstType* >( type2 );
+  if( otherInst && typeInst->get_name() == otherInst->get_name() ) {
+    result = true;
+///   } else {
+///     NamedTypeDecl *nt = indexer.lookupType( typeInst->get_name() );
+///     if( nt ) {
+///       TypeDecl *type = dynamic_cast< TypeDecl* >( nt );
+///       assert( type );
+///       if( type->get_base() ) {
+///         result = unifyExact( type->get_base(), typeInst, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
+///       }
+///     }
+  }
+}
+
+template< typename Iterator1, typename Iterator2 >
+bool
+unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
+  for( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
+    Type *commonType = 0;
+    if( !unifyInexact( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, widenMode, indexer, commonType ) ) {
+      return false;
+    }
+    delete commonType;
+  }
+  if( list1Begin != list1End || list2Begin != list2End ) {
+    return false;
+  } else {
+    return true;
+  }
+}
+
+void 
+Unify::visit(TupleType *tupleType)
+{
+  if( TupleType *otherTuple = dynamic_cast< TupleType* >( type2 ) ) {
+    result = unifyList( tupleType->get_types().begin(), tupleType->get_types().end(), otherTuple->get_types().begin(), otherTuple->get_types().end(), env, needAssertions, haveAssertions, openVars, widenMode, indexer );
+  }
+}
+
+} // namespace ResolvExpr
Index: translator/ResolvExpr/Unify.h
===================================================================
--- translator/ResolvExpr/Unify.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/Unify.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,57 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Unify.h,v 1.4 2005/08/29 20:14:16 rcbilson Exp $
+ *
+ */
+
+#ifndef UNIFY_H
+#define UNIFY_H
+
+#include <map>
+#include <list>
+#include "SynTree/SynTree.h"
+#include "SynTree/Type.h"
+#include "SynTree/Declaration.h"
+#include "SymTab/Indexer.h"
+#include "TypeEnvironment.h"
+#include "utility.h"
+
+namespace ResolvExpr {
+
+bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
+bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType );
+bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
+
+template< typename Iterator1, typename Iterator2 >
+bool
+unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, std::list< Type* > &commonTypes ) {
+  for( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
+    Type *commonType = 0;
+    if( !unify( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
+      return false;
+    }
+    commonTypes.push_back( commonType );
+  }
+  if( list1Begin != list1End || list2Begin != list2End ) {
+    return false;
+  } else {
+    return true;
+  }
+}
+
+template< typename Iterator1, typename Iterator2 >
+bool
+unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
+  std::list< Type* > commonTypes;
+  if( unifyList( list1Begin, list1End, list2Begin, list2End, env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) {
+    deleteAll( commonTypes );
+    return true;
+  } else {
+    return false;
+  }
+}
+
+} // namespace ResolvExpr
+
+#endif /* #ifndef UNIFY_H */
Index: translator/ResolvExpr/module.mk
===================================================================
--- translator/ResolvExpr/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,18 @@
+SRC += ResolvExpr/AlternativeFinder.cc \
+      ResolvExpr/Alternative.cc \
+       ResolvExpr/Unify.cc \
+       ResolvExpr/PtrsAssignable.cc \
+       ResolvExpr/CommonType.cc \
+       ResolvExpr/ConversionCost.cc \
+       ResolvExpr/CastCost.cc \
+       ResolvExpr/PtrsCastable.cc \
+       ResolvExpr/AdjustExprType.cc \
+       ResolvExpr/AlternativePrinter.cc \
+       ResolvExpr/Resolver.cc \
+       ResolvExpr/ResolveTypeof.cc \
+       ResolvExpr/RenameVars.cc \
+       ResolvExpr/FindOpenVars.cc \
+       ResolvExpr/PolyCost.cc \
+       ResolvExpr/Occurs.cc \
+       ResolvExpr/TypeEnvironment.cc
+       
Index: translator/ResolvExpr/typeops.h
===================================================================
--- translator/ResolvExpr/typeops.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/typeops.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,161 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: typeops.h,v 1.14 2005/08/29 20:14:17 rcbilson Exp $
+ *
+ */
+
+#ifndef TYPEOPS_H
+#define TYPEOPS_H
+
+#include "SynTree/SynTree.h"
+#include "SynTree/Type.h"
+#include "SymTab/Indexer.h"
+#include "Cost.h"
+#include "TypeEnvironment.h"
+
+namespace ResolvExpr {
+
+// combos: takes a list of sets and returns a set of lists representing
+// every possible way of forming a list by picking one element out of each set
+template< typename InputIterator, typename OutputIterator >
+void
+combos( InputIterator begin, InputIterator end, OutputIterator out )
+{
+  typedef typename InputIterator::value_type SetType;
+  typedef typename std::list< typename SetType::value_type > ListType;
+  
+  if( begin == end )
+  {
+    *out++ = ListType();
+    return;
+  }
+  
+  InputIterator current = begin;
+  begin++;
+
+  std::list< ListType > recursiveResult;
+  combos( begin, end, back_inserter( recursiveResult ) );
+  
+  for( typename std::list< ListType >::const_iterator i = recursiveResult.begin(); i != recursiveResult.end(); ++i ) {
+    for( typename ListType::const_iterator j = current->begin(); j != current->end(); ++j ) {
+      ListType result;
+      std::back_insert_iterator< ListType > inserter = back_inserter( result );
+      *inserter++ = *j;
+      std::copy( i->begin(), i->end(), inserter );
+      *out++ = result;
+    }
+  }
+}
+  
+// in AdjustExprType.cc
+void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer );
+
+template< typename ForwardIterator >
+void
+adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment &env, const SymTab::Indexer &indexer )
+{
+  while( begin != end ) {
+    adjustExprType( *begin++, env, indexer );
+  }
+}
+
+// in CastCost.cc
+Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
+
+template< typename SrcIterator, typename DestIterator >
+Cost
+castCostList( SrcIterator srcBegin, SrcIterator srcEnd, DestIterator destBegin, DestIterator destEnd, const SymTab::Indexer &indexer, const TypeEnvironment &env )
+{
+  Cost ret;
+  if( destBegin == destEnd ) {
+    if( srcBegin == srcEnd ) {
+      return Cost::zero;
+    } else {
+      return Cost( 0, 0, 1 );
+    }
+  }
+  while( srcBegin != srcEnd && destBegin != destEnd ) {
+    Cost thisCost = castCost( *srcBegin++, *destBegin++, indexer, env );
+    if( thisCost == Cost::infinity ) {
+      return Cost::infinity;
+    }
+    ret += thisCost;
+  }
+  if( srcBegin == srcEnd && destBegin == destEnd ) {
+    return ret;
+  } else {
+    return Cost::infinity;
+  }
+}
+
+// in ConversionCost.cc
+Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
+
+template< typename SrcIterator, typename DestIterator >
+Cost
+conversionCostList( SrcIterator srcBegin, SrcIterator srcEnd, DestIterator destBegin, DestIterator destEnd, const SymTab::Indexer &indexer, const TypeEnvironment &env )
+{
+  Cost ret;
+  while( srcBegin != srcEnd && destBegin != destEnd ) {
+    Cost thisCost = conversionCost( *srcBegin++, *destBegin++, indexer, env );
+    if( thisCost == Cost::infinity ) {
+      return Cost::infinity;
+    }
+    ret += thisCost;
+  }
+  if( srcBegin == srcEnd && destBegin == destEnd ) {
+    return ret;
+  } else {
+    return Cost::infinity;
+  }
+}
+
+// in PtrsAssignable.cc
+int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env );
+
+// in PtrsCastable.cc
+int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
+
+// in Unify.cc
+bool typesCompatible( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
+bool typesCompatibleIgnoreQualifiers( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
+
+inline bool typesCompatible( Type *t1, Type *t2, const SymTab::Indexer &indexer )
+{
+  TypeEnvironment env;
+  return typesCompatible( t1, t2, indexer, env );
+}
+
+inline bool typesCompatibleIgnoreQualifiers( Type *t1, Type *t2, const SymTab::Indexer &indexer )
+{
+  TypeEnvironment env;
+  return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env );
+}
+
+template< typename Container1, typename Container2 >
+bool
+typesCompatibleList( Container1 &c1, Container2 &c2, const SymTab::Indexer &indexer, const TypeEnvironment &env )
+{
+  typename Container1::iterator i1 = c1.begin();
+  typename Container2::iterator i2 = c2.begin();
+  for( ; i1 != c1.end() && i2 != c2.end(); ++i1, ++i2 ) {
+    if( !typesCompatible( *i1, *i2, indexer ) ) {
+      return false;
+    }
+  }
+  return ( i1 == c1.end() ) && ( i2 == c2.end() );
+}
+
+// in CommonType.cc
+Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
+
+// in PolyCost.cc
+int polyCost( Type *type, const TypeEnvironment &env, const SymTab::Indexer &indexer );
+
+// in Occurs.cc
+bool occurs( Type *type, std::string varName, const TypeEnvironment &env );
+
+} // namespace ResolvExpr
+
+#endif /* #ifndef TYPEOPS_H */
Index: translator/SymTab/AddVisit.h
===================================================================
--- translator/SymTab/AddVisit.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/AddVisit.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,102 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: AddVisit.h,v 1.2 2005/08/29 20:14:17 rcbilson Exp $
+ *
+ */
+
+
+namespace SymTab {
+
+void addDecls( std::list< Declaration* > &declsToAdd, std::list< Statement* > &statements, std::list< Statement* >::iterator i );
+
+template< typename Visitor >
+inline void
+addVisitStatementList( std::list< Statement* > &statements, Visitor &visitor )
+{
+  for( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
+    addDecls( visitor.get_declsToAdd(), statements, i );
+    (*i)->accept( visitor );
+  }
+  addDecls( visitor.get_declsToAdd(), statements, statements.end() );
+}
+
+template< typename Visitor >
+inline void
+addVisitStatement( Statement *stmt, Visitor &visitor )
+{
+  maybeAccept( stmt, visitor );
+///   if( !declsToAdd.empty() ) {
+///     CompoundStmt *compound = new CompoundStmt( noLabels );
+///     compound->get_kids().push_back( stmt );
+///     addDecls( declsToAdd, compound->get_kids(), compound->get_kids().end() );
+///   }
+}
+
+template< typename Visitor >
+inline void
+addVisit(CompoundStmt *compoundStmt, Visitor &visitor)
+{
+  addVisitStatementList( compoundStmt->get_kids(), visitor );
+}
+
+template< typename Visitor >
+inline void
+addVisit(IfStmt *ifStmt, Visitor &visitor)
+{
+  addVisitStatement( ifStmt->get_thenPart(), visitor );
+  addVisitStatement( ifStmt->get_elsePart(), visitor );
+  maybeAccept( ifStmt->get_condition(), visitor );
+}
+
+template< typename Visitor >
+inline void
+addVisit(WhileStmt *whileStmt, Visitor &visitor)
+{
+  addVisitStatement( whileStmt->get_body(), visitor );
+  maybeAccept( whileStmt->get_condition(), visitor );
+}
+
+template< typename Visitor >
+inline void
+addVisit(ForStmt *forStmt, Visitor &visitor)
+{
+  addVisitStatement( forStmt->get_body(), visitor );
+  maybeAccept( forStmt->get_initialization(), visitor );
+  maybeAccept( forStmt->get_condition(), visitor );
+  maybeAccept( forStmt->get_increment(), visitor );
+}
+
+template< typename Visitor >
+inline void
+addVisit(SwitchStmt *switchStmt, Visitor &visitor)
+{
+  addVisitStatementList( switchStmt->get_branches(), visitor );
+  maybeAccept( switchStmt->get_condition(), visitor );
+}
+
+template< typename Visitor >
+inline void
+addVisit(ChooseStmt *switchStmt, Visitor &visitor)
+{
+  addVisitStatementList( switchStmt->get_branches(), visitor );
+  maybeAccept( switchStmt->get_condition(), visitor );
+}
+
+template< typename Visitor >
+inline void
+addVisit(CaseStmt *caseStmt, Visitor &visitor)
+{
+  addVisitStatementList( caseStmt->get_statements(), visitor );
+  maybeAccept( caseStmt->get_condition(), visitor );
+}
+
+template< typename Visitor >
+inline void
+addVisit(CatchStmt *cathStmt, Visitor &visitor)
+{
+  addVisitStatement( cathStmt->get_body(), visitor );
+  maybeAccept( cathStmt->get_decl(), visitor );
+}
+
+} // namespace SymTab
Index: translator/SymTab/AggregateTable.h
===================================================================
--- translator/SymTab/AggregateTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/AggregateTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,44 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: AggregateTable.h,v 1.4 2005/08/29 20:14:17 rcbilson Exp $
+ *
+ */
+
+#ifndef SYMTAB_AGGREGATETABLE_H
+#define SYMTAB_AGGREGATETABLE_H
+
+#include <map>
+#include <stack>
+#include <string>
+#include <functional>
+
+#include "StackTable.h"
+#include "SynTree/Declaration.h"
+
+namespace SymTab {
+
+template< class AggregateDeclClass >
+class AggregateTableConflictFunction : public std::binary_function< AggregateDeclClass*, AggregateDeclClass*, AggregateDeclClass* >
+{
+public:
+  AggregateDeclClass *operator()( AggregateDeclClass *existing, AggregateDeclClass *added )
+  {
+    if( existing->get_members().empty() ) {
+      return added;
+    } else if( !added->get_members().empty() ) {
+      throw SemanticError( "redeclaration of ", added );
+    }
+    return existing;
+  }
+  
+};
+
+typedef StackTable< StructDecl, AggregateTableConflictFunction< StructDecl > > StructTable;
+typedef StackTable< EnumDecl, AggregateTableConflictFunction< EnumDecl > > EnumTable;
+typedef StackTable< UnionDecl, AggregateTableConflictFunction< UnionDecl > > UnionTable;
+typedef StackTable< ContextDecl, AggregateTableConflictFunction< ContextDecl > > ContextTable;
+
+} // namespace SymTab
+
+#endif /* #ifndef SYMTAB_AGGREGATETABLE_H */
Index: translator/SymTab/FixFunction.cc
===================================================================
--- translator/SymTab/FixFunction.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/FixFunction.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,86 @@
+#include "FixFunction.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+#include "SynTree/Expression.h"
+#include "utility.h"
+
+namespace SymTab {
+
+FixFunction::FixFunction()
+  : isVoid( false )
+{
+}
+
+DeclarationWithType* 
+FixFunction::mutate(FunctionDecl *functionDecl)
+{
+  ObjectDecl *pointer = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0, new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
+  delete functionDecl;
+  return pointer;
+}
+
+Type* 
+FixFunction::mutate(VoidType *voidType)
+{
+  isVoid = true;
+  return voidType;
+}
+
+Type* 
+FixFunction::mutate(BasicType *basicType)
+{
+  return basicType;
+}
+
+Type* 
+FixFunction::mutate(PointerType *pointerType)
+{
+  return pointerType;
+}
+
+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() );
+  delete arrayType;
+  return pointerType;
+}
+
+Type* 
+FixFunction::mutate(StructInstType *aggregateUseType)
+{
+  return aggregateUseType;
+}
+
+Type* 
+FixFunction::mutate(UnionInstType *aggregateUseType)
+{
+  return aggregateUseType;
+}
+
+Type* 
+FixFunction::mutate(EnumInstType *aggregateUseType)
+{
+  return aggregateUseType;
+}
+
+Type* 
+FixFunction::mutate(ContextInstType *aggregateUseType)
+{
+  return aggregateUseType;
+}
+
+Type* 
+FixFunction::mutate(TypeInstType *aggregateUseType)
+{
+  return aggregateUseType;
+}
+
+Type* 
+FixFunction::mutate(TupleType *tupleType)
+{
+  return tupleType;
+}
+
+
+} // namespace SymTab
Index: translator/SymTab/FixFunction.h
===================================================================
--- translator/SymTab/FixFunction.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/FixFunction.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,44 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: FixFunction.h,v 1.3 2005/08/29 20:14:17 rcbilson Exp $
+ *
+ */
+
+#ifndef SYMTAB_FIXFUNCTION_H
+#define SYMTAB_FIXFUNCTION_H
+
+#include "SynTree/Mutator.h"
+
+namespace SymTab {
+
+class FixFunction : public Mutator
+{
+  typedef Mutator Parent;
+
+public:
+  FixFunction();
+
+  bool get_isVoid() const { return isVoid; }
+  void set_isVoid( bool newValue ) { isVoid = newValue; }
+
+private:
+  virtual DeclarationWithType* mutate(FunctionDecl *functionDecl);
+
+  virtual Type* mutate(VoidType *voidType);
+  virtual Type* mutate(BasicType *basicType);
+  virtual Type* mutate(PointerType *pointerType);
+  virtual Type* mutate(ArrayType *arrayType);
+  virtual Type* mutate(StructInstType *aggregateUseType);
+  virtual Type* mutate(UnionInstType *aggregateUseType);
+  virtual Type* mutate(EnumInstType *aggregateUseType);
+  virtual Type* mutate(ContextInstType *aggregateUseType);
+  virtual Type* mutate(TypeInstType *aggregateUseType);
+  virtual Type* mutate(TupleType *tupleType);
+  
+  bool isVoid;
+};
+
+} // namespace SymTab
+
+#endif /* #ifndef SYMTAB_FIXFUNCTION_H */
Index: translator/SymTab/IdTable.cc
===================================================================
--- translator/SymTab/IdTable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/IdTable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,119 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: IdTable.cc,v 1.6 2005/08/29 20:14:17 rcbilson Exp $
+ *
+ */
+
+#include <cassert>
+
+#include "SynTree/Declaration.h"
+#include "ResolvExpr/typeops.h"
+#include "Indexer.h"
+#include "Mangler.h"
+#include "IdTable.h"
+#include "SemanticError.h"
+
+using std::string;
+
+namespace SymTab {
+
+IdTable::IdTable()
+  : scopeLevel( 0 )
+{
+}
+
+void 
+IdTable::enterScope()
+{
+  scopeLevel++;
+}
+
+void 
+IdTable::leaveScope()
+{
+  for( OuterTableType::iterator outer = table.begin(); outer != table.end(); ++outer ) {
+    for( InnerTableType::iterator inner = outer->second.begin(); inner != outer->second.end(); ++inner ) {
+      std::stack< DeclEntry >& entry = inner->second;
+      if( !entry.empty() && entry.top().second == scopeLevel ) {
+        entry.pop();
+      }
+    }
+  }
+      
+  scopeLevel--;
+  assert( scopeLevel >= 0 );
+}
+
+void 
+IdTable::addDecl( DeclarationWithType *decl )
+{
+  const string &name = decl->get_name();
+  string manglename;
+  if( decl->get_linkage() == LinkageSpec::C ) {
+    manglename = name;
+  } else {
+    manglename = Mangler::mangle( decl );
+  }
+  InnerTableType &declTable = table[ name ];
+  InnerTableType::iterator it = declTable.find( manglename );
+  if( it == declTable.end() ) {
+    declTable[ manglename ].push( DeclEntry( decl, scopeLevel ) );
+  } else {
+    std::stack< DeclEntry >& entry = it->second;
+    if( !entry.empty() && entry.top().second == scopeLevel ) {
+      if( decl->get_linkage() != LinkageSpec::C || ResolvExpr::typesCompatible( decl->get_type(), entry.top().first->get_type(), Indexer() ) ) {
+        FunctionDecl *newentry = dynamic_cast< FunctionDecl* >( decl );
+        FunctionDecl *old = dynamic_cast< FunctionDecl* >( entry.top().first );
+        if( newentry && old && newentry->get_statements() && old->get_statements() ) {
+          throw SemanticError( "duplicate function definition for ", decl );
+        } else {
+          ObjectDecl *newobj = dynamic_cast< ObjectDecl* >( decl );
+          ObjectDecl *oldobj = dynamic_cast< ObjectDecl* >( entry.top().first );
+          if( newobj && oldobj && newobj->get_init() && oldobj->get_init() ) {
+            throw SemanticError( "duplicate definition for ", decl );
+          }
+        }
+      } else {
+        throw SemanticError( "duplicate definition for ", decl );
+      }
+    } else {
+      declTable[ manglename ].push( DeclEntry( decl, scopeLevel ) );
+    }
+  }
+  for( InnerTableType::const_iterator i = declTable.begin(); i != declTable.end(); ++i ) {
+    if( !i->second.empty() && i->second.top().first->get_linkage() == LinkageSpec::C && declTable.size() > 1 ) {
+      throw SemanticError( "invalid overload of C function ", i->second.top().first );
+    }
+  }
+}
+
+void 
+IdTable::lookupId( const std::string &id, std::list< DeclarationWithType* >& decls ) const
+{
+  OuterTableType::const_iterator outer = table.find( id );
+  if( outer == table.end() ) return;
+  const InnerTableType &declTable = outer->second;
+  for( InnerTableType::const_iterator it = declTable.begin(); it != declTable.end(); ++it ) {
+    const std::stack< DeclEntry >& entry = it->second;
+    if( !entry.empty() ) {
+      decls.push_back( entry.top().first );
+    }
+  }
+}
+
+void 
+IdTable::dump( std::ostream &os ) const
+{
+  for( OuterTableType::const_iterator outer = table.begin(); outer != table.end(); ++outer ) {
+    for( InnerTableType::const_iterator inner = outer->second.begin(); inner != outer->second.end(); ++inner ) {
+      const std::stack< DeclEntry >& entry = inner->second;
+      if( !entry.empty() && entry.top().second == scopeLevel ) {
+        os << outer->first << " (" << inner->first << ") (" << scopeLevel << ")" << std::endl;
+      }
+    }
+  }
+}
+
+
+} // namespace SymTab
Index: translator/SymTab/IdTable.h
===================================================================
--- translator/SymTab/IdTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/IdTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,43 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: IdTable.h,v 1.4 2005/08/29 20:14:17 rcbilson Exp $
+ *
+ */
+
+#ifndef SYMTAB_IDTABLE_H
+#define SYMTAB_IDTABLE_H
+
+#include <iostream>
+#include <map>
+#include <string>
+#include <stack>
+
+#include "SynTree/SynTree.h"
+
+namespace SymTab {
+
+class IdTable
+{
+public:
+  IdTable();
+  
+  void enterScope();
+  void leaveScope();
+  void addDecl( DeclarationWithType *decl );
+  void lookupId( const std::string &id, std::list< DeclarationWithType* >& decls ) const;
+  
+  void dump( std::ostream &os ) const; // debugging
+
+ private:
+  typedef std::pair< DeclarationWithType*, int > DeclEntry;
+  typedef std::map< std::string, std::stack< DeclEntry > > InnerTableType;
+  typedef std::map< std::string, InnerTableType > OuterTableType;
+
+  OuterTableType table;
+  int scopeLevel;
+};
+
+} // namespace SymTab
+
+#endif /* #ifndef SYMTAB_IDTABLE_H */
Index: translator/SymTab/ImplementationType.cc
===================================================================
--- translator/SymTab/ImplementationType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/ImplementationType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,140 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: ImplementationType.cc,v 1.4 2005/08/29 20:14:17 rcbilson Exp $
+ *
+ */
+
+#include "ImplementationType.h"
+#include "SynTree/Type.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Visitor.h"
+#include "SymTab/Indexer.h"
+#include "utility.h"
+
+
+namespace SymTab {
+
+class ImplementationType : public Visitor
+{
+public:
+  ImplementationType( const SymTab::Indexer &indexer );
+  
+  Type *get_result() { return result; }
+
+private:
+  virtual void visit(VoidType *voidType);
+  virtual void visit(BasicType *basicType);
+  virtual void visit(PointerType *pointerType);
+  virtual void visit(ArrayType *arrayType);
+  virtual void visit(FunctionType *functionType);
+  virtual void visit(StructInstType *aggregateUseType);
+  virtual void visit(UnionInstType *aggregateUseType);
+  virtual void visit(EnumInstType *aggregateUseType);
+  virtual void visit(ContextInstType *aggregateUseType);
+  virtual void visit(TypeInstType *aggregateUseType);
+  virtual void visit(TupleType *tupleType);
+
+  Type *result;			// synthesized
+  const SymTab::Indexer &indexer;
+};
+
+Type*
+implementationType( Type *type, const SymTab::Indexer& indexer )
+{
+  ImplementationType implementor( indexer );
+  type->accept( implementor );
+  if( implementor.get_result() == 0 ) {
+    return type->clone();
+  } else {
+    return implementor.get_result();
+  }
+}
+
+ImplementationType::ImplementationType( const SymTab::Indexer &indexer )
+  : result( 0 ), indexer( indexer )
+{
+}
+
+void 
+ImplementationType::visit(VoidType *voidType)
+{
+}
+
+void 
+ImplementationType::visit(BasicType *basicType)
+{
+}
+
+void 
+ImplementationType::visit(PointerType *pointerType)
+{
+  PointerType *newType = pointerType->clone();
+  newType->set_base( implementationType( pointerType->get_base(), indexer ) );
+  result = newType;
+}
+
+void 
+ImplementationType::visit(ArrayType *arrayType)
+{
+  ArrayType *newType = arrayType->clone();
+  newType->set_base( implementationType( arrayType->get_base(), indexer ) );
+  result = newType;
+}
+
+void 
+ImplementationType::visit(FunctionType *functionType)
+{
+///   FunctionType *newType = functionType->clone();
+///   for( std::list< DeclarationWithType* >::iterator i = newType->get_parameters().begin(); i != newType->get_parameters().end(); ++i ) {
+///     i->set_type( implementationType( i->get_type(), indexer ) );
+///   }
+///   for( std::list< DeclarationWithType* >::iterator i = newType->get_parameters().begin(); i != newType->get_parameters().end(); ++i ) {
+///     i->set_type( implementationType( i->get_type(), indexer ) );
+///   }
+}
+
+void 
+ImplementationType::visit(StructInstType *aggregateUseType)
+{
+}
+
+void 
+ImplementationType::visit(UnionInstType *aggregateUseType)
+{
+}
+
+void 
+ImplementationType::visit(EnumInstType *aggregateUseType)
+{
+}
+
+void 
+ImplementationType::visit(ContextInstType *aggregateUseType)
+{
+}
+
+void 
+ImplementationType::visit(TypeInstType *inst)
+{
+  NamedTypeDecl *typeDecl = indexer.lookupType( inst->get_name() );
+  if( typeDecl && typeDecl->get_base() ) {
+    Type *base = implementationType( typeDecl->get_base(), indexer );
+    base->get_qualifiers() += inst->get_qualifiers();
+    result = base;
+  }
+}
+
+void 
+ImplementationType::visit(TupleType *tupleType)
+{
+  TupleType *newType = new TupleType( Type::Qualifiers() );
+  for( std::list< Type* >::iterator i = tupleType->get_types().begin(); i != tupleType->get_types().end(); ++i ) {
+    Type *implType = implementationType( *i, indexer );
+    implType->get_qualifiers() += tupleType->get_qualifiers();
+    newType->get_types().push_back( implType );
+  }
+  result = newType;
+}
+
+} // namespace SymTab
Index: translator/SymTab/ImplementationType.h
===================================================================
--- translator/SymTab/ImplementationType.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/ImplementationType.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: ImplementationType.h,v 1.3 2005/08/29 20:14:17 rcbilson Exp $
+ *
+ */
+
+#ifndef SYMTAB_IMPLEMENTATIONTYPE_H
+#define SYMTAB_IMPLEMENTATIONTYPE_H
+
+#include "SynTree/SynTree.h"
+#include "SymTab/Indexer.h"
+
+namespace SymTab {
+
+Type *implementationType( Type *, const SymTab::Indexer &indexer );
+
+template< typename InputIterator, typename OutputIterator >
+void
+implementationTypeList( InputIterator begin, InputIterator end, OutputIterator out, const SymTab::Indexer &indexer )
+{
+  while( begin != end ) {
+    *out++ = implementationType( *begin++, indexer );
+  }
+}
+
+} // namespace SymTab
+
+#endif /* #ifndef SYMTAB_IMPLEMENTATIONTYPE_H */
Index: translator/SymTab/Indexer.cc
===================================================================
--- translator/SymTab/Indexer.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/Indexer.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,282 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Indexer.cc,v 1.12 2005/08/29 20:14:17 rcbilson Exp $
+ *
+ */
+
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Initializer.h"
+#include "SynTree/Statement.h"
+#include "Indexer.h"
+#include <typeinfo>
+#include "utility.h"
+
+#define debugPrint(x) if( doDebug ) { std::cout << x; }
+
+namespace SymTab {
+
+Indexer::Indexer( bool useDebug )
+  : doDebug( useDebug )
+{
+}
+
+Indexer::~Indexer()
+{
+}
+
+void 
+Indexer::visit( ObjectDecl *objectDecl )
+{
+  maybeAccept( objectDecl->get_type(), *this );
+  maybeAccept( objectDecl->get_init(), *this );
+  maybeAccept( objectDecl->get_bitfieldWidth(), *this );
+  if( objectDecl->get_name() != "" ) {
+    debugPrint( "Adding object " << objectDecl->get_name() << std::endl );
+    idTable.addDecl( objectDecl );
+  }
+}
+
+void 
+Indexer::visit( FunctionDecl *functionDecl )
+{
+  if( functionDecl->get_name() == "" ) return;
+  debugPrint( "Adding function " << functionDecl->get_name() << std::endl );
+  idTable.addDecl( functionDecl );
+  enterScope();
+  maybeAccept( functionDecl->get_functionType(), *this );
+  acceptAll( functionDecl->get_oldDecls(), *this );
+  maybeAccept( functionDecl->get_statements(), *this );
+  leaveScope();
+}
+
+/********
+ * A NOTE ON THE ORDER OF TRAVERSAL
+ *
+ * Types and typedefs have their base types visited before they are added to the type table.
+ * This is ok, since there is no such thing as a recursive type or typedef.
+ *             typedef struct { T *x; } T; // never allowed
+ *
+ * for structs/unions, it is possible to have recursion, so the decl should be added as if it's
+ * incomplete to begin, the members are traversed, and then the complete type should be added
+ * (assuming the type is completed by this particular declaration).
+ *             struct T { struct T *x; }; // allowed
+ *
+ * It's important to add the complete type to the symbol table *after* the members/base has been
+ * traversed, since that traversal may modify the definition of the type and these modifications
+ * should be visible when the symbol table is queried later in this pass.
+ *
+ * TODO: figure out whether recursive contexts are sensible/possible/reasonable.
+ */
+
+void 
+Indexer::visit( TypeDecl *typeDecl )
+{
+  // see A NOTE ON THE ORDER OF TRAVERSAL, above
+  // note that assertions come after the type is added to the symtab, since they aren't part
+  // of the type proper and may depend on the type itself
+  enterScope();
+  acceptAll( typeDecl->get_parameters(), *this );
+  maybeAccept( typeDecl->get_base(), *this );
+  leaveScope();
+  debugPrint( "Adding type " << typeDecl->get_name() << std::endl );
+  typeTable.add( typeDecl );
+  acceptAll( typeDecl->get_assertions(), *this );
+}
+
+void 
+Indexer::visit( TypedefDecl *typeDecl )
+{
+  enterScope();
+  acceptAll( typeDecl->get_parameters(), *this );
+  maybeAccept( typeDecl->get_base(), *this );
+  leaveScope();
+  debugPrint( "Adding typedef " << typeDecl->get_name() << std::endl );
+  typeTable.add( typeDecl );
+}
+
+void 
+Indexer::visit( StructDecl *aggregateDecl )
+{
+  // make up a forward declaration and add it before processing the members
+  StructDecl fwdDecl( aggregateDecl->get_name() );
+  cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
+  debugPrint( "Adding fwd decl for struct " << fwdDecl.get_name() << std::endl );
+  structTable.add( &fwdDecl );
+  
+  enterScope();
+  acceptAll( aggregateDecl->get_parameters(), *this );
+  acceptAll( aggregateDecl->get_members(), *this );
+  leaveScope();
+  
+  debugPrint( "Adding struct " << aggregateDecl->get_name() << std::endl );
+  // this addition replaces the forward declaration
+  structTable.add( aggregateDecl );
+}
+
+void 
+Indexer::visit( UnionDecl *aggregateDecl )
+{
+  // make up a forward declaration and add it before processing the members
+  UnionDecl fwdDecl( aggregateDecl->get_name() );
+  cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
+  debugPrint( "Adding fwd decl for union " << fwdDecl.get_name() << std::endl );
+  unionTable.add( &fwdDecl );
+  
+  enterScope();
+  acceptAll( aggregateDecl->get_parameters(), *this );
+  acceptAll( aggregateDecl->get_members(), *this );
+  leaveScope();
+  
+  debugPrint( "Adding union " << aggregateDecl->get_name() << std::endl );
+  unionTable.add( aggregateDecl );
+}
+
+void 
+Indexer::visit( EnumDecl *aggregateDecl )
+{
+  debugPrint( "Adding enum " << aggregateDecl->get_name() << std::endl );
+  enumTable.add( aggregateDecl );
+  // unlike structs, contexts, and unions, enums inject their members into the
+  // global scope
+  acceptAll( aggregateDecl->get_members(), *this );
+}
+
+void 
+Indexer::visit( ContextDecl *aggregateDecl )
+{
+  enterScope();
+  acceptAll( aggregateDecl->get_parameters(), *this );
+  acceptAll( aggregateDecl->get_members(), *this );
+  leaveScope();
+  
+  debugPrint( "Adding context " << aggregateDecl->get_name() << std::endl );
+  contextTable.add( aggregateDecl );
+}
+
+void 
+Indexer::visit( CompoundStmt *compoundStmt )
+{
+  enterScope();
+  acceptAll( compoundStmt->get_kids(), *this );
+  leaveScope();
+}
+
+void 
+Indexer::visit( ContextInstType *contextInst )
+{
+  acceptAll( contextInst->get_parameters(), *this );
+  acceptAll( contextInst->get_members(), *this );
+}
+
+void 
+Indexer::visit( StructInstType *structInst )
+{
+  if( !structTable.lookup( structInst->get_name() ) ) {
+    debugPrint( "Adding struct " << structInst->get_name() << " from implicit forward declaration" << std::endl );
+    structTable.add( structInst->get_name() );
+  }
+  enterScope();
+  acceptAll( structInst->get_parameters(), *this );
+  leaveScope();
+}
+
+void 
+Indexer::visit( UnionInstType *unionInst )
+{
+  if( !unionTable.lookup( unionInst->get_name() ) ) {
+    debugPrint( "Adding union " << unionInst->get_name() << " from implicit forward declaration" << std::endl );
+    unionTable.add( unionInst->get_name() );
+  }
+  enterScope();
+  acceptAll( unionInst->get_parameters(), *this );
+  leaveScope();
+}
+
+void
+Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &list ) const
+{
+  idTable.lookupId( id, list );
+}
+
+NamedTypeDecl *
+Indexer::lookupType( const std::string &id ) const
+{
+  return typeTable.lookup( id );
+}
+
+StructDecl *
+Indexer::lookupStruct( const std::string &id ) const
+{
+  return structTable.lookup( id );
+}
+
+EnumDecl *
+Indexer::lookupEnum( const std::string &id ) const
+{
+  return enumTable.lookup( id );
+}
+
+UnionDecl *
+Indexer::lookupUnion( const std::string &id ) const
+{
+  return unionTable.lookup( id );
+}
+
+ContextDecl *
+Indexer::lookupContext( const std::string &id ) const
+{
+  return contextTable.lookup( id );
+}
+
+void 
+Indexer::enterScope()
+{
+  if( doDebug ) {
+    std::cout << "--- Entering scope" << std::endl;
+  }
+  idTable.enterScope();
+  typeTable.enterScope();
+  structTable.enterScope();
+  enumTable.enterScope();
+  unionTable.enterScope();
+  contextTable.enterScope();
+}
+
+void 
+Indexer::leaveScope()
+{
+  using std::cout;
+  using std::endl;
+  
+  if( doDebug ) {
+    cout << "--- Leaving scope containing" << endl;
+    idTable.dump( cout );
+    typeTable.dump( cout );
+    structTable.dump( cout );
+    enumTable.dump( cout );
+    unionTable.dump( cout );
+    contextTable.dump( cout );
+  }
+  idTable.leaveScope();
+  typeTable.leaveScope();
+  structTable.leaveScope();
+  enumTable.leaveScope();
+  unionTable.leaveScope();
+  contextTable.leaveScope();
+}
+
+void 
+Indexer::print( std::ostream &os, int indent ) const
+{
+    idTable.dump( os );
+    typeTable.dump( os );
+    structTable.dump( os );
+    enumTable.dump( os );
+    unionTable.dump( os );
+    contextTable.dump( os );
+}
+
+} // namespace SymTab
Index: translator/SymTab/Indexer.h
===================================================================
--- translator/SymTab/Indexer.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/Indexer.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,74 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * A class that indexes the syntax tree.  It is intended to be subclassed by a visitor class
+ * that wants to use the index.
+ *
+ * $Id: Indexer.h,v 1.9 2005/08/29 20:14:18 rcbilson Exp $
+ *
+ */
+
+#ifndef SYMTAB_INDEXER_H
+#define SYMTAB_INDEXER_H
+
+#include <list>
+#include <string>
+#include <map>
+
+#include "SynTree/Visitor.h"
+#include "IdTable.h"
+#include "AggregateTable.h"
+#include "TypeTable.h"
+
+namespace SymTab {
+
+class Indexer : public Visitor
+{
+public:
+  Indexer( bool useDebug = false );
+  virtual ~Indexer();
+
+///   using Visitor::visit;
+  virtual void visit( ObjectDecl *objectDecl );
+  virtual void visit( FunctionDecl *functionDecl );
+  virtual void visit( TypeDecl *typeDecl );
+  virtual void visit( TypedefDecl *typeDecl );
+  virtual void visit( StructDecl *aggregateDecl );
+  virtual void visit( UnionDecl *aggregateDecl );
+  virtual void visit( EnumDecl *aggregateDecl );
+  virtual void visit( ContextDecl *aggregateDecl );
+
+  virtual void visit( CompoundStmt *compoundStmt );
+
+  virtual void visit( ContextInstType *contextInst );
+  virtual void visit( StructInstType *contextInst );
+  virtual void visit( UnionInstType *contextInst );
+  
+  // when using an indexer manually (e.g., within a mutator traversal), it is
+  // necessary to tell the indexer explicitly when scopes begin and end
+  void enterScope();
+  void leaveScope();
+
+  void lookupId( const std::string &id, std::list< DeclarationWithType* >& ) const;
+  NamedTypeDecl *lookupType( const std::string &id ) const;
+  StructDecl *lookupStruct( const std::string &id ) const;
+  EnumDecl *lookupEnum( const std::string &id ) const;
+  UnionDecl *lookupUnion( const std::string &id ) const;
+  ContextDecl *lookupContext( const std::string &id ) const;
+  
+  void print( std::ostream &os, int indent = 0 ) const;
+
+ private:
+  IdTable idTable;
+  TypeTable typeTable;
+  StructTable structTable;
+  EnumTable enumTable;
+  UnionTable unionTable;
+  ContextTable contextTable;
+  
+  bool doDebug;		// display debugging trace
+};
+
+} // namespace SymTab
+
+#endif /* #ifndef SYMTAB_INDEXER_H */
Index: translator/SymTab/Mangler.cc
===================================================================
--- translator/SymTab/Mangler.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/Mangler.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,277 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Mangler.cc,v 1.13 2005/08/29 20:14:18 rcbilson Exp $
+ *
+ */
+
+#include <cassert>
+#include <string>
+#include <algorithm>
+#include <iterator>
+#include <functional>
+#include <set>
+
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Initializer.h"
+#include "SynTree/Statement.h"
+#include "Mangler.h"
+#include "CodeGen/OperatorTable.h"
+
+namespace SymTab {
+
+Mangler::Mangler()
+  : nextVarNum( 0 ), isTopLevel( true )
+{
+}
+
+//Mangler::Mangler( const Mangler & )
+//  : mangleName(), varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( isTopLevel )
+//{
+//}
+Mangler::Mangler( const Mangler &rhs )
+  : mangleName()
+{
+  varNums = rhs.varNums;
+  nextVarNum = rhs.nextVarNum;
+  isTopLevel = rhs.isTopLevel;
+}
+
+void 
+Mangler::mangleDecl(DeclarationWithType *declaration)
+{
+  bool wasTopLevel = isTopLevel;
+  if( isTopLevel ) {
+    varNums.clear();
+    nextVarNum = 0;
+    isTopLevel = false;
+  }
+  mangleName << "__";
+  CodeGen::OperatorInfo opInfo;
+  if( operatorLookup( declaration->get_name(), opInfo ) ) {
+    mangleName << opInfo.outputName;
+  } else {
+    mangleName << declaration->get_name();
+  }
+  mangleName << "__";
+  maybeAccept( declaration->get_type(), *this );
+  isTopLevel = wasTopLevel;
+}
+
+void 
+Mangler::visit(ObjectDecl *declaration)
+{
+  mangleDecl( declaration );
+}
+
+void 
+Mangler::visit(FunctionDecl *declaration)
+{
+  mangleDecl( declaration );
+}
+
+void 
+Mangler::visit(VoidType *voidType)
+{
+  printQualifiers( voidType );
+  mangleName << "v";
+}
+
+void 
+Mangler::visit(BasicType *basicType)
+{
+  static const char *btLetter[] = {
+    "b",	// Bool
+    "c",	// Char
+    "Sc",	// SignedChar
+    "Uc",	// UnsignedChar
+    "s",	// ShortSignedInt
+    "Us",	// ShortUnsignedInt
+    "i",	// SignedInt
+    "Ui",	// UnsignedInt
+    "l",	// LongSignedInt
+    "Ul",	// LongUnsignedInt
+    "q",	// LongLongSignedInt
+    "Uq",	// LongLongUnsignedInt
+    "f",	// Float
+    "d",	// Double
+    "r",	// LongDouble
+    "Xf",	// FloatComplex
+    "Xd",	// DoubleComplex
+    "Xr",	// LongDoubleComplex
+    "If",	// FloatImaginary
+    "Id",	// DoubleImaginary
+    "Ir",	// LongDoubleImaginary
+  };
+  
+  printQualifiers( basicType );
+  mangleName << btLetter[ basicType->get_kind() ];
+}
+
+void 
+Mangler::visit(PointerType *pointerType)
+{
+  printQualifiers( pointerType );
+  mangleName << "P";
+  maybeAccept( pointerType->get_base(), *this );
+}
+
+void 
+Mangler::visit(ArrayType *arrayType)
+{
+  // TODO: encode dimension
+  printQualifiers( arrayType );
+  mangleName << "A0";
+  maybeAccept( arrayType->get_base(), *this );
+}
+
+namespace {
+  inline std::list< Type* >
+  getTypes( const std::list< DeclarationWithType* > decls )
+  {
+    std::list< Type* > ret;
+    std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
+                    std::mem_fun( &DeclarationWithType::get_type ) );
+    return ret;
+  }
+}
+
+void 
+Mangler::visit(FunctionType *functionType)
+{
+  printQualifiers( functionType );
+  mangleName << "F";
+  std::list< Type* > returnTypes = getTypes( functionType->get_returnVals() );
+  acceptAll( returnTypes, *this );
+  mangleName << "_";
+  std::list< Type* > paramTypes = getTypes( functionType->get_parameters() );
+  acceptAll( paramTypes, *this );
+  mangleName << "_";
+}
+
+void 
+Mangler::mangleRef(ReferenceToType *refType, std::string prefix)
+{
+  printQualifiers( refType );
+  mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name();
+}
+
+void 
+Mangler::visit(StructInstType *aggregateUseType)
+{
+  mangleRef( aggregateUseType, "s" );
+}
+
+void 
+Mangler::visit(UnionInstType *aggregateUseType)
+{
+  mangleRef( aggregateUseType, "u" );
+}
+
+void 
+Mangler::visit(EnumInstType *aggregateUseType)
+{
+  mangleRef( aggregateUseType, "e" );
+}
+
+void 
+Mangler::visit(TypeInstType *typeInst)
+{
+  VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
+  if( varNum == varNums.end() ) {
+    mangleRef( typeInst, "t" );
+  } else {
+    printQualifiers( typeInst );
+    std::ostrstream numStream;
+    numStream << varNum->second.first;
+    mangleName << (numStream.pcount() + 1);
+    switch( (TypeDecl::Kind)varNum->second.second ) {
+    case TypeDecl::Any:
+      mangleName << "t";
+      break;
+    case TypeDecl::Dtype:
+      mangleName << "d";
+      break;
+    case TypeDecl::Ftype:
+      mangleName << "f";
+      break;
+    }
+    mangleName << std::string( numStream.str(), numStream.pcount() );
+  }
+}
+
+void 
+Mangler::visit(TupleType *tupleType)
+{
+  printQualifiers( tupleType );
+  mangleName << "T";
+  acceptAll( tupleType->get_types(), *this );
+  mangleName << "_";
+}
+
+void 
+Mangler::visit(TypeDecl *decl)
+{
+  static const char *typePrefix[] = { "BT", "BD", "BF" };
+  mangleName << typePrefix[ decl->get_kind() ] << ( decl->get_name().length() + 1 ) << decl->get_name();
+}
+
+void
+printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os )
+{
+  for( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
+    os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;
+  }
+}
+
+void 
+Mangler::printQualifiers( Type *type )
+{
+  if( !type->get_forall().empty() ) {
+    std::list< std::string > assertionNames;
+    int tcount = 0, dcount = 0, fcount = 0;
+    mangleName << "A";
+    for( std::list< TypeDecl* >::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
+      switch( (*i)->get_kind() ) {
+      case TypeDecl::Any:
+        tcount++;
+        break;
+      case TypeDecl::Dtype:
+        dcount++;
+        break;
+      case TypeDecl::Ftype:
+        fcount++;
+        break;
+      }
+      varNums[ (*i)->get_name() ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() );
+      for( std::list< DeclarationWithType* >::iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
+        Mangler sub_mangler;
+        sub_mangler.nextVarNum = nextVarNum;
+        sub_mangler.isTopLevel = false;
+        sub_mangler.varNums = varNums;
+        (*assert)->accept( sub_mangler );
+        assertionNames.push_back( std::string( sub_mangler.mangleName.str(), sub_mangler.mangleName.pcount() ) );
+      }
+    }
+    mangleName << tcount << "_" << dcount << "_" << fcount << "_";
+    std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
+    mangleName << "_";
+  }
+  if( type->get_isConst() ) {
+    mangleName << "C";
+  }
+  if( type->get_isVolatile() ) {
+    mangleName << "V";
+  }
+  if( type->get_isRestrict() ) {
+    mangleName << "R";
+  }
+  if( type->get_isLvalue() ) {
+    mangleName << "L";
+  }
+}
+
+
+} // namespace SymTab
Index: translator/SymTab/Mangler.h
===================================================================
--- translator/SymTab/Mangler.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/Mangler.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,69 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Mangler.h,v 1.6 2005/08/29 20:14:18 rcbilson Exp $
+ *
+ */
+
+#ifndef SYMTAB_MANGLER_H
+#define SYMTAB_MANGLER_H
+
+#include <strstream>
+#include "SynTree/SynTree.h"
+#include "SynTree/Visitor.h"
+
+namespace SymTab {
+
+class Mangler : public Visitor
+{
+public:
+  template< typename SynTreeClass >
+  static std::string mangle( SynTreeClass *decl );		// interface to clients
+
+///   using Visitor::visit;
+  virtual void visit(ObjectDecl *declaration);
+  virtual void visit(FunctionDecl *declaration);
+  virtual void visit(TypeDecl *declaration);
+
+  virtual void visit(VoidType *voidType);
+  virtual void visit(BasicType *basicType);
+  virtual void visit(PointerType *pointerType);
+  virtual void visit(ArrayType *arrayType);
+  virtual void visit(FunctionType *functionType);
+  virtual void visit(StructInstType *aggregateUseType);
+  virtual void visit(UnionInstType *aggregateUseType);
+  virtual void visit(EnumInstType *aggregateUseType);
+  virtual void visit(TypeInstType *aggregateUseType);
+  virtual void visit(TupleType *tupleType);
+  
+  std::string get_mangleName() { return std::string( mangleName.str(), mangleName.pcount() ); }
+
+private:
+  std::ostrstream mangleName;
+  typedef std::map< std::string, std::pair< int, int > > VarMapType;
+  VarMapType varNums;
+  int nextVarNum;
+  bool isTopLevel;
+  
+  Mangler();
+  Mangler( const Mangler & );
+  
+  void mangleDecl(DeclarationWithType *declaration);
+  void mangleRef(ReferenceToType *refType, std::string prefix);
+  
+  void printQualifiers( Type *type );
+};
+
+/* static class method */
+template< typename SynTreeClass >
+std::string 
+Mangler::mangle( SynTreeClass *decl )
+{
+  Mangler mangler;
+  maybeAccept( decl, mangler );
+  return mangler.get_mangleName();
+}
+
+} // namespace SymTab
+
+#endif /* #ifndef SYMTAB_MANGLER_H */
Index: translator/SymTab/StackTable.cc
===================================================================
--- translator/SymTab/StackTable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/StackTable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,87 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: StackTable.cc,v 1.3 2002/09/19 21:02:44 rcbilson Exp $
+ *
+ */
+ 
+#include <cassert>
+
+#include "StackTable.h"
+
+namespace SymTab {
+
+template< typename Element, typename ConflictFunction >
+StackTable< Element, ConflictFunction >::StackTable()
+  : scopeLevel( 0 )
+{
+}
+
+template< typename Element, typename ConflictFunction >
+void 
+StackTable< Element, ConflictFunction >::enterScope()
+{
+  scopeLevel++;
+}
+
+template< typename Element, typename ConflictFunction >
+void 
+StackTable< Element, ConflictFunction >::leaveScope()
+{
+  for( typename TableType::iterator it = table.begin(); it != table.end(); ++it ) {
+    std::stack< Entry >& entry = it->second;
+    if( !entry.empty() && entry.top().second == scopeLevel ) {
+      entry.pop();
+    }
+  }
+      
+  scopeLevel--;
+  assert( scopeLevel >= 0 );
+}
+
+template< typename Element, typename ConflictFunction >
+void 
+StackTable< Element, ConflictFunction >::add( Element *type )
+{
+  std::stack< Entry >& entry = table[ type->get_name() ];
+  if( !entry.empty() && entry.top().second == scopeLevel ) {
+    entry.top().first = conflictFunction( entry.top().first, type );
+  } else {
+    entry.push( Entry( type, scopeLevel ) );
+  }
+}
+
+template< typename Element, typename ConflictFunction >
+void 
+StackTable< Element, ConflictFunction >::add( std::string fwdDeclName )
+{
+  add( new Element( fwdDeclName ) );
+}
+
+template< typename Element, typename ConflictFunction >
+Element *
+StackTable< Element, ConflictFunction >::lookup( std::string id ) const
+{
+  typename TableType::const_iterator it = table.find( id );
+  if( it == table.end() ) {
+    return 0;
+  } else if( !it->second.empty() ) {
+    return it->second.top().first;
+  } else {
+    return 0;
+  }
+}
+
+template< typename Element, typename ConflictFunction >
+void 
+StackTable< Element, ConflictFunction >::dump( std::ostream &os ) const
+{
+  for( typename TableType::const_iterator it = table.begin(); it != table.end(); ++it ) {
+    const std::stack< Entry >& entry = it->second;
+    if( !entry.empty() && entry.top().second == scopeLevel ) {
+      os << it->first << std::endl;
+    }
+  }
+}
+
+} // namespace SymTab
Index: translator/SymTab/StackTable.h
===================================================================
--- translator/SymTab/StackTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/StackTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: StackTable.h,v 1.2 2002/09/19 21:02:44 rcbilson Exp $
+ *
+ */
+
+#ifndef SYMTAB_STACKTABLE_H
+#define SYMTAB_STACKTABLE_H
+
+#include <map>
+#include <stack>
+#include <string>
+#include <functional>
+
+namespace SymTab {
+
+template< typename Element, typename ConflictFunction >
+class StackTable
+{
+public:
+  StackTable();
+
+  void enterScope();
+  void leaveScope();
+  void add( Element *type );
+  void add( std::string fwdDeclName );
+  Element *lookup( std::string id ) const;
+
+  void dump( std::ostream &os ) const; // debugging
+  
+private:
+  typedef std::pair< Element*, int > Entry;
+  typedef std::map< std::string, std::stack< Entry > > TableType;
+  
+  ConflictFunction conflictFunction;
+  TableType table;
+  int scopeLevel;
+};
+
+} // namespace SymTab
+
+#include "StackTable.cc"
+
+#endif /* #ifndef SYMTAB_STACKTABLE_H */
Index: translator/SymTab/TypeTable.h
===================================================================
--- translator/SymTab/TypeTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/TypeTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,44 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: TypeTable.h,v 1.2 2005/08/29 20:14:18 rcbilson Exp $
+ *
+ */
+
+#ifndef SYMTAB_TYPETABLE_H
+#define SYMTAB_TYPETABLE_H
+
+#include <cassert>
+#include <map>
+#include <stack>
+#include <string>
+#include <functional>
+
+#include "StackTable.h"
+#include "SynTree/Declaration.h"
+
+namespace SymTab {
+
+class TypeTableConflictFunction : public std::binary_function< NamedTypeDecl*, NamedTypeDecl*, NamedTypeDecl* >
+{
+public:
+  NamedTypeDecl *operator()( NamedTypeDecl *existing, NamedTypeDecl *added )
+  {
+    if( existing->get_base() == 0 ) {
+      return added;
+    } else if( added->get_base() == 0 ) {
+      return existing;
+    } else {
+      throw SemanticError( "redeclaration of ", added );
+    }
+    assert( false );
+    return 0;
+  }
+  
+};
+
+typedef StackTable< NamedTypeDecl, TypeTableConflictFunction > TypeTable;
+
+} // namespace SymTab
+
+#endif /* #ifndef SYMTAB_TYPETABLE_H */
Index: translator/SymTab/Validate.cc
===================================================================
--- translator/SymTab/Validate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/Validate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,907 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Validate.cc,v 1.22 2005/08/29 20:14:18 rcbilson Exp $
+ *
+ */
+
+/*
+   The "validate" phase of translation is used to take a syntax tree and convert it into a
+   standard form that aims to be as regular in structure as possible.  Some assumptions can be
+   made regarding the state of the tree after this pass is complete, including:
+
+   - No nested structure or union definitions; any in the input are "hoisted" to the level of
+     the containing struct or union.
+
+   - All enumeration constants have type EnumInstType.
+
+   - The type "void" never occurs in lists of function parameter or return types; neither do
+     tuple types.  A function taking no arguments has no argument types, and tuples are flattened.
+
+   - No context instances exist; they are all replaced by the set of declarations signified by
+     the context, instantiated by the particular set of type arguments.
+
+   - Every declaration is assigned a unique id.
+
+   - No typedef declarations or instances exist; the actual type is substituted for each instance.
+
+   - Each type, struct, and union definition is followed by an appropriate assignment operator.
+
+   - Each use of a struct or union is connected to a complete definition of that struct or union,
+     even if that definition occurs later in the input.
+*/
+
+#include <list>
+#include <iterator>
+#include "Validate.h"
+#include "SynTree/Visitor.h"
+#include "SynTree/Mutator.h"
+#include "SynTree/Type.h"
+#include "SynTree/Statement.h"
+#include "Indexer.h"
+#include "SynTree/TypeSubstitution.h"
+#include "FixFunction.h"
+#include "ImplementationType.h"
+#include "utility.h"
+#include "UniqueName.h"
+#include "AddVisit.h"
+
+
+#define debugPrint(x) if( doDebug ) { std::cout << x; }
+
+namespace SymTab {
+
+class HoistStruct : public Visitor
+{
+public:
+  static void hoistStruct( std::list< Declaration* > &translationUnit );
+  
+  std::list< Declaration* > &get_declsToAdd() { return declsToAdd; }
+  
+  virtual void visit(StructDecl *aggregateDecl);
+  virtual void visit(UnionDecl *aggregateDecl);
+
+  virtual void visit(CompoundStmt *compoundStmt);
+  virtual void visit(IfStmt *ifStmt);
+  virtual void visit(WhileStmt *whileStmt);
+  virtual void visit(ForStmt *forStmt);
+  virtual void visit(SwitchStmt *switchStmt);
+  virtual void visit(ChooseStmt *chooseStmt);
+  virtual void visit(CaseStmt *caseStmt);
+  virtual void visit(CatchStmt *catchStmt);
+  
+private:
+  HoistStruct();
+
+  template< typename AggDecl > void handleAggregate( AggDecl *aggregateDecl );
+
+  std::list< Declaration* > declsToAdd;
+  bool inStruct;
+};
+
+class Pass1 : public Visitor
+{
+  typedef Visitor Parent;
+  virtual void visit( EnumDecl *aggregateDecl);
+  virtual void visit( FunctionType *func );
+};
+  
+class Pass2 : public Indexer
+{
+  typedef Indexer Parent;
+
+public:
+  Pass2( bool doDebug, const Indexer *indexer );
+
+private:
+  virtual void visit( StructInstType *structInst );
+  virtual void visit( UnionInstType *unionInst );
+  virtual void visit( ContextInstType *contextInst );
+  virtual void visit( StructDecl *structDecl );
+  virtual void visit( UnionDecl *unionDecl );
+  virtual void visit( TypeInstType *typeInst );
+
+  const Indexer *indexer;
+  
+  typedef std::map< std::string, std::list< StructInstType* > > ForwardStructsType;
+  typedef std::map< std::string, std::list< UnionInstType* > > ForwardUnionsType;
+  ForwardStructsType forwardStructs;
+  ForwardUnionsType forwardUnions;
+};
+
+class Pass3 : public Indexer
+{
+  typedef Indexer Parent;
+
+public:
+  Pass3( const Indexer *indexer );
+
+private:
+  virtual void visit( ObjectDecl *object );
+  virtual void visit( FunctionDecl *func );
+
+  const Indexer *indexer;
+};
+
+class AddStructAssignment : public Visitor
+{
+public:
+  static void addStructAssignment( std::list< Declaration* > &translationUnit );
+
+  std::list< Declaration* > &get_declsToAdd() { return declsToAdd; }
+  
+  virtual void visit( StructDecl *structDecl );
+  virtual void visit( UnionDecl *structDecl );
+  virtual void visit( TypeDecl *typeDecl );
+  virtual void visit( ContextDecl *ctxDecl );
+
+  virtual void visit( FunctionType *ftype );
+  virtual void visit( PointerType *ftype );
+  
+  virtual void visit(CompoundStmt *compoundStmt);
+  virtual void visit(IfStmt *ifStmt);
+  virtual void visit(WhileStmt *whileStmt);
+  virtual void visit(ForStmt *forStmt);
+  virtual void visit(SwitchStmt *switchStmt);
+  virtual void visit(ChooseStmt *chooseStmt);
+  virtual void visit(CaseStmt *caseStmt);
+  virtual void visit(CatchStmt *catchStmt);
+  
+private:
+  template< typename StmtClass > void visitStatement(StmtClass *stmt);
+  
+  std::list< Declaration* > declsToAdd;
+  std::set< std::string > structsDone;
+};
+
+class EliminateTypedef : public Mutator
+{
+public:
+  static void eliminateTypedef( std::list< Declaration* > &translationUnit );
+  
+private:
+  virtual Declaration* mutate(TypedefDecl *typeDecl);
+  virtual TypeDecl* mutate(TypeDecl *typeDecl);
+  virtual DeclarationWithType* mutate(FunctionDecl *funcDecl);
+  virtual ObjectDecl* mutate(ObjectDecl *objDecl);
+  virtual CompoundStmt* mutate(CompoundStmt *compoundStmt);
+  virtual Type* mutate(TypeInstType *aggregateUseType);
+  virtual Expression* mutate(CastExpr *castExpr);
+  
+  std::map< std::string, TypedefDecl* > typedefNames;
+};
+
+void 
+validate( std::list< Declaration* > &translationUnit, bool doDebug, const Indexer *indexer )
+{
+  Pass1 pass1;
+  Pass2 pass2( doDebug, indexer );
+  Pass3 pass3( indexer );
+  EliminateTypedef::eliminateTypedef( translationUnit );
+  HoistStruct::hoistStruct( translationUnit );
+  acceptAll( translationUnit, pass1 );
+  acceptAll( translationUnit, pass2 );
+  AddStructAssignment::addStructAssignment( translationUnit );
+  acceptAll( translationUnit, pass3 );
+}
+
+void
+validateType( Type *type, const Indexer *indexer )
+{
+  Pass1 pass1;
+  Pass2 pass2( false, indexer );
+  Pass3 pass3( indexer );
+  type->accept( pass1 );
+  type->accept( pass2 );
+  type->accept( pass3 );
+}
+
+template< typename Visitor >
+void
+acceptAndAdd( std::list< Declaration* > &translationUnit, Visitor &visitor, bool addBefore )
+{
+  std::list< Declaration* >::iterator i = translationUnit.begin();
+  while( i != translationUnit.end() ) {
+    (*i)->accept( visitor );
+    std::list< Declaration* >::iterator next = i;
+    next++;
+    if( !visitor.get_declsToAdd().empty() ) {
+      translationUnit.splice( addBefore ? i : next, visitor.get_declsToAdd() );
+    }
+    i = next;
+  }
+}
+
+/* static class method */
+void 
+HoistStruct::hoistStruct( std::list< Declaration* > &translationUnit )
+{
+  HoistStruct hoister;
+  acceptAndAdd( translationUnit, hoister, true );
+}
+
+HoistStruct::HoistStruct()
+  : inStruct( false )
+{
+}
+
+void
+filter( std::list< Declaration* > &declList, bool (*pred)( Declaration* ), bool doDelete )
+{
+  std::list< Declaration* >::iterator i = declList.begin();
+  while( i != declList.end() ) {
+    std::list< Declaration* >::iterator next = i;
+    ++next;
+    if( pred( *i ) ) {
+      if( doDelete ) {
+        delete *i;
+      }
+      declList.erase( i );
+    }
+    i = next;
+  }
+}
+
+bool
+isStructOrUnion( Declaration *decl )
+{
+  return dynamic_cast< StructDecl* >( decl ) || dynamic_cast< UnionDecl* >( decl );
+}
+
+template< typename AggDecl >
+void
+HoistStruct::handleAggregate( AggDecl *aggregateDecl )
+{
+  if( inStruct ) {
+    declsToAdd.push_back( aggregateDecl );
+    Visitor::visit( aggregateDecl );
+  } else {
+    inStruct = true;
+    Visitor::visit( aggregateDecl );
+    inStruct = false;
+    filter( aggregateDecl->get_members(), isStructOrUnion, false );
+  }
+}
+
+void 
+HoistStruct::visit(StructDecl *aggregateDecl)
+{
+  handleAggregate( aggregateDecl );
+}
+
+void 
+HoistStruct::visit(UnionDecl *aggregateDecl)
+{
+  handleAggregate( aggregateDecl );
+}
+
+void
+HoistStruct::visit(CompoundStmt *compoundStmt)
+{
+  addVisit( compoundStmt, *this );
+}
+
+void
+HoistStruct::visit(IfStmt *ifStmt)
+{
+  addVisit( ifStmt, *this );
+}
+
+void
+HoistStruct::visit(WhileStmt *whileStmt)
+{
+  addVisit( whileStmt, *this );
+}
+
+void
+HoistStruct::visit(ForStmt *forStmt)
+{
+  addVisit( forStmt, *this );
+}
+
+void
+HoistStruct::visit(SwitchStmt *switchStmt)
+{
+  addVisit( switchStmt, *this );
+}
+
+void
+HoistStruct::visit(ChooseStmt *switchStmt)
+{
+  addVisit( switchStmt, *this );
+}
+
+void
+HoistStruct::visit(CaseStmt *caseStmt)
+{
+  addVisit( caseStmt, *this );
+}
+
+void
+HoistStruct::visit(CatchStmt *cathStmt)
+{
+  addVisit( cathStmt, *this );
+}
+
+void 
+Pass1::visit( EnumDecl *enumDecl)
+{
+  // Set the type of each member of the enumeration to be EnumConstant
+  
+  for( std::list< Declaration* >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
+    ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
+    assert( obj );
+    obj->set_type( new EnumInstType( Type::Qualifiers( true, false, false, false ), enumDecl->get_name() ) );
+  }
+  Parent::visit( enumDecl );
+}
+
+namespace {
+template< typename DWTIterator >
+void
+fixFunctionList( DWTIterator begin, DWTIterator end, FunctionType *func )
+{
+  // the only case in which "void" is valid is where it is the only one in the list; then
+  // it should be removed entirely
+  // other fix ups are handled by the FixFunction class
+  if( begin == end ) return;
+  FixFunction fixer;
+  DWTIterator i = begin;
+  *i = (*i)->acceptMutator( fixer );
+  if( fixer.get_isVoid() ) {
+    DWTIterator j = i;
+    ++i;
+    func->get_parameters().erase( j );
+    if( i != end ) { 
+      throw SemanticError( "invalid type void in function type ", func );
+    }
+  } else {
+    ++i;
+    for( ; i != end; ++i ) {
+      FixFunction fixer;
+      *i = (*i)->acceptMutator( fixer );
+      if( fixer.get_isVoid() ) {
+        throw SemanticError( "invalid type void in function type ", func );
+      }
+    }
+  }
+}
+}
+
+void 
+Pass1::visit( FunctionType *func )
+{
+  // Fix up parameters and return types
+  fixFunctionList( func->get_parameters().begin(), func->get_parameters().end(), func );
+  fixFunctionList( func->get_returnVals().begin(), func->get_returnVals().end(), func );
+  Visitor::visit( func );
+}
+
+Pass2::Pass2( bool doDebug, const Indexer *other_indexer )
+  : Indexer( doDebug )
+{
+  if( other_indexer ) {
+    indexer = other_indexer;
+  } else {
+    indexer = this;
+  }
+}
+
+void 
+Pass2::visit( StructInstType *structInst )
+{
+  Parent::visit( structInst );
+  StructDecl *st = indexer->lookupStruct( structInst->get_name() );
+  // it's not a semantic error if the struct is not found, just an implicit forward declaration
+  if( st ) {
+    assert( !structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || !st->get_members().empty() );
+    structInst->set_baseStruct( st );
+  }
+  if( !st || st->get_members().empty() ) {
+    // use of forward declaration
+    forwardStructs[ structInst->get_name() ].push_back( structInst );
+  }
+}
+
+void 
+Pass2::visit( UnionInstType *unionInst )
+{
+  Parent::visit( unionInst );
+  UnionDecl *un = indexer->lookupUnion( unionInst->get_name() );
+  // it's not a semantic error if the union is not found, just an implicit forward declaration
+  if( un ) {
+    unionInst->set_baseUnion( un );
+  }
+  if( !un || un->get_members().empty() ) {
+    // use of forward declaration
+    forwardUnions[ unionInst->get_name() ].push_back( unionInst );
+  }
+}
+
+void 
+Pass2::visit( ContextInstType *contextInst )
+{
+  Parent::visit( contextInst );
+  ContextDecl *ctx = indexer->lookupContext( contextInst->get_name() );
+  if( !ctx ) {
+    throw SemanticError( "use of undeclared context " + contextInst->get_name() );
+  }
+  for( std::list< TypeDecl* >::const_iterator i = ctx->get_parameters().begin(); i != ctx->get_parameters().end(); ++i ) {
+    for( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
+      if( ContextInstType *otherCtx = dynamic_cast< ContextInstType* >(*assert) ) {
+        cloneAll( otherCtx->get_members(), contextInst->get_members() );
+      } else {
+        contextInst->get_members().push_back( (*assert)->clone() );
+      }
+    }
+  }
+  applySubstitution( ctx->get_parameters().begin(), ctx->get_parameters().end(), contextInst->get_parameters().begin(), ctx->get_members().begin(), ctx->get_members().end(), back_inserter( contextInst->get_members() ) );
+}
+
+void 
+Pass2::visit( StructDecl *structDecl )
+{
+  if( !structDecl->get_members().empty() ) {
+    ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->get_name() );
+    if( fwds != forwardStructs.end() ) {
+      for( std::list< StructInstType* >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
+        (*inst)->set_baseStruct( structDecl );
+      }
+      forwardStructs.erase( fwds );
+    }
+  }
+  Indexer::visit( structDecl );
+}
+
+void 
+Pass2::visit( UnionDecl *unionDecl )
+{
+  if( !unionDecl->get_members().empty() ) {
+    ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->get_name() );
+    if( fwds != forwardUnions.end() ) {
+      for( std::list< UnionInstType* >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
+        (*inst)->set_baseUnion( unionDecl );
+      }
+      forwardUnions.erase( fwds );
+    }
+  }
+  Indexer::visit( unionDecl );
+}
+
+void 
+Pass2::visit( TypeInstType *typeInst )
+{
+  if( NamedTypeDecl *namedTypeDecl = lookupType( typeInst->get_name() ) ) {
+    if( TypeDecl *typeDecl = dynamic_cast< TypeDecl* >( namedTypeDecl ) ) {
+      typeInst->set_isFtype( typeDecl->get_kind() == TypeDecl::Ftype );
+    }
+  }
+}
+
+Pass3::Pass3( const Indexer *other_indexer )
+  : Indexer( false )
+{
+  if( other_indexer ) {
+    indexer = other_indexer;
+  } else {
+    indexer = this;
+  }
+}
+
+void 
+forallFixer( Type *func )
+{
+  // Fix up assertions
+  for( std::list< TypeDecl* >::iterator type = func->get_forall().begin(); type != func->get_forall().end(); ++type ) {
+    std::list< DeclarationWithType* > toBeDone, nextRound;
+    toBeDone.splice( toBeDone.end(), (*type)->get_assertions() );
+    while( !toBeDone.empty() ) {
+      for( std::list< DeclarationWithType* >::iterator assertion = toBeDone.begin(); assertion != toBeDone.end(); ++assertion ) {
+        if( ContextInstType *ctx = dynamic_cast< ContextInstType* >( (*assertion)->get_type() ) ) {
+          for( std::list< Declaration* >::const_iterator i = ctx->get_members().begin(); i != ctx->get_members().end(); ++i ) {
+            DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i );
+            assert( dwt );
+            nextRound.push_back( dwt->clone() );
+          }
+          delete ctx;
+        } else {
+          FixFunction fixer;
+          *assertion = (*assertion)->acceptMutator( fixer );
+          if( fixer.get_isVoid() ) {
+            throw SemanticError( "invalid type void in assertion of function ", func );
+          }
+          (*type)->get_assertions().push_back( *assertion );
+        }
+      }
+      toBeDone.clear();
+      toBeDone.splice( toBeDone.end(), nextRound );
+    }
+  }
+}
+
+void 
+Pass3::visit( ObjectDecl *object )
+{
+  forallFixer( object->get_type() );
+  if( PointerType *pointer = dynamic_cast< PointerType* >( object->get_type() ) ) {
+    forallFixer( pointer->get_base() );
+  }
+  Parent::visit( object );
+  object->fixUniqueId();
+}
+
+void 
+Pass3::visit( FunctionDecl *func )
+{
+  forallFixer( func->get_type() );
+  Parent::visit( func );
+  func->fixUniqueId();
+}
+
+static const std::list< std::string > noLabels;
+
+/* static class method */
+void
+AddStructAssignment::addStructAssignment( std::list< Declaration* > &translationUnit )
+{
+  AddStructAssignment visitor;
+  acceptAndAdd( translationUnit, visitor, false );
+}
+
+template< typename OutputIterator >
+void
+makeScalarAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, OutputIterator out )
+{
+  UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
+  
+  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 ) );
+  assignExpr->get_args().push_back( dstselect );
+  
+  Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
+  assignExpr->get_args().push_back( srcselect );
+  
+  *out++ = new ExprStmt( noLabels, assignExpr );
+}
+
+template< typename OutputIterator >
+void
+makeArrayAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, OutputIterator out )
+{
+  static UniqueName indexName( "_index" );
+  
+  // for a flexible array member nothing is done -- user must define own assignment
+  if( !array->get_dimension() ) return;
+  
+  ObjectDecl *index = new ObjectDecl( indexName.newName(), Declaration::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 );
+  *out++ = new DeclStmt( noLabels, index );
+  
+  UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
+  init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
+  init->get_args().push_back( new NameExpr( "0" ) );
+  Statement *initStmt = new ExprStmt( noLabels, init );
+  
+  UntypedExpr *cond = new UntypedExpr( new NameExpr( "?<?" ) );
+  cond->get_args().push_back( new VariableExpr( index ) );
+  cond->get_args().push_back( array->get_dimension()->clone() );
+  
+  UntypedExpr *inc = new UntypedExpr( new NameExpr( "++?" ) );
+  inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
+  
+  UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
+  
+  UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
+  derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
+  
+  Expression *dstselect = new MemberExpr( member, derefExpr );
+  UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) );
+  dstIndex->get_args().push_back( dstselect );
+  dstIndex->get_args().push_back( new VariableExpr( index ) );
+  assignExpr->get_args().push_back( dstIndex );
+  
+  Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
+  UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
+  srcIndex->get_args().push_back( srcselect );
+  srcIndex->get_args().push_back( new VariableExpr( index ) );
+  assignExpr->get_args().push_back( srcIndex );
+  
+  *out++ = new ForStmt( noLabels, initStmt, cond, inc, new ExprStmt( noLabels, assignExpr ) );
+}
+
+Declaration*
+makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType )
+{
+  FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
+  
+  ObjectDecl *returnVal = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
+  assignType->get_returnVals().push_back( returnVal );
+  
+  ObjectDecl *dstParam = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
+  assignType->get_parameters().push_back( dstParam );
+  
+  ObjectDecl *srcParam = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
+  assignType->get_parameters().push_back( srcParam );
+  
+  FunctionDecl *assignDecl = new FunctionDecl( "?=?", Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true );
+  assignDecl->fixUniqueId();
+  
+  for( std::list< Declaration* >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) {
+    if( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *member ) ) {
+      if( ArrayType *array = dynamic_cast< ArrayType* >( dwt->get_type() ) ) {
+        makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
+      } else {
+        makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
+      }
+    }
+  }
+  assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
+  
+  return assignDecl;
+}
+
+Declaration*
+makeUnionAssignment( UnionDecl *aggregateDecl, UnionInstType *refType )
+{
+  FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
+  
+  ObjectDecl *returnVal = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
+  assignType->get_returnVals().push_back( returnVal );
+  
+  ObjectDecl *dstParam = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
+  assignType->get_parameters().push_back( dstParam );
+  
+  ObjectDecl *srcParam = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
+  assignType->get_parameters().push_back( srcParam );
+  
+  FunctionDecl *assignDecl = new FunctionDecl( "?=?", Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true );
+  assignDecl->fixUniqueId();
+  
+  UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
+  copy->get_args().push_back( new VariableExpr( dstParam ) );
+  copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
+  copy->get_args().push_back( new SizeofExpr( refType->clone() ) );
+
+  assignDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, copy ) );
+  assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
+  
+  return assignDecl;
+}
+
+void
+AddStructAssignment::visit( StructDecl *structDecl )
+{
+  if( !structDecl->get_members().empty() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
+    StructInstType *structInst = new StructInstType( Type::Qualifiers(), structDecl->get_name() );
+    structInst->set_baseStruct( structDecl );
+    declsToAdd.push_back( makeStructAssignment( structDecl, structInst ) );
+    structsDone.insert( structDecl->get_name() );
+  }
+}
+
+void
+AddStructAssignment::visit( UnionDecl *unionDecl )
+{
+  if( !unionDecl->get_members().empty() ) {
+    UnionInstType *unionInst = new UnionInstType( Type::Qualifiers(), unionDecl->get_name() );
+    unionInst->set_baseUnion( unionDecl );
+    declsToAdd.push_back( makeUnionAssignment( unionDecl, unionInst ) );
+  }
+}
+
+void
+AddStructAssignment::visit( TypeDecl *typeDecl )
+{
+  CompoundStmt *stmts = 0;
+  TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false );
+  typeInst->set_baseType( typeDecl );
+  ObjectDecl *src = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, typeInst->clone(), 0 );
+  ObjectDecl *dst = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), typeInst->clone() ), 0 );
+  if( typeDecl->get_base() ) {
+    stmts = new CompoundStmt( std::list< Label >() );
+    UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
+    assign->get_args().push_back( new CastExpr( new VariableExpr( dst ), new PointerType( Type::Qualifiers(), typeDecl->get_base()->clone() ) ) );
+    assign->get_args().push_back( new CastExpr( new VariableExpr( src ), typeDecl->get_base()->clone() ) );
+    stmts->get_kids().push_back( new ReturnStmt( std::list< Label >(), assign ) );
+  }
+  FunctionType *type = new FunctionType( Type::Qualifiers(), false );
+  type->get_returnVals().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, typeInst, 0 ) );
+  type->get_parameters().push_back( dst );
+  type->get_parameters().push_back( src );
+  FunctionDecl *func = new FunctionDecl( "?=?", Declaration::NoStorageClass, LinkageSpec::AutoGen, type, stmts, false );
+  declsToAdd.push_back( func );
+}
+
+void
+addDecls( std::list< Declaration* > &declsToAdd, std::list< Statement* > &statements, std::list< Statement* >::iterator i )
+{
+  if( !declsToAdd.empty() ) {
+    for( std::list< Declaration* >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) {
+      statements.insert( i, new DeclStmt( noLabels, *decl ) );
+    }
+    declsToAdd.clear();
+  }
+}
+
+void
+AddStructAssignment::visit(FunctionType *)
+{
+  // ensure that we don't add assignment ops for types defined
+  // as part of the function
+}
+
+void
+AddStructAssignment::visit(PointerType *)
+{
+  // ensure that we don't add assignment ops for types defined
+  // as part of the pointer
+}
+
+void
+AddStructAssignment::visit(ContextDecl *)
+{
+  // ensure that we don't add assignment ops for types defined
+  // as part of the context
+}
+
+template< typename StmtClass >
+inline void
+AddStructAssignment::visitStatement(StmtClass *stmt)
+{
+  std::set< std::string > oldStructs = structsDone;
+  addVisit( stmt, *this );
+  structsDone = oldStructs;
+}
+
+void
+AddStructAssignment::visit(CompoundStmt *compoundStmt)
+{
+  visitStatement( compoundStmt );
+}
+
+void
+AddStructAssignment::visit(IfStmt *ifStmt)
+{
+  visitStatement( ifStmt );
+}
+
+void
+AddStructAssignment::visit(WhileStmt *whileStmt)
+{
+  visitStatement( whileStmt );
+}
+
+void
+AddStructAssignment::visit(ForStmt *forStmt)
+{
+  visitStatement( forStmt );
+}
+
+void
+AddStructAssignment::visit(SwitchStmt *switchStmt)
+{
+  visitStatement( switchStmt );
+}
+
+void
+AddStructAssignment::visit(ChooseStmt *switchStmt)
+{
+  visitStatement( switchStmt );
+}
+
+void
+AddStructAssignment::visit(CaseStmt *caseStmt)
+{
+  visitStatement( caseStmt );
+}
+
+void
+AddStructAssignment::visit(CatchStmt *cathStmt)
+{
+  visitStatement( cathStmt );
+}
+
+bool
+isTypedef( Declaration *decl )
+{
+  return dynamic_cast< TypedefDecl* >( decl );
+}
+
+
+/* static class method */
+void 
+EliminateTypedef::eliminateTypedef( std::list< Declaration* > &translationUnit )
+{
+  EliminateTypedef eliminator;
+  mutateAll( translationUnit, eliminator );
+  filter( translationUnit, isTypedef, true );
+}
+
+Type*
+EliminateTypedef::mutate( TypeInstType *typeInst )
+{
+  std::map< std::string, TypedefDecl* >::const_iterator def = typedefNames.find( typeInst->get_name() );
+  if( def != typedefNames.end() ) {
+    Type *ret = def->second->get_base()->clone();
+    ret->get_qualifiers() += typeInst->get_qualifiers();
+    delete typeInst;
+    return ret;
+  }
+  return typeInst;
+}
+
+Declaration*
+EliminateTypedef::mutate( TypedefDecl *tyDecl )
+{
+  Declaration *ret = Mutator::mutate( tyDecl );
+  typedefNames[ tyDecl->get_name() ] = tyDecl;
+  if( AggregateDecl *aggDecl = dynamic_cast< AggregateDecl* >( tyDecl->get_base() ) ) {
+    tyDecl->set_base( 0 );
+    delete tyDecl;
+    return aggDecl;
+  } else {
+    return ret;
+  }
+}
+
+TypeDecl*
+EliminateTypedef::mutate(TypeDecl *typeDecl)
+{
+  std::map< std::string, TypedefDecl* >::iterator i = typedefNames.find( typeDecl->get_name() );
+  if( i != typedefNames.end() ) {
+    typedefNames.erase( i ) ;
+  }
+  return typeDecl;
+}
+
+DeclarationWithType*
+EliminateTypedef::mutate(FunctionDecl *funcDecl)
+{
+  std::map< std::string, TypedefDecl* > oldNames = typedefNames;
+  DeclarationWithType *ret = Mutator::mutate( funcDecl );
+  typedefNames = oldNames;
+  return ret;
+}
+
+ObjectDecl*
+EliminateTypedef::mutate(ObjectDecl *objDecl)
+{
+  std::map< std::string, TypedefDecl* > oldNames = typedefNames;
+  ObjectDecl *ret = Mutator::mutate( objDecl );
+  typedefNames = oldNames;
+  return ret;
+}
+
+Expression*
+EliminateTypedef::mutate(CastExpr *castExpr)
+{
+  std::map< std::string, TypedefDecl* > oldNames = typedefNames;
+  Expression *ret = Mutator::mutate( castExpr );
+  typedefNames = oldNames;
+  return ret;
+}
+
+CompoundStmt * 
+EliminateTypedef::mutate( CompoundStmt *compoundStmt )
+{
+  std::map< std::string, TypedefDecl* > oldNames = typedefNames;
+  CompoundStmt *ret = Mutator::mutate( compoundStmt );
+  std::list< Statement* >::iterator i = compoundStmt->get_kids().begin();
+  while( i != compoundStmt->get_kids().end() ) {
+    std::list< Statement* >::iterator next = i;
+    ++next;
+    if( DeclStmt *declStmt = dynamic_cast< DeclStmt* >( *i ) ) {
+      if( dynamic_cast< TypedefDecl* >( declStmt->get_decl() ) ) {
+        delete *i;
+        compoundStmt->get_kids().erase( i );
+      }
+    }
+    i = next;
+  }
+  typedefNames = oldNames;
+  return ret;
+}
+
+} // namespace SymTab
Index: translator/SymTab/Validate.h
===================================================================
--- translator/SymTab/Validate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/Validate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * This class is intended to perform pre-processing of declarations, validating their
+ * correctness and computing some auxilliary data that is necessary for the indexer.
+ *
+ * $Id: Validate.h,v 1.7 2005/08/29 20:14:18 rcbilson Exp $
+ *
+ */
+
+#ifndef SYMTAB_VALIDATE_H
+#define SYMTAB_VALIDATE_H
+
+#include "SynTree/SynTree.h"
+
+namespace SymTab {
+
+class Indexer;
+
+void validate( std::list< Declaration* > &translationUnit, bool doDebug = false,
+               const Indexer *indexer = 0 );
+
+void validateType( Type *type, const Indexer *indexer );
+
+} // namespace SymTab
+
+#endif /* #ifndef SYMTAB_VALIDATE_H */
Index: translator/SymTab/module.mk
===================================================================
--- translator/SymTab/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,7 @@
+SRC += SymTab/IdTable.cc \
+       SymTab/Indexer.cc \
+       SymTab/Mangler.cc \
+       SymTab/Validate.cc \
+       SymTab/FixFunction.cc \
+       SymTab/ImplementationType.cc
+
Index: translator/SynTree/AddressExpr.cc
===================================================================
--- translator/SynTree/AddressExpr.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/AddressExpr.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: AddressExpr.cc,v 1.6 2005/08/29 20:59:25 rcbilson Exp $
+ *
+ */
+
+#include "Expression.h"
+#include "Type.h"
+#include "utility.h"
+
+
+AddressExpr::AddressExpr( Expression *arg, Expression *_aname )
+    : Expression( _aname ), arg( arg )
+{
+    for( std::list< Type* >::const_iterator i = arg->get_results().begin(); i != arg->get_results().end(); ++i ) {
+	get_results().push_back( new PointerType( Type::Qualifiers(), (*i)->clone() ) );
+    }
+}
+
+AddressExpr::AddressExpr( const AddressExpr &other )
+    : Expression( other ), arg( maybeClone( other.arg ) )
+{
+}
+
+AddressExpr::~AddressExpr()
+{
+    delete arg;
+}
+
+void 
+AddressExpr::print( std::ostream &os, int indent ) const
+{
+    os << std::string( indent, ' ' ) << "Address of:" << std::endl;
+    if( arg ) {
+	arg->print( os, indent+2 );
+    }
+}
+
+
Index: translator/SynTree/AggregateDecl.cc
===================================================================
--- translator/SynTree/AggregateDecl.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/AggregateDecl.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,68 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: AggregateDecl.cc,v 1.7 2005/08/29 20:59:25 rcbilson Exp $
+ *
+ */
+
+#include "Declaration.h"
+#include "Type.h"
+#include "utility.h"
+
+
+AggregateDecl::AggregateDecl( const std::string &name )
+    : Parent( name, Declaration::NoStorageClass, LinkageSpec::Cforall )
+{
+}
+
+AggregateDecl::AggregateDecl( const AggregateDecl &other )
+    : Parent( other )
+{
+    cloneAll( other.members, members );
+    cloneAll( other.parameters, parameters );
+}
+
+AggregateDecl::~AggregateDecl()
+{
+    deleteAll( members );
+    deleteAll( parameters );
+}
+
+void 
+AggregateDecl::print( std::ostream &os, int indent ) const
+{
+    using std::string;
+    using std::endl;
+
+    os << typeString() << " " << get_name();
+    if( !parameters.empty() ) {
+	os << endl << string( indent+2, ' ' ) << "with parameters" << endl;
+	printAll( parameters, os, indent+4 );
+    }
+    if( !members.empty() ) {
+	os << endl << string( indent+2, ' ' ) << "with members" << endl;
+	printAll( members, os, indent+4 );
+    }
+}
+
+void 
+AggregateDecl::printShort( std::ostream &os, int indent ) const
+{
+    using std::string;
+    using std::endl;
+
+    os << typeString() << " " << get_name();
+    if( !parameters.empty() ) {
+	os << endl << string( indent+2, ' ' ) << "with parameters" << endl;
+	printAll( parameters, os, indent+4 );
+    }
+}
+
+std::string StructDecl::typeString() const { return "struct"; }
+
+std::string UnionDecl::typeString() const { return "union"; }
+
+std::string EnumDecl::typeString() const { return "enum"; }
+
+std::string ContextDecl::typeString() const { return "context"; }
+
Index: translator/SynTree/ApplicationExpr.cc
===================================================================
--- translator/SynTree/ApplicationExpr.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/ApplicationExpr.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,77 @@
+#include <cassert>
+
+#include "Expression.h"
+#include "Declaration.h"
+#include "Type.h"
+#include "TypeSubstitution.h"
+#include "utility.h"
+
+
+ParamEntry::ParamEntry( const ParamEntry &other )
+    : decl( other.decl ), actualType( maybeClone( other.actualType ) ), formalType( maybeClone( other.formalType ) ), expr( maybeClone( other.expr ) )
+{
+}
+
+ParamEntry &
+ParamEntry::operator=( const ParamEntry &other )
+{
+    if( &other == this ) return *this;
+    decl = other.decl;
+    actualType = maybeClone( other.actualType );
+    formalType = maybeClone( other.formalType );
+    expr = maybeClone( other.expr );
+    return *this;
+}
+
+ParamEntry::~ParamEntry()
+{
+    delete actualType;
+    delete formalType;
+    delete expr;
+}
+
+ApplicationExpr::ApplicationExpr( Expression *funcExpr )
+    : function( funcExpr )
+{
+    PointerType *pointer = dynamic_cast< PointerType* >( funcExpr->get_results().front() );
+    assert( pointer );
+    FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
+    assert( function );
+    
+    for( std::list< DeclarationWithType* >::const_iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) {
+	get_results().push_back( (*i)->get_type()->clone() );
+    }
+}
+
+ApplicationExpr::ApplicationExpr( const ApplicationExpr &other )
+    : Expression( other ), function( maybeClone( other.function ) ), inferParams( other.inferParams )
+{
+    cloneAll( other.args, args );
+}
+
+ApplicationExpr::~ApplicationExpr()
+{
+    delete function;
+    deleteAll( args );
+}
+
+void 
+ApplicationExpr::print( std::ostream &os, int indent ) const
+{
+    os << std::string( indent, ' ' ) << "Application of" << std::endl;
+    function->print( os, indent+2 );
+    if( !args.empty() ) {
+	os << std::string( indent, ' ' ) << "to arguments" << std::endl;
+	printAll( args, os, indent+2 );
+    }
+    if( !inferParams.empty() ) {
+	os << std::string(indent, ' ') << "with inferred parameters:" << std::endl;
+	for( InferredParams::const_iterator i = inferParams.begin(); i != inferParams.end(); ++i ) {
+	    os << std::string(indent+2, ' ');
+	    Declaration::declFromId( i->second.decl )->printShort( os, indent+2 );
+	    os << std::endl;
+	}
+    }
+    Expression::print( os, indent );
+}
+
Index: translator/SynTree/ArrayType.cc
===================================================================
--- translator/SynTree/ArrayType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/ArrayType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,50 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: ArrayType.cc,v 1.6 2005/08/29 20:59:25 rcbilson Exp $
+ *
+ */
+
+#include "Type.h"
+#include "Expression.h"
+#include "utility.h"
+
+
+ArrayType::ArrayType( const Type::Qualifiers &tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic )
+    : Type( tq ), base( base ), dimension( dimension ), isVarLen( isVarLen ), isStatic( isStatic )
+{
+    base->set_isLvalue( false );
+}
+
+ArrayType::ArrayType( const ArrayType &other )
+    : Type( other ), base( maybeClone( other.base ) ), dimension( maybeClone( other.dimension ) ),
+	isVarLen( other.isVarLen ), isStatic( other.isStatic )
+{
+}
+
+ArrayType::~ArrayType()
+{
+    delete base;
+    delete dimension;
+}
+
+void 
+ArrayType::print( std::ostream &os, int indent ) const
+{
+    Type::print( os, indent );
+    if( isStatic ) {
+	os << "static ";
+    }
+    if( isVarLen ) {
+	os << "variable length array of ";
+    } else if( dimension ) {
+	os << "array of ";
+	dimension->print( os, indent );
+    } else {
+	os << "open array of ";
+    }
+    if( base ) {
+	base->print( os, indent );
+    }
+}
+
Index: translator/SynTree/AttrType.cc
===================================================================
--- translator/SynTree/AttrType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/AttrType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: AttrType.cc,v 1.3 2005/08/29 20:59:25 rcbilson Exp $
+ *
+ */
+
+#include "Type.h"
+#include "Expression.h"
+#include "utility.h"
+
+
+AttrType::AttrType( const Type::Qualifiers &tq, const std::string &name, Expression *expr )
+    : Type( tq ), name( name ), expr( expr ), type( 0 ), isType( false )
+{
+}
+
+AttrType::AttrType( const Type::Qualifiers &tq, const std::string &name, Type *type )
+    : Type( tq ), name( name ), expr( 0 ), type( type ), isType( true )
+{
+}
+
+AttrType::AttrType( const AttrType &other )
+    : Type( other ), name( other.name ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType )
+{
+}
+
+AttrType::~AttrType()
+{
+    delete expr;
+    delete type;
+}
+
+void 
+AttrType::print( std::ostream &os, int indent ) const
+{
+    Type::print( os, indent );
+    os << "attribute " << name << " applied to ";
+    if( expr ) {
+	os << "expression ";
+	expr->print( os, indent );
+    }
+    if( type ) {
+	os << "type ";
+	type->print( os, indent );
+    }
+}
+
Index: translator/SynTree/BasicType.cc
===================================================================
--- translator/SynTree/BasicType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/BasicType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,68 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: BasicType.cc,v 1.10 2005/08/29 20:59:25 rcbilson Exp $
+ *
+ */
+
+#include <cassert>
+
+#include "Type.h"
+
+
+BasicType::BasicType( const Type::Qualifiers &tq, Kind bt )
+    : Type( tq ), kind( bt )
+{
+}
+
+void
+BasicType::print( std::ostream &os, int indent ) const
+{
+    static const char *kindNames[] = {	
+	"bool", "char", "signed char", "unsigned char", "short signed int", "short unsigned int",
+	"signed int", "unsigned int", "long signed int", "long unsigned int", "long long signed int",
+	"long long unsigned int", "float", "double", "long double", "float complex", "double complex",
+	"long double complex", "float imaginary", "double imaginary", "long double imaginary"
+    };
+
+    Type::print( os, indent );
+    os << kindNames[ kind ] << ' ';
+}
+
+bool 
+BasicType::isInteger() const
+{
+    switch( kind ) {
+    case Bool:
+    case Char:
+    case SignedChar:
+    case UnsignedChar:
+    case ShortSignedInt:
+    case ShortUnsignedInt:
+    case SignedInt:
+    case UnsignedInt:
+    case LongSignedInt:
+    case LongUnsignedInt:
+    case LongLongSignedInt:
+    case LongLongUnsignedInt:
+	return true;
+
+    case Float:
+    case Double:
+    case LongDouble:
+    case FloatComplex:
+    case DoubleComplex:
+    case LongDoubleComplex:
+    case FloatImaginary:
+    case DoubleImaginary:
+    case LongDoubleImaginary:
+	return false;
+
+    case NUMBER_OF_BASIC_TYPES:
+	assert( false );
+    }
+    assert( false );
+    return false;
+}
+
+
Index: translator/SynTree/CodeGenVisitor.cc
===================================================================
--- translator/SynTree/CodeGenVisitor.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/CodeGenVisitor.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,44 @@
+#include <iostream>
+#include <list>
+
+#include "Statement.h"
+#include "Expression.h"
+#include "CodeGenVisitor.h"
+using namespace std;
+
+//*** Types
+void CodeGenVisitor::visit(Type *type){ }
+void CodeGenVisitor::visit(BasicType *basicType) { }
+
+//*** Constant
+void CodeGenVisitor::visit(Constant *constant) { 
+    cout << constant->get_value() << endl;
+}
+
+//*** Expressions
+void CodeGenVisitor::visit(Expression *expr){ }
+
+void CodeGenVisitor::visit(ConstantExpr *cnst){
+    if(cnst != 0)
+	visit(cnst->get_constant());
+}
+
+//*** Statements
+void CodeGenVisitor::visit(Statement *stmt){ }
+
+void CodeGenVisitor::visit(ExprStmt *exprStmt){
+    if(exprStmt != 0)
+	exprStmt->get_expr()->accept(*this);	// visit(exprStmt->get_expr()) doesn't work
+}
+
+void CodeGenVisitor::visit(SwitchStmt *switchStmt){
+    cout << "switch(" << endl;	    
+    // visit(switchStmt->get_condition());   // why doesn't this work?
+    switchStmt->get_condition()->accept(*this);
+
+    cout << ") {" << endl;	
+    // visit(switchStmt->get_body());  // why doesn't this work?
+    cout << "}" << endl;	
+}
+
+
Index: translator/SynTree/CodeGenVisitor.h
===================================================================
--- translator/SynTree/CodeGenVisitor.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/CodeGenVisitor.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,30 @@
+#ifndef CODEGENV_H
+#define CODEGENV_H
+
+#include <typeinfo>
+
+#include "SynTree.h"
+#include "Visitor.h"
+
+
+class CodeGenVisitor : public Visitor {
+public:
+    //*** Types
+    virtual void visit(Type *);
+    virtual void visit(BasicType *);
+
+    //*** Constant
+    virtual void visit(Constant *);
+
+    //*** Expressions
+    virtual void visit(Expression *);
+    virtual void visit(ConstantExpr *);
+
+    //*** Statements
+    virtual void visit(Statement *);
+    virtual void visit(ExprStmt *);
+    virtual void visit(SwitchStmt *);
+};
+
+
+#endif /* #ifndef CODEGENV_H */
Index: translator/SynTree/CommaExpr.cc
===================================================================
--- translator/SynTree/CommaExpr.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/CommaExpr.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: CommaExpr.cc,v 1.7 2005/08/29 20:59:25 rcbilson Exp $
+ *
+ */
+
+#include "Expression.h"
+#include "Type.h"
+#include "utility.h"
+
+
+CommaExpr::CommaExpr( Expression *arg1, Expression *arg2, Expression *_aname )
+    : Expression( _aname ), arg1( arg1 ), arg2( arg2 )
+{
+    cloneAll( arg2->get_results(), get_results() );
+}
+
+CommaExpr::CommaExpr( const CommaExpr &other )
+    : Expression( other ), arg1( maybeClone( other.arg1 ) ), arg2( maybeClone( other.arg2 ) )
+{
+}
+
+CommaExpr::~CommaExpr()
+{
+    delete arg1;
+    delete arg2;
+}
+
+void 
+CommaExpr::print( std::ostream &os, int indent ) const
+{
+    os << std::string( indent, ' ' ) << "Comma Expression:" << std::endl;
+    arg1->print( os, indent+2 );
+    os << std::endl;
+    arg2->print( os, indent+2 );
+    Expression::print( os, indent );
+}
+
+
Index: translator/SynTree/CompoundStmt.cc
===================================================================
--- translator/SynTree/CompoundStmt.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/CompoundStmt.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: CompoundStmt.cc,v 1.4 2005/08/29 20:59:25 rcbilson Exp $
+ *
+ */
+
+#include "Statement.h"
+#include "utility.h"
+#include <algorithm>
+#include <functional>
+
+
+CompoundStmt::CompoundStmt( std::list<Label> labels )
+    : Statement( labels )
+{
+}
+
+CompoundStmt::CompoundStmt( const CompoundStmt &other )
+    : Statement( other )
+{
+    cloneAll( other.kids, kids );
+}
+
+CompoundStmt::~CompoundStmt()
+{
+    deleteAll( kids );
+}
+
+void 
+CompoundStmt::print( std::ostream &os, int indent )
+{
+    printAll( kids, os, indent );
+}
+
+
+
+
+
Index: translator/SynTree/Constant.cc
===================================================================
--- translator/SynTree/Constant.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/Constant.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,26 @@
+#include <iostream>
+#include <list>
+
+#include "Constant.h"
+#include "Type.h"
+
+
+Constant::Constant(Type *_type, std::string _value):
+    type(_type), value(_value) {}
+
+Constant::~Constant() {}
+
+Constant *Constant::clone() const { return 0; }
+
+void Constant::print( std::ostream &os ) const {
+    os << value;
+    if( type ) {
+	os << " (type: ";
+	type->print( os );
+	os << ")";
+    }
+}
+
+
+
+
Index: translator/SynTree/Constant.h
===================================================================
--- translator/SynTree/Constant.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/Constant.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Constant.h,v 1.6 2005/08/29 20:59:25 rcbilson Exp $
+ *
+ */
+
+#ifndef CONSTANT_H
+#define CONSTANT_H
+
+#include "SynTree.h"
+#include "Visitor.h"
+#include "Mutator.h"
+
+
+class Constant
+{
+public:
+    Constant( Type *type, std::string value );
+    virtual ~Constant();
+
+    Type *get_type() { return type; }
+    void set_type( Type *newValue ) { type = newValue; }
+    std::string get_value() { return value; }
+    void set_value( std::string newValue ) { value = newValue; }
+
+    virtual Constant *clone() const;
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Constant *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os ) const;
+    
+private:
+    Type *type;
+    std::string value;
+};
+
+
+
+
+#endif /* #ifndef CONSTANT_H */
Index: translator/SynTree/DeclStmt.cc
===================================================================
--- translator/SynTree/DeclStmt.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/DeclStmt.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: DeclStmt.cc,v 1.4 2005/08/29 20:59:25 rcbilson Exp $
+ *
+ */
+
+#include "Statement.h"
+#include "Declaration.h"
+#include "utility.h"
+
+
+DeclStmt::DeclStmt( std::list<Label> labels, Declaration *decl )
+    : Statement( labels ), decl( decl )
+{
+}
+
+DeclStmt::DeclStmt( const DeclStmt &other )
+    : Statement( other ), decl( maybeClone( other.decl ) )
+{
+}
+
+DeclStmt::~DeclStmt()
+{
+    delete decl;
+}
+
+void 
+DeclStmt::print( std::ostream &os, int indent )
+{
+    os << "Declaration of ";
+    if( decl ) {
+	decl->print( os, indent );
+    }
+}
+
+
Index: translator/SynTree/Declaration.cc
===================================================================
--- translator/SynTree/Declaration.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/Declaration.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,66 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Declaration.cc,v 1.8 2005/08/29 20:59:25 rcbilson Exp $
+ *
+ */
+
+#include <string>
+#include <map>
+#include "Declaration.h"
+#include "Expression.h"
+#include "Initializer.h"
+#include "Type.h"
+#include "utility.h"
+
+
+const char* Declaration::storageClassName[] = { "", "auto", "static", "extern", "register" };  
+
+static UniqueId lastUniqueId = 0;
+typedef std::map< UniqueId, Declaration* > IdMapType;
+static IdMapType idMap;
+
+Declaration::Declaration( const std::string &name, StorageClass sc, LinkageSpec::Type linkage )
+    : name( name ), storageClass( sc ), linkage( linkage ), uniqueId( 0 )
+{
+}
+
+Declaration::Declaration( const Declaration &other )
+    : name( other.name ), storageClass( other.storageClass ), linkage( other.linkage ), uniqueId( other.uniqueId )
+{
+}
+
+Declaration::~Declaration()
+{
+}
+
+void
+Declaration::fixUniqueId()
+{
+    uniqueId = ++lastUniqueId;
+    idMap[ uniqueId ] = this;
+}
+
+/* static class method */
+Declaration *
+Declaration::declFromId( UniqueId id )
+{
+    IdMapType::const_iterator i = idMap.find( id );
+    if( i != idMap.end() ) {
+	return i->second;
+    } else {
+	return 0;
+    }
+}
+
+/* static class method */
+void 
+Declaration::dumpIds( std::ostream &os )
+{
+    for( IdMapType::const_iterator i = idMap.begin(); i != idMap.end(); ++i ) {
+	os << i->first << " -> ";
+	i->second->printShort( os );
+	os << std::endl;
+    }
+}
+
Index: translator/SynTree/Declaration.h
===================================================================
--- translator/SynTree/Declaration.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/Declaration.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,300 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Declaration.h,v 1.22 2005/08/29 20:59:25 rcbilson Exp $
+ *
+ */
+
+#ifndef DECLARATION_H
+#define DECLARATION_H
+
+#include "SynTree.h"
+#include "Visitor.h"
+#include "Mutator.h"
+#include "Parser/LinkageSpec.h"
+
+
+class Declaration
+{
+public:
+    enum StorageClass
+    {  
+	NoStorageClass,
+	Auto,
+	Static,
+	Extern,
+	Register,
+	Fortran
+    };	
+    
+    Declaration( const std::string &name, StorageClass sc, LinkageSpec::Type linkage );
+    Declaration( const Declaration &other );
+    virtual ~Declaration();
+
+    std::string get_name() const { return name; }
+    void set_name( std::string newValue ) { name = newValue; }
+    StorageClass get_storageClass() const { return storageClass; }
+    void set_storageClass( StorageClass newValue ) { storageClass = newValue; }
+    LinkageSpec::Type get_linkage() const { return linkage; }
+    void set_linkage( LinkageSpec::Type newValue ) { linkage = newValue; }
+    UniqueId get_uniqueId() const { return uniqueId; }
+    
+    void fixUniqueId( void );
+    virtual Declaration *clone() const = 0;
+    virtual void accept( Visitor &v ) = 0;
+    virtual Declaration *acceptMutator( Mutator &m ) = 0;
+    virtual void print( std::ostream &os, int indent = 0 ) const = 0;
+    virtual void printShort( std::ostream &os, int indent = 0 ) const = 0;
+    
+    static const char* storageClassName[];  
+    
+    static void dumpIds( std::ostream &os );
+    static Declaration *declFromId( UniqueId id );
+    
+private:
+    std::string name;
+    StorageClass storageClass;
+    LinkageSpec::Type linkage;
+    UniqueId uniqueId;
+};
+
+class DeclarationWithType : public Declaration
+{
+public:
+    DeclarationWithType( const std::string &name, StorageClass sc, LinkageSpec::Type linkage );
+    DeclarationWithType( const DeclarationWithType &other );
+    virtual ~DeclarationWithType();
+
+    std::string get_mangleName() const { return mangleName; }
+    void set_mangleName( std::string newValue ) { mangleName = newValue; }
+    
+    virtual DeclarationWithType *clone() const = 0;
+    virtual DeclarationWithType *acceptMutator( Mutator &m ) = 0;
+    
+    virtual Type *get_type() const = 0;
+    virtual void set_type(Type *) = 0;
+    
+private:
+    // this represents the type with all types and typedefs expanded
+    // it is generated by SymTab::Validate::Pass2
+    std::string mangleName;
+};
+
+class ObjectDecl : public DeclarationWithType
+{
+    typedef DeclarationWithType Parent;
+
+public:
+    ObjectDecl( const std::string &name, StorageClass sc, LinkageSpec::Type linkage, Expression *bitfieldWidth, Type *type, Initializer *init );
+    ObjectDecl( const ObjectDecl &other );
+    virtual ~ObjectDecl();
+
+    virtual Type *get_type() const { return type; }
+    virtual void set_type(Type *newType) { type = newType; }
+
+    Initializer *get_init() const { return init; }
+    void set_init( Initializer *newValue ) { init = newValue; }
+    Expression *get_bitfieldWidth() const { return bitfieldWidth; }
+    void set_bitfieldWidth( Expression *newValue ) { bitfieldWidth = newValue; }
+    
+    virtual ObjectDecl *clone() const { return new ObjectDecl( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual ObjectDecl *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+    virtual void printShort( std::ostream &os, int indent = 0 ) const;
+    
+private:
+    Type *type;
+    Initializer *init;
+    Expression *bitfieldWidth;
+};
+
+class FunctionDecl : public DeclarationWithType
+{
+    typedef DeclarationWithType Parent;
+
+public:
+    FunctionDecl( const std::string &name, StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline );
+    FunctionDecl( const FunctionDecl &other );
+    virtual ~FunctionDecl();
+
+    Type *get_type() const;
+    virtual void set_type(Type *);
+
+    FunctionType *get_functionType() const { return type; }
+    void set_functionType( FunctionType *newValue ) { type = newValue; }
+    CompoundStmt *get_statements() const { return statements; }
+    void set_statements( CompoundStmt *newValue ) { statements = newValue; }
+    bool get_isInline() const { return isInline; }
+    void set_isInline( bool newValue ) { isInline = newValue; }
+    std::list< std::string >& get_oldIdents() { return oldIdents; }
+    std::list< Declaration* >& get_oldDecls() { return oldDecls; }
+    
+    virtual FunctionDecl *clone() const { return new FunctionDecl( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual DeclarationWithType *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+    virtual void printShort( std::ostream &os, int indent = 0 ) const;
+    
+private:
+    FunctionType *type;
+    CompoundStmt *statements;
+    bool isInline;
+    std::list< std::string > oldIdents;
+    std::list< Declaration* > oldDecls;
+};
+
+class NamedTypeDecl : public Declaration
+{
+    typedef Declaration Parent;
+
+public:
+    NamedTypeDecl( const std::string &name, StorageClass sc, Type *type );
+    NamedTypeDecl( const TypeDecl &other );
+    virtual ~NamedTypeDecl();
+
+    Type *get_base() const { return base; }
+    void set_base( Type *newValue ) { base = newValue; }
+    std::list< TypeDecl* >& get_parameters() { return parameters; }
+    std::list< DeclarationWithType* >& get_assertions() { return assertions; }
+
+    virtual NamedTypeDecl *clone() const = 0;
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+    virtual void printShort( std::ostream &os, int indent = 0 ) const;
+    
+protected:
+    virtual std::string typeString() const = 0;
+    
+private:
+    Type *base;
+    std::list< TypeDecl* > parameters;
+    std::list< DeclarationWithType* > assertions;
+};
+
+class TypeDecl : public NamedTypeDecl
+{
+    typedef NamedTypeDecl Parent;
+
+public:
+    enum Kind { Any, Dtype, Ftype };
+
+    TypeDecl( const std::string &name, StorageClass sc, Type *type, Kind kind );
+    TypeDecl( const TypeDecl &other );
+    
+    Kind get_kind() const { return kind; }
+
+    virtual TypeDecl *clone() const { return new TypeDecl( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual TypeDecl *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+
+private:
+    virtual std::string typeString() const;
+    Kind kind;
+};
+    
+class TypedefDecl : public NamedTypeDecl
+{
+    typedef NamedTypeDecl Parent;
+
+public:
+    TypedefDecl( const std::string &name, StorageClass sc, Type *type ) : Parent( name, sc, type ) {}
+    TypedefDecl( const TypedefDecl &other ) : Parent( other ) {}
+    
+    virtual TypedefDecl *clone() const { return new TypedefDecl( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+
+private:
+    virtual std::string typeString() const;
+};
+    
+class AggregateDecl : public Declaration
+{
+    typedef Declaration Parent;
+
+public:
+    AggregateDecl( const std::string &name );
+    AggregateDecl( const AggregateDecl &other );
+    virtual ~AggregateDecl();
+
+    std::list<Declaration*>& get_members() { return members; }
+    std::list<TypeDecl*>& get_parameters() { return parameters; }
+    
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+    virtual void printShort( std::ostream &os, int indent = 0 ) const;
+
+protected:
+    virtual std::string typeString() const = 0;
+    
+private:
+    std::list<Declaration*> members;
+    std::list<TypeDecl*> parameters;
+};
+
+class StructDecl : public AggregateDecl
+{
+    typedef AggregateDecl Parent;
+
+public:
+    StructDecl( const std::string &name ) : Parent( name ) {}
+    StructDecl( const StructDecl &other ) : Parent( other ) {}
+    
+    virtual StructDecl *clone() const { return new StructDecl( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+
+private:
+    virtual std::string typeString() const;
+};
+    
+class UnionDecl : public AggregateDecl
+{
+    typedef AggregateDecl Parent;
+
+public:
+    UnionDecl( const std::string &name ) : Parent( name ) {}
+    UnionDecl( const UnionDecl &other ) : Parent( other ) {}
+    
+    virtual UnionDecl *clone() const { return new UnionDecl( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+
+private:
+    virtual std::string typeString() const;
+};
+    
+class EnumDecl : public AggregateDecl
+{
+    typedef AggregateDecl Parent;
+
+public:
+    EnumDecl( const std::string &name ) : Parent( name ) {}
+    EnumDecl( const EnumDecl &other ) : Parent( other ) {}
+    
+    virtual EnumDecl *clone() const { return new EnumDecl( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+
+private:
+    virtual std::string typeString() const;
+};
+    
+class ContextDecl : public AggregateDecl
+{
+    typedef AggregateDecl Parent;
+
+public:
+    ContextDecl( const std::string &name ) : Parent( name ) {}
+    ContextDecl( const ContextDecl &other ) : Parent( other ) {}
+    
+    virtual ContextDecl *clone() const { return new ContextDecl( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+
+private:
+    virtual std::string typeString() const;
+};
+    
+
+
+#endif /* #ifndef DECLARATION_H */
Index: translator/SynTree/DeclarationWithType.cc
===================================================================
--- translator/SynTree/DeclarationWithType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/DeclarationWithType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: DeclarationWithType.cc,v 1.9 2005/08/29 20:59:25 rcbilson Exp $
+ *
+ */
+
+#include "Declaration.h"
+#include "Type.h"
+#include "utility.h"
+
+
+DeclarationWithType::DeclarationWithType( const std::string &name, StorageClass sc, LinkageSpec::Type linkage )
+    : Declaration( name, sc, linkage )
+{
+}
+
+DeclarationWithType::DeclarationWithType( const DeclarationWithType &other )
+    : Declaration( other ), mangleName( other.mangleName )
+{
+}
+
+DeclarationWithType::~DeclarationWithType()
+{
+}
+
Index: translator/SynTree/Expression.cc
===================================================================
--- translator/SynTree/Expression.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/Expression.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,368 @@
+#include <iostream>
+#include <cassert>
+#include <list>
+#include <algorithm>
+
+#include <iterator>
+
+#include "Type.h"
+#include "Expression.h"
+#include "Declaration.h"
+#include "Statement.h"
+#include "TypeSubstitution.h"
+#include "utility.h"
+
+
+//*** Expression
+Expression::Expression( Expression *_aname ) : env( 0 ), argName( _aname ) {}
+Expression::Expression( const Expression &other )
+    : env( maybeClone( other.env ) )
+ {
+     cloneAll( other.results, results );
+     argName = other.get_argName();
+ }
+Expression::~Expression()
+{
+    delete env;
+    // delete argName;	// xxx -- there's a problem in cloning ConstantExpr I still don't know how to fix
+    deleteAll( results );
+}
+
+void
+Expression::add_result( Type *t )
+{
+    if( TupleType *tuple = dynamic_cast< TupleType* >( t ) ) {
+	std::copy( tuple->get_types().begin(), tuple->get_types().end(), back_inserter( results ) );
+    } else {
+	results.push_back(t);
+    }
+}
+
+void Expression::print(std::ostream &os, int indent) const {
+    if( env ) {
+	os << std::string(indent, ' ') << "with environment:" << std::endl;
+	env->print( os, indent+2 );
+    }
+
+    if( argName ) {
+	os << std::string(indent, ' ') << "with designator:";
+	argName->print( os, indent+2 );
+    }
+}
+
+//*** ConstantExpr
+ConstantExpr::ConstantExpr(Constant _c, Expression *_aname ):
+    Expression( _aname ), constant(_c)
+{
+    add_result( constant.get_type()->clone() );
+}
+
+ConstantExpr::ConstantExpr( const ConstantExpr &other)
+    : Expression( other ), constant( other.constant )
+{}
+
+ConstantExpr::~ConstantExpr() {}
+
+void ConstantExpr::print(std::ostream &os, int indent) const {
+    os << std::string(indent, ' ') << "Constant Expression: " ;
+    constant.print(os);
+    os << std::endl;
+    Expression::print( os, indent );
+}
+
+//*** VariableExpr
+VariableExpr::VariableExpr( DeclarationWithType *_var, Expression *_aname ) : Expression( _aname ), var( _var )
+{
+    add_result( var->get_type()->clone() );
+    for( std::list< Type* >::iterator i = get_results().begin(); i != get_results().end(); ++i ) {
+	(*i)->set_isLvalue( true );
+    }
+}
+
+VariableExpr::VariableExpr( const VariableExpr &other )
+    : Expression( other ), var( other.var )
+{
+}
+
+VariableExpr::~VariableExpr()
+{
+    // don't delete the declaration, since it points somewhere else in the tree
+}
+
+void VariableExpr::print(std::ostream &os, int indent) const {
+    os << std::string(indent, ' ') << "Variable Expression: ";
+
+    Declaration *decl = get_var();
+    // if( decl != 0) decl->print(os, indent + 2);
+    if( decl != 0) decl->printShort(os, indent + 2);
+    os << std::endl;
+    Expression::print( os, indent );
+}
+
+//*** SizeofExpr
+SizeofExpr::SizeofExpr( Expression *expr_, Expression *_aname ) :
+    Expression( _aname ), expr(expr_), type(0), isType(false)
+{
+    add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) );
+}
+
+SizeofExpr::SizeofExpr( Type *type_, Expression *_aname ) :
+    Expression( _aname ), expr(0), type(type_), isType(true)
+{
+    add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) );
+}
+
+SizeofExpr::SizeofExpr( const SizeofExpr &other )
+    : Expression( other ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType )
+{
+}
+
+SizeofExpr::~SizeofExpr(){
+    delete expr;
+    delete type;
+}
+
+void SizeofExpr::print( std::ostream &os, int indent) const {
+    os << std::string(indent, ' ') << "Sizeof Expression on: ";
+
+    if(isType)
+	type->print(os, indent + 2);
+    else
+	expr->print(os, indent + 2);
+
+    os << std::endl;
+    Expression::print( os, indent );
+}
+
+//*** AttrExpr
+AttrExpr::AttrExpr( Expression *attr, Expression *expr_, Expression *_aname ) :
+    Expression( _aname ), attr( attr ), expr(expr_), type(0), isType(false)
+{
+}
+
+AttrExpr::AttrExpr( Expression *attr, Type *type_, Expression *_aname ) :
+    Expression( _aname ), attr( attr ), expr(0), type(type_), isType(true)
+{
+}
+
+AttrExpr::AttrExpr( const AttrExpr &other )
+    : Expression( other ), attr( maybeClone( other.attr ) ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType )
+{
+}
+
+AttrExpr::~AttrExpr(){
+    delete attr;
+    delete expr;
+    delete type;
+}
+
+void AttrExpr::print( std::ostream &os, int indent) const {
+    os << std::string(indent, ' ') << "Attr ";
+    attr->print( os, indent + 2 );
+    if( isType || expr ) {
+	os << "applied to: ";
+
+	if(isType)
+	    type->print(os, indent + 2);
+	else
+	    expr->print(os, indent + 2);
+    }
+
+    os << std::endl;
+    Expression::print( os, indent );
+}
+
+//*** CastExpr
+CastExpr::CastExpr( Expression *arg_, Type *toType, Expression *_aname ) : Expression( _aname ), arg(arg_)
+{
+    add_result(toType);
+}
+
+CastExpr::CastExpr( Expression *arg_, Expression *_aname ) : Expression( _aname ), arg(arg_) {
+}
+
+CastExpr::CastExpr( const CastExpr &other )
+    : Expression( other ), arg( maybeClone( other.arg ) )
+{
+}
+
+CastExpr::~CastExpr() {
+    delete arg;
+}
+
+// CastExpr *CastExpr::clone() const { return 0; }
+
+void CastExpr::print( std::ostream &os, int indent ) const {
+    os << std::string(indent, ' ') << "Cast of:" << std::endl;
+    arg->print(os, indent+2);
+    os << std::endl << std::string(indent, ' ') << "to:" << std::endl;
+    if( results.empty() ) {
+	os << std::string(indent+2, ' ') << "nothing" << std::endl;
+    } else {
+	printAll(results, os, indent+2);
+    }
+    Expression::print( os, indent );
+}
+
+//*** UntypedMemberExpr
+UntypedMemberExpr::UntypedMemberExpr( std::string _member, Expression *_aggregate, Expression *_aname ) :
+    Expression( _aname ), member(_member), aggregate(_aggregate) {}
+
+UntypedMemberExpr::UntypedMemberExpr( const UntypedMemberExpr &other )
+    : Expression( other ),   member( other.member ), aggregate( maybeClone( other.aggregate ) )
+{
+}
+
+UntypedMemberExpr::~UntypedMemberExpr() {
+    delete aggregate;
+}
+
+void UntypedMemberExpr::print( std::ostream &os, int indent ) const {
+    os << std::string(indent, ' ') << "Member Expression, with field: " << get_member();
+
+    Expression *agg = get_aggregate();
+    os << std::string(indent, ' ') << "from aggregate: ";
+    if (agg != 0) agg->print(os, indent + 2);
+    Expression::print( os, indent );
+}
+
+
+//*** MemberExpr
+MemberExpr::MemberExpr( DeclarationWithType *_member, Expression *_aggregate, Expression *_aname ) :
+    Expression( _aname ), member(_member), aggregate(_aggregate)
+{
+    add_result( member->get_type()->clone() );
+    for( std::list< Type* >::iterator i = get_results().begin(); i != get_results().end(); ++i ) {
+	(*i)->set_isLvalue( true );
+    }
+}
+
+MemberExpr::MemberExpr( const MemberExpr &other )
+    : Expression( other ),   member( maybeClone( other.member ) ), aggregate( maybeClone( other.aggregate ) )
+{
+}
+
+MemberExpr::~MemberExpr() {
+    delete member;
+    delete aggregate;
+}
+
+void MemberExpr::print( std::ostream &os, int indent ) const {
+    os << std::string(indent, ' ') << "Member Expression, with field: " << std::endl;
+
+    assert( member );
+    os << std::string(indent + 2, ' ');
+    member->print( os, indent + 2 );
+    os << std::endl;
+
+    Expression *agg = get_aggregate();
+    os << std::string(indent, ' ') << "from aggregate: " << std::endl;
+    if (agg != 0) agg->print(os, indent + 2);
+    Expression::print( os, indent );
+}
+
+
+//*** UntypedExpr
+UntypedExpr::UntypedExpr( Expression *_function, Expression *_aname ) : Expression( _aname ), function( _function ) {}
+
+UntypedExpr::UntypedExpr( const UntypedExpr &other )
+    : Expression( other ), function( maybeClone( other.function ) )
+{
+    cloneAll( other.args, args );
+}
+
+UntypedExpr::UntypedExpr( Expression *_function, std::list<Expression *> &_args, Expression *_aname ) :
+    Expression( _aname ), function(_function), args(_args) {}
+
+UntypedExpr::~UntypedExpr() {}
+
+void UntypedExpr::print( std::ostream &os, int indent ) const {
+    os << std::string(indent, ' ') << "Applying untyped: " << std::endl;
+    function->print(os, indent + 4);
+    os << "\r" << std::string(indent, ' ') << "...to: " << std::endl;
+    printArgs(os, indent + 4);
+    Expression::print( os, indent );
+}
+
+void UntypedExpr::printArgs(std::ostream &os, int indent ) const {
+    std::list<Expression *>::const_iterator i;
+    for(i = args.begin(); i != args.end(); i++)
+	(*i)->print(os, indent);
+}
+
+//*** NameExpr
+NameExpr::NameExpr( std::string _name, Expression *_aname ) : Expression( _aname ), name(_name) {}
+
+NameExpr::NameExpr( const NameExpr &other )
+    : Expression( other ), name( other.name )
+{
+}
+
+NameExpr::~NameExpr() {}
+
+void NameExpr::print( std::ostream &os, int indent ) const {
+    os << std::string(indent, ' ') << "Name: " << get_name() << std::endl;
+    Expression::print( os, indent );
+}
+
+//*** LogicalExpr
+LogicalExpr::LogicalExpr( Expression *arg1_, Expression *arg2_, bool andp, Expression *_aname ) :
+    Expression( _aname ), arg1(arg1_), arg2(arg2_), isAnd(andp)
+{
+    add_result( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
+}
+
+LogicalExpr::LogicalExpr( const LogicalExpr &other )
+    : Expression( other ), arg1( maybeClone( other.arg1 ) ), arg2( maybeClone( other.arg2 ) ), isAnd( other.isAnd )
+{
+}
+
+LogicalExpr::~LogicalExpr(){
+    delete arg1;
+    delete arg2;
+}
+
+void LogicalExpr::print( std::ostream &os, int indent )const {
+    os << std::string(indent, ' ') << "Short-circuited operation (" << (isAnd?"and":"or") << ") on: ";
+    arg1->print(os);
+    os << " and ";
+    arg2->print(os);
+    os << std::endl;
+    Expression::print( os, indent );
+}
+
+//*** ConditionalExpr
+ConditionalExpr::ConditionalExpr( Expression *arg1_, Expression *arg2_, Expression *arg3_, Expression *_aname ) :
+    Expression( _aname ), arg1(arg1_), arg2(arg2_), arg3(arg3_) {}
+
+ConditionalExpr::ConditionalExpr( const ConditionalExpr &other )
+     : Expression( other ), arg1( maybeClone( other.arg1 ) ), arg2( maybeClone( other.arg2 ) ), arg3( maybeClone( other.arg3 ) )
+ {
+ }
+
+ConditionalExpr::~ConditionalExpr() {
+    delete arg1;
+    delete arg2;
+    delete arg3;
+}
+
+void ConditionalExpr::print( std::ostream &os, int indent ) const {
+    os << std::string(indent, ' ') << "Conditional expression on: " << std::endl;
+    arg1->print( os, indent+2 );
+    os << std::string(indent, ' ') << "First alternative:" << std::endl;
+    arg2->print( os, indent+2 );
+    os << std::string(indent, ' ') << "Second alternative:" << std::endl;
+    arg3->print( os, indent+2 );
+    os << std::endl;
+    Expression::print( os, indent );
+}
+
+//*** UntypedValofExpr
+void UntypedValofExpr::print( std::ostream &os, int indent ) const
+{
+    os << std::string(indent, ' ') << "Valof Expression: " << std::endl;
+    if( get_body() != 0 )
+	get_body()->print( os, indent + 2 );
+}
+
+
Index: translator/SynTree/Expression.h
===================================================================
--- translator/SynTree/Expression.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/Expression.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,507 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Expression.h,v 1.31 2005/08/29 20:59:25 rcbilson Exp $
+ *
+ */
+
+#ifndef EXPRESSION_H
+#define EXPRESSION_H
+
+#include <map>
+#include "SynTree.h"
+#include "Visitor.h"
+#include "Mutator.h"
+#include "Constant.h"
+
+
+class Expression
+{
+public:
+    Expression(Expression *_aname = 0 );
+    Expression( const Expression &other );
+    virtual ~Expression();
+
+    std::list<Type *>& get_results() { return results; }
+    void add_result(Type *t);
+
+    TypeSubstitution *get_env() const { return env; }
+    void set_env( TypeSubstitution *newValue ) { env = newValue; }
+    Expression *get_argName() const { return argName; }
+    void set_argName( Expression *name ) { argName = name; }
+
+    virtual Expression *clone() const = 0;
+    virtual void accept( Visitor &v ) = 0;
+    virtual Expression *acceptMutator( Mutator &m ) = 0;
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+    
+protected:
+    std::list<Type *> results;
+    TypeSubstitution *env;
+    Expression* argName; // if expression is used as an argument, it can be "designated" by this name
+};
+
+// ParamEntry contains the i.d. of a declaration and a type that is derived from that declaration,
+// but subject to decay-to-pointer and type parameter renaming
+struct ParamEntry
+{
+    ParamEntry(): decl( 0 ), actualType( 0 ), formalType( 0 ), expr( 0 ) {}
+    ParamEntry( UniqueId decl, Type *actualType, Type *formalType, Expression* expr ): decl( decl ), actualType( actualType ), formalType( formalType ), expr( expr ) {}
+    ParamEntry( const ParamEntry &other );
+    ~ParamEntry();
+    ParamEntry &operator=( const ParamEntry &other );
+
+    UniqueId decl;
+    Type *actualType;
+    Type *formalType;
+    Expression* expr;
+};
+
+typedef std::map< UniqueId, ParamEntry > InferredParams;
+
+// ApplicationExpr represents the application of a function to a set of parameters.  This is the
+// result of running an UntypedExpr through the expression analyzer.
+class ApplicationExpr : public Expression
+{
+public:
+    ApplicationExpr( Expression *function );
+    ApplicationExpr( const ApplicationExpr &other );
+    virtual ~ApplicationExpr();
+
+    Expression *get_function() const { return function; }
+    void set_function( Expression *newValue ) { function = newValue; }
+    std::list<Expression *>& get_args() { return args; }
+    InferredParams &get_inferParams() { return inferParams; }
+
+    virtual ApplicationExpr *clone() const { return new ApplicationExpr( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+    
+private:
+    Expression *function;
+    std::list<Expression *> args;
+    InferredParams inferParams;
+};
+
+// UntypedExpr represents the application of a function to a set of parameters, but where the
+// particular overload for the function name has not yet been determined.  Most operators are
+// converted into functional form automatically, to permit operator overloading.
+class UntypedExpr : public Expression
+{
+public:
+    UntypedExpr( Expression *function, Expression *_aname = 0 );
+    UntypedExpr( const UntypedExpr &other );
+    UntypedExpr( Expression *function, std::list<Expression *> &args, Expression *_aname = 0 );
+    virtual ~UntypedExpr();
+
+    Expression *get_function() const { return function; }
+    void set_function( Expression *newValue ) { function = newValue; }
+
+    void set_args( std::list<Expression *> &listArgs ) { args = listArgs; }
+    std::list<Expression*>::iterator begin_args() { return args.begin(); }
+    std::list<Expression*>::iterator end_args() { return args.end(); }
+    std::list<Expression*>& get_args() { return args; }
+
+    virtual UntypedExpr *clone() const { return new UntypedExpr( *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;
+    virtual void printArgs(std::ostream &os, int indent = 0) const;
+    
+private:
+    
+    Expression *function;
+    std::list<Expression*> args;
+};
+
+// this class contains a name whose meaning is still not determined
+class NameExpr : public Expression
+{
+public:
+    NameExpr( std::string name, Expression *_aname = 0 );
+    NameExpr( const NameExpr &other );
+    virtual ~NameExpr();
+
+    std::string get_name() const { return name; }
+    void set_name( std::string newValue ) { name = newValue; }
+
+    virtual NameExpr *clone() const { return new NameExpr( *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::string name;
+};
+
+// The following classes are used to represent expression types that cannot be converted into
+// function-call format.
+
+// AddressExpr represents a address-of expression, e.g. &e
+class AddressExpr : public Expression
+{
+public:
+    AddressExpr( Expression *arg, Expression *_aname = 0 );
+    AddressExpr( const AddressExpr &other );
+    virtual ~AddressExpr();
+
+    Expression *get_arg() const { return arg; }
+    void set_arg(Expression *newValue ) { arg = newValue; }
+
+    virtual AddressExpr *clone() const { return new AddressExpr( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+    
+private:
+    Expression *arg;
+};
+
+class LabelAddressExpr : public Expression
+{
+public:
+    LabelAddressExpr( Expression *arg );
+    LabelAddressExpr( const AddressExpr &other );
+    virtual ~LabelAddressExpr();
+
+    Expression *get_arg() const { return arg; }
+    void set_arg(Expression *newValue ) { arg = newValue; }
+
+    virtual LabelAddressExpr *clone() const { return new LabelAddressExpr( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+    
+private:
+    Expression *arg;
+};
+
+// CastExpr represents a type cast expression, e.g. (int)e
+class CastExpr : public Expression
+{
+public:
+    CastExpr( Expression *arg, Expression *_aname = 0 );
+    CastExpr( Expression *arg, Type *toType, Expression *_aname = 0 );
+    CastExpr( const CastExpr &other );
+    virtual ~CastExpr();
+
+    Expression *get_arg() const { return arg; }
+    void set_arg(Expression *newValue ) { arg = newValue; }
+
+    virtual CastExpr *clone() const { return new CastExpr( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+    
+private:
+    Expression *arg;
+};
+
+// UntypedMemberExpr represents a member selection operation, e.g. q.p
+// before processing by the expression analyzer
+class UntypedMemberExpr : public Expression
+{
+public:
+    UntypedMemberExpr( std::string member, Expression *aggregate, Expression *_aname = 0 );
+    UntypedMemberExpr( const UntypedMemberExpr &other );
+    virtual ~UntypedMemberExpr();
+
+    std::string get_member() const { return member; }
+    void set_member( const std::string &newValue ) { member = newValue; }
+    Expression *get_aggregate() const { return aggregate; }
+    void set_aggregate( Expression *newValue ) { aggregate = newValue; }
+
+    virtual UntypedMemberExpr *clone() const { return new UntypedMemberExpr( *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::string member;
+    Expression *aggregate;
+};
+
+// MemberExpr represents a member selection operation, e.g. q.p
+// after processing by the expression analyzer
+class MemberExpr : public Expression
+{
+public:
+    MemberExpr( DeclarationWithType *member, Expression *aggregate, Expression *_aname = 0 );
+    MemberExpr( const MemberExpr &other );
+    virtual ~MemberExpr();
+
+    DeclarationWithType *get_member() const { return member; }
+    void set_member( DeclarationWithType *newValue ) { member = newValue; }
+    Expression *get_aggregate() const { return aggregate; }
+    void set_aggregate( Expression *newValue ) { aggregate = newValue; }
+
+    virtual MemberExpr *clone() const { return new MemberExpr( *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:
+    DeclarationWithType *member;
+    Expression *aggregate;
+};
+
+// VariableExpr represents an expression that simply refers to the value of a named variable
+class VariableExpr : public Expression
+{
+public:
+    VariableExpr( DeclarationWithType *var, Expression *_aname = 0 );
+    VariableExpr( const VariableExpr &other );
+    virtual ~VariableExpr();
+
+    DeclarationWithType *get_var() const { return var; }
+    void set_var( DeclarationWithType *newValue ) { var = newValue; }
+
+    virtual VariableExpr *clone() const { return new VariableExpr( *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:
+    DeclarationWithType *var;
+};
+
+// ConstantExpr represents an expression that simply refers to the value of a constant 
+class ConstantExpr : public Expression
+{
+public:
+    ConstantExpr( Constant constant, Expression *_aname = 0 );
+    ConstantExpr( const ConstantExpr &other );
+    virtual ~ConstantExpr();
+
+    Constant *get_constant() { return &constant; }
+    void set_constant( const Constant &newValue ) { constant = newValue; }
+
+    virtual ConstantExpr *clone() const { return new ConstantExpr( *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:
+    Constant constant;
+};
+
+// SizeofExpr represents a sizeof expression (could be sizeof(int) or sizeof 3+4)
+class SizeofExpr : public Expression
+{
+public:
+    SizeofExpr( Expression *expr, Expression *_aname = 0 );
+    SizeofExpr( const SizeofExpr &other );
+    SizeofExpr( Type *type, Expression *_aname = 0 );
+    virtual ~SizeofExpr();
+
+    Expression *get_expr() const { return expr; }
+    void set_expr( Expression *newValue ) { expr = newValue; }
+    Type *get_type() const { return type; }
+    void set_type( Type *newValue ) { type = newValue; }
+    bool get_isType() const { return isType; }
+    void set_isType( bool newValue ) { isType = newValue; }
+
+    virtual SizeofExpr *clone() const { return new SizeofExpr( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+    
+private:
+    Expression *expr;
+    Type *type;
+    bool isType;
+};
+
+// AttrExpr represents an @attribute expression (like sizeof, but user-defined)
+class AttrExpr : public Expression
+{
+public:
+    AttrExpr(Expression *attr, Expression *expr, Expression *_aname = 0 );
+    AttrExpr( const AttrExpr &other );
+    AttrExpr( Expression *attr, Type *type, Expression *_aname = 0 );
+    virtual ~AttrExpr();
+
+    Expression *get_attr() const { return attr; }
+    void set_attr( Expression *newValue ) { attr = newValue; }
+    Expression *get_expr() const { return expr; }
+    void set_expr( Expression *newValue ) { expr = newValue; }
+    Type *get_type() const { return type; }
+    void set_type( Type *newValue ) { type = newValue; }
+    bool get_isType() const { return isType; }
+    void set_isType( bool newValue ) { isType = newValue; }
+
+    virtual AttrExpr *clone() const { return new AttrExpr( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+    
+private:
+    Expression *attr;
+    Expression *expr;
+    Type *type;
+    bool isType;
+};
+
+// LogicalExpr represents a short-circuit boolean expression (&& or ||)
+class LogicalExpr : public Expression
+{
+public:
+    LogicalExpr( Expression *arg1, Expression *arg2, bool andp = true, Expression *_aname = 0 );
+    LogicalExpr( const LogicalExpr &other );
+    virtual ~LogicalExpr();
+
+    bool get_isAnd() const { return isAnd; }
+    Expression *get_arg1() { return arg1; }
+    void set_arg1( Expression *newValue ) { arg1 = newValue; }
+    Expression *get_arg2() const { return arg2; }
+    void set_arg2( Expression *newValue ) { arg2 = newValue; }
+
+    virtual LogicalExpr *clone() const { return new LogicalExpr( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+    
+private:
+    Expression *arg1;
+    Expression *arg2;
+    bool isAnd;
+};
+
+// ConditionalExpr represents the three-argument conditional ( p ? a : b )
+class ConditionalExpr : public Expression
+{
+public:
+    ConditionalExpr( Expression *arg1, Expression *arg2, Expression *arg3, Expression *_aname = 0 );
+    ConditionalExpr( const ConditionalExpr &other );
+    virtual ~ConditionalExpr();
+
+    Expression *get_arg1() const { return arg1; }
+    void set_arg1( Expression *newValue ) { arg1 = newValue; }
+    Expression *get_arg2() const { return arg2; }
+    void set_arg2( Expression *newValue ) { arg2 = newValue; }
+    Expression *get_arg3() const { return arg3; }
+    void set_arg3( Expression *newValue ) { arg3 = newValue; }
+
+    virtual ConditionalExpr *clone() const { return new ConditionalExpr( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+    
+private:
+    Expression *arg1;
+    Expression *arg2;
+    Expression *arg3;
+};
+
+// CommaExpr represents the sequence operator ( a, b )
+class CommaExpr : public Expression
+{
+public:
+    CommaExpr( Expression *arg1, Expression *arg2, Expression *_aname = 0 );
+    CommaExpr( const CommaExpr &other );
+    virtual ~CommaExpr();
+
+    Expression *get_arg1() const { return arg1; }
+    void set_arg1( Expression *newValue ) { arg1 = newValue; }
+    Expression *get_arg2() const { return arg2; }
+    void set_arg2( Expression *newValue ) { arg2 = newValue; }
+
+    virtual CommaExpr *clone() const { return new CommaExpr( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+    
+private:
+    Expression *arg1;
+    Expression *arg2;
+};
+
+// TupleExpr represents a tuple expression ( [a, b, c] )
+class TupleExpr : public Expression
+{
+public:
+    TupleExpr( Expression *_aname = 0 );
+    TupleExpr( const TupleExpr &other );
+    virtual ~TupleExpr();
+
+    void set_exprs( std::list<Expression*> newValue ) { exprs = newValue; }
+    std::list<Expression*>& get_exprs() { return exprs; }
+
+    virtual TupleExpr *clone() const { return new TupleExpr( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+    
+private:
+    std::list<Expression*> exprs;
+};
+
+// SolvedTupleExpr represents a TupleExpr whose components have been type-resolved. It is effectively a shell for the code generator to work on
+class SolvedTupleExpr : public Expression
+{
+public:
+
+    SolvedTupleExpr( Expression *_aname = 0 ) : Expression( _aname ) {}
+    SolvedTupleExpr( std::list<Expression *> &, Expression *_aname = 0 );
+    SolvedTupleExpr( const SolvedTupleExpr &other );
+    virtual ~SolvedTupleExpr() {}
+
+    std::list<Expression*> &get_exprs() { return exprs; }
+
+    virtual SolvedTupleExpr *clone() const { return new SolvedTupleExpr( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+private:
+    std::list<Expression*> exprs;
+};
+
+// TypeExpr represents a type used in an expression (e.g. as a type generator parameter)
+class TypeExpr : public Expression
+{
+public:
+    TypeExpr( Type *type );
+    TypeExpr( const TypeExpr &other );
+    virtual ~TypeExpr();
+
+    Type *get_type() const { return type; }
+    void set_type( Type *newValue ) { type = newValue; }
+
+    virtual TypeExpr *clone() const { return new TypeExpr( *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:
+    Type *type;
+};
+
+// ValofExpr represents a GCC 'lambda expression'
+class UntypedValofExpr : public Expression
+{
+public:
+    UntypedValofExpr( Statement *_body, Expression *_aname = 0 ) : Expression( _aname ), body ( _body ) {}
+    virtual ~UntypedValofExpr() {}
+
+    Expression *get_value();
+    Statement *get_body() const { return body; }
+
+    virtual UntypedValofExpr *clone() const { return new UntypedValofExpr( *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:
+    Statement *body;
+};
+
+
+#endif /* #ifndef EXPRESSION_H */
+
+/*
+    Local Variables:
+    mode: c++
+    End:
+*/
Index: translator/SynTree/FunctionDecl.cc
===================================================================
--- translator/SynTree/FunctionDecl.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/FunctionDecl.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,111 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: FunctionDecl.cc,v 1.15 2005/08/29 20:59:25 rcbilson Exp $
+ *
+ */
+
+#include <cassert>
+
+#include "Declaration.h"
+#include "Statement.h"
+#include "Type.h"
+#include "utility.h"
+
+
+FunctionDecl::FunctionDecl( const std::string &name, StorageClass sc, LinkageSpec::Type linkage, FunctionType *type,
+					    CompoundStmt *statements, bool isInline )
+    : Parent( name, sc, linkage ), type( type ), statements( statements ), isInline( isInline )
+{
+    // this is a pretty brazen hack to force the function "main" to have C linkage
+    if( name == "main" ) {
+	set_linkage( LinkageSpec::C );
+    }
+}
+
+FunctionDecl::FunctionDecl( const FunctionDecl &other )
+    : Parent( other ), type( maybeClone( other.type ) ), statements( maybeClone( other.statements ) ),
+	isInline( other.isInline )
+{
+}
+
+FunctionDecl::~FunctionDecl()
+{
+    delete type;
+    delete statements;
+}
+
+Type*
+FunctionDecl::get_type() const
+{
+    return type;
+}
+
+void 
+FunctionDecl::set_type(Type *t)
+{
+    type = dynamic_cast< FunctionType* >( t );
+    assert( type );
+}
+
+void
+FunctionDecl::print( std::ostream &os, int indent ) const
+{
+    using std::endl;
+    using std::string;
+    
+    if( get_name() != "" ) {
+	os << get_name() << ": a ";
+    }
+    if( get_linkage() != LinkageSpec::Cforall ) {
+	os << LinkageSpec::toString( get_linkage() ) << " ";
+    }
+    if( isInline ) {
+	os << "inline ";
+    }
+    if( get_storageClass() != NoStorageClass ) {
+	os << storageClassName[ get_storageClass() ] << ' ';
+    }
+    if( get_type() ) {
+	get_type()->print( os, indent );
+    } else {
+	os << "untyped entity ";
+    }
+    if( !oldIdents.empty() ) {
+	os << string( indent+2, ' ' ) << "with parameter names" << endl;
+	for( std::list< std::string >::const_iterator i = oldIdents.begin(); i != oldIdents.end(); ++i ) {
+	    os << string( indent+4, ' ' ) << *i << endl;
+	}
+    }
+    if( !oldDecls.empty() ) {
+	os << string( indent+2, ' ' ) << "with parameter declarations" << endl;
+	printAll( oldDecls, os, indent+4 );
+    }
+    if( statements ) {
+	os << string( indent+2, ' ' ) << "with body " << endl;
+	statements->print( os, indent+4 );
+    }
+}
+
+void
+FunctionDecl::printShort( std::ostream &os, int indent ) const
+{
+    using std::endl;
+    using std::string;
+    
+    if( get_name() != "" ) {
+	os << get_name() << ": a ";
+    }
+    if( isInline ) {
+	os << "inline ";
+    }
+    if( get_storageClass() != NoStorageClass ) {
+	os << storageClassName[ get_storageClass() ] << ' ';
+    }
+    if( get_type() ) {
+	get_type()->print( os, indent );
+    } else {
+	os << "untyped entity ";
+    }
+}
+
Index: translator/SynTree/FunctionType.cc
===================================================================
--- translator/SynTree/FunctionType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/FunctionType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: FunctionType.cc,v 1.8 2005/08/29 20:59:25 rcbilson Exp $
+ *
+ */
+
+#include <algorithm>
+
+#include "Type.h"
+#include "Declaration.h"
+#include "utility.h"
+
+
+FunctionType::FunctionType( const Type::Qualifiers &tq, bool isVarArgs )
+    : Type( tq ), isVarArgs( isVarArgs )
+{
+}
+
+FunctionType::FunctionType( const FunctionType &other )
+    : Type( other ), isVarArgs( other.isVarArgs )
+{
+    cloneAll( other.returnVals, returnVals );
+    cloneAll( other.parameters, parameters );
+}
+
+FunctionType::~FunctionType()
+{
+    deleteAll( returnVals );
+    deleteAll( parameters );
+}
+
+void 
+FunctionType::print( std::ostream &os, int indent ) const
+{
+    using std::string;
+    using std::endl;
+
+    Type::print( os, indent );
+    os << "function" << endl;
+    if( !parameters.empty() ) {
+	os << string( indent+2, ' ' ) << "with parameters" << endl;
+	printAll( parameters, os, indent+4 );
+	if( isVarArgs ) {
+	    os << string( indent+4, ' ' ) << "and a variable number of other arguments" << endl;
+	}
+    } else if( isVarArgs ) {
+	os << string( indent+4, ' ' ) << "accepting unspecified arguments" << endl;
+    }
+    os << string( indent+2, ' ' ) << "returning ";
+    if( returnVals.empty() ) {
+	os << endl << string( indent+4, ' ' ) << "nothing " << endl;
+    } else {
+	os << endl;
+	printAll( returnVals, os, indent+4 );
+    }
+
+}
+
Index: translator/SynTree/Initializer.cc
===================================================================
--- translator/SynTree/Initializer.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/Initializer.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,113 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Initializer.cc,v 1.10 2005/08/29 20:59:25 rcbilson Exp $
+ *
+ */
+
+#include "Initializer.h"
+#include "Expression.h"
+#include "utility.h"
+
+
+Initializer::Initializer( )
+{
+}
+
+Initializer::~Initializer( )
+{
+}
+
+std::string Initializer::designator_name( Expression *des ) {
+    if( NameExpr *n = dynamic_cast<NameExpr *>(des) )
+	return n->get_name();
+    else
+	throw 0;
+}
+
+void 
+Initializer::print( std::ostream &os, int indent )
+{
+}
+
+SingleInit::SingleInit ( Expression *v, std::list< Expression *> &_designators )
+    : value ( v ), designators( _designators )
+{ 
+}
+
+SingleInit::SingleInit ( const SingleInit &other )
+    : value ( other.value )
+{
+    cloneAll(other.designators, designators );
+}
+
+SingleInit::~SingleInit()
+{
+}
+
+SingleInit *SingleInit::clone() const { return new SingleInit( *this); }
+
+void SingleInit::print( std::ostream &os, int indent )
+{
+    os << std::endl << std::string(indent, ' ' ) << "Simple Initializer: ";
+    value->print( os, indent+2 );
+
+    if ( ! designators.empty() )
+	{
+	    os << std::endl << std::string(indent + 2, ' ' ) << "designated by: "  ;
+	    for ( std::list < Expression * >::iterator i = designators.begin(); i != designators.end(); i++ )
+		( *i )->print(os, indent + 4 );
+	}
+}
+
+MemberInit::MemberInit( Expression *_value, std::string _member )
+    : member ( _member ), value ( _value )
+{
+}
+
+MemberInit::~MemberInit()
+{
+}
+
+MemberInit * MemberInit::clone() const
+{
+    return new MemberInit( *this );
+}
+
+void MemberInit::print( std::ostream &os, int indent )
+{
+    os << "Member Initializer";
+    value->print( os, indent+2 );
+}
+
+ListInit::ListInit( std::list<Initializer*> &_initializers, std::list<Expression *> &_designators )
+    : initializers( _initializers ), designators( _designators )
+{
+}
+
+ListInit::~ListInit()
+{
+}
+
+ListInit *ListInit::clone() const
+{
+    return new ListInit( *this );
+}
+
+void ListInit::print( std::ostream &os, int indent )
+{
+    os << std::endl << std::string(indent, ' ') << "Compound initializer:  "; 
+    if( ! designators.empty() ) {
+	os << std::string(indent + 2, ' ' ) << "designated by: [";
+	for ( std::list < Expression * >::iterator i = designators.begin();
+		    i != designators.end(); i++ ) {
+	    ( *i )->print(os, indent + 4 ); 
+	}
+	
+	os << std::string(indent + 2, ' ' ) << "]";
+    }
+
+    for( std::list<Initializer *>::iterator i = initializers.begin(); i != initializers.end(); i++ ) 
+	(*i)->print( os, indent + 2 );
+}
+
Index: translator/SynTree/Initializer.h
===================================================================
--- translator/SynTree/Initializer.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/Initializer.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,154 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Initializer.h,v 1.14 2005/08/29 20:59:25 rcbilson Exp $
+ *
+ */
+
+#ifndef INITIALIZER_H
+#define INITIALIZER_H
+
+#include "SynTree.h"
+#include "Visitor.h"
+#include "Mutator.h"
+
+#include <cassert>
+
+
+// Initializer: base class for object initializers (provide default values)
+class Initializer
+{
+public:
+    //	Initializer( std::string _name = std::string(""), int _pos = 0 );
+    Initializer( );
+    virtual ~Initializer();
+
+    static std::string designator_name( Expression *designator );
+
+    //	void set_name( std::string newValue ) { name = newValue; }
+    //	std::string get_name() const { return name; }
+
+    //	void set_pos( int newValue ) { pos = newValue; }
+    //	int get_pos() const { return pos; }
+    virtual void set_designators( std::list<Expression *> & ) { assert(false); }
+    virtual std::list<Expression *> &get_designators() {
+	assert(false);
+	std::list<Expression *> *ret = 0; return *ret;	// never reached
+    }
+
+    virtual Initializer *clone() const = 0;
+    virtual void accept( Visitor &v ) = 0;
+    virtual Initializer *acceptMutator( Mutator &m ) = 0;
+    virtual void print( std::ostream &os, int indent = 0 );
+    
+private:
+    //	std::string name;
+    //	int pos;
+};
+
+// SingleInit represents an initializer for a common object (e.g., int x = 4)
+class SingleInit : public Initializer
+{
+public:
+    SingleInit( Expression *value, std::list< Expression *> &designators );
+    SingleInit( const SingleInit &other );
+    virtual ~SingleInit();
+    
+    Expression *get_value() { return value; }
+    void set_value( Expression *newValue ) { value = newValue; }
+
+    void set_designators( std::list<Expression *> &newValue ) { designators = newValue; }
+    std::list<Expression *> &get_designators() { return designators; }
+
+    virtual SingleInit *clone() const;
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 );
+    
+private:
+    //Constant *value;
+    Expression *value;	// has to be a compile-time constant
+    std::list< Expression * > designators;
+};
+
+// MemberInit represents an initializer for a member of an aggregate object
+// (e.g., struct q { int a } x = { a: 4 } )
+class MemberInit : public Initializer
+{
+public:
+    MemberInit( Expression *value, std::string member = std::string("") );
+    virtual ~MemberInit();
+    
+    std::string get_member() { return member; }
+    void set_member( std::string newValue ) { member = newValue; }
+    Expression *get_value() { return value; }
+    void set_value( Expression *newValue ) { value = newValue; }
+
+    virtual MemberInit *clone() const;
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 );
+    
+private:
+    std::string member;
+    Expression *value;
+};
+
+// ElementInit represents an initializer of an element of an array
+// (e.g., [10] int x = { [7]: 4 }
+class ElementInit : public Initializer
+{
+public:
+    ElementInit( Expression *value );
+    virtual ~ElementInit();
+    
+    int get_index() { return index; }
+    void set_index( int newValue ) { index = newValue; }
+    Expression *get_value() { return value; }
+    void set_value( Expression *newValue ) { value = newValue; }
+
+    virtual ElementInit *clone() const;
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 );
+    
+private:
+    int index;
+    Expression *value;
+};
+
+// ListInit represents an initializer that is composed recursively of a list of initializers; this
+// is used to initialize an array or aggregate
+class ListInit : public Initializer
+{
+public:
+    ListInit( std::list<Initializer*> &, 
+	    std::list<Expression *> &designators = *(new std::list<Expression *>()) );
+    virtual ~ListInit();
+
+    void set_designators( std::list<Expression *> &newValue ) { designators = newValue; }
+    std::list<Expression *> &get_designators() { return designators; }
+    void set_initializers( std::list<Initializer*> &newValue ) { initializers = newValue; }
+    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(); }
+
+    virtual ListInit *clone() const;
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 );
+    
+private:
+    std::list<Initializer*> initializers;  // order *is* important
+    std::list<Expression *> designators;
+};
+
+
+#endif /* #ifndef INITIALIZER_H */
+
+/*
+    Local Variables:
+    mode: c++
+    End:
+*/
Index: translator/SynTree/Makefile
===================================================================
--- translator/SynTree/Makefile	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/Makefile	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,22 @@
+CXX=g++
+CXXFLAGS=-g -Wall #-Wno-unused
+
+SRCS:=Type.cc Constant.cc Expression.cc Statement.cc CodeGenVisitor.cc translate.cc
+OBJECTS:=$(SRCS:.cc=.o)
+DEPS:=$(SRCS:.cc=.d)
+
+# libSynTree.a:  $(OBJECTS)
+# 	ar -rs $@ $(OBJECTS)
+#	$(CXX) $(CXXFLAGS) $(OBJS) -o $@ $(EXTRALIBS)
+
+%.d: %.cc
+	g++ -M $(CXXFLAGS) $< | sed -e '1s/^\(.*\)\.o/\1.d \1.o/' > $@
+
+all: $(OBJECTS)
+
+ifneq ($(MAKECMDGOALS),clean)
+include $(DEPS)
+endif
+
+clean:
+	rm -f cfa $(OBJECTS) $(DEPS) core
Index: translator/SynTree/Mutator.cc
===================================================================
--- translator/SynTree/Mutator.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/Mutator.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,539 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Mutator.cc,v 1.30 2005/08/29 20:59:25 rcbilson Exp $
+ *
+ */
+
+#include <cassert>
+#include "Mutator.h"
+#include "Initializer.h"
+#include "Statement.h"
+#include "Type.h"
+#include "Declaration.h"
+#include "Expression.h"
+#include "Constant.h"
+#include "utility.h"
+
+Mutator::Mutator()
+{
+}
+
+Mutator::~Mutator()
+{
+}
+
+ObjectDecl*
+Mutator::mutate(ObjectDecl *objectDecl)
+{
+    objectDecl->set_type( maybeMutate( objectDecl->get_type(), *this ) );
+    objectDecl->set_init( maybeMutate( objectDecl->get_init(), *this ) );
+    objectDecl->set_bitfieldWidth( maybeMutate( objectDecl->get_bitfieldWidth(), *this ) );
+    return objectDecl;
+}
+
+DeclarationWithType*
+Mutator::mutate(FunctionDecl *functionDecl)
+{
+    functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
+    mutateAll( functionDecl->get_oldDecls(), *this );
+    functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
+    return functionDecl;
+}
+
+Declaration*
+Mutator::handleAggregateDecl(AggregateDecl *aggregateDecl)
+{
+    mutateAll( aggregateDecl->get_parameters(), *this );
+    mutateAll( aggregateDecl->get_members(), *this );
+    return aggregateDecl;
+}
+
+Declaration* 
+Mutator::mutate(StructDecl *aggregateDecl)
+{
+    handleAggregateDecl( aggregateDecl );
+    return aggregateDecl;
+}
+
+Declaration* 
+Mutator::mutate(UnionDecl *aggregateDecl)
+{
+    handleAggregateDecl( aggregateDecl );
+    return aggregateDecl;
+}
+
+Declaration* 
+Mutator::mutate(EnumDecl *aggregateDecl)
+{
+    handleAggregateDecl( aggregateDecl );
+    return aggregateDecl;
+}
+
+Declaration* 
+Mutator::mutate(ContextDecl *aggregateDecl)
+{
+    handleAggregateDecl( aggregateDecl );
+    return aggregateDecl;
+}
+
+Declaration*
+Mutator::handleNamedTypeDecl(NamedTypeDecl *typeDecl)
+{
+    mutateAll( typeDecl->get_parameters(), *this );
+    mutateAll( typeDecl->get_assertions(), *this );
+    typeDecl->set_base( maybeMutate( typeDecl->get_base(), *this ) );
+    return typeDecl;
+}
+
+TypeDecl* 
+Mutator::mutate(TypeDecl *typeDecl)
+{
+    handleNamedTypeDecl( typeDecl );
+    return typeDecl;
+}
+
+Declaration* 
+Mutator::mutate(TypedefDecl *typeDecl)
+{
+    handleNamedTypeDecl( typeDecl );
+    return typeDecl;
+}
+
+CompoundStmt*
+Mutator::mutate(CompoundStmt *compoundStmt)
+{
+    mutateAll( compoundStmt->get_kids(), *this );
+    return compoundStmt;
+}
+
+Statement*
+Mutator::mutate(ExprStmt *exprStmt)
+{
+    exprStmt->set_expr( maybeMutate( exprStmt->get_expr(), *this ) );
+    return exprStmt;
+}
+
+Statement*
+Mutator::mutate(IfStmt *ifStmt)
+{
+    ifStmt->set_condition(  maybeMutate( ifStmt->get_condition(), *this ) );
+    ifStmt->set_thenPart(  maybeMutate( ifStmt->get_thenPart(), *this ) );
+    ifStmt->set_elsePart(  maybeMutate( ifStmt->get_elsePart(), *this ) );
+    return ifStmt;
+}
+
+Statement*
+Mutator::mutate(WhileStmt *whileStmt)
+{
+    whileStmt->set_condition(  maybeMutate( whileStmt->get_condition(), *this ) );
+    whileStmt->set_body(    maybeMutate( whileStmt->get_body(), *this ) );
+    return whileStmt;
+}
+
+Statement*
+Mutator::mutate(ForStmt *forStmt)
+{
+    forStmt->set_initialization(    maybeMutate( forStmt->get_initialization(), *this ) );
+    forStmt->set_condition(  maybeMutate( forStmt->get_condition(), *this ) );
+    forStmt->set_increment(  maybeMutate( forStmt->get_increment(), *this ) );
+    forStmt->set_body(	maybeMutate( forStmt->get_body(), *this ) );
+    return forStmt;
+}
+
+Statement*
+Mutator::mutate(SwitchStmt *switchStmt)
+{
+    switchStmt->set_condition( maybeMutate( switchStmt->get_condition(), *this ) );
+    mutateAll( switchStmt->get_branches(), *this );
+    return switchStmt;
+}
+
+Statement*
+Mutator::mutate(ChooseStmt *switchStmt)
+{
+    switchStmt->set_condition(	maybeMutate( switchStmt->get_condition(), *this ) );
+    mutateAll( switchStmt->get_branches(), *this );
+    return switchStmt;
+}
+
+Statement*
+Mutator::mutate(FallthruStmt *fallthruStmt)
+{
+    return fallthruStmt;
+}
+
+Statement*
+Mutator::mutate(CaseStmt *caseStmt)
+{
+    caseStmt->set_condition(	maybeMutate( caseStmt->get_condition(), *this ) );
+    mutateAll (caseStmt->get_statements(), *this );
+
+    return caseStmt;
+}
+
+Statement*
+Mutator::mutate(BranchStmt *branchStmt)
+{
+    return branchStmt;
+}
+
+Statement*
+Mutator::mutate(ReturnStmt *returnStmt)
+{
+    returnStmt->set_expr(  maybeMutate( returnStmt->get_expr(), *this ) );
+    return returnStmt;
+}
+
+Statement*
+Mutator::mutate(TryStmt *tryStmt)
+{
+    tryStmt->set_block( maybeMutate( tryStmt->get_block(), *this ) );
+    mutateAll( tryStmt->get_catchers(), *this );
+    return tryStmt;
+}
+
+Statement*
+Mutator::mutate(CatchStmt *catchStmt)
+{
+    catchStmt->set_decl( maybeMutate( catchStmt->get_decl(), *this ) );
+    catchStmt->set_body( maybeMutate( catchStmt->get_body(), *this ) );
+    return catchStmt;
+}
+
+Statement*
+Mutator::mutate(FinallyStmt *finalStmt)
+{
+    finalStmt->set_block( maybeMutate( finalStmt->get_block(), *this ) );
+    return finalStmt;
+}
+
+NullStmt*
+Mutator::mutate(NullStmt *nullStmt)
+{
+    return nullStmt;
+}
+
+Statement*
+Mutator::mutate(DeclStmt *declStmt)
+{
+    declStmt->set_decl( maybeMutate( declStmt->get_decl(), *this ) );
+    return declStmt;
+}
+
+Expression*
+Mutator::mutate(ApplicationExpr *applicationExpr)
+{
+    mutateAll( applicationExpr->get_results(), *this );
+    applicationExpr->set_function(  maybeMutate( applicationExpr->get_function(), *this ) );
+    mutateAll( applicationExpr->get_args(), *this );
+    return applicationExpr;
+}
+
+Expression*
+Mutator::mutate(UntypedExpr *untypedExpr)
+{
+    mutateAll( untypedExpr->get_results(), *this );
+    mutateAll( untypedExpr->get_args(), *this );
+    return untypedExpr;
+}
+
+Expression*
+Mutator::mutate(NameExpr *nameExpr)
+{
+    mutateAll( nameExpr->get_results(), *this );
+    return nameExpr;
+}
+
+Expression*
+Mutator::mutate(AddressExpr *addressExpr)
+{
+    mutateAll( addressExpr->get_results(), *this );
+    addressExpr->set_arg(  maybeMutate( addressExpr->get_arg(), *this ) );
+    return addressExpr;
+}
+
+Expression*
+Mutator::mutate(LabelAddressExpr *labelAddressExpr)
+{
+    mutateAll( labelAddressExpr->get_results(), *this );
+    labelAddressExpr->set_arg(	maybeMutate( labelAddressExpr->get_arg(), *this ) );
+    return labelAddressExpr;
+}
+
+Expression*
+Mutator::mutate(CastExpr *castExpr)
+{
+    mutateAll( castExpr->get_results(), *this );
+    castExpr->set_arg(	maybeMutate( castExpr->get_arg(), *this ) );
+    return castExpr;
+}
+
+Expression*
+Mutator::mutate(UntypedMemberExpr *memberExpr)
+{
+    mutateAll( memberExpr->get_results(), *this );
+    memberExpr->set_aggregate(	maybeMutate( memberExpr->get_aggregate(), *this ) );
+    return memberExpr;
+}
+
+Expression*
+Mutator::mutate(MemberExpr *memberExpr)
+{
+    mutateAll( memberExpr->get_results(), *this );
+    memberExpr->set_aggregate(	maybeMutate( memberExpr->get_aggregate(), *this ) );
+    return memberExpr;
+}
+
+Expression*
+Mutator::mutate(VariableExpr *variableExpr)
+{
+    mutateAll( variableExpr->get_results(), *this );
+    return variableExpr;
+}
+
+Expression*
+Mutator::mutate(ConstantExpr *constantExpr)
+{
+    mutateAll( constantExpr->get_results(), *this );
+//  maybeMutate( constantExpr->get_constant(), *this )
+    return constantExpr;
+}
+
+Expression*
+Mutator::mutate(SizeofExpr *sizeofExpr)
+{
+    mutateAll( sizeofExpr->get_results(), *this );
+    if( sizeofExpr->get_isType() ) {
+	sizeofExpr->set_type(	 maybeMutate( sizeofExpr->get_type(), *this ) );
+    } else {
+	sizeofExpr->set_expr(	 maybeMutate( sizeofExpr->get_expr(), *this ) );
+    }
+    return sizeofExpr;
+}
+
+Expression*
+Mutator::mutate(AttrExpr *attrExpr)
+{
+    mutateAll( attrExpr->get_results(), *this );
+    if( attrExpr->get_isType() ) {
+	attrExpr->set_type(	 maybeMutate( attrExpr->get_type(), *this ) );
+    } else {
+	attrExpr->set_expr(	 maybeMutate( attrExpr->get_expr(), *this ) );
+    }
+    return attrExpr;
+}
+
+Expression*
+Mutator::mutate(LogicalExpr *logicalExpr)
+{
+    mutateAll( logicalExpr->get_results(), *this );
+    logicalExpr->set_arg1(  maybeMutate( logicalExpr->get_arg1(), *this ) );
+    logicalExpr->set_arg2(  maybeMutate( logicalExpr->get_arg2(), *this ) );
+    return logicalExpr;
+}
+
+Expression*
+Mutator::mutate(ConditionalExpr *conditionalExpr)
+{
+    mutateAll( conditionalExpr->get_results(), *this );
+    conditionalExpr->set_arg1(	maybeMutate( conditionalExpr->get_arg1(), *this ) );
+    conditionalExpr->set_arg2(	maybeMutate( conditionalExpr->get_arg2(), *this ) );
+    conditionalExpr->set_arg3(	maybeMutate( conditionalExpr->get_arg3(), *this ) );
+    return conditionalExpr;
+}
+
+Expression*
+Mutator::mutate(CommaExpr *commaExpr)
+{
+    mutateAll( commaExpr->get_results(), *this );
+    commaExpr->set_arg1(    maybeMutate( commaExpr->get_arg1(), *this ) );
+    commaExpr->set_arg2(    maybeMutate( commaExpr->get_arg2(), *this ) );
+    return commaExpr;
+}
+
+Expression*
+Mutator::mutate(TupleExpr *tupleExpr)
+{
+    mutateAll( tupleExpr->get_results(), *this );
+    mutateAll( tupleExpr->get_exprs(), *this );
+    return tupleExpr;
+}
+
+Expression*
+Mutator::mutate(SolvedTupleExpr *tupleExpr)
+{
+    mutateAll( tupleExpr->get_results(), *this );
+    mutateAll( tupleExpr->get_exprs(), *this );
+    return tupleExpr;
+}
+
+Expression*
+Mutator::mutate(TypeExpr *typeExpr)
+{
+    mutateAll( typeExpr->get_results(), *this );
+    typeExpr->set_type( maybeMutate( typeExpr->get_type(), *this ) );
+    return typeExpr;
+}
+
+Expression*
+Mutator::mutate(UntypedValofExpr *valofExpr)
+{
+    mutateAll( valofExpr->get_results(), *this );
+    return valofExpr;
+}
+
+Type*
+Mutator::mutate(VoidType *voidType)
+{
+    mutateAll( voidType->get_forall(), *this );
+    return voidType;
+}
+
+Type*
+Mutator::mutate(BasicType *basicType)
+{
+    mutateAll( basicType->get_forall(), *this );
+    return basicType;
+}
+
+Type*
+Mutator::mutate(PointerType *pointerType)
+{
+    mutateAll( pointerType->get_forall(), *this );
+    pointerType->set_base( maybeMutate( pointerType->get_base(), *this ) );
+    return pointerType;
+}
+
+Type*
+Mutator::mutate(ArrayType *arrayType)
+{
+    mutateAll( arrayType->get_forall(), *this );
+    arrayType->set_dimension( maybeMutate( arrayType->get_dimension(), *this ) );
+    arrayType->set_base( maybeMutate( arrayType->get_base(), *this ) );
+    return arrayType;
+}
+
+Type*
+Mutator::mutate(FunctionType *functionType)
+{
+    mutateAll( functionType->get_forall(), *this );
+    mutateAll( functionType->get_returnVals(), *this );
+    mutateAll( functionType->get_parameters(), *this );
+    return functionType;
+}
+
+Type*
+Mutator::handleReferenceToType(ReferenceToType *aggregateUseType)
+{
+    mutateAll( aggregateUseType->get_forall(), *this );
+    mutateAll( aggregateUseType->get_parameters(), *this );
+    return aggregateUseType;
+}
+
+Type* 
+Mutator::mutate(StructInstType *aggregateUseType)
+{
+    handleReferenceToType( aggregateUseType );
+    return aggregateUseType;
+}
+
+Type* 
+Mutator::mutate(UnionInstType *aggregateUseType)
+{
+    handleReferenceToType( aggregateUseType );
+    return aggregateUseType;
+}
+
+Type* 
+Mutator::mutate(EnumInstType *aggregateUseType)
+{
+    handleReferenceToType( aggregateUseType );
+    return aggregateUseType;
+}
+
+Type* 
+Mutator::mutate(ContextInstType *aggregateUseType)
+{
+    handleReferenceToType( aggregateUseType );
+    mutateAll( aggregateUseType->get_members(), *this );
+    return aggregateUseType;
+}
+
+Type* 
+Mutator::mutate(TypeInstType *aggregateUseType)
+{
+    handleReferenceToType( aggregateUseType );
+    return aggregateUseType;
+}
+
+Type*
+Mutator::mutate(TupleType *tupleType)
+{
+    mutateAll( tupleType->get_forall(), *this );
+    mutateAll( tupleType->get_types(), *this );
+    return tupleType;
+}
+
+Type*
+Mutator::mutate(TypeofType *typeofType)
+{
+    assert( typeofType->get_expr() );
+    typeofType->set_expr( typeofType->get_expr()->acceptMutator( *this ) );
+    return typeofType;
+}
+
+Type*
+Mutator::mutate(AttrType *attrType)
+{
+    if( attrType->get_isType() ) {
+	assert( attrType->get_type() );
+	attrType->set_type( attrType->get_type()->acceptMutator( *this ) );
+    } else {
+	assert( attrType->get_expr() );
+	attrType->set_expr( attrType->get_expr()->acceptMutator( *this ) );
+    }
+    return attrType;
+}
+
+Initializer*
+Mutator::mutate(MemberInit *memberInit)
+{
+    memberInit->set_value( memberInit->get_value()->acceptMutator( *this ) );
+    return memberInit;
+}
+
+Initializer*
+Mutator::mutate(ElementInit *elementInit)
+{
+    elementInit->set_value( elementInit->get_value()->acceptMutator( *this ) );
+    return elementInit;
+}
+
+Initializer*
+Mutator::mutate(SingleInit *singleInit)
+{
+    singleInit->set_value( singleInit->get_value()->acceptMutator( *this ) );
+    return singleInit;
+}
+
+Initializer*
+Mutator::mutate(ListInit *listInit)
+{
+    mutateAll( listInit->get_designators(), *this );
+    mutateAll( listInit->get_initializers(), *this );
+    return listInit;
+}
+
+Subrange *
+Mutator::mutate(Subrange *subrange)
+{
+    return subrange;
+}
+
+Constant *
+Mutator::mutate(Constant *constant)
+{
+    return constant;
+}
+
Index: translator/SynTree/Mutator.h
===================================================================
--- translator/SynTree/Mutator.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/Mutator.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,140 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Mutator.h,v 1.19 2005/08/29 20:59:25 rcbilson Exp $
+ *
+ */
+
+#include <cassert>
+
+#include "SynTree.h"
+#include "SemanticError.h"
+
+#ifndef SYNTREE_MUTATOR_H
+#define SYNTREE_MUTATOR_H
+
+
+class Mutator
+{
+protected:
+    Mutator();
+    virtual ~Mutator();
+
+public:
+    virtual ObjectDecl* mutate(ObjectDecl *objectDecl);
+    virtual DeclarationWithType* mutate(FunctionDecl *functionDecl);
+    virtual Declaration* mutate(StructDecl *aggregateDecl);
+    virtual Declaration* mutate(UnionDecl *aggregateDecl);
+    virtual Declaration* mutate(EnumDecl *aggregateDecl);
+    virtual Declaration* mutate(ContextDecl *aggregateDecl);
+    virtual TypeDecl* mutate(TypeDecl *typeDecl);
+    virtual Declaration* mutate(TypedefDecl *typeDecl);
+
+    virtual CompoundStmt* mutate(CompoundStmt *compoundStmt);
+    virtual Statement* mutate(ExprStmt *exprStmt);
+    virtual Statement* mutate(IfStmt *ifStmt);
+    virtual Statement* mutate(WhileStmt *whileStmt);
+    virtual Statement* mutate(ForStmt *forStmt);
+    virtual Statement* mutate(SwitchStmt *switchStmt);
+    virtual Statement* mutate(ChooseStmt *chooseStmt);
+    virtual Statement* mutate(FallthruStmt *fallthruStmt);
+    virtual Statement* mutate(CaseStmt *caseStmt);
+    virtual Statement* mutate(BranchStmt *branchStmt);
+    virtual Statement* mutate(ReturnStmt *returnStmt);
+    virtual Statement* mutate(TryStmt *returnStmt);
+    virtual Statement* mutate(CatchStmt *catchStmt);
+    virtual Statement* mutate(FinallyStmt *catchStmt);
+    virtual NullStmt* mutate(NullStmt *nullStmt);
+    virtual Statement* mutate(DeclStmt *declStmt);
+
+    virtual Expression* mutate(ApplicationExpr *applicationExpr);
+    virtual Expression* mutate(UntypedExpr *untypedExpr);
+    virtual Expression* mutate(NameExpr *nameExpr);
+    virtual Expression* mutate(AddressExpr *castExpr);
+    virtual Expression* mutate(LabelAddressExpr *labAddressExpr);
+    virtual Expression* mutate(CastExpr *castExpr);
+    virtual Expression* mutate(UntypedMemberExpr *memberExpr);
+    virtual Expression* mutate(MemberExpr *memberExpr);
+    virtual Expression* mutate(VariableExpr *variableExpr);
+    virtual Expression* mutate(ConstantExpr *constantExpr); 
+    virtual Expression* mutate(SizeofExpr *sizeofExpr);
+    virtual Expression* mutate(AttrExpr *attrExpr);
+    virtual Expression* mutate(LogicalExpr *logicalExpr);
+    virtual Expression* mutate(ConditionalExpr *conditionalExpr);
+    virtual Expression* mutate(CommaExpr *commaExpr);
+    virtual Expression* mutate(TupleExpr *tupleExpr);
+    virtual Expression* mutate(SolvedTupleExpr *tupleExpr);
+    virtual Expression* mutate(TypeExpr *typeExpr);
+    virtual Expression* mutate(UntypedValofExpr *valofExpr);
+
+    virtual Type* mutate(VoidType *basicType);
+    virtual Type* mutate(BasicType *basicType);
+    virtual Type* mutate(PointerType *pointerType);
+    virtual Type* mutate(ArrayType *arrayType);
+    virtual Type* mutate(FunctionType *functionType);
+    virtual Type* mutate(StructInstType *aggregateUseType);
+    virtual Type* mutate(UnionInstType *aggregateUseType);
+    virtual Type* mutate(EnumInstType *aggregateUseType);
+    virtual Type* mutate(ContextInstType *aggregateUseType);
+    virtual Type* mutate(TypeInstType *aggregateUseType);
+    virtual Type* mutate(TupleType *tupleType);
+    virtual Type* mutate(TypeofType *typeofType);
+    virtual Type* mutate(AttrType *attrType);
+
+    virtual Initializer* mutate(MemberInit *memberInit);
+    virtual Initializer* mutate(ElementInit *elementInit);
+    virtual Initializer* mutate(SingleInit *singleInit);
+    virtual Initializer* mutate(ListInit *listInit);
+
+    virtual Subrange *mutate(Subrange *subrange);
+
+    virtual Constant *mutate(Constant *constant);
+
+private:
+    virtual Declaration* handleAggregateDecl(AggregateDecl *aggregateDecl);
+    virtual Declaration* handleNamedTypeDecl(NamedTypeDecl *typeDecl);
+    virtual Type* handleReferenceToType(ReferenceToType *aggregateUseType);
+};
+
+template< typename TreeType, typename MutatorType >
+inline TreeType *
+maybeMutate( TreeType *tree, MutatorType &mutator )
+{
+    if( tree ) {
+	TreeType *newnode = dynamic_cast< TreeType* >( tree->acceptMutator( mutator ) );
+	assert( newnode );
+	return newnode;
+///	    return tree->acceptMutator( mutator );
+    } else {
+	return 0;
+    }
+}
+
+template< typename Container, typename MutatorType >
+inline void
+mutateAll( Container &container, MutatorType &mutator )
+{
+    SemanticError errors;
+    for( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
+	try {
+	    if( *i ) {
+///		    *i = (*i)->acceptMutator( mutator );
+		*i = dynamic_cast< typename Container::value_type >( (*i)->acceptMutator( mutator ) );
+		assert( *i );
+	    }
+	} catch( SemanticError &e ) {
+	    errors.append( e );
+	}
+    }
+    if( !errors.isEmpty() ) {
+	throw errors;
+    }
+}
+
+
+
+#endif /* #ifndef SYNTREE_MUTATOR_H */
+
+// Local Variables: //
+// mode: c++ //
+// End:  //
Index: translator/SynTree/NamedTypeDecl.cc
===================================================================
--- translator/SynTree/NamedTypeDecl.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/NamedTypeDecl.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,74 @@
+#include "Declaration.h"
+#include "Type.h"
+#include "utility.h"
+
+
+NamedTypeDecl::NamedTypeDecl( const std::string &name, StorageClass sc, Type *base )
+    : Parent( name, sc, LinkageSpec::Cforall ), base( base )
+{
+}
+
+NamedTypeDecl::NamedTypeDecl( const TypeDecl &other )
+    : Parent( other ), base( maybeClone( other.base ) )
+{
+    cloneAll( other.parameters, parameters );
+    cloneAll( other.assertions, assertions );
+}
+
+NamedTypeDecl::~NamedTypeDecl()
+{
+    delete base;
+    deleteAll( parameters );
+    deleteAll( assertions );
+}
+
+void 
+NamedTypeDecl::print( std::ostream &os, int indent ) const
+{
+    using namespace std;
+    
+    if( get_name() != "" ) {
+	os << get_name() << ": a ";
+    }
+    if( get_storageClass() != NoStorageClass ) {
+	os << storageClassName[ get_storageClass() ] << ' ';
+    }
+    os << typeString();
+    if( base ) {
+	os << " for ";
+	base->print( os, indent );
+    }
+    if( !parameters.empty() ) {
+	os << endl << string( indent, ' ' ) << "with parameters" << endl;
+	printAll( parameters, os, indent+2 );
+    }
+    if( !assertions.empty() ) {
+	os << endl << string( indent, ' ' ) << "with assertions" << endl;
+	printAll( assertions, os, indent+2 );
+    }
+}
+
+void 
+NamedTypeDecl::printShort( std::ostream &os, int indent ) const
+{
+    using namespace std;
+    
+    if( get_name() != "" ) {
+	os << get_name() << ": a ";
+    }
+    if( get_storageClass() != NoStorageClass ) {
+	os << storageClassName[ get_storageClass() ] << ' ';
+    }
+    os << typeString();
+    if( base ) {
+	os << " for ";
+	base->print( os, indent );
+    }
+    if( !parameters.empty() ) {
+	os << endl << string( indent, ' ' ) << "with parameters" << endl;
+	printAll( parameters, os, indent+2 );
+    }
+}
+
+std::string TypedefDecl::typeString() const { return "typedef"; }
+    
Index: translator/SynTree/ObjectDecl.cc
===================================================================
--- translator/SynTree/ObjectDecl.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/ObjectDecl.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,78 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: ObjectDecl.cc,v 1.8 2005/08/29 20:59:25 rcbilson Exp $
+ *
+ */
+
+#include "Declaration.h"
+#include "Type.h"
+#include "Initializer.h"
+#include "Expression.h"
+#include "utility.h"
+
+
+ObjectDecl::ObjectDecl( const std::string &name, StorageClass sc, LinkageSpec::Type linkage, Expression *bitfieldWidth, Type *type, Initializer *init )
+    : Parent( name, sc, linkage ), type( type ), init( init ), bitfieldWidth( bitfieldWidth )
+{
+}
+
+ObjectDecl::ObjectDecl( const ObjectDecl &other )
+    : Parent( other ), type( maybeClone( other.type ) ), init( maybeClone( other.init ) ), bitfieldWidth( maybeClone( other.bitfieldWidth ) )
+{
+}
+
+ObjectDecl::~ObjectDecl()
+{
+    delete type;
+    delete init;
+    delete bitfieldWidth;
+}
+
+void 
+ObjectDecl::print( std::ostream &os, int indent ) const
+{
+    if( get_name() != "" ) {
+	os << get_name() << ": a ";
+    }
+    if( get_linkage() != LinkageSpec::Cforall ) {
+	os << LinkageSpec::toString( get_linkage() ) << " ";
+    }
+    if( get_storageClass() != NoStorageClass ) {
+	os << storageClassName[ get_storageClass() ] << ' ';
+    }
+    if( get_type() ) {
+	get_type()->print( os, indent );
+    } else {
+	os << "untyped entity ";
+    }
+    if( init ) {
+	os << "with initializer ";
+	init->print( os, indent );
+    }
+    if( bitfieldWidth ) {
+	os << "with bitfield width ";
+	bitfieldWidth->print( os );
+    }
+}
+
+void 
+ObjectDecl::printShort( std::ostream &os, int indent ) const
+{
+    if( get_name() != "" ) {
+	os << get_name() << ": a ";
+    }
+    if( get_storageClass() != NoStorageClass ) {
+	os << storageClassName[ get_storageClass() ] << ' ';
+    }
+    if( get_type() ) {
+	get_type()->print( os, indent );
+    } else {
+	os << "untyped entity ";
+    }
+    if( bitfieldWidth ) {
+	os << "with bitfield width ";
+	bitfieldWidth->print( os );
+    }
+}
+
Index: translator/SynTree/PointerType.cc
===================================================================
--- translator/SynTree/PointerType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/PointerType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: PointerType.cc,v 1.8 2005/08/29 20:59:26 rcbilson Exp $
+ *
+ */
+
+#include "Type.h"
+#include "Expression.h"
+#include "utility.h"
+
+
+PointerType::PointerType( const Type::Qualifiers &tq, Type *base )
+    : Type( tq ), base( base ), dimension( 0 ), isVarLen( false ), isStatic( false )
+{
+    base->set_isLvalue( false );
+}
+
+PointerType::PointerType( const Type::Qualifiers &tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic )
+    : Type( tq ), base( base ), dimension( dimension ), isVarLen( isVarLen ), isStatic( isStatic )
+{
+    base->set_isLvalue( false );
+}
+
+PointerType::PointerType( const PointerType &other )
+    : Type( other ), base( maybeClone( other.base ) ), dimension( maybeClone( other.dimension ) ),
+	isVarLen( other.isVarLen ), isStatic( other.isStatic )
+{
+}
+
+PointerType::~PointerType()
+{
+    delete base;
+    delete dimension;
+}
+
+void
+PointerType::print( std::ostream &os, int indent ) const
+{
+    Type::print( os, indent );
+    os << "pointer to ";
+    if( isStatic ) {
+	os << "static ";
+    }
+    if( isVarLen ) {
+	os << "variable length array of ";
+    } else if( dimension ) {
+	os << "array of ";
+	dimension->print( os, indent );
+    }
+    if( base ) {
+	base->print( os, indent );
+    }
+}
+
Index: translator/SynTree/ReferenceToType.cc
===================================================================
--- translator/SynTree/ReferenceToType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/ReferenceToType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,125 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: ReferenceToType.cc,v 1.16 2005/08/29 20:59:26 rcbilson Exp $
+ *
+ */
+
+#include <string>
+#include <cassert>
+
+#include "Type.h"
+#include "Declaration.h"
+#include "Expression.h"
+#include "TypeSubstitution.h"
+#include "utility.h"
+
+
+ReferenceToType::ReferenceToType( const Type::Qualifiers &tq, const std::string &name )
+    : Type( tq ), name( name )
+{
+}
+
+ReferenceToType::ReferenceToType( const ReferenceToType &other )
+    : Type( other ), name( other.name )
+{
+    cloneAll( other.parameters, parameters );
+}
+
+ReferenceToType::~ReferenceToType()
+{
+    deleteAll( parameters );
+}
+
+void 
+ReferenceToType::print( std::ostream &os, int indent ) const
+{
+    using std::endl;
+    
+    Type::print( os, indent );
+    os << "instance of " << typeString() << " " << name << " ";
+    if( !parameters.empty() ) {
+	os << endl << std::string( indent, ' ' ) << "with parameters" << endl;
+	printAll( parameters, os, indent+2 );
+    }
+}
+
+namespace {
+
+void
+doLookup( const std::list< Declaration* > &members, const std::list< TypeDecl* > &parms, const std::list< Expression* > &args, const std::string &name, std::list< Declaration* > &foundDecls )
+{
+    std::list< Declaration* > found;
+    for( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
+	if( (*i)->get_name() == name ) {
+	    found.push_back( *i );
+	}
+    }
+    applySubstitution( parms.begin(), parms.end(), args.begin(), found.begin(), found.end(), back_inserter( foundDecls ) );
+}
+
+} // namespace
+
+std::string StructInstType::typeString() const { return "struct"; }
+
+void
+StructInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const
+{
+    assert( baseStruct );
+    doLookup( baseStruct->get_members(), baseStruct->get_parameters(), parameters, name, foundDecls );
+}
+
+std::string UnionInstType::typeString() const { return "union"; }
+
+void
+UnionInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const
+{
+    assert( baseUnion );
+    doLookup( baseUnion->get_members(), baseUnion->get_parameters(), parameters, name, foundDecls );
+}
+
+std::string EnumInstType::typeString() const { return "enum"; }
+
+std::string ContextInstType::typeString() const { return "context"; }
+
+ContextInstType::ContextInstType( const ContextInstType &other )
+    : Parent( other )
+{
+    cloneAll( other.members, members );
+}
+
+ContextInstType::~ContextInstType()
+{
+    deleteAll( members );
+}
+
+TypeInstType::TypeInstType( const Type::Qualifiers &tq, const std::string &name, TypeDecl *baseType ) : Parent( tq, name )
+{
+    set_baseType( baseType );
+}
+
+TypeInstType::TypeInstType( const Type::Qualifiers &tq, const std::string &name, bool isFtype ) : Parent( tq, name ), baseType( 0 ), isFtype( isFtype )
+{
+}
+
+void TypeInstType::set_baseType( TypeDecl *newValue )
+{
+    baseType = newValue;
+    isFtype = newValue->get_kind() == TypeDecl::Ftype;
+}
+
+std::string TypeInstType::typeString() const { return "type"; }
+
+void 
+TypeInstType::print( std::ostream &os, int indent ) const
+{
+    using std::endl;
+    
+    Type::print( os, indent );
+    os << "instance of " << typeString() << " " << get_name() << " (" << ( isFtype ? "" : "not" ) << " a function type) ";
+    if( !parameters.empty() ) {
+	os << endl << std::string( indent, ' ' ) << "with parameters" << endl;
+	printAll( parameters, os, indent+2 );
+    }
+}
+
Index: translator/SynTree/Statement.cc
===================================================================
--- translator/SynTree/Statement.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/Statement.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,324 @@
+#include <functional>
+#include <algorithm>
+#include <iostream>
+#include <list>
+#include <cassert>
+
+#include "Statement.h"
+#include "Expression.h"
+#include "Declaration.h"
+#include "Common/SemanticError.h"
+
+using std::string;
+using std::endl;
+
+
+// *** Statement
+Statement::Statement(std::list<Label> _labels):
+    labels(_labels) {}
+
+void Statement::print(std::ostream &, int indent) {}
+
+Statement::~Statement() {}
+
+//*** ExprStmt
+ExprStmt::ExprStmt( std::list<Label> _labels, Expression *_expr ):
+    Statement(_labels), expr(_expr) {}
+
+ExprStmt::~ExprStmt() {}
+
+void ExprStmt::print( std::ostream &os, int indent ) {
+    os << "\r" << string(indent, ' ') << "Expression Statement:" << endl;
+    expr->print(os, indent + 2);
+} 
+
+//*** BranchStmt
+const char *BranchStmt::brType[] = { "Goto", "Break", "Continue" };
+
+BranchStmt::BranchStmt( std::list<Label> labels, Label _target, Type _type ) 
+    throw (SemanticError) :
+    Statement(labels), target(_target), type(_type)
+{
+    //actually this is a syntactic error signaled by the parser
+    if(type == BranchStmt::Goto && target.size() == 0)
+	throw SemanticError("goto without target");
+}
+
+BranchStmt::BranchStmt( std::list<Label> labels, Expression *_computedTarget, Type _type)
+    throw (SemanticError) :
+    Statement(labels), computedTarget(_computedTarget), type(_type)
+{
+    if(type != BranchStmt::Goto || computedTarget == 0)
+	throw SemanticError("Computed target not valid in branch statement");
+}
+
+void BranchStmt::print( std::ostream &os, int indent ){
+    os << "\r" << string(indent, ' ') << "Branch (" << brType[type] << ")" << endl ;
+}
+
+//*** ReturnStmt
+ReturnStmt::ReturnStmt( std::list<Label> labels, Expression *_expr, bool throwP ) :
+    Statement( labels ), expr( _expr ), isThrow( throwP ) {}
+
+ReturnStmt::~ReturnStmt() {
+    delete expr;
+}
+
+void ReturnStmt::print( std::ostream &os, int indent ){
+    os << "\r" << std::string(indent, ' ') << string ( isThrow? "Throw":"Return" ) << " Statement, returning: ";
+    if(expr != 0) expr->print(os);
+    os << endl;
+}
+
+
+// *** IfStmt
+IfStmt::IfStmt( std::list<Label> _labels, Expression *_condition, Statement *_thenPart, Statement *_elsePart ):
+    Statement(_labels), condition(_condition), thenPart(_thenPart), elsePart(_elsePart) {}
+
+IfStmt::~IfStmt() {}
+
+void IfStmt::print( std::ostream &os, int indent ){
+    os << "\r" << string(indent, ' ') << "If on condition: " << endl ;
+    condition->print(os, indent + 4);
+
+    os << string(indent, ' ') << ".... and branches: " << endl;
+
+    thenPart->print(os, indent + 4);
+
+    if(elsePart != 0){
+	elsePart->print(os, indent + 4);
+    }
+}
+
+// *** SwitchStmt
+SwitchStmt::SwitchStmt(std::list<Label> _labels, Expression * _condition, std::list<Statement *> &_branches):
+    Statement(_labels), condition(_condition), branches(_branches)
+{ }
+
+SwitchStmt::~SwitchStmt() {
+    delete condition;
+    // destroy branches
+}
+
+void SwitchStmt::add_case(CaseStmt *c) {}
+
+void SwitchStmt::print(std::ostream &os, int indent) {
+    os << "\r" << string(indent, ' ') << "Switch on condition: ";
+    condition->print(os);
+    os << endl;
+
+    // branches
+    std::list<Statement *>::iterator i;
+    for(i = branches.begin(); i != branches.end(); i++)
+	(*i)->print(os, indent + 4);
+
+    //for_each(branches.begin(), branches.end(), mem_fun(bind1st(&Statement::print), os));
+}
+
+// *** CaseStmt
+CaseStmt::CaseStmt( std::list<Label> _labels, Expression *_condition,
+					std::list<Statement *> &_statements, bool deflt )
+    throw (SemanticError) : 
+    Statement(_labels), condition(_condition), stmts(_statements), _isDefault(deflt)
+{
+    if(isDefault() && condition != 0)
+	throw SemanticError("default with conditions");
+}
+
+CaseStmt::~CaseStmt() {
+    delete condition;
+}
+
+void CaseStmt::print(std::ostream &os, int indent) {
+    os << "\r" << string(indent, ' ');
+
+    if(isDefault())
+	os << "Default ";
+    else {
+	os << "Case ";
+	condition->print(os);
+    }
+
+    os << endl;
+
+    std::list<Statement *>::iterator i;
+    for(i = stmts.begin(); i != stmts.end(); i++)
+	(*i)->print(os, indent + 4);
+}
+
+//*** ChooseStmt
+//ChooseStmt::ChooseStmt( std::list<Label> labels, Expression *condition, Statement *body ) {}
+ChooseStmt::ChooseStmt(std::list<Label> _labels, Expression * _condition, std::list<Statement *> &_branches):
+    Statement(_labels), condition(_condition), branches(_branches)
+{ }
+
+ChooseStmt::~ChooseStmt() {
+    delete condition;
+}
+
+void ChooseStmt::add_case(CaseStmt *c) {}
+
+void ChooseStmt::print(std::ostream &os, int indent) {
+    os << "\r" << string(indent, ' ') << "Choose on condition: ";
+    condition->print(os);
+    os << endl;
+
+    // branches
+    std::list<Statement *>::iterator i;
+    for(i = branches.begin(); i != branches.end(); i++)
+	(*i)->print(os, indent + 4);
+
+    //for_each(branches.begin(), branches.end(), mem_fun(bind1st(&Statement::print), os));
+}
+
+//*** FallthruStmt
+void FallthruStmt::print(std::ostream &os, int indent) {
+    os << "\r" << string(indent, ' ') << "Fall-through statement" << endl;
+}
+
+//*** WhileStmt
+WhileStmt::WhileStmt( std::list<Label> labels, Expression *condition_,
+					    Statement *body_, bool isDoWhile_ ):
+    Statement( labels ), condition(condition_), body(body_), isDoWhile(isDoWhile_)
+{}
+
+WhileStmt::~WhileStmt(){
+    delete body;
+}
+
+void WhileStmt::print( std::ostream &os, int indent ){
+    os << "\r" << string(indent, ' ') << "While on condition: " << endl ;
+    condition->print(os, indent + 4);
+
+    os << string(indent, ' ') << ".... with body: " << endl;
+
+    if(body != 0) body->print(os, indent + 4);
+}
+
+//*** ForStmt
+ForStmt::ForStmt( std::list<Label> labels, Statement *initialization_,
+				    Expression *condition_, Expression *increment_, Statement *body_ ):
+    Statement( labels ), initialization( initialization_ ),
+    condition( condition_ ), increment( increment_ ), body( body_ )
+{ }
+
+
+ForStmt::~ForStmt() {
+    delete initialization;
+    delete condition;
+    delete increment;
+    delete body;
+}
+
+void ForStmt::print( std::ostream &os, int indent ){
+    os << "\r" << string(indent, ' ') << "For Statement" << endl ;
+
+    os << "\r" << string(indent + 2, ' ') << "initialization: \n"; 
+    if (initialization != 0)
+	initialization->print(os, indent + 4);
+
+    os << "\n\r" << string(indent + 2, ' ') << "condition: \n"; 
+    if (condition != 0)
+	condition->print(os, indent + 4);
+
+    os << "\n\r" << string(indent + 2, ' ') << "increment: \n"; 
+    if (increment != 0)
+	increment->print(os, indent + 4);
+
+    os << "\n\r" << string(indent + 2, ' ') << "statement block: \n"; 
+    if(body != 0)
+	body->print(os, indent + 4);
+
+    os << endl;
+}
+
+//*** TryStmt
+TryStmt::TryStmt( std::list<Label> labels, CompoundStmt *tryBlock, std::list<Statement *> &_handlers, FinallyStmt *_finallyBlock ) :
+    Statement( labels ), block( tryBlock ),  handlers( _handlers ), finallyBlock( _finallyBlock )
+{ }
+
+TryStmt::TryStmt( const TryStmt &other) : Statement( other.labels ) {
+    block = other.block;
+    std::copy( other.handlers.begin(), other.handlers.end(), back_inserter(handlers) );
+    finallyBlock = other.finallyBlock;
+}
+
+TryStmt::~TryStmt(){
+    delete block;
+}
+
+void TryStmt::print( std::ostream &os, int indent ) {
+    os << "\r" << string(indent, ' ') << "Try Statement" << endl;
+    os << string(indent + 2, ' ') << "with block: " << endl;
+    block->print(os, indent + 4);
+
+    // handlers
+    os << string(indent + 2, ' ') << "and handlers: " << endl;
+    std::list<Statement *>::iterator i;
+    for(i = handlers.begin(); i != handlers.end(); i++)
+	(*i)->print(os, indent + 4);
+
+    // finally block
+    if ( finallyBlock != 0 ) {
+	os << string(indent + 2, ' ') << "Finally block: " << endl;
+	finallyBlock->print(os, indent + 4 );
+    }
+}
+
+//*** CatchStmt
+CatchStmt::CatchStmt( std::list<Label> labels, Declaration *_decl, Statement *_body, bool isCatchRest ) :
+    Statement( labels ), decl ( _decl ), body( _body ), catchRest ( isCatchRest )
+{ }
+
+CatchStmt::~CatchStmt(){
+    delete decl;
+    delete body;
+}
+
+void CatchStmt::print( std::ostream &os, int indent ) {
+    os << "\r" << string(indent, ' ') << "Catch Statement" << endl;
+
+    os << "\r" << string(indent, ' ') << "... catching" << endl;
+    if( decl ) {
+	decl->printShort( os, indent + 4 );
+	os << endl;
+    } else if ( catchRest )
+	os << "\r" << string(indent + 4 , ' ') << "the rest" << endl;
+    else
+	os << "\r" << string(indent + 4 , ' ') << ">>> Error:  this catch clause must have a declaration <<<" << endl;
+}
+
+
+//*** FinallyStmt
+FinallyStmt::FinallyStmt( std::list<Label> labels, CompoundStmt *_block ) :
+    Statement( labels ), block( _block )
+{
+    assert( labels.empty() ); // finally statement cannot be labeled
+}
+
+FinallyStmt::~FinallyStmt(){
+    delete block;
+}
+
+void FinallyStmt::print( std::ostream &os, int indent ) {
+    os << "\r" << string(indent, ' ') << "Finally Statement" << endl;
+    os << string(indent + 2, ' ') << "with block: " << endl;
+    block->print(os, indent + 4);
+}
+
+//*** NullStmt
+NullStmt::NullStmt( std::list<Label> labels ) : CompoundStmt( labels ) {}
+NullStmt::NullStmt() : CompoundStmt( std::list<Label>() ) {}
+NullStmt::~NullStmt() {}
+
+void NullStmt::print( std::ostream &os, int indent ) {
+    os << "\r" << string(indent, ' ') << "Null Statement" << endl ;
+}
+
+
+
+/*
+Local Variables:
+compile-command: "cd ..; gmake"
+End:
+*/
Index: translator/SynTree/Statement.h
===================================================================
--- translator/SynTree/Statement.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/Statement.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,394 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Statement.h,v 1.18 2005/08/29 20:59:26 rcbilson Exp $
+ *
+ */
+
+#ifndef STATEMENT_H
+#define STATEMENT_H
+
+#include "SynTree.h"
+#include "Visitor.h"
+#include "Mutator.h"
+#include "Common/SemanticError.h"
+
+
+class Statement
+{
+public:
+    Statement( std::list<Label> labels );
+    virtual ~Statement();
+
+    std::list<Label> & get_labels() { return labels; }
+
+    virtual Statement *clone() const = 0;
+    virtual void accept( Visitor &v ) = 0;
+    virtual Statement *acceptMutator( Mutator &m ) = 0;
+    virtual void print( std::ostream &os, int indent = 0 );
+    
+protected:
+    std::list<Label> labels;
+};
+
+class CompoundStmt : public Statement
+{
+public:
+    CompoundStmt( std::list<Label> labels );
+    CompoundStmt( const CompoundStmt &other );
+    virtual ~CompoundStmt();
+
+    std::list<Statement*>& get_kids() { return kids; }
+
+    virtual CompoundStmt *clone() const { return new CompoundStmt( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual CompoundStmt *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 );
+    
+private:
+    std::list<Statement*> kids;
+};
+
+class ExprStmt : public Statement
+{
+public:
+    ExprStmt( std::list<Label> labels, Expression *expr );
+    virtual ~ExprStmt();
+
+    Expression *get_expr() { return expr; }
+    void set_expr( Expression *newValue ) { expr = newValue; }
+
+    virtual ExprStmt *clone() const { return new ExprStmt( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 );
+    
+private:
+    Expression *expr;
+};
+
+class IfStmt : public Statement
+{
+public:
+    IfStmt( std::list<Label> labels, Expression *condition, Statement *thenPart, Statement *elsePart );
+    virtual ~IfStmt();
+
+    Expression *get_condition() { return condition; }
+    void set_condition( Expression *newValue ) { condition = newValue; }
+    Statement *get_thenPart() { return thenPart; }
+    void set_thenPart( Statement *newValue ) { thenPart = newValue; }
+    Statement *get_elsePart() { return elsePart; }
+    void set_elsePart( Statement *newValue ) { elsePart = newValue; }
+    
+    virtual IfStmt *clone() const { return new IfStmt( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 );
+    
+private:
+    Expression *condition;
+    Statement *thenPart;
+    Statement *elsePart;
+};
+
+class SwitchStmt : public Statement
+{
+public:
+    SwitchStmt( std::list<Label> labels, Expression *condition, std::list<Statement *> &branches );
+    virtual ~SwitchStmt();
+
+    Expression *get_condition() { return condition; }
+    void set_condition( Expression *newValue ) { condition = newValue; }
+
+    std::list<Statement *>& get_branches() { return branches; }
+    void add_case( CaseStmt * );
+
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+
+    virtual SwitchStmt *clone() const { return new SwitchStmt( *this ); }
+    virtual void print( std::ostream &os, int indent = 0 );
+    
+private:
+    Expression * condition;
+    std::list<Statement *> branches; // should be list of CaseStmt
+};
+
+class ChooseStmt : public Statement
+{
+public:
+    ChooseStmt( std::list<Label> labels, Expression *condition, std::list<Statement *> &branches );
+    virtual ~ChooseStmt();
+
+    Expression *get_condition() { return condition; }
+    void set_condition( Expression *newValue ) { condition = newValue; }
+
+    std::list<Statement *>& get_branches() { return branches; }
+    void add_case( CaseStmt * );
+    
+
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+
+    virtual ChooseStmt *clone() const { return new ChooseStmt( *this ); }
+    virtual void print( std::ostream &os, int indent = 0 );
+    
+private:
+    Expression *condition;
+    std::list<Statement *> branches; // should be list of CaseStmt
+};
+
+class FallthruStmt : public Statement {
+public:
+    FallthruStmt( std::list<Label> labels ) : Statement( labels ) { }
+
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+
+    virtual FallthruStmt *clone() const { return new FallthruStmt( *this ); }
+    virtual void print( std::ostream &os, int indent = 0 );
+};
+
+class CaseStmt : public Statement
+{
+public:
+    CaseStmt( std::list<Label> labels, Expression *conditions, 
+	    std::list<Statement *> &stmts, bool isdef = false ) throw(SemanticError);
+    virtual ~CaseStmt();
+
+    bool isDefault() { return _isDefault; }
+    void set_default(bool b) { _isDefault = b; }
+
+    Expression * &get_condition() { return condition; }
+    void set_condition( Expression *newValue ) { condition = newValue; }
+
+    std::list<Statement *> &get_statements() { return stmts; }
+    void set_statements( std::list<Statement *> &newValue ) { stmts = newValue; }
+    
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+
+    virtual CaseStmt *clone() const { return new CaseStmt( *this ); }
+    virtual void print( std::ostream &os, int indent = 0 );
+
+private:
+    Expression * condition;
+    std::list<Statement *> stmts;
+    bool _isDefault;
+};
+
+class WhileStmt : public Statement
+{
+public:
+    WhileStmt( std::list<Label> labels, Expression *condition,
+				    Statement *body, bool isDoWhile = false );
+    virtual ~WhileStmt();
+
+    Expression *get_condition() { return condition; }
+    void set_condition( Expression *newValue ) { condition = newValue; }
+    Statement *get_body() { return body; }
+    void set_body( Statement *newValue ) { body = newValue; }
+    bool get_isDoWhile() { return isDoWhile; }
+    void set_isDoWhile( bool newValue ) { isDoWhile = newValue; }
+    
+    virtual WhileStmt *clone() const { return new WhileStmt( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 );
+    
+private:
+    Expression *condition;
+    Statement *body;
+    bool isDoWhile;
+};
+
+class ForStmt : public Statement
+{
+public:
+    ForStmt( std::list<Label> labels, Statement *initialization = 0,
+	 Expression *condition = 0, Expression *increment = 0, Statement *body = 0 );
+    virtual ~ForStmt();
+
+    Statement *get_initialization() { return initialization; }
+    void set_initialization( Statement *newValue ) { initialization = newValue; }
+    Expression *get_condition() { return condition; }
+    void set_condition( Expression *newValue ) { condition = newValue; }
+    Expression *get_increment() { return increment; }
+    void set_increment( Expression *newValue ) { increment = newValue; }
+    Statement *get_body() { return body; }
+    void set_body( Statement *newValue ) { body = newValue; }
+    
+    virtual ForStmt *clone() const { return new ForStmt( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 );
+    
+private:
+    Statement *initialization;
+    Expression *condition;
+    Expression *increment;
+    Statement *body;
+};
+
+class BranchStmt : public Statement
+{
+public:
+
+    enum Type { Goto = 0 , Break, Continue };
+
+    BranchStmt( std::list<Label> labels, Label target, Type ) throw (SemanticError);
+    BranchStmt( std::list<Label> labels, Expression *computedTarget, Type ) throw (SemanticError);
+    virtual ~BranchStmt() {}
+
+    Label get_target() { return target; }
+    void set_target( Label newValue ) { target = newValue; }
+    
+    Expression *get_computedTarget() { return computedTarget; }
+    void set_target( Expression * newValue ) { computedTarget = newValue; }
+
+    Type get_type() { return type; }
+    const char *get_typename() { return brType[ type ]; }
+
+    virtual BranchStmt *clone() const { return new BranchStmt( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 );
+    
+private:
+    static const char *brType[];
+    Label target;
+    Expression *computedTarget;
+    Type type;
+};
+
+class ReturnStmt : public Statement
+{
+public:
+    ReturnStmt( std::list<Label> labels, Expression *expr, bool throwP = false );
+    virtual ~ReturnStmt();
+
+    Expression *get_expr() { return expr; }
+    void set_expr( Expression *newValue ) { expr = newValue; }
+    
+    virtual ReturnStmt *clone() const { return new ReturnStmt( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 );
+    
+private:
+    Expression *expr;
+    bool isThrow;
+};
+
+
+class NullStmt : public CompoundStmt
+{
+public:
+    NullStmt();
+    NullStmt( std::list<Label> labels );
+    virtual ~NullStmt();
+
+    virtual NullStmt *clone() const { return new NullStmt( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual NullStmt *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 );
+    
+private:
+};
+
+class TryStmt : public Statement
+{ 
+public:
+    TryStmt( std::list<Label> labels, CompoundStmt *tryBlock, std::list<Statement *> &handlers, FinallyStmt *finallyBlock = 0 );
+    TryStmt( const TryStmt &other );
+    virtual ~TryStmt();
+
+    CompoundStmt *get_block() const { return block; }
+    void set_block( CompoundStmt *newValue ) { block = newValue; }
+    std::list<Statement *>& get_catchers() { return handlers; }
+
+    FinallyStmt *get_finally() const { return finallyBlock; }
+    void set_finally( FinallyStmt *newValue ) { finallyBlock = newValue; }
+
+    virtual TryStmt *clone() const { return new TryStmt( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 );
+    
+private:
+    CompoundStmt *block;
+    std::list<Statement *> handlers;
+    FinallyStmt *finallyBlock;
+}; 
+
+class CatchStmt : public Statement
+{
+public:
+    CatchStmt( std::list<Label> labels, Declaration *decl, Statement *body, bool isCatchRest = false );
+    virtual ~CatchStmt();
+
+    Declaration *get_decl() { return decl; }
+    void set_decl( Declaration *newValue ) { decl = newValue; }
+
+    Statement *get_body() { return body; }
+    void set_body( Statement *newValue ) { body = newValue; }
+    
+    virtual CatchStmt *clone() const { return new CatchStmt( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 );
+    
+private:
+    Declaration *decl;
+    Statement *body;
+    bool catchRest;
+};
+
+class FinallyStmt : public Statement
+{ 
+public:
+    FinallyStmt( std::list<Label> labels, CompoundStmt *block );
+    virtual ~FinallyStmt();
+
+    CompoundStmt *get_block() const { return block; }
+    void set_block( CompoundStmt *newValue ) { block = newValue; }
+    
+    virtual FinallyStmt *clone() const { return new FinallyStmt( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 );
+    
+private:
+    CompoundStmt *block;
+}; 
+
+
+// represents a declaration that occurs as part of a compound statement
+class DeclStmt : public Statement
+{
+public:
+    DeclStmt( std::list<Label> labels, Declaration *decl );
+    DeclStmt( const DeclStmt &other );
+    virtual ~DeclStmt();
+
+    Declaration *get_decl() { return decl; }
+    void set_decl( Declaration *newValue ) { decl = newValue; }
+
+    virtual DeclStmt *clone() const { return new DeclStmt( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 );
+    
+private:
+    Declaration *decl;
+};
+
+
+
+#endif /* #ifndef STATEMENT_H */
+
+/*
+    Local Variables:
+    mode: c++
+    End:
+*/
Index: translator/SynTree/SynTree.h
===================================================================
--- translator/SynTree/SynTree.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/SynTree.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,107 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: SynTree.h,v 1.22 2005/08/29 20:59:26 rcbilson Exp $
+ *
+ * Forward declarations for syntax tree classes, so that they can be mutually
+ * interdependent
+ */
+
+#ifndef SYNTREE_H
+#define SYNTREE_H
+
+#include <string>
+#include <list>
+#include <map>
+#include <iostream>
+
+
+class Declaration;
+class DeclarationWithType;
+class ObjectDecl;
+class FunctionDecl;
+class AggregateDecl;
+class StructDecl;
+class UnionDecl;
+class EnumDecl;
+class ContextDecl;
+class NamedTypeDecl;
+class TypeDecl;
+class FtypeDecl;
+class DtypeDecl;
+class TypedefDecl;
+
+class Statement;
+class CompoundStmt;
+class ExprStmt;
+class IfStmt;
+class WhileStmt;
+class ForStmt;
+class SwitchStmt;
+class ChooseStmt;
+class FallthruStmt;
+class CaseStmt;
+class BranchStmt;
+class ReturnStmt;
+class TryStmt;
+class CatchStmt;
+class FinallyStmt;
+class NullStmt;
+class DeclStmt;
+class NullStmt;
+
+class Expression;
+class ApplicationExpr;
+class UntypedExpr;
+class NameExpr;
+class AddressExpr;
+class LabelAddressExpr;
+class CastExpr;
+class MemberExpr;
+class UntypedMemberExpr;
+class VariableExpr;
+class ConstantExpr;
+class SizeofExpr;
+class AttrExpr;
+class LogicalExpr;
+class ConditionalExpr;
+class CommaExpr;
+class TupleExpr;
+class SolvedTupleExpr;
+class TypeExpr;
+class UntypedValofExpr;
+
+class Type;
+class VoidType;
+class BasicType;
+class PointerType;
+class ArrayType;
+class FunctionType;
+class ReferenceToType;
+class StructInstType;
+class UnionInstType;
+class EnumInstType;
+class ContextInstType;
+class TypeInstType;
+class TupleType;
+class TypeofType;
+class AttrType;
+
+class Initializer;
+class MemberInit;
+class ElementInit;
+class SingleInit;
+class ListInit;
+
+class Subrange;
+
+//template <class T>	// emulate a union with templates?
+class Constant;
+
+typedef std::string Label;
+typedef unsigned int UniqueId;
+
+class TypeSubstitution;
+
+
+#endif /* #ifndef SYNTREE_H */
Index: translator/SynTree/TupleExpr.cc
===================================================================
--- translator/SynTree/TupleExpr.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/TupleExpr.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: TupleExpr.cc,v 1.11 2005/08/29 20:59:26 rcbilson Exp $
+ *
+ */
+
+#include "Expression.h"
+#include "utility.h"
+
+
+TupleExpr::TupleExpr( Expression *_aname ) : Expression( _aname )
+{
+}
+
+TupleExpr::TupleExpr( const TupleExpr &other )
+    : Expression( other )
+{
+    cloneAll( other.exprs, exprs );
+}
+
+TupleExpr::~TupleExpr()
+{
+    deleteAll( exprs );
+}
+
+void 
+TupleExpr::print( std::ostream &os, int indent ) const
+{
+    os << std::string( indent, ' ' ) << "Tuple:" << std::endl;
+    printAll( exprs, os, indent+2 );
+    Expression::print( os, indent );
+}
+
+SolvedTupleExpr::SolvedTupleExpr( std::list<Expression *> &_exprs, Expression *_aname )
+    :  Expression( _aname )
+{
+    std::copy(_exprs.begin(), _exprs.end(), back_inserter(exprs));
+}
+
+SolvedTupleExpr::SolvedTupleExpr( const SolvedTupleExpr &other )
+    : Expression( other )
+{
+    cloneAll( other.exprs, exprs );
+}
+
+void
+SolvedTupleExpr::print( std::ostream &os, int indent ) const
+{
+    os << std::string( indent, ' ' ) << "Solved Tuple:" << std::endl;
+    printAll( exprs, os, indent+2 );
+    Expression::print( os, indent );
+}
+
Index: translator/SynTree/TupleType.cc
===================================================================
--- translator/SynTree/TupleType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/TupleType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: TupleType.cc,v 1.6 2005/08/29 20:59:26 rcbilson Exp $
+ *
+ */
+
+#include "Type.h"
+#include "utility.h"
+
+
+TupleType::TupleType( const Type::Qualifiers &tq )
+    : Type( tq )
+{
+}
+
+TupleType::TupleType( const TupleType& other )
+    : Type( other )
+{
+    cloneAll( other.types, types );
+}
+
+TupleType::~TupleType()
+{
+    deleteAll( types );
+}
+
+void 
+TupleType::print( std::ostream &os, int indent ) const
+{
+    Type::print( os, indent );
+    os << "tuple of types" << std::endl;
+    printAll( types, os, indent+2 );
+}
+
Index: translator/SynTree/Type.cc
===================================================================
--- translator/SynTree/Type.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/Type.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,52 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Type.cc,v 1.6 2005/08/29 20:59:26 rcbilson Exp $
+ *
+ */
+
+#include "SynTree.h"
+#include "Visitor.h"
+#include "Type.h"
+#include "Declaration.h"
+#include "utility.h"
+
+
+Type::Type( const Qualifiers &tq )
+    : tq( tq )
+{
+}
+
+Type::Type( const Type &other )
+    : tq( other.tq )
+{
+    cloneAll( other.forall, forall );
+}
+
+Type::~Type()
+{
+    deleteAll( forall );
+}
+
+void
+Type::print( std::ostream &os, int indent ) const
+{
+    if( !forall.empty() ) {
+	os << "forall" << std::endl;
+	printAll( forall, os, indent + 4 );
+	os << std::string( indent+2, ' ' );
+    }
+    if( tq.isConst ) {
+	os << "const ";
+    }
+    if( tq.isVolatile ) {
+	os << "volatile ";
+    }
+    if( tq.isRestrict ) {
+	os << "restrict ";
+    }
+    if( tq.isLvalue ) {
+	os << "lvalue ";
+    }
+}
+
Index: translator/SynTree/Type.h
===================================================================
--- translator/SynTree/Type.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/Type.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,495 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Type.h,v 1.30 2005/08/29 20:59:26 rcbilson Exp $
+ *
+ */
+
+#ifndef TYPE_H
+#define TYPE_H
+
+#include "SynTree.h"
+#include "Visitor.h"
+#include "Mutator.h"
+
+
+class Type
+{
+public:
+    struct Qualifiers
+    {  
+	Qualifiers(): isConst( false ), isVolatile( false ), isRestrict( false ), isLvalue( false ) {}
+	Qualifiers( bool isConst, bool isVolatile, bool isRestrict, bool isLvalue ): isConst( isConst ), isVolatile( isVolatile ), isRestrict( isRestrict ), isLvalue( isLvalue ) {}
+	
+	Qualifiers &operator+=( const Qualifiers &other);
+	Qualifiers &operator-=( const Qualifiers &other);
+	Qualifiers operator+( const Type::Qualifiers &other );
+	bool operator==( const Qualifiers &other);
+	bool operator!=( const Qualifiers &other);
+	bool operator<=( const Qualifiers &other );
+	bool operator>=( const Qualifiers &other );
+	bool operator<( const Qualifiers &other );
+	bool operator>( const Qualifiers &other );
+	
+	bool isConst;
+	bool isVolatile;
+	bool isRestrict;
+	bool isLvalue;
+    };	
+
+    Type( const Qualifiers &tq );
+    Type( const Type &other );
+    virtual ~Type();
+
+    Qualifiers &get_qualifiers() { return tq; }
+    bool get_isConst() { return tq.isConst; }
+    bool get_isVolatile() { return tq.isVolatile; }
+    bool get_isRestrict() { return tq.isRestrict; }
+    bool get_isLvalue() { return tq.isLvalue; }
+    void set_isConst( bool newValue ) { tq.isConst = newValue; }
+    void set_iisVolatile( bool newValue ) { tq.isVolatile = newValue; }
+    void set_isRestrict( bool newValue ) { tq.isRestrict = newValue; }
+    void set_isLvalue( bool newValue ) { tq.isLvalue = newValue; }
+    std::list<TypeDecl*>& get_forall() { return forall; }
+
+    virtual Type *clone() const = 0;
+    virtual void accept( Visitor &v ) = 0;
+    virtual Type *acceptMutator( Mutator &m ) = 0;
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+
+private:
+    Qualifiers tq;
+    std::list<TypeDecl*> forall;
+};
+
+class VoidType : public Type
+{
+public:
+    VoidType( const Type::Qualifiers &tq );
+
+    virtual VoidType *clone() const { return new VoidType( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+};
+
+class BasicType : public Type
+{
+public:
+    enum Kind
+	{  
+	    Bool,
+	    Char,
+	    SignedChar,
+	    UnsignedChar,
+	    ShortSignedInt,
+	    ShortUnsignedInt,
+	    SignedInt,
+	    UnsignedInt,
+	    LongSignedInt,
+	    LongUnsignedInt,
+	    LongLongSignedInt,
+	    LongLongUnsignedInt,
+	    Float,
+	    Double,
+	    LongDouble,
+	    FloatComplex,
+	    DoubleComplex,
+	    LongDoubleComplex,
+	    FloatImaginary,
+	    DoubleImaginary,
+	    LongDoubleImaginary,
+	    NUMBER_OF_BASIC_TYPES
+	};  
+
+    BasicType( const Type::Qualifiers &tq, Kind bt );
+
+    Kind get_kind() { return kind; }
+    void set_kind( Kind newValue ) { kind = newValue; }
+
+    virtual BasicType *clone() const { return new BasicType( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+
+    bool isInteger() const;
+
+private:
+    Kind kind;
+};
+
+class PointerType : public Type
+{
+public:
+    PointerType( const Type::Qualifiers &tq, Type *base );
+    PointerType( const Type::Qualifiers &tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic );
+    PointerType( const PointerType& );
+    virtual ~PointerType();
+
+    Type *get_base() { return base; }
+    void set_base( Type *newValue ) { base = newValue; }
+    Expression *get_dimension() { return dimension; }
+    void set_dimension( Expression *newValue ) { dimension = newValue; }
+    bool get_isVarLen() { return isVarLen; }
+    void set_isVarLen( bool newValue ) { isVarLen = newValue; }
+    bool get_isStatic() { return isStatic; }
+    void set_isStatic( bool newValue ) { isStatic = newValue; }
+
+    virtual PointerType *clone() const { return new PointerType( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+
+private:
+    Type *base;
+    
+    // in C99, pointer types can be qualified in many ways
+    // e.g., int f( int a[ static 3 ] )
+    Expression *dimension;
+    bool isVarLen;
+    bool isStatic;
+};
+
+class ArrayType : public Type
+{
+public:
+    ArrayType( const Type::Qualifiers &tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic );
+    ArrayType( const ArrayType& );
+    virtual ~ArrayType();
+
+    Type *get_base() { return base; }
+    void set_base( Type *newValue ) { base = newValue; }
+    Expression *get_dimension() { return dimension; }
+    void set_dimension( Expression *newValue ) { dimension = newValue; }
+    bool get_isVarLen() { return isVarLen; }
+    void set_isVarLen( bool newValue ) { isVarLen = newValue; }
+    bool get_isStatic() { return isStatic; }
+    void set_isStatic( bool newValue ) { isStatic = newValue; }
+
+    virtual ArrayType *clone() const { return new ArrayType( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+
+private:
+    Type *base;
+    Expression *dimension;
+    bool isVarLen;
+    bool isStatic;
+};
+
+class FunctionType : public Type
+{
+public:
+    FunctionType( const Type::Qualifiers &tq, bool isVarArgs );
+    FunctionType( const FunctionType& );
+    virtual ~FunctionType();
+
+    std::list<DeclarationWithType*>& get_returnVals() { return returnVals; }
+    std::list<DeclarationWithType*>& get_parameters() { return parameters; }
+    bool get_isVarArgs() { return isVarArgs; }
+    void set_isVarArgs( bool newValue ) { isVarArgs = newValue; }
+
+    virtual FunctionType *clone() const { return new FunctionType( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+
+private:
+    std::list<DeclarationWithType*> returnVals;
+    std::list<DeclarationWithType*> parameters;
+
+    // does the function accept a variable number of arguments following the arguments
+    // specified in the parameters list.    This could be because of
+    // - an ellipsis in a prototype declaration
+    // - an unprototyped declaration
+    bool isVarArgs;
+};
+
+class ReferenceToType : public Type
+{
+public:
+    ReferenceToType( const Type::Qualifiers &tq, const std::string &name );
+    ReferenceToType( const ReferenceToType &other );
+    virtual ~ReferenceToType();
+
+    std::string get_name() const { return name; }
+    void set_name( std::string newValue ) { name = newValue; }
+    std::list< Expression* >& get_parameters() { return parameters; }
+    
+    virtual ReferenceToType *clone() const = 0;
+    virtual void accept( Visitor &v ) = 0;
+    virtual Type *acceptMutator( Mutator &m ) = 0;
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+
+protected:
+    virtual std::string typeString() const = 0;
+    std::list< Expression* > parameters;
+    
+private:
+    std::string name;
+    
+};
+
+class StructInstType : public ReferenceToType
+{
+    typedef ReferenceToType Parent;
+    
+public:
+    StructInstType( const Type::Qualifiers &tq, const std::string &name ) : Parent( tq, name ), baseStruct( 0 ) {}
+    StructInstType( const StructInstType &other ) : Parent( other ), baseStruct( other.baseStruct ) {}
+
+    StructDecl *get_baseStruct() const { return baseStruct; }
+    void set_baseStruct( StructDecl *newValue ) { baseStruct = newValue; }
+    
+    // a utility function
+    void lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const;
+
+    virtual StructInstType *clone() const { return new StructInstType( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+
+private:
+    virtual std::string typeString() const;
+    
+    // this decl is not "owned" by the struct inst; it is merely a pointer to elsewhere in the tree,
+    // where the structure used in this type is actually defined
+    StructDecl *baseStruct;
+};
+
+class UnionInstType : public ReferenceToType
+{
+    typedef ReferenceToType Parent;
+    
+public:
+    UnionInstType( const Type::Qualifiers &tq, const std::string &name ) : Parent( tq, name ), baseUnion( 0 ) {}
+    UnionInstType( const UnionInstType &other ) : Parent( other ), baseUnion( other.baseUnion ) {}
+
+    UnionDecl *get_baseUnion() const { return baseUnion; }
+    void set_baseUnion( UnionDecl *newValue ) { baseUnion = newValue; }
+    
+    // a utility function
+    void lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const;
+
+    virtual UnionInstType *clone() const { return new UnionInstType( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+
+private:
+    virtual std::string typeString() const;
+    
+    // this decl is not "owned" by the union inst; it is merely a pointer to elsewhere in the tree,
+    // where the union used in this type is actually defined
+    UnionDecl *baseUnion;
+};
+
+class EnumInstType : public ReferenceToType
+{
+    typedef ReferenceToType Parent;
+    
+public:
+    EnumInstType( const Type::Qualifiers &tq, const std::string &name ) : Parent( tq, name ) {}
+    EnumInstType( const EnumInstType &other ) : Parent( other ) {}
+
+    virtual EnumInstType *clone() const { return new EnumInstType( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+
+private:
+    virtual std::string typeString() const;
+};
+
+class ContextInstType : public ReferenceToType
+{
+    typedef ReferenceToType Parent;
+    
+public:
+    ContextInstType( const Type::Qualifiers &tq, const std::string &name ) : Parent( tq, name ) {}
+    ContextInstType( const ContextInstType &other );
+    ~ContextInstType();
+
+    std::list< Declaration* >& get_members() { return members; }
+
+    virtual ContextInstType *clone() const { return new ContextInstType( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+
+private:
+    virtual std::string typeString() const;
+    
+    // this member is filled in by the validate pass, which instantiates the members of the correponding
+    // aggregate with the actual type parameters specified for this use of the context
+    std::list< Declaration* > members;
+};
+
+class TypeInstType : public ReferenceToType
+{
+    typedef ReferenceToType Parent;
+    
+public:
+    TypeInstType( const Type::Qualifiers &tq, const std::string &name, TypeDecl *baseType );
+    TypeInstType( const Type::Qualifiers &tq, const std::string &name, bool isFtype );
+    TypeInstType( const TypeInstType &other ) : Parent( other ), baseType( other.baseType ), isFtype( other.isFtype ) {}
+
+    TypeDecl *get_baseType() const { return baseType; }
+    void set_baseType( TypeDecl *newValue );
+    bool get_isFtype() const { return isFtype; }
+    void set_isFtype( bool newValue ) { isFtype = newValue; }
+    
+    virtual TypeInstType *clone() const { return new TypeInstType( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+
+private:
+    virtual std::string typeString() const;
+    
+    // this decl is not "owned" by the type inst; it is merely a pointer to elsewhere in the tree,
+    // where the type used here is actually defined
+    TypeDecl *baseType;
+    bool isFtype;
+};
+
+class TupleType : public Type
+{
+public:
+    TupleType( const Type::Qualifiers &tq );
+    TupleType( const TupleType& );
+    virtual ~TupleType();
+
+    std::list<Type*>& get_types() { return types; }
+
+    virtual TupleType *clone() const { return new TupleType( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+
+private:
+    std::list<Type*> types;
+};
+
+class TypeofType : public Type
+{
+public:
+    TypeofType( const Type::Qualifiers &tq, Expression *expr );
+    TypeofType( const TypeofType& );
+    virtual ~TypeofType();
+
+    Expression *get_expr() const { return expr; }
+    void set_expr( Expression *newValue ) { expr = newValue; }
+
+    virtual TypeofType *clone() const { return new TypeofType( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+
+private:
+    Expression *expr;
+};
+
+class AttrType : public Type
+{
+public:
+    AttrType( const Type::Qualifiers &tq, const std::string &name, Expression *expr );
+    AttrType( const Type::Qualifiers &tq, const std::string &name, Type *type );
+    AttrType( const AttrType& );
+    virtual ~AttrType();
+
+    std::string get_name() const { return name; }
+    void set_name( const std::string &newValue ) { name = newValue; }
+    Expression *get_expr() const { return expr; }
+    void set_expr( Expression *newValue ) { expr = newValue; }
+    Type *get_type() const { return type; }
+    void set_type( Type *newValue ) { type = newValue; }
+    bool get_isType() const { return isType; }
+    void set_isType( bool newValue ) { isType = newValue; }
+
+    virtual AttrType *clone() const { return new AttrType( *this ); }
+    virtual void accept( Visitor &v ) { v.visit( this ); }
+    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+    virtual void print( std::ostream &os, int indent = 0 ) const;
+
+private:
+    std::string name;
+    Expression *expr;
+    Type *type;
+    bool isType;
+};
+
+inline Type::Qualifiers &
+Type::Qualifiers::operator+=( const Type::Qualifiers &other )
+{
+    isConst |= other.isConst;
+    isVolatile |= other.isVolatile;
+    isRestrict |= other.isRestrict;
+    isLvalue |= other.isLvalue;
+    return *this;
+}
+
+inline Type::Qualifiers &
+Type::Qualifiers::operator-=( const Type::Qualifiers &other )
+{
+    if( other.isConst ) isConst = 0;
+    if( other.isVolatile ) isVolatile = 0;
+    if( other.isRestrict ) isRestrict = 0;
+    return *this;
+}
+
+inline Type::Qualifiers
+Type::Qualifiers::operator+( const Type::Qualifiers &other )
+{
+    Qualifiers q = other;
+    q += *this;
+    return q;
+}
+
+inline bool 
+Type::Qualifiers::operator==( const Qualifiers &other)
+{
+    return isConst == other.isConst
+	&& isVolatile == other.isVolatile
+	&& isRestrict == other.isRestrict;
+///	    && isLvalue == other.isLvalue;
+}
+
+inline bool 
+Type::Qualifiers::operator!=( const Qualifiers &other)
+{
+    return isConst != other.isConst
+	|| isVolatile != other.isVolatile
+	|| isRestrict != other.isRestrict;
+///	    && isLvalue == other.isLvalue;
+}
+
+inline bool 
+Type::Qualifiers::operator<=( const Type::Qualifiers &other )
+{
+    return isConst <= other.isConst
+	&& isVolatile <= other.isVolatile
+	&& isRestrict <= other.isRestrict;
+///	    && isLvalue >= other.isLvalue;
+}
+
+inline bool 
+Type::Qualifiers::operator>=( const Type::Qualifiers &other )
+{
+    return isConst >= other.isConst
+	&& isVolatile >= other.isVolatile
+	&& isRestrict >= other.isRestrict;
+///	    && isLvalue <= other.isLvalue;
+}
+
+inline bool 
+Type::Qualifiers::operator<( const Type::Qualifiers &other )
+{
+    return operator!=( other ) && operator<=( other );
+}
+
+inline bool 
+Type::Qualifiers::operator>( const Type::Qualifiers &other )
+{
+    return operator!=( other ) && operator>=( other );
+}
+
+
+#endif /* #ifndef TYPE_H */
Index: translator/SynTree/TypeDecl.cc
===================================================================
--- translator/SynTree/TypeDecl.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/TypeDecl.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,22 @@
+#include "Declaration.h"
+#include "Type.h"
+#include "utility.h"
+
+
+TypeDecl::TypeDecl( const std::string &name, StorageClass sc, Type *type, Kind kind )
+    : Parent( name, sc, type ), kind( kind )
+{
+}
+
+TypeDecl::TypeDecl( const TypeDecl &other )
+    : Parent( other ), kind( other.kind )
+{
+}
+
+std::string
+TypeDecl::typeString() const
+{
+    static const char *kindNames[] = { "type", "incomplete type", "function type" };
+    return kindNames[ kind ];
+}
+
Index: translator/SynTree/TypeExpr.cc
===================================================================
--- translator/SynTree/TypeExpr.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/TypeExpr.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: TypeExpr.cc,v 1.4 2005/08/29 20:59:26 rcbilson Exp $
+ *
+ */
+
+#include "Expression.h"
+#include "Type.h"
+#include "utility.h"
+
+
+TypeExpr::TypeExpr( Type *type )
+    : type( type )
+{
+}
+
+TypeExpr::TypeExpr( const TypeExpr &other )
+    : type( maybeClone( other.type ) )
+{
+}
+
+TypeExpr::~TypeExpr()
+{
+    delete type;
+}
+
+void 
+TypeExpr::print( std::ostream &os, int indent ) const
+{
+    if( type ) type->print( os, indent );
+    Expression::print( os, indent );
+}
+
Index: translator/SynTree/TypeSubstitution.cc
===================================================================
--- translator/SynTree/TypeSubstitution.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/TypeSubstitution.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,232 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: TypeSubstitution.cc,v 1.9 2005/08/29 20:59:26 rcbilson Exp $
+ *
+ */
+
+#include "Type.h"
+#include "TypeSubstitution.h"
+
+
+TypeSubstitution::TypeSubstitution()
+{
+}
+
+TypeSubstitution::TypeSubstitution( const TypeSubstitution &other )
+{
+    initialize( other, *this );
+}
+
+TypeSubstitution::~TypeSubstitution()
+{
+    for( TypeEnvType::iterator i = typeEnv.begin(); i != typeEnv.end(); ++i ) {
+	delete( i->second );
+    }
+    for( VarEnvType::iterator i = varEnv.begin(); i != varEnv.end(); ++i ) {
+	delete( i->second );
+    }
+}
+
+TypeSubstitution &
+TypeSubstitution::operator=( const TypeSubstitution &other )
+{
+    if( this == &other ) return *this;
+    initialize( other, *this );
+    return *this;
+}
+
+void 
+TypeSubstitution::initialize( const TypeSubstitution &src, TypeSubstitution &dest )
+{
+    dest.typeEnv.clear();
+    dest.varEnv.clear();
+    dest.add( src );
+}
+
+void 
+TypeSubstitution::add( const TypeSubstitution &other )
+{
+    for( TypeEnvType::const_iterator i = other.typeEnv.begin(); i != other.typeEnv.end(); ++i ) {
+	typeEnv[ i->first ] = i->second->clone();
+    }
+    for( VarEnvType::const_iterator i = other.varEnv.begin(); i != other.varEnv.end(); ++i ) {
+	varEnv[ i->first ] = i->second->clone();
+    }
+}
+
+void 
+TypeSubstitution::add( std::string formalType, Type *actualType )
+{
+    TypeEnvType::iterator i = typeEnv.find( formalType );
+    if( i != typeEnv.end() ) {
+	delete i->second;
+    }
+    typeEnv[ formalType ] = actualType->clone();
+}
+
+void 
+TypeSubstitution::remove( std::string formalType )
+{
+    TypeEnvType::iterator i = typeEnv.find( formalType );
+    if( i != typeEnv.end() ) {
+	delete i->second;
+	typeEnv.erase( formalType );
+    }
+}
+
+Type *
+TypeSubstitution::lookup( std::string formalType ) const
+{
+    TypeEnvType::const_iterator i = typeEnv.find( formalType );
+    if( i == typeEnv.end() ) {
+	return 0;
+    } else {
+	return i->second;
+    }
+}
+
+bool 
+TypeSubstitution::empty() const
+{
+    return typeEnv.empty() && varEnv.empty();
+}
+
+void
+TypeSubstitution::normalize()
+{
+    do {
+	subCount = 0;
+	freeOnly = true;
+	for( TypeEnvType::iterator i = typeEnv.begin(); i != typeEnv.end(); ++i ) {
+	    i->second = i->second->acceptMutator( *this );
+	}
+    } while( subCount );
+}
+
+Type* 
+TypeSubstitution::mutate(TypeInstType *inst)
+{
+    BoundVarsType::const_iterator bound = boundVars.find( inst->get_name() );
+    if( bound != boundVars.end() ) return inst;
+    
+    TypeEnvType::const_iterator i = typeEnv.find( inst->get_name() );
+    if( i == typeEnv.end() ) {
+	return inst;
+    } else {
+///	    std::cout << "found " << inst->get_name() << ", replacing with ";
+///	    i->second->print( std::cout );
+///	    std::cout << std::endl;
+	subCount++;
+	Type *newtype = i->second->clone();
+	newtype->get_qualifiers() += inst->get_qualifiers();
+	delete inst;
+	return newtype;
+    }
+}
+
+Expression* 
+TypeSubstitution::mutate(NameExpr *nameExpr)
+{
+    VarEnvType::const_iterator i = varEnv.find( nameExpr->get_name() );
+    if( i == varEnv.end() ) {
+	return nameExpr;
+    } else {
+	subCount++;
+	delete nameExpr;
+	return i->second->clone();
+    }
+}
+
+template< typename TypeClass >
+Type *
+TypeSubstitution::handleType( TypeClass *type )
+{
+    BoundVarsType oldBoundVars( boundVars );
+    if( freeOnly ) {
+	for( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) {
+	    boundVars.insert( (*tyvar)->get_name() );
+	}
+    }
+    Type *ret = Mutator::mutate( type );
+    boundVars = oldBoundVars;
+    return ret;
+}
+
+Type* 
+TypeSubstitution::mutate(VoidType *basicType)
+{
+    return handleType( basicType );
+}
+
+Type* 
+TypeSubstitution::mutate(BasicType *basicType)
+{
+    return handleType( basicType );
+}
+
+Type* 
+TypeSubstitution::mutate(PointerType *pointerType)
+{
+    return handleType( pointerType );
+}
+
+Type* 
+TypeSubstitution::mutate(ArrayType *arrayType)
+{
+    return handleType( arrayType );
+}
+
+Type* 
+TypeSubstitution::mutate(FunctionType *functionType)
+{
+    return handleType( functionType );
+}
+
+Type* 
+TypeSubstitution::mutate(StructInstType *aggregateUseType)
+{
+    return handleType( aggregateUseType );
+}
+
+Type* 
+TypeSubstitution::mutate(UnionInstType *aggregateUseType)
+{
+    return handleType( aggregateUseType );
+}
+
+Type* 
+TypeSubstitution::mutate(EnumInstType *aggregateUseType)
+{
+    return handleType( aggregateUseType );
+}
+
+Type* 
+TypeSubstitution::mutate(ContextInstType *aggregateUseType)
+{
+    return handleType( aggregateUseType );
+}
+
+Type* 
+TypeSubstitution::mutate(TupleType *tupleType)
+{
+    return handleType( tupleType );
+}
+
+void 
+TypeSubstitution::print( std::ostream &os, int indent ) const
+{
+    os << std::string( indent, ' ' ) << "Types:" << std::endl;
+    for( TypeEnvType::const_iterator i = typeEnv.begin(); i != typeEnv.end(); ++i ) {
+	os << std::string( indent+2, ' ' ) << i->first << " -> ";
+	i->second->print( os, indent+4 );
+	os << std::endl;
+    }
+    os << std::string( indent, ' ' ) << "Non-types:" << std::endl;
+    for( VarEnvType::const_iterator i = varEnv.begin(); i != varEnv.end(); ++i ) {
+	os << std::string( indent+2, ' ' ) << i->first << " -> ";
+	i->second->print( os, indent+4 );
+	os << std::endl;
+    }
+}
+
Index: translator/SynTree/TypeSubstitution.h
===================================================================
--- translator/SynTree/TypeSubstitution.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/TypeSubstitution.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,180 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: TypeSubstitution.h,v 1.9 2005/08/29 20:59:26 rcbilson Exp $
+ *
+ */
+
+#ifndef SYNTREE_TYPESUBSTITUTION_H
+#define SYNTREE_TYPESUBSTITUTION_H
+
+#include <map>
+#include <set>
+#include <cassert>
+
+#include "SynTree/Mutator.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Expression.h"
+
+
+class TypeSubstitution : public Mutator
+{
+    typedef Mutator Parent;
+    
+public:
+    TypeSubstitution();
+    template< typename FormalIterator, typename ActualIterator >
+    TypeSubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin );
+    TypeSubstitution( const TypeSubstitution &other );
+    virtual ~TypeSubstitution();
+    
+    TypeSubstitution &operator=( const TypeSubstitution &other );
+    
+    template< typename SynTreeClass > int apply( SynTreeClass *&input );
+    template< typename SynTreeClass > int applyFree( SynTreeClass *&input );
+    
+    void add( std::string formalType, Type *actualType );
+    void add( const TypeSubstitution &other );
+    void remove( std::string formalType );
+    Type *lookup( std::string formalType ) const;
+    bool empty() const;
+    
+    template< typename FormalIterator, typename ActualIterator >
+    void add( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin );
+    
+    template< typename TypeInstListIterator >
+    void extract( TypeInstListIterator begin, TypeInstListIterator end, TypeSubstitution &result );
+    
+    void normalize();
+
+    void print( std::ostream &os, int indent = 0 ) const;
+    TypeSubstitution *clone() const { return new TypeSubstitution( *this ); }
+    
+private:
+    virtual Type* mutate(TypeInstType *aggregateUseType);
+    virtual Expression* mutate(NameExpr *nameExpr);
+    
+    template< typename TypeClass > Type *handleType( TypeClass *type );
+    
+    virtual Type* mutate(VoidType *basicType);
+    virtual Type* mutate(BasicType *basicType);
+    virtual Type* mutate(PointerType *pointerType);
+    virtual Type* mutate(ArrayType *arrayType);
+    virtual Type* mutate(FunctionType *functionType);
+    virtual Type* mutate(StructInstType *aggregateUseType);
+    virtual Type* mutate(UnionInstType *aggregateUseType);
+    virtual Type* mutate(EnumInstType *aggregateUseType);
+    virtual Type* mutate(ContextInstType *aggregateUseType);
+    virtual Type* mutate(TupleType *tupleType);
+    
+    // TODO: worry about traversing into a forall-qualified function type or type decl with assertions
+    
+    void initialize( const TypeSubstitution &src, TypeSubstitution &dest );
+
+    typedef std::map< std::string, Type* > TypeEnvType;
+    typedef std::map< std::string, Expression* > VarEnvType;
+    typedef std::set< std::string > BoundVarsType;
+    TypeEnvType typeEnv;
+    VarEnvType varEnv;
+    BoundVarsType boundVars;
+    int subCount;
+    bool freeOnly;
+};
+
+template< typename FormalIterator, typename ActualIterator >
+void 
+TypeSubstitution::add( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin )
+{
+    // FormalIterator points to a TypeDecl
+    // ActualIterator points to a Type
+    FormalIterator formalIt = formalBegin;
+    ActualIterator actualIt = actualBegin;
+    for( ; formalIt != formalEnd; ++formalIt, ++actualIt ) {
+	if( TypeDecl *formal = dynamic_cast< TypeDecl* >( *formalIt ) ) {
+	    if( TypeExpr *actual = dynamic_cast< TypeExpr* >( *actualIt ) ) {
+		if( formal->get_name() != "" ) {
+		    TypeEnvType::iterator i = typeEnv.find( formal->get_name() );
+		    if( i != typeEnv.end() ) {
+			delete i->second;
+		    }
+		    typeEnv[ formal->get_name() ] = actual->get_type()->clone();
+		}
+	    } else {
+		throw SemanticError( "Attempt to provide non-type parameter for type parameter", formal );
+	    }
+	} else {
+	    // TODO: type check the formal and actual parameters
+	    if( (*formalIt)->get_name() != "" ) {
+		varEnv[ (*formalIt)->get_name() ] = (*actualIt)->clone();
+	    }
+	}
+    }
+}
+
+template< typename FormalIterator, typename ActualIterator >
+TypeSubstitution::TypeSubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin )
+{
+    add( formalBegin, formalEnd, actualBegin );
+}
+
+template< typename SynTreeClass >
+int
+TypeSubstitution::apply( SynTreeClass *&input )
+{
+    assert( input );
+    subCount = 0;
+    freeOnly = false;
+    input = dynamic_cast< SynTreeClass *>( input->acceptMutator( *this ) );
+    assert( input );
+///	std::cout << "substitution result is: ";
+///	newType->print( std::cout );
+///	std::cout << std::endl;
+    return subCount;
+}
+    
+template< typename SynTreeClass >
+int
+TypeSubstitution::applyFree( SynTreeClass *&input )
+{
+    assert( input );
+    subCount = 0;
+    freeOnly = true;
+    input = dynamic_cast< SynTreeClass *>( input->acceptMutator( *this ) );
+    assert( input );
+///	std::cout << "substitution result is: ";
+///	newType->print( std::cout );
+///	std::cout << std::endl;
+    return subCount;
+}
+    
+template< typename TypeInstListIterator >
+void
+TypeSubstitution::extract( TypeInstListIterator begin, TypeInstListIterator end, TypeSubstitution &result )
+{
+    while( begin != end ) {
+	TypeEnvType::iterator cur = typeEnv.find( (*begin++)->get_name() );
+	if( cur != typeEnv.end() ) {
+	    result.typeEnv[ cur->first ] = cur->second;
+	    typeEnv.erase( cur );
+	}
+    }
+}
+
+// helper function
+template< typename FormalIterator, typename ActualIterator, typename MemberIterator, typename OutputIterator >
+void
+applySubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actual, MemberIterator memberBegin, MemberIterator memberEnd, OutputIterator out )
+{
+    // Instantiate each member of the context given the actual parameters specified, and store the
+    // instantiations for use by the indexer
+
+    TypeSubstitution sub = TypeSubstitution( formalBegin, formalEnd, actual );
+    for( std::list< Declaration* >::iterator i = memberBegin; i != memberEnd; ++i ) {
+	Declaration *newdecl = (*i)->clone();
+	sub.apply( newdecl );
+	*out++ = newdecl;
+    }
+}
+
+
+#endif /* #ifndef SYNTREE_TYPESUBSTITUTION_H */
Index: translator/SynTree/TypeofType.cc
===================================================================
--- translator/SynTree/TypeofType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/TypeofType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: TypeofType.cc,v 1.3 2005/08/29 20:59:27 rcbilson Exp $
+ *
+ */
+
+#include "Type.h"
+#include "Expression.h"
+#include "utility.h"
+
+
+TypeofType::TypeofType( const Type::Qualifiers &tq, Expression *expr )
+    : Type( tq ), expr( expr )
+{
+}
+
+TypeofType::TypeofType( const TypeofType &other )
+    : Type( other ), expr( maybeClone( other.expr ) )
+{
+}
+
+TypeofType::~TypeofType()
+{
+    delete expr;
+}
+
+void 
+TypeofType::print( std::ostream &os, int indent ) const
+{
+    Type::print( os, indent );
+    os << "type-of expression ";
+    if( expr ) {
+	expr->print( os, indent );
+    }
+}
+
Index: translator/SynTree/Visitor.cc
===================================================================
--- translator/SynTree/Visitor.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/Visitor.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,473 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Visitor.cc,v 1.30 2005/08/29 20:59:27 rcbilson Exp $
+ *
+ */
+
+#include <cassert>
+#include "Visitor.h"
+#include "Initializer.h"
+#include "Statement.h"
+#include "Type.h"
+#include "Declaration.h"
+#include "Expression.h"
+#include "Constant.h"
+
+
+Visitor::Visitor()
+{
+}
+
+Visitor::~Visitor()
+{
+}
+
+void
+Visitor::visit(ObjectDecl *objectDecl)
+{
+    maybeAccept( objectDecl->get_type(), *this );
+    maybeAccept( objectDecl->get_init(), *this );
+    maybeAccept( objectDecl->get_bitfieldWidth(), *this );
+}
+
+void
+Visitor::visit(FunctionDecl *functionDecl)
+{
+    maybeAccept( functionDecl->get_functionType(), *this );
+    acceptAll( functionDecl->get_oldDecls(), *this );
+    maybeAccept( functionDecl->get_statements(), *this );
+}
+
+void
+Visitor::visit(AggregateDecl *aggregateDecl)
+{
+    acceptAll( aggregateDecl->get_parameters(), *this );
+    acceptAll( aggregateDecl->get_members(), *this );
+}
+
+void 
+Visitor::visit(StructDecl *aggregateDecl)
+{
+    visit( static_cast< AggregateDecl* >( aggregateDecl ) );
+}
+
+void 
+Visitor::visit(UnionDecl *aggregateDecl)
+{
+    visit( static_cast< AggregateDecl* >( aggregateDecl ) );
+}
+
+void 
+Visitor::visit(EnumDecl *aggregateDecl)
+{
+    visit( static_cast< AggregateDecl* >( aggregateDecl ) );
+}
+
+void 
+Visitor::visit(ContextDecl *aggregateDecl)
+{
+    visit( static_cast< AggregateDecl* >( aggregateDecl ) );
+}
+
+void
+Visitor::visit(NamedTypeDecl *typeDecl)
+{
+    acceptAll( typeDecl->get_parameters(), *this );
+    acceptAll( typeDecl->get_assertions(), *this );
+    maybeAccept( typeDecl->get_base(), *this );
+}
+
+void 
+Visitor::visit(TypeDecl *typeDecl)
+{
+    visit( static_cast< NamedTypeDecl* >( typeDecl ) );
+}
+
+void 
+Visitor::visit(TypedefDecl *typeDecl)
+{
+    visit( static_cast< NamedTypeDecl* >( typeDecl ) );
+}
+
+void
+Visitor::visit(CompoundStmt *compoundStmt)
+{
+    acceptAll( compoundStmt->get_kids(), *this );
+}
+
+void
+Visitor::visit(ExprStmt *exprStmt)
+{
+    maybeAccept( exprStmt->get_expr(), *this );
+}
+
+void
+Visitor::visit(IfStmt *ifStmt)
+{
+    maybeAccept( ifStmt->get_condition(), *this );
+    maybeAccept( ifStmt->get_thenPart(), *this );
+    maybeAccept( ifStmt->get_elsePart(), *this );
+}
+
+void
+Visitor::visit(WhileStmt *whileStmt)
+{
+    maybeAccept( whileStmt->get_condition(), *this );
+    maybeAccept( whileStmt->get_body(), *this );
+}
+
+void
+Visitor::visit(ForStmt *forStmt)
+{
+    // ForStmt still needs to be fixed
+    maybeAccept( forStmt->get_initialization(), *this );
+    maybeAccept( forStmt->get_condition(), *this );
+    maybeAccept( forStmt->get_increment(), *this );
+    maybeAccept( forStmt->get_body(), *this );
+}
+
+void
+Visitor::visit(SwitchStmt *switchStmt)
+{
+    maybeAccept( switchStmt->get_condition(), *this );
+    acceptAll( switchStmt->get_branches(), *this );
+}
+
+void
+Visitor::visit(ChooseStmt *switchStmt)
+{
+    maybeAccept( switchStmt->get_condition(), *this );
+    acceptAll( switchStmt->get_branches(), *this );
+}
+
+void
+Visitor::visit(FallthruStmt *fallthruStmt){}
+
+void
+Visitor::visit(CaseStmt *caseStmt)
+{
+    maybeAccept( caseStmt->get_condition(), *this );
+    acceptAll( caseStmt->get_statements(), *this );
+}
+
+void
+Visitor::visit(BranchStmt *branchStmt)
+{
+}
+
+void
+Visitor::visit(ReturnStmt *returnStmt)
+{
+    maybeAccept( returnStmt->get_expr(), *this );
+}
+
+void
+Visitor::visit(TryStmt *tryStmt)
+{
+    maybeAccept( tryStmt->get_block(), *this );
+    acceptAll( tryStmt->get_catchers(), *this );
+}
+
+void
+Visitor::visit(CatchStmt *catchStmt)
+{
+    maybeAccept( catchStmt->get_decl(), *this );
+    maybeAccept( catchStmt->get_body(), *this );
+}
+
+void
+Visitor::visit(FinallyStmt *finalStmt)
+{
+    maybeAccept( finalStmt->get_block(), *this );
+}
+
+void
+Visitor::visit(NullStmt *nullStmt)
+{
+}
+
+void
+Visitor::visit(DeclStmt *declStmt)
+{
+    maybeAccept( declStmt->get_decl(), *this );
+}
+
+void
+Visitor::visit(ApplicationExpr *applicationExpr)
+{
+    acceptAll( applicationExpr->get_results(), *this );
+    maybeAccept( applicationExpr->get_function(), *this );
+    acceptAll( applicationExpr->get_args(), *this );
+}
+
+void
+Visitor::visit(UntypedExpr *untypedExpr)
+{
+    acceptAll( untypedExpr->get_results(), *this );
+    acceptAll( untypedExpr->get_args(), *this );
+}
+
+void
+Visitor::visit(NameExpr *nameExpr)
+{
+    acceptAll( nameExpr->get_results(), *this );
+}
+
+void
+Visitor::visit(AddressExpr *addressExpr)
+{
+    acceptAll( addressExpr->get_results(), *this );
+    maybeAccept( addressExpr->get_arg(), *this );
+}
+
+void
+Visitor::visit(LabelAddressExpr *labAddressExpr)
+{
+    acceptAll( labAddressExpr->get_results(), *this );
+    maybeAccept( labAddressExpr->get_arg(), *this );
+}
+
+void
+Visitor::visit(CastExpr *castExpr)
+{
+    acceptAll( castExpr->get_results(), *this );
+    maybeAccept( castExpr->get_arg(), *this );
+}
+
+void
+Visitor::visit(UntypedMemberExpr *memberExpr)
+{
+    acceptAll( memberExpr->get_results(), *this );
+    maybeAccept( memberExpr->get_aggregate(), *this );
+}
+
+void
+Visitor::visit(MemberExpr *memberExpr)
+{
+    acceptAll( memberExpr->get_results(), *this );
+    maybeAccept( memberExpr->get_aggregate(), *this );
+}
+
+void
+Visitor::visit(VariableExpr *variableExpr)
+{
+    acceptAll( variableExpr->get_results(), *this );
+}
+
+void
+Visitor::visit(ConstantExpr *constantExpr)
+{
+    acceptAll( constantExpr->get_results(), *this );
+    maybeAccept( constantExpr->get_constant(), *this );
+}
+
+void
+Visitor::visit(SizeofExpr *sizeofExpr)
+{
+    acceptAll( sizeofExpr->get_results(), *this );
+    if( sizeofExpr->get_isType() ) {
+	maybeAccept( sizeofExpr->get_type(), *this );
+    } else {
+	maybeAccept( sizeofExpr->get_expr(), *this );
+    }
+}
+
+void
+Visitor::visit(AttrExpr *attrExpr)
+{
+    acceptAll( attrExpr->get_results(), *this );
+    if( attrExpr->get_isType() ) {
+	maybeAccept( attrExpr->get_type(), *this );
+    } else {
+	maybeAccept( attrExpr->get_expr(), *this );
+    }
+}
+
+void
+Visitor::visit(LogicalExpr *logicalExpr)
+{
+    acceptAll( logicalExpr->get_results(), *this );
+    maybeAccept( logicalExpr->get_arg1(), *this );
+    maybeAccept( logicalExpr->get_arg2(), *this );
+}
+
+void
+Visitor::visit(ConditionalExpr *conditionalExpr)
+{
+    acceptAll( conditionalExpr->get_results(), *this );
+    maybeAccept( conditionalExpr->get_arg1(), *this );
+    maybeAccept( conditionalExpr->get_arg2(), *this );
+    maybeAccept( conditionalExpr->get_arg3(), *this );
+}
+
+void
+Visitor::visit(CommaExpr *commaExpr)
+{
+    acceptAll( commaExpr->get_results(), *this );
+    maybeAccept( commaExpr->get_arg1(), *this );
+    maybeAccept( commaExpr->get_arg2(), *this );
+}
+
+void
+Visitor::visit(TupleExpr *tupleExpr)
+{
+    acceptAll( tupleExpr->get_results(), *this );
+    acceptAll( tupleExpr->get_exprs(), *this );
+}
+
+void
+Visitor::visit(SolvedTupleExpr *tupleExpr)
+{
+    acceptAll( tupleExpr->get_results(), *this );
+    acceptAll( tupleExpr->get_exprs(), *this );
+}
+
+void
+Visitor::visit(TypeExpr *typeExpr)
+{
+    acceptAll( typeExpr->get_results(), *this );
+    maybeAccept( typeExpr->get_type(), *this );
+}
+
+void
+Visitor::visit(UntypedValofExpr *valofExpr)
+{
+    acceptAll( valofExpr->get_results(), *this );
+    maybeAccept( valofExpr->get_body(), *this );
+}
+
+void
+Visitor::visit(VoidType *voidType)
+{
+    acceptAll( voidType->get_forall(), *this );
+}
+
+void
+Visitor::visit(BasicType *basicType)
+{
+    acceptAll( basicType->get_forall(), *this );
+}
+
+void
+Visitor::visit(PointerType *pointerType)
+{
+    acceptAll( pointerType->get_forall(), *this );
+    maybeAccept( pointerType->get_base(), *this );
+}
+
+void
+Visitor::visit(ArrayType *arrayType)
+{
+    acceptAll( arrayType->get_forall(), *this );
+    maybeAccept( arrayType->get_dimension(), *this );
+    maybeAccept( arrayType->get_base(), *this );
+}
+
+void
+Visitor::visit(FunctionType *functionType)
+{
+    acceptAll( functionType->get_forall(), *this );
+    acceptAll( functionType->get_returnVals(), *this );
+    acceptAll( functionType->get_parameters(), *this );
+}
+
+void
+Visitor::visit(ReferenceToType *aggregateUseType)
+{
+    acceptAll( aggregateUseType->get_forall(), *this );
+    acceptAll( aggregateUseType->get_parameters(), *this );
+}
+
+void 
+Visitor::visit(StructInstType *aggregateUseType)
+{
+    visit( static_cast< ReferenceToType* >( aggregateUseType ) );
+}
+
+void 
+Visitor::visit(UnionInstType *aggregateUseType)
+{
+    visit( static_cast< ReferenceToType* >( aggregateUseType ) );
+}
+
+void 
+Visitor::visit(EnumInstType *aggregateUseType)
+{
+    visit( static_cast< ReferenceToType* >( aggregateUseType ) );
+}
+
+void 
+Visitor::visit(ContextInstType *aggregateUseType)
+{
+    visit( static_cast< ReferenceToType* >( aggregateUseType ) );
+    acceptAll( aggregateUseType->get_members(), *this );
+}
+
+void 
+Visitor::visit(TypeInstType *aggregateUseType)
+{
+    visit( static_cast< ReferenceToType* >( aggregateUseType ) );
+}
+
+void
+Visitor::visit(TupleType *tupleType)
+{
+    acceptAll( tupleType->get_forall(), *this );
+    acceptAll( tupleType->get_types(), *this );
+}
+
+void
+Visitor::visit(TypeofType *typeofType)
+{
+    assert( typeofType->get_expr() );
+    typeofType->get_expr()->accept( *this );
+}
+
+void
+Visitor::visit(AttrType *attrType)
+{
+    if( attrType->get_isType() ) {
+	assert( attrType->get_type() );
+	attrType->get_type()->accept( *this );
+    } else {
+	assert( attrType->get_expr() );
+	attrType->get_expr()->accept( *this );
+    }
+}
+
+void
+Visitor::visit(MemberInit *memberInit)
+{
+    memberInit->get_value()->accept( *this );
+}
+
+void
+Visitor::visit(ElementInit *elementInit)
+{
+    elementInit->get_value()->accept( *this );
+}
+
+void
+Visitor::visit(SingleInit *singleInit)
+{
+    singleInit->get_value()->accept( *this );
+}
+
+void
+Visitor::visit(ListInit *listInit)
+{
+    acceptAll( listInit->get_designators(), *this );
+    acceptAll( listInit->get_initializers(), *this );
+}
+
+void
+Visitor::visit(Subrange *subrange)
+{
+}
+
+void
+Visitor::visit(Constant *constant)
+{
+}
+
Index: translator/SynTree/Visitor.h
===================================================================
--- translator/SynTree/Visitor.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/Visitor.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,162 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Visitor.h,v 1.23 2005/08/29 20:59:27 rcbilson Exp $
+ *
+ */
+
+#ifndef VISITOR_H
+#define VISITOR_H
+
+#include "SynTree.h"
+#include "SemanticError.h"
+#include "CompilerError.h"
+
+
+class Visitor
+{
+protected:
+    Visitor();
+    virtual ~Visitor();
+
+public:
+    virtual void visit(ObjectDecl *objectDecl);
+    virtual void visit(FunctionDecl *functionDecl);
+    virtual void visit(StructDecl *aggregateDecl);
+    virtual void visit(UnionDecl *aggregateDecl);
+    virtual void visit(EnumDecl *aggregateDecl);
+    virtual void visit(ContextDecl *aggregateDecl);
+    virtual void visit(TypeDecl *typeDecl);
+    virtual void visit(TypedefDecl *typeDecl);
+
+    virtual void visit(CompoundStmt *compoundStmt);
+    virtual void visit(ExprStmt *exprStmt);
+    virtual void visit(IfStmt *ifStmt);
+    virtual void visit(WhileStmt *whileStmt);
+    virtual void visit(ForStmt *forStmt);
+    virtual void visit(SwitchStmt *switchStmt);
+    virtual void visit(ChooseStmt *switchStmt);
+    virtual void visit(FallthruStmt *switchStmt);
+    virtual void visit(CaseStmt *caseStmt);
+    virtual void visit(BranchStmt *branchStmt);
+    virtual void visit(ReturnStmt *returnStmt);
+    virtual void visit(TryStmt *tryStmt);
+    virtual void visit(CatchStmt *catchStmt);
+    virtual void visit(FinallyStmt *finallyStmt);
+    virtual void visit(NullStmt *nullStmt);
+    virtual void visit(DeclStmt *declStmt);
+
+    virtual void visit(ApplicationExpr *applicationExpr);
+    virtual void visit(UntypedExpr *untypedExpr);
+    virtual void visit(NameExpr *nameExpr);
+    virtual void visit(CastExpr *castExpr);
+    virtual void visit(AddressExpr *addressExpr);
+    virtual void visit(LabelAddressExpr *labAddressExpr);
+    virtual void visit(UntypedMemberExpr *memberExpr);
+    virtual void visit(MemberExpr *memberExpr);
+    virtual void visit(VariableExpr *variableExpr);
+    virtual void visit(ConstantExpr *constantExpr); 
+    virtual void visit(SizeofExpr *sizeofExpr);
+    virtual void visit(AttrExpr *attrExpr);
+    virtual void visit(LogicalExpr *logicalExpr);
+    virtual void visit(ConditionalExpr *conditionalExpr);
+    virtual void visit(CommaExpr *commaExpr);
+    virtual void visit(TupleExpr *tupleExpr);
+    virtual void visit(SolvedTupleExpr *tupleExpr);
+    virtual void visit(TypeExpr *typeExpr);
+    virtual void visit(UntypedValofExpr *valofExpr);
+
+    virtual void visit(VoidType *basicType);
+    virtual void visit(BasicType *basicType);
+    virtual void visit(PointerType *pointerType);
+    virtual void visit(ArrayType *arrayType);
+    virtual void visit(FunctionType *functionType);
+    virtual void visit(StructInstType *aggregateUseType);
+    virtual void visit(UnionInstType *aggregateUseType);
+    virtual void visit(EnumInstType *aggregateUseType);
+    virtual void visit(ContextInstType *aggregateUseType);
+    virtual void visit(TypeInstType *aggregateUseType);
+    virtual void visit(TupleType *tupleType);
+    virtual void visit(TypeofType *typeofType);
+    virtual void visit(AttrType *attrType);
+
+    virtual void visit(MemberInit *memberInit);
+    virtual void visit(ElementInit *elementInit);
+    virtual void visit(SingleInit *singleInit);
+    virtual void visit(ListInit *listInit);
+
+    virtual void visit(Subrange *subrange);
+
+    virtual void visit(Constant *constant);
+
+private:
+    virtual void visit(AggregateDecl *aggregateDecl);
+    virtual void visit(NamedTypeDecl *typeDecl);
+    virtual void visit(ReferenceToType *aggregateUseType);
+};
+
+template< typename TreeType, typename VisitorType >
+inline void
+maybeAccept( TreeType *tree, VisitorType &visitor )
+{
+    if( tree ) {
+	tree->accept( visitor );
+    }
+}
+
+template< typename Container, typename VisitorType >
+inline void
+acceptAll( Container &container, VisitorType &visitor )
+{
+    SemanticError errors;
+    for( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
+	try {
+	    if( *i ) {
+		(*i)->accept( visitor );
+	    }
+	} catch( SemanticError &e ) {
+	    errors.append( e );
+	}
+    }
+    if( !errors.isEmpty() ) {
+	throw errors;
+    }
+}
+
+template< typename Container, typename VisitorType >
+void
+acceptAllFold( Container &container, VisitorType &visitor, VisitorType &around )
+{
+    SemanticError errors;
+    for( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
+	try {
+	    if( *i ) {
+    VisitorType *v = new VisitorType;
+		(*i)->accept( *v );
+
+    typename Container::iterator nxt = i; nxt++; // forward_iterator
+    if( nxt == container.end() )
+	visitor += *v;
+    else
+	visitor += *v + around;
+
+    delete v;
+	    }
+	} catch( SemanticError &e ) {
+	    errors.append( e );
+	}
+    }
+    if( !errors.isEmpty() ) {
+	throw errors;
+    }
+}
+
+
+#endif /* #ifndef VISITOR_H */
+
+
+/*
+    Local Variables:
+    mode: c++
+    End:
+*/
Index: translator/SynTree/VoidType.cc
===================================================================
--- translator/SynTree/VoidType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/VoidType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,22 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: VoidType.cc,v 1.3 2005/08/29 20:59:27 rcbilson Exp $
+ *
+ */
+
+#include "Type.h"
+
+
+VoidType::VoidType( const Type::Qualifiers &tq )
+    : Type( tq )
+{
+}
+
+void
+VoidType::print( std::ostream &os, int indent ) const
+{
+    Type::print( os, indent );
+    os << "void ";
+}
+
Index: translator/SynTree/module.mk
===================================================================
--- translator/SynTree/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,34 @@
+SRC += SynTree/Type.cc \
+       SynTree/VoidType.cc \
+       SynTree/BasicType.cc \
+       SynTree/PointerType.cc \
+       SynTree/ArrayType.cc \
+       SynTree/FunctionType.cc \
+       SynTree/ReferenceToType.cc \
+       SynTree/TupleType.cc \
+       SynTree/TypeofType.cc \
+       SynTree/AttrType.cc \
+       SynTree/Constant.cc \
+       SynTree/Expression.cc \
+       SynTree/TupleExpr.cc \
+       SynTree/CommaExpr.cc \
+       SynTree/TypeExpr.cc \
+       SynTree/ApplicationExpr.cc \
+       SynTree/AddressExpr.cc \
+       SynTree/Statement.cc \
+       SynTree/CompoundStmt.cc \
+       SynTree/DeclStmt.cc \
+       SynTree/Declaration.cc \
+       SynTree/DeclarationWithType.cc \
+       SynTree/ObjectDecl.cc \
+       SynTree/FunctionDecl.cc \
+       SynTree/AggregateDecl.cc \
+       SynTree/NamedTypeDecl.cc \
+       SynTree/TypeDecl.cc \
+       SynTree/Initializer.cc \
+       SynTree/Visitor.cc \
+       SynTree/Mutator.cc \
+       SynTree/CodeGenVisitor.cc \
+       SynTree/TypeSubstitution.cc \
+	$(NULL)
+
Index: translator/SynTree/translate.cc
===================================================================
--- translator/SynTree/translate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/translate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,158 @@
+#include "translate.h"
+#include "../Parser/ParseNode.h"
+
+
+#include "Statement.h"
+#include "Expression.h"
+#include "Constant.h"
+#include "Type.h"
+
+int translate_driver(ParseNode *pn){
+    // in effect, this function is a visitor of sorts
+
+    if (pn == 0)
+	exit(1);
+
+    /* Type switching considered harmful */
+
+    switch(pn->what_kind()){
+    case ParseNode::Statement:
+	translate((StatementNode *)pn);
+	break;
+    case ParseNode::Expression:
+	translate((ExpressionNode *)pn);
+	break;
+    default:
+	translate(pn);
+	break;
+    }
+
+    return 0;
+}
+
+Expression *translate(ExpressionNode *en){
+    Expression *expr;
+
+    switch(en->what_kind()){
+    case ParseNode::CompositeExpression:
+	break;
+    case ParseNode::Constant:
+	expr = translate((ConstantNode *)en);
+	break;
+    case ParseNode::VarRef:
+	cout << "It's a varref" << endl;
+	break;
+    case ParseNode::Operator:
+	cout << "It's an operator" << endl;
+	break;
+    default:
+	break;
+    }
+
+    return expr;
+}
+
+Statement *translate(StatementNode *sn){
+    Statement *stmt = 0;
+
+    switch(sn->get_type()){
+    case StatementNode::Exp:
+	translate(sn->get_control());
+	break;
+    case StatementNode::If:
+	cout << "if" << endl;
+	translate(sn->get_control());
+	break;
+    case StatementNode::Switch:
+	cout << "switch" << endl;
+	break;
+    case StatementNode::Case:
+	cout << "case" << endl;
+	break;
+    case StatementNode::Default:
+	cout << "default" << endl;
+	break;
+    case StatementNode::Choose:
+	cout << "choose" << endl;
+	break;
+    case StatementNode::Fallthru:
+	cout << "fallthru" << endl;
+	break;
+    case StatementNode::While:
+	cout << "while" << endl;
+	break;
+    case StatementNode::Do:
+	cout << "do" << endl;
+	break;
+    case StatementNode::For:
+	cout << "for" << endl;
+	break;
+    case StatementNode::Goto:
+	cout << "goto" << endl;
+	break;
+    case StatementNode::Continue:
+	cout << "continue" << endl;
+	break;
+    case StatementNode::Break:
+	cout << "break" << endl;
+	break;
+    case StatementNode::Return:
+	cout << "return" << endl;
+	break;
+    case StatementNode::Throw:
+	cout << "throw" << endl;
+	break;
+    case StatementNode::Try:
+	cout << "try" << endl;
+	break;
+    case StatementNode::Catch:
+	cout << "catch" << endl;
+	break;
+    case StatementNode::Asm:
+	cout << "asm" << endl;
+	break;
+    default:
+	break;
+    }
+
+    return stmt;
+}
+
+ConstantExpr *translate(ConstantNode *cn){
+    ConstantExpr *cnst;
+    BasicType::Kind knd;
+
+    struct Type::Qualifiers tq = {0,0,0};
+    struct BasicType::Modifiers tm = {0,0,0,0};
+
+    switch(cn->get_type()){
+    case ConstantNode::Integer:
+	knd = BasicType::Int;
+	break;
+    case ConstantNode::Float:
+	knd = BasicType::Float;
+	break;
+    case ConstantNode::Character:
+	knd = BasicType::Char;
+	break;
+    case ConstantNode::String:
+	break;
+    default:
+	break;
+    }
+
+    Constant *c = new Constant(new BasicType(tq,tm,knd), cn->get_name());
+    cnst = new ConstantExpr(*c);
+
+    return cnst;
+}
+
+Expression *translate(CompositeExprNode *ce){
+    return 0;
+}
+
+int translate(ParseNode *pn){
+    cout << "In translate - parsenode" << endl;
+
+    return 0;
+}
Index: translator/SynTree/translate.h
===================================================================
--- translator/SynTree/translate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SynTree/translate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,14 @@
+#ifndef __TRANSLATE_H_
+#define __TRANSLATE_H_
+
+#include "SynTree.h"
+#include "../Parser/ParseNode.h"
+
+int translate_driver(ParseNode *);
+int translate(ParseNode *);
+Expression *translate(ExpressionNode *);
+Expression *translate(CompositeExprNode *);
+ConstantExpr *translate(ConstantNode *);
+Statement *translate(StatementNode *);
+
+#endif	/* #define __TRANSLATE_H_ */
Index: translator/Tests/Parser/Array.c
===================================================================
--- translator/Tests/Parser/Array.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Array.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,33 @@
+int a1[];
+int a2[*];
+int a4[3];
+
+int m1[][3];
+int m2[*][*];
+int m4[3][3];
+
+typedef int T;
+
+int fred() {
+    int a1[];
+    int a2[*];
+    int a4[3];
+    int T[3];
+}
+
+int mary( int T[3],
+	  int p1[const 3],
+	  int p2[static 3],
+	  int p3[static const 3]
+    ) {
+}
+
+int (*tom())[3] {
+}
+
+int (*(jane)())( int T[3],
+		 int p1[const 3],
+		 int p2[static 3],
+		 int p3[static const 3]
+    ) {
+}
Index: translator/Tests/Parser/Constant0-1.c
===================================================================
--- translator/Tests/Parser/Constant0-1.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Constant0-1.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,35 @@
+// Cforall extension
+
+// value
+
+int 0;
+const int 0;
+static const int 0;
+int 1;
+const int 1;
+static const int 1;
+int 0, 1;
+const int 0, 1;
+static const int 0, 1;
+struct { int i; } 0;
+const struct { int i; } 1;
+static const struct { int i; } 1;
+
+// pointer
+
+int 1, * 0;
+int (1), ((1)), * (0), (* 0), ((* 0));
+int * const (0), (* const 0), ((* const 0));
+struct { int i; } * 0;
+
+// Cforall style
+
+* int x, 0;
+const * int x, 0;
+static const * int x, 0;
+* struct { int i; } 0;
+const * struct { int i; } 0;
+static const * struct { int i; } 0;
+static * int x, 0;
+static const * int x, 0;
+const * * int x, 0;
Index: translator/Tests/Parser/DeclarationSpecifier.c
===================================================================
--- translator/Tests/Parser/DeclarationSpecifier.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/DeclarationSpecifier.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,90 @@
+typedef short int Int;
+
+
+const short int volatile x1;
+static const short int volatile x2;
+const static short int volatile x3;
+const short static int volatile x4;
+const static volatile short int x4;
+const short int static volatile x5;
+const short int volatile static x6;
+const short volatile int static x7;
+short int volatile static const x8;
+static short int volatile static const x9;		// duplicate static
+
+const volatile struct { int i; } x10;
+const struct { int i; } volatile x11;
+struct { int i; } const volatile x12;
+static const volatile struct { int i; } x13;
+const static struct { int i; } volatile x14;
+struct { int i; } static const volatile x15;
+struct { int i; } const static volatile x16;
+struct { int i; } const volatile static x17;
+struct { int i; } const static volatile static x18;	// duplicate static
+struct { int i; } const static volatile static volatile x19; // duplicate static & volatile
+
+const Int volatile x20;
+static const Int volatile x21;
+const static Int volatile x22;
+const static Int volatile x23;
+const Int static volatile x24;
+const Int volatile static x25;
+const volatile Int static x26;
+Int volatile static const x27;
+static Int volatile static const x28;			// duplicate static
+
+const volatile struct { Int i; } x29;
+const struct { Int i; } volatile x30;
+struct { Int i; } const volatile x31;
+static const volatile struct { Int i; } x32;
+const static struct { Int i; } volatile x33;
+struct { Int i; } static const volatile x34;
+struct { Int i; } const static volatile x35;
+struct { Int i; } const volatile static x36;
+
+
+const static inline const volatile int f01();		// duplicate const
+volatile inline const volatile static int f02();	// duplicate volatile
+const inline const volatile int static f03();		// duplicate const
+volatile inline static const volatile int f04();	// duplicate volatile
+const static const inline volatile int f05();		// duplicate const
+volatile static const volatile inline int f06();	// duplicate volatile
+const static const volatile int inline f07();		// duplicate const
+volatile static const int inline volatile f08();	// duplicate volatile
+
+static inline const volatile int f11();
+inline const volatile static int f12();
+inline const volatile int static f13();
+inline static const volatile int f14();
+static const inline volatile int f15();
+static const volatile inline int f16();
+static const volatile int inline f17();
+static const int inline volatile f18();
+
+short static inline const volatile int f21();
+inline short const volatile static int f22();
+inline const short volatile int static f23();
+inline static const short volatile int f24();
+static const inline volatile short int f25();
+static const volatile inline int short f26();
+static const volatile int inline short f27();
+static const int inline volatile short f28();
+
+static inline const volatile struct { int i; } f31();
+inline const volatile static struct { int i; } f32();
+inline const volatile struct { int i; } static f33();
+inline static const volatile struct { int i; } f34();
+static const inline volatile struct { int i; } f35();
+static const volatile inline struct { int i; } f36();
+static const volatile struct { int i; } inline f37();
+static const struct { int i; } inline volatile f38();
+
+static inline const volatile Int f41();
+inline const volatile static Int f42();
+inline const volatile Int static f43();
+inline static const volatile Int f44();
+static const inline volatile Int f45();
+static const volatile inline Int f46();
+static const volatile Int inline f47();
+static const Int inline volatile f48();
+
Index: translator/Tests/Parser/Expected/Array.tst
===================================================================
--- translator/Tests/Parser/Expected/Array.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Expected/Array.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,48 @@
+a1: a open array of int 
+a2: a variable-length array of int 
+a4: a array of 3 int 
+m1: a open array of array of 3 int 
+m2: a variable-length array of variable-length array of int 
+m4: a array of 3 array of 3 int 
+T: a typedef definition for int 
+fred: a function
+  with no parameters 
+  returning int 
+  with body 
+    a1: a open array of int 
+    a2: a variable-length array of int 
+    a4: a array of     3 int 
+    T: a array of     3 int 
+
+mary: a function
+  with parameters 
+    T: a array of     3 int 
+    p1: a const array of     3 int 
+    p2: a static array of     3 int 
+    p3: a const static array of     3 int 
+  returning int 
+  with body 
+
+  Null Statement:
+
+tom: a function
+  with no parameters 
+  returning pointer to array of     3 int 
+  with body 
+
+  Null Statement:
+
+jane: a function
+  with no parameters 
+  returning pointer to function
+      with parameters 
+        T: a array of         3 int 
+        p1: a const array of         3 int 
+        p2: a static array of         3 int 
+        p3: a const static array of         3 int 
+      returning int 
+
+  with body 
+
+  Null Statement:
+
Index: translator/Tests/Parser/Expected/Constant0-1.tst
===================================================================
--- translator/Tests/Parser/Expected/Constant0-1.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Expected/Constant0-1.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,62 @@
+0: a int 
+0: a const int 
+0: a static const int 
+1: a int 
+1: a const int 
+1: a static const int 
+0: a int 
+1: a int 
+0: a const int 
+1: a const int 
+0: a static const int 
+1: a static const int 
+0: a instance of struct __anonymous0
+  with members 
+    i: a int 
+
+1: a const instance of struct __anonymous1
+  with members 
+    i: a int 
+
+1: a static const instance of struct __anonymous2
+  with members 
+    i: a int 
+
+1: a int 
+0: a pointer to int 
+1: a int 
+1: a int 
+0: a pointer to int 
+0: a pointer to int 
+0: a pointer to int 
+0: a const pointer to int 
+0: a const pointer to int 
+0: a const pointer to int 
+0: a pointer to instance of struct __anonymous3
+  with members 
+    i: a int 
+
+x: a pointer to int 
+0: a pointer to int 
+x: a const pointer to int 
+0: a const pointer to int 
+x: a static const pointer to int 
+0: a static const pointer to int 
+0: a pointer to instance of struct __anonymous4
+  with members 
+    i: a int 
+
+0: a const pointer to instance of struct __anonymous5
+  with members 
+    i: a int 
+
+0: a static const pointer to instance of struct __anonymous6
+  with members 
+    i: a int 
+
+x: a static pointer to int 
+0: a static pointer to int 
+x: a static const pointer to int 
+0: a static const pointer to int 
+x: a const pointer to pointer to int 
+0: a const pointer to pointer to int 
Index: translator/Tests/Parser/Expected/DeclarationSpecifier.tst
===================================================================
--- translator/Tests/Parser/Expected/DeclarationSpecifier.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Expected/DeclarationSpecifier.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,276 @@
+Int: a typedef definition for short int 
+x1: a const volatile short int 
+x2: a static const volatile short int 
+x3: a static volatile const short int 
+x4: a static volatile const short int 
+x4: a static volatile const short int 
+x5: a static const volatile short int 
+x6: a static const volatile short int 
+x7: a static const volatile short int 
+x8: a static volatile const short int 
+x9: a static static volatile const short int 
+x10: a const volatile instance of struct __anonymous0
+  with members 
+    i: a int 
+
+x11: a const volatile instance of struct __anonymous1
+  with members 
+    i: a int 
+
+x12: a const volatile instance of struct __anonymous2
+  with members 
+    i: a int 
+
+x13: a static const volatile instance of struct __anonymous3
+  with members 
+    i: a int 
+
+x14: a static volatile const instance of struct __anonymous4
+  with members 
+    i: a int 
+
+x15: a static const volatile instance of struct __anonymous5
+  with members 
+    i: a int 
+
+x16: a static const volatile instance of struct __anonymous6
+  with members 
+    i: a int 
+
+x17: a static const volatile instance of struct __anonymous7
+  with members 
+    i: a int 
+
+x18: a static static const volatile instance of struct __anonymous8
+  with members 
+    i: a int 
+
+x19: a static static const volatile volatile instance of struct __anonymous9
+  with members 
+    i: a int 
+
+x20: a const volatile instance of type Int
+x21: a static const volatile instance of type Int
+x22: a static volatile const instance of type Int
+x23: a static volatile const instance of type Int
+x24: a static const volatile instance of type Int
+x25: a static const volatile instance of type Int
+x26: a static const volatile instance of type Int
+x27: a static volatile const instance of type Int
+x28: a static static volatile const instance of type Int
+x29: a const volatile instance of struct __anonymous10
+  with members 
+    i: a instance of type Int
+
+x30: a const volatile instance of struct __anonymous11
+  with members 
+    i: a instance of type Int
+
+x31: a const volatile instance of struct __anonymous12
+  with members 
+    i: a instance of type Int
+
+x32: a static const volatile instance of struct __anonymous13
+  with members 
+    i: a instance of type Int
+
+x33: a static volatile const instance of struct __anonymous14
+  with members 
+    i: a instance of type Int
+
+x34: a static const volatile instance of struct __anonymous15
+  with members 
+    i: a instance of type Int
+
+x35: a static const volatile instance of struct __anonymous16
+  with members 
+    i: a instance of type Int
+
+x36: a static const volatile instance of struct __anonymous17
+  with members 
+    i: a instance of type Int
+
+f01: a static inline function
+  with no parameters 
+  returning const volatile const int 
+
+f02: a inline static function
+  with no parameters 
+  returning volatile const volatile int 
+
+f03: a inline static function
+  with no parameters 
+  returning const volatile const int 
+
+f04: a inline static function
+  with no parameters 
+  returning const volatile volatile int 
+
+f05: a static inline function
+  with no parameters 
+  returning volatile const const int 
+
+f06: a static inline function
+  with no parameters 
+  returning volatile const volatile int 
+
+f07: a static inline function
+  with no parameters 
+  returning const volatile const int 
+
+f08: a static inline function
+  with no parameters 
+  returning const volatile volatile int 
+
+f11: a static inline function
+  with no parameters 
+  returning const volatile int 
+
+f12: a inline static function
+  with no parameters 
+  returning const volatile int 
+
+f13: a inline static function
+  with no parameters 
+  returning const volatile int 
+
+f14: a inline static function
+  with no parameters 
+  returning const volatile int 
+
+f15: a static inline function
+  with no parameters 
+  returning volatile const int 
+
+f16: a static inline function
+  with no parameters 
+  returning const volatile int 
+
+f17: a static inline function
+  with no parameters 
+  returning const volatile int 
+
+f18: a static inline function
+  with no parameters 
+  returning const volatile int 
+
+f21: a inline static function
+  with no parameters 
+  returning const volatile short int 
+
+f22: a static inline function
+  with no parameters 
+  returning const volatile short int 
+
+f23: a inline static function
+  with no parameters 
+  returning const volatile short int 
+
+f24: a inline static function
+  with no parameters 
+  returning const volatile short int 
+
+f25: a static inline function
+  with no parameters 
+  returning volatile const short int 
+
+f26: a static inline function
+  with no parameters 
+  returning const volatile short int 
+
+f27: a inline static function
+  with no parameters 
+  returning const volatile short int 
+
+f28: a inline static function
+  with no parameters 
+  returning volatile const short int 
+
+f31: a static inline function
+  with no parameters 
+  returning const volatile instance of struct __anonymous18
+      with members 
+        i: a int 
+
+
+f32: a inline static function
+  with no parameters 
+  returning const volatile instance of struct __anonymous19
+      with members 
+        i: a int 
+
+
+f33: a inline static function
+  with no parameters 
+  returning const volatile instance of struct __anonymous20
+      with members 
+        i: a int 
+
+
+f34: a inline static function
+  with no parameters 
+  returning const volatile instance of struct __anonymous21
+      with members 
+        i: a int 
+
+
+f35: a static inline function
+  with no parameters 
+  returning volatile const instance of struct __anonymous22
+      with members 
+        i: a int 
+
+
+f36: a static inline function
+  with no parameters 
+  returning const volatile instance of struct __anonymous23
+      with members 
+        i: a int 
+
+
+f37: a static inline function
+  with no parameters 
+  returning const volatile instance of struct __anonymous24
+      with members 
+        i: a int 
+
+
+f38: a static inline function
+  with no parameters 
+  returning const volatile instance of struct __anonymous25
+      with members 
+        i: a int 
+
+
+f41: a static inline function
+  with no parameters 
+  returning const volatile instance of type Int
+
+f42: a inline static function
+  with no parameters 
+  returning const volatile instance of type Int
+
+f43: a inline static function
+  with no parameters 
+  returning const volatile instance of type Int
+
+f44: a inline static function
+  with no parameters 
+  returning const volatile instance of type Int
+
+f45: a static inline function
+  with no parameters 
+  returning volatile const instance of type Int
+
+f46: a static inline function
+  with no parameters 
+  returning const volatile instance of type Int
+
+f47: a static inline function
+  with no parameters 
+  returning const volatile instance of type Int
+
+f48: a static inline function
+  with no parameters 
+  returning const volatile instance of type Int
+
Index: translator/Tests/Parser/Expected/Forall.tst
===================================================================
--- translator/Tests/Parser/Expected/Forall.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Expected/Forall.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,319 @@
+f: a typedef definition for pointer to forall 
+      T: a type variable 
+function
+    with parameters 
+      int 
+    returning int 
+
+swap: a forall 
+    T: a type variable 
+function
+  with parameters 
+    left: a instance of type T
+    right: a instance of type T
+  returning void 
+  with body 
+    temp: a instance of type T
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Referencing: Variable: left
+
+        Referencing: Variable: right
+
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Referencing: Variable: right
+
+        Referencing: Variable: temp
+
+
+context sumable
+  with type parameters 
+    T: a type variable 
+  with members 
+    0: a const instance of type T
+    ?+?: a function
+      with parameters 
+        instance of type T
+        instance of type T
+      returning instance of type T
+
+    ?++: a function
+      with parameters 
+        instance of type T
+      returning instance of type T
+
+    ?+=?: a function
+      with parameters 
+        instance of type T
+        instance of type T
+      returning tuple with members 
+          instance of type T
+
+
+
+T1: a type definition 
+  with assertions
+    0: a const instance of type T1
+    ?+?: a function
+      with parameters 
+        instance of type T1
+        instance of type T1
+      returning instance of type T1
+
+    ?++: a function
+      with parameters 
+        instance of type T1
+      returning instance of type T1
+
+    ?+=?: a function
+      with parameters 
+        instance of type T1
+        instance of type T1
+      returning tuple with members 
+          instance of type T1
+
+
+  
+T2: a type definition 
+  with parameters
+  P1: a type variable 
+  P2: a type variable 
+
+T3: a type definition 
+  with assertions
+    instance of context sumable
+      with parameters 
+      Type:        instance of type T3
+
+  
+T2: a type definition 
+  with parameters
+  P1: a type variable 
+  P2: a type variable 
+
+  with assertions
+    instance of context sumable
+      with parameters 
+      Type:        instance of type T2 with parameters
+          Type:            instance of type P1
+          Type:            instance of type P2
+
+
+  for instance of struct __anonymous0
+    with members 
+      i: a instance of type P1
+      j: a instance of type P2
+
+w1: a instance of type T2 with parameters
+  Type:    int 
+  Type:    int 
+
+w2: a typedef definition for instance of type T2 with parameters
+    Type:      int 
+    Type:      int 
+
+g2: a instance of type w2
+w3: a type definition for instance of type T2 with parameters
+    Type:      int 
+    Type:      int 
+
+g3: a instance of type w3
+sum: a forall 
+    T: a type variable 
+      with assertions
+        instance of context sumable
+          with parameters 
+          Type:            instance of type T
+
+      
+function
+  with parameters 
+    n: a int 
+    a: a open array of instance of type T
+  returning instance of type T
+  with body 
+    total: a instance of type T
+    i: a int 
+
+    For
+
+        Expression: 
+
+            Application of: 
+
+                Operator: Assign
+
+            ... on arguments: 
+
+                Referencing: Variable: i
+
+                Referencing: Variable: 0
+
+            Application of: 
+
+                Operator: LThan
+
+            ... on arguments: 
+
+                Referencing: Variable: i
+
+                Referencing: Variable: n
+
+            Application of: 
+
+                Operator: PlusAssn
+
+            ... on arguments: 
+
+                Referencing: Variable: i
+
+                Referencing: Variable: 1
+
+        Branches of execution: 
+            
+            Application of: 
+
+                Operator: Assign
+
+            ... on arguments: 
+
+                Referencing: Variable: total
+
+                Application of: 
+
+                    Operator: Plus
+
+                ... on arguments: 
+
+                    Referencing: Variable: total
+
+                    Application of: 
+
+                        Operator: Index
+
+                    ... on arguments: 
+
+                        Referencing: Variable: a
+
+                        Referencing: Variable: i
+
+
+    Return
+
+        Expression: 
+
+            Referencing: Variable: total
+
+twice: a forall 
+    T: a type variable 
+      with assertions
+        0: a const instance of type T
+        ?+?: a function
+          with parameters 
+            instance of type T
+            instance of type T
+          returning instance of type T
+
+        ?++: a function
+          with parameters 
+            instance of type T
+          returning instance of type T
+
+        ?+=?: a function
+          with parameters 
+            instance of type T
+            instance of type T
+          returning tuple with members 
+              instance of type T
+
+
+      
+function
+  with parameters 
+    t: a instance of type T
+  returning instance of type T
+  with body 
+
+    Return
+
+        Expression: 
+
+            Application of: 
+
+                Operator: Plus
+
+            ... on arguments: 
+
+                Referencing: Variable: t
+
+                Referencing: Variable: t
+
+main: a function
+  with no parameters 
+  returning int 
+  with body 
+    x: a int 
+    y: a int 
+    a: a array of     10 int 
+    f: a float 
+    
+    Application of: 
+
+        Referencing: Variable: swap
+
+    ... on arguments: 
+
+        Referencing: Variable: x
+
+        Referencing: Variable: y
+
+    
+    Application of: 
+
+        Referencing: Variable: twice
+
+    ... on arguments: 
+
+        Referencing: Variable: x
+
+        Referencing: Variable: y
+
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Referencing: Variable: f
+
+        Application of: 
+
+            Referencing: Variable: min
+
+        ... on arguments: 
+            4.0 
+            3.0 
+
+    
+    Application of: 
+
+        Referencing: Variable: sum
+
+    ... on arguments: 
+        10 
+
+        Referencing: Variable: a
+
+
Index: translator/Tests/Parser/Expected/Functions.tst
===================================================================
--- translator/Tests/Parser/Expected/Functions.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Expected/Functions.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,741 @@
+h: a function
+  with parameters 
+    void 
+  returning void 
+  with body 
+
+  Null Statement:
+
+f: a function
+  with parameters 
+    function
+      with parameters 
+        void 
+      returning int 
+
+    function
+      with parameters 
+        int 
+      returning int 
+
+    function
+      with parameters 
+        void 
+      returning int 
+
+    function
+      with parameters 
+        int 
+      returning int 
+
+    g: a function
+      with parameters 
+        void 
+      returning void 
+
+  returning int 
+  with body 
+    
+    Application of: 
+
+        Application of: 
+
+            Operator: PointTo
+
+        ... on arguments: 
+
+            Referencing: Variable: g
+
+    ... on no arguments: 
+
+    
+    Application of: 
+
+        Referencing: Variable: g
+
+    ... on no arguments: 
+
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Referencing: Variable: g
+
+        Referencing: Variable: h
+
+
+f1: a function
+  with no parameters 
+  returning int 
+  with body 
+
+  Null Statement:
+
+f2: a function
+  with no parameters 
+  returning int 
+  with body 
+
+  Null Statement:
+
+f3: a function
+  with no parameters 
+  returning pointer to function
+      with no parameters 
+      returning int 
+
+  with body 
+
+  Null Statement:
+
+f4: a function
+  with no parameters 
+  returning pointer to int 
+  with body 
+
+  Null Statement:
+
+f5: a function
+  with no parameters 
+  returning pointer to function
+      with no parameters 
+      returning int 
+
+  with body 
+
+  Null Statement:
+
+f6: a function
+  with no parameters 
+  returning pointer to int 
+  with body 
+
+  Null Statement:
+
+f7: a function
+  with no parameters 
+  returning pointer to int 
+  with body 
+
+  Null Statement:
+
+f8: a function
+  with no parameters 
+  returning pointer to pointer to int 
+  with body 
+
+  Null Statement:
+
+f9: a function
+  with no parameters 
+  returning pointer to const pointer to int 
+  with body 
+
+  Null Statement:
+
+f10: a function
+  with no parameters 
+  returning pointer to open array of int 
+  with body 
+
+  Null Statement:
+
+f11: a function
+  with no parameters 
+  returning pointer to open array of array of     3 int 
+  with body 
+
+  Null Statement:
+
+f12: a function
+  with no parameters 
+  returning pointer to open array of array of     3 int 
+  with body 
+
+  Null Statement:
+
+fII1: a function
+  with parameters 
+    i: a int 
+  returning nothing 
+  with body 
+
+  Null Statement:
+
+fII2: a function
+  with parameters 
+    i: a int 
+  returning const entity of unknown type 
+  with body 
+
+  Null Statement:
+
+fII3: a extern function
+  with parameters 
+    i: a int 
+  returning nothing 
+  with body 
+
+  Null Statement:
+
+fII4: a extern function
+  with parameters 
+    i: a int 
+  returning const entity of unknown type 
+  with body 
+
+  Null Statement:
+
+fII5: a function
+  with no parameters 
+  returning pointer 
+  with body 
+
+  Null Statement:
+
+fII6: a function
+  with no parameters 
+  returning const pointer 
+  with body 
+
+  Null Statement:
+
+fII7: a function
+  with no parameters 
+  returning pointer to const long 
+  with body 
+
+  Null Statement:
+
+fII8: a static function
+  with no parameters 
+  returning pointer to const long 
+  with body 
+
+  Null Statement:
+
+fII9: a static function
+  with no parameters 
+  returning pointer to const long 
+  with body 
+
+  Null Statement:
+
+fO1: a function
+  with no parameters 
+  with old-style identifier list 
+    i: a untyped entity 
+  with old-style declaration list 
+    i: a int 
+  returning nothing 
+  with body 
+
+  Null Statement:
+
+fO2: a function
+  with no parameters 
+  with old-style identifier list 
+    i: a untyped entity 
+  with old-style declaration list 
+    i: a int 
+  returning int 
+  with body 
+
+  Null Statement:
+
+fO3: a function
+  with no parameters 
+  with old-style identifier list 
+    i: a untyped entity 
+  with old-style declaration list 
+    i: a int 
+  returning const entity of unknown type 
+  with body 
+
+  Null Statement:
+
+fO4: a extern function
+  with no parameters 
+  with old-style identifier list 
+    i: a untyped entity 
+  with old-style declaration list 
+    i: a int 
+  returning nothing 
+  with body 
+
+  Null Statement:
+
+fO5: a extern function
+  with no parameters 
+  with old-style identifier list 
+    i: a untyped entity 
+  with old-style declaration list 
+    i: a int 
+  returning const entity of unknown type 
+  with body 
+
+  Null Statement:
+
+f: a function
+  with no parameters 
+  returning tuple 
+
+f: a function
+  with no parameters 
+  returning tuple with members 
+      int 
+
+
+f: a function
+  with parameters 
+    int 
+  returning tuple 
+
+f: a function
+  with parameters 
+    int 
+  returning tuple with members 
+      int 
+
+
+f: a function
+  with no parameters 
+  returning tuple 
+  with body 
+
+  Null Statement:
+
+f: a function
+  with no parameters 
+  returning tuple with members 
+      int 
+
+  with body 
+
+  Null Statement:
+
+f: a function
+  with parameters 
+    int 
+  returning tuple 
+  with body 
+
+  Null Statement:
+
+f: a function
+  with parameters 
+    int 
+  returning tuple with members 
+      int 
+
+  with body 
+
+  Null Statement:
+
+f: a function
+  with no parameters 
+  returning tuple with members 
+      x: a int 
+
+
+f: a function
+  with parameters 
+    x: a int 
+  returning tuple 
+
+f: a function
+  with parameters 
+    x: a int 
+  returning tuple with members 
+      x: a int 
+
+
+f: a function
+  with no parameters 
+  returning tuple with members 
+      x: a int 
+
+  with body 
+
+  Null Statement:
+
+f: a function
+  with parameters 
+    x: a int 
+  returning tuple 
+  with body 
+
+  Null Statement:
+
+f: a function
+  with parameters 
+    x: a int 
+  returning tuple with members 
+      x: a int 
+
+  with body 
+
+  Null Statement:
+
+f: a function
+  with no parameters 
+  returning tuple with members 
+      int 
+      x: a int 
+
+
+f: a function
+  with parameters 
+    int 
+    x: a int 
+  returning tuple 
+
+f: a function
+  with parameters 
+    int 
+    x: a int 
+  returning tuple with members 
+      int 
+      x: a int 
+
+
+f: a function
+  with no parameters 
+  returning tuple with members 
+      int 
+      x: a int 
+
+  with body 
+
+  Null Statement:
+
+f: a function
+  with parameters 
+    int 
+    x: a int 
+  returning tuple 
+  with body 
+
+  Null Statement:
+
+f: a function
+  with parameters 
+    int 
+    x: a int 
+  returning tuple with members 
+      int 
+      x: a int 
+
+  with body 
+
+  Null Statement:
+
+f: a function
+  with no parameters 
+  returning tuple with members 
+      int 
+      x: a int 
+      int 
+
+
+f: a function
+  with parameters 
+    int 
+    x: a int 
+    int 
+  returning tuple 
+
+f: a function
+  with parameters 
+    int 
+    x: a int 
+    int 
+  returning tuple with members 
+      int 
+      x: a int 
+      int 
+
+
+f: a function
+  with no parameters 
+  returning tuple with members 
+      int 
+      x: a int 
+      int 
+
+  with body 
+
+  Null Statement:
+
+f: a function
+  with parameters 
+    int 
+    x: a int 
+    int 
+  returning tuple 
+  with body 
+
+  Null Statement:
+
+f: a function
+  with parameters 
+    int 
+    x: a int 
+    int 
+  returning tuple with members 
+      int 
+      x: a int 
+      int 
+
+  with body 
+
+  Null Statement:
+
+f: a function
+  with no parameters 
+  returning tuple with members 
+      int 
+      x: a int 
+      y: a pointer to int 
+
+
+f: a function
+  with parameters 
+    int 
+    x: a int 
+    y: a pointer to int 
+  returning tuple 
+
+f: a function
+  with parameters 
+    int 
+    x: a int 
+    y: a pointer to int 
+  returning tuple with members 
+      int 
+      x: a int 
+      y: a pointer to int 
+
+
+f: a function
+  with no parameters 
+  returning tuple with members 
+      int 
+      x: a int 
+      y: a pointer to int 
+
+  with body 
+
+  Null Statement:
+
+f: a function
+  with parameters 
+    int 
+    x: a int 
+    y: a pointer to int 
+  returning tuple 
+  with body 
+
+  Null Statement:
+
+f: a function
+  with parameters 
+    int 
+    x: a int 
+    y: a pointer to int 
+  returning tuple with members 
+      int 
+      x: a int 
+      y: a pointer to int 
+
+  with body 
+
+  Null Statement:
+
+f11: a function
+  with parameters 
+    int 
+  returning tuple with members 
+      int 
+
+
+f12: a function
+  with parameters 
+    int 
+  returning tuple with members 
+      int 
+
+
+f: a function
+  with parameters 
+    function
+      with parameters 
+        int 
+        p: a int 
+      returning int 
+
+    function
+      with parameters 
+        int 
+      returning tuple with members 
+          int 
+
+
+  returning tuple with members 
+      int 
+
+  with body 
+    p: a pointer to open array of array of     10 pointer to open array of array of     3 int 
+    p: a pointer to open array of array of     10 pointer to open array of array of     3 int 
+    p: a pointer to open array of pointer to function
+      with parameters 
+        int 
+      returning tuple with members 
+          int 
+
+
+
+f1: a static function
+  with no parameters 
+  returning pointer to const int 
+  with body 
+
+  Null Statement:
+
+f2: a static function
+  with no parameters 
+  returning tuple with members 
+      const int 
+
+  with body 
+
+  Null Statement:
+
+f3: a static inline function
+  with no parameters 
+  returning tuple with members 
+      const pointer to int 
+
+  with body 
+
+  Null Statement:
+
+f4: a static inline function
+  with no parameters 
+  returning tuple with members 
+      const tuple with members 
+        pointer to int 
+        int 
+
+
+  with body 
+
+  Null Statement:
+
+f5: a static function
+  with no parameters 
+  returning tuple with members 
+      const tuple with members 
+        pointer to int 
+        const int 
+
+
+  with body 
+
+  Null Statement:
+
+f: a function
+  with parameters 
+    function
+      with no parameters 
+      returning int 
+
+    function
+      with no parameters 
+      returning pointer to int 
+
+    function
+      with no parameters 
+      returning pointer to pointer to int 
+
+    function
+      with no parameters 
+      returning pointer to const pointer to int 
+
+    function
+      with no parameters 
+      returning const pointer to const pointer to int 
+
+    open array of int 
+    array of     10 int 
+    open array of pointer to int 
+    array of     10 pointer to int 
+    open array of pointer to pointer to int 
+    array of     10 pointer to pointer to int 
+    open array of pointer to const pointer to int 
+    array of     10 pointer to const pointer to int 
+    open array of const pointer to const pointer to int 
+    array of     10 const pointer to const pointer to int 
+  returning int 
+
+f: a function
+  with parameters 
+    function
+      with no parameters 
+      returning int 
+
+    function
+      with no parameters 
+      returning pointer to int 
+
+    function
+      with no parameters 
+      returning pointer to pointer to int 
+
+    function
+      with no parameters 
+      returning pointer to const pointer to int 
+
+    function
+      with no parameters 
+      returning const pointer to const pointer to int 
+
+    open array of int 
+    array of     10 int 
+    open array of pointer to int 
+    array of     10 pointer to int 
+    open array of pointer to pointer to int 
+    array of     10 pointer to pointer to int 
+    open array of pointer to const pointer to int 
+    array of     10 pointer to const pointer to int 
+    open array of const pointer to const pointer to int 
+    array of     10 const pointer to const pointer to int 
+  returning int 
+  with body 
+
+  Null Statement:
+
+T: a typedef definition for int 
+f: a function
+  with parameters 
+    function
+      with parameters 
+        instance of type T
+      returning instance of type T
+
+    T: a instance of type T
+  returning int 
+  with body 
+    
+    Application of: 
+
+        Referencing: Variable: T
+
+    ... on arguments: 
+
+        Referencing: Variable: T
+
+
Index: translator/Tests/Parser/Expected/IdentFuncDeclarator.tst
===================================================================
--- translator/Tests/Parser/Expected/IdentFuncDeclarator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Expected/IdentFuncDeclarator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,163 @@
+main: a function
+  with no parameters 
+  returning int 
+  with body 
+    f1: a int 
+    f2: a int 
+    f3: a pointer to int 
+    f4: a pointer to pointer to int 
+    f5: a pointer to const pointer to int 
+    f6: a const pointer to const pointer to int 
+    f7: a pointer to int 
+    f8: a pointer to pointer to int 
+    f9: a pointer to const pointer to int 
+    f10: a const pointer to const pointer to int 
+    f11: a pointer to int 
+    f12: a pointer to pointer to int 
+    f13: a pointer to const pointer to int 
+    f14: a const pointer to const pointer to int 
+    f15: a open array of int 
+    f16: a array of     10 int 
+    f17: a open array of int 
+    f18: a array of     10 int 
+    f19: a open array of pointer to int 
+    f20: a array of     10 pointer to int 
+    f21: a open array of pointer to pointer to int 
+    f22: a array of     10 pointer to pointer to int 
+    f23: a open array of pointer to const pointer to int 
+    f24: a array of     10 pointer to const pointer to int 
+    f25: a open array of const pointer to const pointer to int 
+    f26: a array of     10 const pointer to const pointer to int 
+    f27: a open array of pointer to int 
+    f28: a array of     10 pointer to int 
+    f29: a open array of pointer to pointer to int 
+    f30: a array of     10 pointer to pointer to int 
+    f31: a open array of pointer to const pointer to int 
+    f32: a array of     10 pointer to const pointer to int 
+    f33: a open array of const pointer to const pointer to int 
+    f34: a array of     10 const pointer to const pointer to int 
+    f35: a open array of pointer to int 
+    f36: a array of     10 pointer to int 
+    f37: a open array of pointer to pointer to int 
+    f38: a array of     10 pointer to pointer to int 
+    f39: a open array of pointer to const pointer to int 
+    f40: a array of     10 pointer to const pointer to int 
+    f41: a open array of const pointer to const pointer to int 
+    f42: a array of     10 const pointer to const pointer to int 
+    f43: a open array of array of     3 int 
+    f44: a array of     3 array of     3 int 
+    f45: a open array of array of     3 int 
+    f46: a array of     3 array of     3 int 
+    f47: a open array of array of     3 int 
+    f48: a array of     3 array of     3 int 
+    f49: a open array of array of     3 pointer to int 
+    f50: a array of     3 array of     3 pointer to int 
+    f51: a open array of array of     3 pointer to pointer to int 
+    f52: a array of     3 array of     3 pointer to pointer to int 
+    f53: a open array of array of     3 pointer to const pointer to int 
+    f54: a array of     3 array of     3 pointer to const pointer to int 
+    f55: a open array of array of     3 const pointer to const pointer to int 
+    f56: a array of     3 array of     3 const pointer to const pointer to int 
+    f57: a open array of array of     3 pointer to int 
+    f58: a array of     3 array of     3 pointer to int 
+    f59: a open array of array of     3 pointer to pointer to int 
+    f60: a array of     3 array of     3 pointer to pointer to int 
+    f61: a open array of array of     3 pointer to const pointer to int 
+    f62: a array of     3 array of     3 pointer to const pointer to int 
+    f63: a open array of array of     3 const pointer to const pointer to int 
+    f64: a array of     3 array of     3 const pointer to const pointer to int 
+    f65: a function
+      with parameters 
+        int 
+      returning int 
+
+    f66: a function
+      with parameters 
+        int 
+      returning int 
+
+    f67: a function
+      with parameters 
+        int 
+      returning pointer to int 
+
+    f68: a function
+      with parameters 
+        int 
+      returning pointer to pointer to int 
+
+    f69: a function
+      with parameters 
+        int 
+      returning pointer to const pointer to int 
+
+    f70: a function
+      with parameters 
+        int 
+      returning const pointer to const pointer to int 
+
+    f71: a function
+      with parameters 
+        int 
+      returning pointer to int 
+
+    f72: a function
+      with parameters 
+        int 
+      returning pointer to pointer to int 
+
+    f73: a function
+      with parameters 
+        int 
+      returning pointer to const pointer to int 
+
+    f74: a function
+      with parameters 
+        int 
+      returning const pointer to const pointer to int 
+
+    f75: a pointer to function
+      with parameters 
+        int 
+      returning int 
+
+    f76: a pointer to pointer to function
+      with parameters 
+        int 
+      returning int 
+
+    f77: a pointer to const pointer to function
+      with parameters 
+        int 
+      returning int 
+
+    f78: a const pointer to const pointer to function
+      with parameters 
+        int 
+      returning int 
+
+    f79: a pointer to function
+      with parameters 
+        int 
+      returning pointer to function
+          with no parameters 
+          returning int 
+
+
+    f80: a const pointer to function
+      with parameters 
+        int 
+      returning pointer to function
+          with no parameters 
+          returning int 
+
+
+    f81: a const pointer to function
+      with parameters 
+        int 
+      returning const pointer to function
+          with no parameters 
+          returning int 
+
+
+
Index: translator/Tests/Parser/Expected/IdentFuncParamDeclarator.tst
===================================================================
--- translator/Tests/Parser/Expected/IdentFuncParamDeclarator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Expected/IdentFuncParamDeclarator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,199 @@
+fred: a function
+  with parameters 
+    f1: a int 
+    f2: a int 
+    f3: a pointer to int 
+    f4: a pointer to pointer to int 
+    f5: a pointer to const pointer to int 
+    f6: a const pointer to const pointer to int 
+    f7: a pointer to int 
+    f8: a pointer to pointer to int 
+    f9: a pointer to const pointer to int 
+    f10: a const pointer to const pointer to int 
+    f11: a pointer to int 
+    f12: a pointer to pointer to int 
+    f13: a pointer to const pointer to int 
+    f14: a const pointer to const pointer to int 
+    f15: a open array of int 
+    f16: a array of     10 int 
+    f17: a open array of int 
+    f18: a array of     10 int 
+    f19: a open array of pointer to int 
+    f20: a array of     10 pointer to int 
+    f21: a open array of pointer to pointer to int 
+    f22: a array of     10 pointer to pointer to int 
+    f23: a open array of pointer to const pointer to int 
+    f24: a array of     10 pointer to const pointer to int 
+    f25: a open array of const pointer to const pointer to int 
+    f26: a array of     10 const pointer to const pointer to int 
+    f27: a open array of pointer to int 
+    f28: a array of     10 pointer to int 
+    f29: a open array of pointer to pointer to int 
+    f30: a array of     10 pointer to pointer to int 
+    f31: a open array of pointer to const pointer to int 
+    f32: a array of     10 pointer to const pointer to int 
+    f33: a open array of const pointer to const pointer to int 
+    f34: a array of     10 const pointer to const pointer to int 
+    f35: a open array of pointer to int 
+    f36: a array of     10 pointer to int 
+    f37: a open array of pointer to pointer to int 
+    f38: a array of     10 pointer to pointer to int 
+    f39: a open array of pointer to const pointer to int 
+    f40: a array of     10 pointer to const pointer to int 
+    f41: a open array of const pointer to const pointer to int 
+    f42: a array of     10 const pointer to const pointer to int 
+    f43: a open array of array of     3 int 
+    f44: a array of     3 array of     3 int 
+    f45: a open array of array of     3 int 
+    f46: a array of     3 array of     3 int 
+    f47: a open array of array of     3 int 
+    f48: a array of     3 array of     3 int 
+    f49: a open array of array of     3 pointer to int 
+    f50: a array of     3 array of     3 pointer to int 
+    f51: a open array of array of     3 pointer to pointer to int 
+    f52: a array of     3 array of     3 pointer to pointer to int 
+    f53: a open array of array of     3 pointer to const pointer to int 
+    f54: a array of     3 array of     3 pointer to const pointer to int 
+    f55: a open array of array of     3 const pointer to const pointer to int 
+    f56: a array of     3 array of     3 const pointer to const pointer to int 
+    f57: a open array of array of     3 pointer to int 
+    f58: a array of     3 array of     3 pointer to int 
+    f59: a open array of array of     3 pointer to pointer to int 
+    f60: a array of     3 array of     3 pointer to pointer to int 
+    f61: a open array of array of     3 pointer to const pointer to int 
+    f62: a array of     3 array of     3 pointer to const pointer to int 
+    f63: a open array of array of     3 const pointer to const pointer to int 
+    f64: a array of     3 array of     3 const pointer to const pointer to int 
+    f65: a function
+      with parameters 
+        int 
+      returning int 
+
+    f66: a function
+      with parameters 
+        int 
+      returning int 
+
+    f67: a function
+      with parameters 
+        int 
+      returning pointer to int 
+
+    f68: a function
+      with parameters 
+        int 
+      returning pointer to pointer to int 
+
+    f69: a function
+      with parameters 
+        int 
+      returning pointer to const pointer to int 
+
+    f70: a function
+      with parameters 
+        int 
+      returning const pointer to const pointer to int 
+
+    f71: a function
+      with parameters 
+        int 
+      returning pointer to int 
+
+    f72: a function
+      with parameters 
+        int 
+      returning pointer to pointer to int 
+
+    f73: a function
+      with parameters 
+        int 
+      returning pointer to const pointer to int 
+
+    f74: a function
+      with parameters 
+        int 
+      returning const pointer to const pointer to int 
+
+    f75: a pointer to function
+      with parameters 
+        int 
+      returning int 
+
+    f76: a pointer to pointer to function
+      with parameters 
+        int 
+      returning int 
+
+    f77: a pointer to const pointer to function
+      with parameters 
+        int 
+      returning int 
+
+    f78: a const pointer to const pointer to function
+      with parameters 
+        int 
+      returning int 
+
+    f79: a pointer to function
+      with parameters 
+        int 
+      returning pointer to function
+          with no parameters 
+          returning int 
+
+
+    f80: a const pointer to function
+      with parameters 
+        int 
+      returning pointer to function
+          with no parameters 
+          returning int 
+
+
+    f81: a const pointer to function
+      with parameters 
+        int 
+      returning const pointer to function
+          with no parameters 
+          returning int 
+
+
+    f82: a const variable-length array of int 
+    f83: a const array of     3 int 
+    f84: a static array of     3 int 
+    f85: a const static array of     3 int 
+    f86: a const variable-length array of int 
+    f87: a const array of     3 int 
+    f88: a static array of     3 int 
+    f89: a const static array of     3 int 
+    f90: a const variable-length array of pointer to int 
+    f91: a const array of     3 pointer to int 
+    f92: a static array of     3 pointer to pointer to int 
+    f93: a const static array of     3 pointer to const pointer to int 
+    f94: a const static array of     3 const pointer to const pointer to int 
+    f95: a const variable-length array of pointer to int 
+    f96: a const array of     3 pointer to int 
+    f97: a static array of     3 pointer to pointer to int 
+    f98: a const static array of     3 pointer to const pointer to int 
+    f99: a const static array of     3 const pointer to const pointer to int 
+    f100: a const variable-length array of array of     3 int 
+    f101: a const array of     3 array of     3 int 
+    f102: a static array of     3 array of     3 int 
+    f103: a const static array of     3 array of     3 int 
+    f104: a const variable-length array of array of     3 int 
+    f105: a const array of     3 array of     3 int 
+    f106: a static array of     3 array of     3 int 
+    f107: a const static array of     3 array of     3 int 
+    f108: a const variable-length array of array of     3 pointer to int 
+    f109: a const array of     3 array of     3 pointer to int 
+    f110: a static array of     3 array of     3 pointer to pointer to int 
+    f111: a const static array of     3 array of     3 pointer to const pointer to int 
+    f112: a const static array of     3 array of     3 const pointer to const pointer to int 
+    f113: a const variable-length array of array of     3 pointer to int 
+    f114: a const array of     3 array of     3 pointer to int 
+    f115: a static array of     3 array of     3 pointer to pointer to int 
+    f116: a const static array of     3 array of     3 pointer to const pointer to int 
+    f117: a const static array of     3 array of     3 const pointer to const pointer to int 
+  returning int 
+  with body 
+
Index: translator/Tests/Parser/Expected/Initialization.tst
===================================================================
--- translator/Tests/Parser/Expected/Initialization.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Expected/Initialization.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,29 @@
+x21: a pointer to int 
+x22: a int 
+x21: a pointer to int 
+x22: a int 
+y1: a array of 20 int 
+y2: a array of 20 int 
+a: a instance of struct __anonymous0
+  with members 
+    w: a tuple with members 
+      int 
+
+
+w: a open array of instance of struct __anonymous1
+  with members 
+    a: a array of     3 int 
+    b: a int 
+
+v7: a instance of struct __anonymous3
+  with members 
+    f1: a int 
+    f2: a int 
+    f3: a int 
+    f4: a array of     4 instance of struct __anonymous2
+      with members 
+        g1: a int 
+        g2: a int 
+        g3: a int 
+
+
Index: translator/Tests/Parser/Expected/Scope.tst
===================================================================
--- translator/Tests/Parser/Expected/Scope.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Expected/Scope.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,152 @@
+x: a int 
+y: a typedef definition for double 
+t: a typedef definition for float 
+z: a instance of type y
+u: a type definition for instance of struct __anonymous0
+    with members 
+      a: a int 
+      b: a double 
+
+f: a function
+  with parameters 
+    y: a int 
+  returning int 
+
+q: a instance of type y
+w: a function
+  with parameters 
+    y: a instance of type y
+    v: a instance of type u
+  returning instance of type y
+  with body 
+    x: a type definition 
+      with assertions
+        t: a function
+          with parameters 
+            instance of type u
+          returning instance of type x
+
+      
+    u: a instance of type u
+      with initializer y 
+    z: a instance of type x
+      with initializer ( t u ) 
+
+p: a instance of type y
+context has_u
+  with type parameters 
+    z: a type variable 
+  with members 
+    u: a function
+      with parameters 
+        instance of type z
+      returning instance of type z
+
+
+q: a forall 
+    t: a type variable 
+      with assertions
+        instance of context has_u
+          with parameters 
+          Type:            instance of type t
+
+      
+function
+  with parameters 
+    the_t: a instance of type t
+  returning instance of type y
+  with body 
+    y: a instance of type t
+      with initializer ( u the_t ) 
+
+f: a function
+  with parameters 
+    p: a instance of type y
+  returning instance of type t
+  with body 
+    y: a int 
+    x: a typedef definition for char 
+      y: a instance of type x
+      z: a typedef definition for instance of type x
+        x: a instance of type z
+        y: a typedef definition for instance of type z
+        z: a instance of type y
+          with initializer x 
+      x: a instance of type z
+        with initializer y 
+    q: a instance of type x
+      with initializer y 
+
+g: a function
+  with parameters 
+    void 
+  returning instance of type t
+  with body 
+    x: a typedef definition for char 
+
+    Try
+
+        Branches of execution: 
+              
+              Application of: 
+
+                  Referencing: Variable: some_func
+
+              ... on no arguments: 
+
+
+            Catch
+
+                Declaration: 
+                    x: a instance of type x
+
+                Branches of execution: 
+                      y: a instance of type t
+                        with initializer x 
+    z: a instance of type x
+
+q: a function
+  with no parameters 
+  with old-style identifier list 
+    i: a untyped entity 
+  with old-style declaration list 
+    i: a int 
+  returning instance of type y
+  with body 
+
+    Switch
+
+        Expression: 
+
+            Referencing: Variable: i
+
+        Branches of execution: 
+
+            Case
+
+                Expression: 
+
+                    Referencing: Variable: 0
+
+                Branches of execution: 
+
+                    Return
+
+                        Expression: 
+
+                            Referencing: Variable: q
+
+            Default
+
+                Expression: 
+
+                    Null Expression
+
+                Branches of execution: 
+
+                    Return
+
+                        Expression: 
+
+                            Referencing: Variable: i
+
Index: translator/Tests/Parser/Expected/StructMember.tst
===================================================================
--- translator/Tests/Parser/Expected/StructMember.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Expected/StructMember.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,73 @@
+T: a typedef definition for int 
+struct S
+  with members 
+    m1: a int 
+      with bitfield width 3 
+    m2: a int 
+      with bitfield width 4 
+    int 
+      with bitfield width 2 
+    int 
+      with bitfield width 3 
+    int 
+      with bitfield width 4 
+    m3: a int 
+    m4: a int 
+    m5: a int 
+    m6: a int 
+    m7: a pointer to int 
+    m8: a pointer to int 
+    m9: a pointer to int 
+    m10: a pointer to function
+      with no parameters 
+      returning int 
+
+    m11: a pointer to function
+      with parameters 
+        int 
+      returning pointer to int 
+
+    T: a instance of type T
+    T: a instance of type T
+    m12: a pointer to int 
+    m13: a pointer to int 
+    m14: a pointer to function
+      with parameters 
+        int 
+      returning tuple with members 
+          pointer to int 
+
+
+    int 
+    int 
+    int 
+    int 
+    pointer to int 
+    int 
+    int 
+    pointer to int 
+    pointer to int 
+    pointer to int 
+    pointer to int 
+    pointer to int 
+    pointer to int 
+    pointer to function
+      with no parameters 
+      returning int 
+
+    pointer to pointer to function
+      with parameters 
+        int 
+      returning int 
+
+    instance of type T
+
+s: a instance of struct S
+
+u: a instance of union U
+  with members 
+    m1: a array of     5 int 
+    m2: a array of     5 int 
+    m3: a pointer to int 
+    m4: a pointer to int 
+
Index: translator/Tests/Parser/Expected/Tuple.tst
===================================================================
--- translator/Tests/Parser/Expected/Tuple.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Expected/Tuple.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,788 @@
+f: a function
+  with parameters 
+    int 
+    int 
+  returning int 
+
+g: a function
+  with parameters 
+    int 
+    int 
+    int 
+  returning int 
+
+h: a static function
+  with parameters 
+    a: a int 
+    b: a int 
+    c: a pointer to int 
+    d: a open array of char 
+  returning tuple with members 
+      int 
+      pointer to int 
+      pointer to int 
+      int 
+
+
+struct inner
+  with members 
+    f2: a int 
+    f3: a int 
+
+s: a instance of struct outer
+  with members 
+    f1: a int 
+    i: a instance of struct inner
+
+    f4: a double 
+
+sp: a pointer to instance of struct outer
+
+t1: a const volatile tuple with members 
+  int 
+  int 
+
+t2: a static const tuple with members 
+  int 
+  const int 
+
+t3: a static const tuple with members 
+  int 
+  const int 
+
+printf: a function
+  with parameters 
+    fmt: a pointer to char 
+    and a variable number of other arguments
+  returning tuple with members 
+      rc: a int 
+
+
+printf: a function
+  with parameters 
+    fmt: a pointer to char 
+    and a variable number of other arguments
+  returning int 
+
+f1: a function
+  with parameters 
+    w: a int 
+  returning tuple with members 
+      x: a short 
+      y: a unsigned 
+
+  with body 
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Application of: 
+
+            Operator: TupleC
+
+        ... on arguments: 
+
+            Referencing: Variable: y
+
+            Referencing: Variable: x
+
+        Application of: 
+
+            Operator: Assign
+
+        ... on arguments: 
+
+            Application of: 
+
+                Operator: TupleC
+
+            ... on arguments: 
+
+                Referencing: Variable: x
+
+                Referencing: Variable: y
+
+            Application of: 
+
+                Operator: TupleC
+
+            ... on arguments: 
+
+                Referencing: Variable: w
+                23 
+
+
+g1: a function
+  with no parameters 
+  returning tuple with members 
+      r: a tuple with members 
+        int 
+        char 
+        long 
+        int 
+
+
+  with body 
+    x: a short 
+    p: a short 
+    y: a unsigned int 
+    z: a tuple with members 
+      int 
+      int 
+
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Application of: 
+
+            Operator: TupleC
+
+        ... on arguments: 
+
+            Referencing: Variable: x
+
+            Referencing: Variable: y
+
+            Referencing: Variable: z
+
+        Application of: 
+
+            Operator: Cast
+
+        ... on arguments: 
+            Type:              tuple with members 
+                short 
+                unsigned int 
+                tuple with members 
+                  int 
+                  int 
+
+
+
+            Application of: 
+
+                Operator: TupleC
+
+            ... on arguments: 
+
+                Referencing: Variable: p
+
+                Application of: 
+
+                    Referencing: Variable: f
+
+                ... on arguments: 
+                    17 
+                3 
+
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Referencing: Variable: r
+
+        Application of: 
+
+            Operator: TupleC
+
+        ... on arguments: 
+
+            Referencing: Variable: x
+
+            Referencing: Variable: y
+
+            Referencing: Variable: z
+
+
+main: a function
+  with parameters 
+    argc: a int 
+    argv: a pointer to pointer to char 
+  returning tuple with members 
+      rc: a int 
+
+  with body 
+    a: a int 
+    b: a int 
+    c: a int 
+    d: a int 
+    t: a instance of struct outer
+
+      with initializer [designated by: ()( TupleC 1 7.0 ) ]
+    
+    Application of: 
+
+        Referencing: Variable: f
+
+    ... on arguments: 
+
+        Application of: 
+
+            Operator: TupleC
+
+        ... on arguments: 
+            3 
+            5 
+
+    
+    Application of: 
+
+        Referencing: Variable: g
+
+    ... on arguments: 
+
+        Application of: 
+
+            Operator: TupleC
+
+        ... on arguments: 
+            3 
+            5 
+        3 
+
+    
+    Application of: 
+
+        Referencing: Variable: f
+
+    ... on arguments: 
+
+        Referencing: Variable: t1
+
+    
+    Application of: 
+
+        Referencing: Variable: g
+
+    ... on arguments: 
+
+        Referencing: Variable: t1
+        3 
+
+    
+    Application of: 
+
+        Operator: TupleC
+
+    ... on arguments: 
+        3 
+        5 
+
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Application of: 
+
+            Operator: TupleC
+
+        ... on arguments: 
+
+            Referencing: Variable: a
+
+            Referencing: Variable: b
+        3 
+
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Application of: 
+
+            Operator: TupleC
+
+        ... on arguments: 
+
+            Referencing: Variable: a
+
+            Referencing: Variable: b
+
+        Application of: 
+
+            Operator: TupleC
+
+        ... on arguments: 
+            4.6 
+
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Application of: 
+
+            Operator: TupleC
+
+        ... on arguments: 
+
+            Referencing: Variable: a
+
+            Referencing: Variable: b
+
+        Application of: 
+
+            Operator: Assign
+
+        ... on arguments: 
+
+            Application of: 
+
+                Operator: TupleC
+
+            ... on arguments: 
+
+                Referencing: Variable: c
+
+                Referencing: Variable: d
+
+            Application of: 
+
+                Operator: TupleC
+
+            ... on arguments: 
+                3 
+                5 
+
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Application of: 
+
+            Operator: TupleC
+
+        ... on arguments: 
+
+            Referencing: Variable: a
+
+            Referencing: Variable: b
+
+            Application of: 
+
+                Operator: TupleC
+
+            ... on arguments: 
+
+                Referencing: Variable: c
+
+        Application of: 
+
+            Operator: TupleC
+
+        ... on arguments: 
+            2 
+
+            Referencing: Variable: a
+
+            Referencing: Variable: b
+
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Application of: 
+
+            Operator: TupleC
+
+        ... on arguments: 
+
+            Referencing: Variable: a
+
+            Referencing: Variable: b
+
+        Application of: 
+
+            Operator: Cond
+
+        ... on arguments: 
+
+            Application of: 
+
+                Operator: GThan
+
+            ... on arguments: 
+                3 
+                4 
+
+            Application of: 
+
+                Operator: TupleC
+
+            ... on arguments: 
+
+                Referencing: Variable: b
+                6 
+
+            Application of: 
+
+                Operator: TupleC
+
+            ... on arguments: 
+                7 
+                8 
+
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Referencing: Variable: t1
+
+        Application of: 
+
+            Operator: TupleC
+
+        ... on arguments: 
+
+            Referencing: Variable: a
+
+            Referencing: Variable: b
+
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Referencing: Variable: t1
+
+        Application of: 
+
+            Operator: Assign
+
+        ... on arguments: 
+
+            Referencing: Variable: t2
+
+            Application of: 
+
+                Operator: TupleC
+
+            ... on arguments: 
+
+                Referencing: Variable: a
+
+                Referencing: Variable: b
+
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Application of: 
+
+            Operator: TupleC
+
+        ... on arguments: 
+
+            Referencing: Variable: a
+
+            Referencing: Variable: b
+
+        Application of: 
+
+            Operator: Assign
+
+        ... on arguments: 
+
+            Application of: 
+
+                Operator: TupleC
+
+            ... on arguments: 
+
+                Referencing: Variable: c
+
+                Referencing: Variable: d
+
+            Application of: 
+
+                Operator: PlusAssn
+
+            ... on arguments: 
+
+                Referencing: Variable: d
+
+                Application of: 
+
+                    Operator: PlusAssn
+
+                ... on arguments: 
+
+                    Referencing: Variable: c
+
+                    Referencing: Variable: 1
+
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Application of: 
+
+            Operator: TupleC
+
+        ... on arguments: 
+
+            Referencing: Variable: a
+
+            Referencing: Variable: b
+
+        Application of: 
+
+            Operator: Assign
+
+        ... on arguments: 
+
+            Application of: 
+
+                Operator: TupleC
+
+            ... on arguments: 
+
+                Referencing: Variable: c
+
+                Referencing: Variable: d
+
+            Referencing: Variable: t1
+
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Application of: 
+
+            Operator: TupleC
+
+        ... on arguments: 
+
+            Referencing: Variable: a
+
+            Referencing: Variable: b
+
+        Application of: 
+
+            Operator: Assign
+
+        ... on arguments: 
+
+            Referencing: Variable: t1
+
+            Application of: 
+
+                Operator: TupleC
+
+            ... on arguments: 
+
+                Referencing: Variable: c
+
+                Referencing: Variable: d
+
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Application of: 
+
+            Operator: TupleC
+
+        ... on arguments: 
+
+            Referencing: Variable: a
+
+            Referencing: Variable: b
+
+        Application of: 
+
+            Operator: Assign
+
+        ... on arguments: 
+
+            Referencing: Variable: t1
+
+            Application of: 
+
+                Operator: Assign
+
+            ... on arguments: 
+
+                Referencing: Variable: t2
+
+                Application of: 
+
+                    Operator: TupleC
+
+                ... on arguments: 
+
+                    Referencing: Variable: c
+
+                    Referencing: Variable: d
+
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Referencing: Variable: t1
+
+        Application of: 
+
+            Operator: Assign
+
+        ... on arguments: 
+
+            Application of: 
+
+                Operator: TupleC
+
+            ... on arguments: 
+                3 
+                4 
+
+            Application of: 
+
+                Operator: Assign
+
+            ... on arguments: 
+
+                Application of: 
+
+                    Operator: TupleC
+
+                ... on arguments: 
+                    3 
+                    4 
+
+                Application of: 
+
+                    Operator: Assign
+
+                ... on arguments: 
+
+                    Referencing: Variable: t1
+
+                    Application of: 
+
+                        Operator: TupleC
+
+                    ... on arguments: 
+                        3 
+                        4 
+
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Referencing: Variable: s
+
+        Application of: 
+
+            Operator: TupleC
+
+        ... on arguments: 
+            11 
+
+            Application of: 
+
+                Operator: Comma
+
+            ... on arguments: 
+                12 
+                13 
+            3.14159 
+
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Referencing: Variable: s
+
+        Application of: 
+
+            Referencing: Variable: h
+
+        ... on arguments: 
+            3 
+            3 
+
+            Referencing: Variable: 0
+            ""abc"" 
+
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Referencing: Variable: sp
+
+        Referencing: Variable: sp
+
+    
+    Application of: 
+
+        Referencing: Variable: printf
+
+    ... on arguments: 
+        ""expecting 3, 17, 23, 4; got %d, %d, %d, %d\n"" 
+
+        Referencing: Variable: s
+
+    
+    Application of: 
+
+        Operator: Assign
+
+    ... on arguments: 
+
+        Referencing: Variable: rc
+
+        Referencing: Variable: 0
+
+
Index: translator/Tests/Parser/Expected/TypeGenerator.tst
===================================================================
--- translator/Tests/Parser/Expected/TypeGenerator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Expected/TypeGenerator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,112 @@
+context addable
+  with type parameters 
+    T: a type variable 
+  with members 
+    ?+?: a function
+      with parameters 
+        instance of type T
+        instance of type T
+      returning instance of type T
+
+
+List: a type definition 
+  with parameters
+  T: a type variable 
+    with assertions
+      instance of context addable
+        with parameters 
+        Type:          instance of type T
+
+    
+
+  with assertions
+    instance of context addable
+      with parameters 
+      Type:        instance of type T
+
+  for pointer to instance of struct __anonymous0
+    with members 
+      data: a instance of type T
+      next: a pointer to instance of type List with parameters
+        Type:          instance of type T
+
+
+ListOfIntegers: a typedef definition for instance of type List with parameters
+    Type:      int 
+
+li: a instance of type ListOfIntegers
+f: a function
+  with parameters 
+    g: a pointer to function
+      with parameters 
+        int 
+      returning instance of type List with parameters
+          Type:            int 
+
+
+  returning int 
+
+h: a function
+  with parameters 
+    p: a pointer to instance of type List with parameters
+      Type:        int 
+
+  returning tuple with members 
+      int 
+
+
+struct node
+  with type parameters 
+    T: a type variable 
+      with assertions
+        instance of context addable
+          with parameters 
+          Type:            instance of type T
+
+      
+  with members 
+    data: a instance of type T
+    next: a pointer to instance of struct node
+      instantiated with actual parameters 
+        Type:          instance of type T
+      with parameters 
+      Type:        instance of type T
+
+
+List: a type definition 
+  with parameters
+  T: a type variable 
+for pointer to instance of struct node
+    instantiated with actual parameters 
+      Type:        instance of type T
+    with parameters 
+    Type:      instance of type T
+
+my_list: a instance of type List with parameters
+  Type:    int 
+
+Complex: a type definition 
+  with assertions
+    instance of context addable
+      with parameters 
+      Type:        instance of type Complex
+
+  
+main: a function
+  with no parameters 
+  returning int 
+  with body 
+    
+    Application of: 
+
+        Operator: Cast
+
+    ... on arguments: 
+        Type:          struct node
+            instantiated with actual parameters 
+              Type:                int 
+
+
+        Referencing: Variable: my_list
+
+
Index: translator/Tests/Parser/Expected/Typedef.tst
===================================================================
--- translator/Tests/Parser/Expected/Typedef.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Expected/Typedef.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,97 @@
+T: a typedef definition for int 
+f: a function
+  with parameters 
+    void 
+  returning void 
+  with body 
+    T: a function
+      with parameters 
+        instance of type T
+      returning int 
+
+    
+    Application of: 
+
+        Referencing: Variable: T
+
+    ... on arguments: 
+        3 
+
+
+fred: a instance of struct __anonymous0
+  with members 
+    T: a instance of type T
+
+  with initializer [3 ]
+a: a typedef definition for pointer to function
+    with parameters 
+      int 
+      char 
+    returning int 
+
+b: a instance of type a
+g: a function
+  with parameters 
+    void 
+  returning int 
+  with body 
+    a: a double 
+
+c: a instance of type a
+main: a function
+  with no parameters 
+  returning int 
+  with body 
+
+  Null Statement:
+
+arrayOf10Pointers: a typedef definition for array of   10 pointer to int 
+x: a instance of type arrayOf10Pointers
+constantPointer: a typedef definition for const pointer to int 
+funcPtr: a typedef definition for pointer to function
+    with parameters 
+      open array of int 
+    returning tuple with members 
+        int 
+
+
+funcProto: a typedef definition for function
+    with parameters 
+      open array of int 
+    returning tuple with members 
+        int 
+
+
+tupleType: a typedef definition for tuple with members 
+    int 
+    int 
+
+tupleTypePtr: a typedef definition for pointer to tuple with members 
+    int 
+    int 
+
+a: a typedef definition for pointer to int 
+b: a typedef definition for pointer to int 
+f: a typedef definition for function
+    with parameters 
+      pointer to int 
+    returning tuple with members 
+        int 
+
+
+g: a typedef definition for function
+    with parameters 
+      pointer to int 
+    returning tuple with members 
+        int 
+
+
+t: a typedef definition for tuple with members 
+    pointer to static array of     10 int 
+
+f: a typedef definition for function
+    with no parameters 
+    returning tuple with members 
+        x: a pointer to static array of         10 int 
+
+
Index: translator/Tests/Parser/Expected/TypedefDeclarator.tst
===================================================================
--- translator/Tests/Parser/Expected/TypedefDeclarator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Expected/TypedefDeclarator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,253 @@
+f0: a typedef definition for int 
+f1: a typedef definition for int 
+f2: a typedef definition for int 
+f3: a typedef definition for int 
+f4: a typedef definition for int 
+f5: a typedef definition for int 
+f6: a typedef definition for int 
+f7: a typedef definition for int 
+f8: a typedef definition for int 
+f9: a typedef definition for int 
+f10: a typedef definition for int 
+f11: a typedef definition for int 
+f12: a typedef definition for int 
+f13: a typedef definition for int 
+f14: a typedef definition for int 
+f15: a typedef definition for int 
+f16: a typedef definition for int 
+f17: a typedef definition for int 
+f18: a typedef definition for int 
+f19: a typedef definition for int 
+f20: a typedef definition for int 
+f21: a typedef definition for int 
+f22: a typedef definition for int 
+f23: a typedef definition for int 
+f24: a typedef definition for int 
+f25: a typedef definition for int 
+f26: a typedef definition for int 
+f27: a typedef definition for int 
+f28: a typedef definition for int 
+f29: a typedef definition for int 
+f30: a typedef definition for int 
+f31: a typedef definition for int 
+f32: a typedef definition for int 
+f33: a typedef definition for int 
+f34: a typedef definition for int 
+f35: a typedef definition for int 
+f36: a typedef definition for int 
+f37: a typedef definition for int 
+f38: a typedef definition for int 
+f39: a typedef definition for int 
+f40: a typedef definition for int 
+f41: a typedef definition for int 
+f42: a typedef definition for int 
+f43: a typedef definition for int 
+f44: a typedef definition for int 
+f45: a typedef definition for int 
+f46: a typedef definition for int 
+f47: a typedef definition for int 
+f48: a typedef definition for int 
+f49: a typedef definition for int 
+f50: a typedef definition for int 
+f51: a typedef definition for int 
+f52: a typedef definition for int 
+f53: a typedef definition for int 
+f54: a typedef definition for int 
+f55: a typedef definition for int 
+f56: a typedef definition for int 
+f57: a typedef definition for int 
+f58: a typedef definition for int 
+f59: a typedef definition for int 
+f60: a typedef definition for int 
+f61: a typedef definition for int 
+f62: a typedef definition for int 
+f63: a typedef definition for int 
+f64: a typedef definition for int 
+f65: a typedef definition for int 
+f66: a typedef definition for int 
+f67: a typedef definition for int 
+f68: a typedef definition for int 
+f69: a typedef definition for int 
+f70: a typedef definition for int 
+f71: a typedef definition for int 
+f72: a typedef definition for int 
+f73: a typedef definition for int 
+f74: a typedef definition for int 
+f75: a typedef definition for int 
+f76: a typedef definition for int 
+f77: a typedef definition for int 
+f78: a typedef definition for int 
+f79: a typedef definition for int 
+f80: a typedef definition for int 
+f81: a typedef definition for int 
+f82: a typedef definition for int 
+f83: a typedef definition for int 
+f84: a typedef definition for int 
+f85: a typedef definition for int 
+f86: a typedef definition for int 
+f87: a typedef definition for int 
+f88: a typedef definition for int 
+f89: a typedef definition for int 
+main: a function
+  with no parameters 
+  returning int 
+  with body 
+    f1: a int 
+    f2: a int 
+    f3: a pointer to int 
+    f4: a pointer to pointer to int 
+    f5: a pointer to const pointer to int 
+    f6: a const pointer to const pointer to int 
+    f7: a pointer to int 
+    f8: a pointer to pointer to int 
+    f9: a pointer to const pointer to int 
+    f10: a const pointer to const pointer to int 
+    f11: a pointer to int 
+    f12: a pointer to pointer to int 
+    f13: a pointer to const pointer to int 
+    f14: a const pointer to const pointer to int 
+    f15: a open array of int 
+    f16: a array of     10 int 
+    f17: a open array of int 
+    f18: a array of     10 int 
+    f19: a open array of pointer to int 
+    f20: a array of     10 pointer to int 
+    f21: a open array of pointer to pointer to int 
+    f22: a array of     10 pointer to pointer to int 
+    f23: a open array of pointer to const pointer to int 
+    f24: a array of     10 pointer to const pointer to int 
+    f25: a open array of const pointer to const pointer to int 
+    f26: a array of     10 const pointer to const pointer to int 
+    f27: a open array of pointer to int 
+    f28: a array of     10 pointer to int 
+    f29: a open array of pointer to pointer to int 
+    f30: a array of     10 pointer to pointer to int 
+    f31: a open array of pointer to const pointer to int 
+    f32: a array of     10 pointer to const pointer to int 
+    f33: a open array of const pointer to const pointer to int 
+    f34: a array of     10 const pointer to const pointer to int 
+    f35: a open array of pointer to int 
+    f36: a array of     10 pointer to int 
+    f37: a open array of pointer to pointer to int 
+    f38: a array of     10 pointer to pointer to int 
+    f39: a open array of pointer to const pointer to int 
+    f40: a array of     10 pointer to const pointer to int 
+    f41: a open array of const pointer to const pointer to int 
+    f42: a array of     10 const pointer to const pointer to int 
+    f43: a open array of array of     3 int 
+    f44: a array of     3 array of     3 int 
+    f45: a open array of array of     3 int 
+    f46: a array of     3 array of     3 int 
+    f47: a open array of array of     3 int 
+    f48: a array of     3 array of     3 int 
+    f49: a open array of array of     3 pointer to int 
+    f50: a array of     3 array of     3 pointer to int 
+    f51: a open array of array of     3 pointer to pointer to int 
+    f52: a array of     3 array of     3 pointer to pointer to int 
+    f53: a open array of array of     3 pointer to const pointer to int 
+    f54: a array of     3 array of     3 pointer to const pointer to int 
+    f55: a open array of array of     3 const pointer to const pointer to int 
+    f56: a array of     3 array of     3 const pointer to const pointer to int 
+    f57: a open array of array of     3 pointer to int 
+    f58: a array of     3 array of     3 pointer to int 
+    f59: a open array of array of     3 pointer to pointer to int 
+    f60: a array of     3 array of     3 pointer to pointer to int 
+    f61: a open array of array of     3 pointer to const pointer to int 
+    f62: a array of     3 array of     3 pointer to const pointer to int 
+    f63: a open array of array of     3 const pointer to const pointer to int 
+    f64: a array of     3 array of     3 const pointer to const pointer to int 
+    f65: a function
+      with parameters 
+        int 
+      returning int 
+
+    f66: a function
+      with parameters 
+        int 
+      returning int 
+
+    f67: a function
+      with parameters 
+        int 
+      returning pointer to int 
+
+    f68: a function
+      with parameters 
+        int 
+      returning pointer to pointer to int 
+
+    f69: a function
+      with parameters 
+        int 
+      returning pointer to const pointer to int 
+
+    f70: a function
+      with parameters 
+        int 
+      returning const pointer to const pointer to int 
+
+    f71: a function
+      with parameters 
+        int 
+      returning pointer to int 
+
+    f72: a function
+      with parameters 
+        int 
+      returning pointer to pointer to int 
+
+    f73: a function
+      with parameters 
+        int 
+      returning pointer to const pointer to int 
+
+    f74: a function
+      with parameters 
+        int 
+      returning const pointer to const pointer to int 
+
+    f75: a pointer to function
+      with parameters 
+        int 
+      returning int 
+
+    f76: a pointer to pointer to function
+      with parameters 
+        int 
+      returning int 
+
+    f77: a pointer to const pointer to function
+      with parameters 
+        int 
+      returning int 
+
+    f78: a const pointer to const pointer to function
+      with parameters 
+        int 
+      returning int 
+
+    f79: a pointer to function
+      with parameters 
+        int 
+      returning pointer to function
+          with no parameters 
+          returning int 
+
+
+    f80: a const pointer to function
+      with parameters 
+        int 
+      returning pointer to function
+          with no parameters 
+          returning int 
+
+
+    f81: a const pointer to function
+      with parameters 
+        int 
+      returning const pointer to function
+          with no parameters 
+          returning int 
+
+
+
Index: translator/Tests/Parser/Expected/TypedefParamDeclarator.tst
===================================================================
--- translator/Tests/Parser/Expected/TypedefParamDeclarator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Expected/TypedefParamDeclarator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,349 @@
+f0: a typedef definition for int 
+f1: a typedef definition for int 
+f2: a typedef definition for int 
+f3: a typedef definition for int 
+f4: a typedef definition for int 
+f5: a typedef definition for int 
+f6: a typedef definition for int 
+f7: a typedef definition for int 
+f8: a typedef definition for int 
+f9: a typedef definition for int 
+f10: a typedef definition for int 
+f11: a typedef definition for int 
+f12: a typedef definition for int 
+f13: a typedef definition for int 
+f14: a typedef definition for int 
+f15: a typedef definition for int 
+f16: a typedef definition for int 
+f17: a typedef definition for int 
+f18: a typedef definition for int 
+f19: a typedef definition for int 
+f20: a typedef definition for int 
+f21: a typedef definition for int 
+f22: a typedef definition for int 
+f23: a typedef definition for int 
+f24: a typedef definition for int 
+f25: a typedef definition for int 
+f26: a typedef definition for int 
+f27: a typedef definition for int 
+f28: a typedef definition for int 
+f29: a typedef definition for int 
+f30: a typedef definition for int 
+f31: a typedef definition for int 
+f32: a typedef definition for int 
+f33: a typedef definition for int 
+f34: a typedef definition for int 
+f35: a typedef definition for int 
+f36: a typedef definition for int 
+f37: a typedef definition for int 
+f38: a typedef definition for int 
+f39: a typedef definition for int 
+f40: a typedef definition for int 
+f41: a typedef definition for int 
+f42: a typedef definition for int 
+f43: a typedef definition for int 
+f44: a typedef definition for int 
+f45: a typedef definition for int 
+f46: a typedef definition for int 
+f47: a typedef definition for int 
+f48: a typedef definition for int 
+f49: a typedef definition for int 
+f50: a typedef definition for int 
+f51: a typedef definition for int 
+f52: a typedef definition for int 
+f53: a typedef definition for int 
+f54: a typedef definition for int 
+f55: a typedef definition for int 
+f56: a typedef definition for int 
+f57: a typedef definition for int 
+f58: a typedef definition for int 
+f59: a typedef definition for int 
+f60: a typedef definition for int 
+f61: a typedef definition for int 
+f62: a typedef definition for int 
+f63: a typedef definition for int 
+f64: a typedef definition for int 
+f65: a typedef definition for int 
+f66: a typedef definition for int 
+f67: a typedef definition for int 
+f68: a typedef definition for int 
+f69: a typedef definition for int 
+f70: a typedef definition for int 
+f71: a typedef definition for int 
+f72: a typedef definition for int 
+f73: a typedef definition for int 
+f74: a typedef definition for int 
+f75: a typedef definition for int 
+f76: a typedef definition for int 
+f77: a typedef definition for int 
+f78: a typedef definition for int 
+f79: a typedef definition for int 
+f80: a typedef definition for int 
+f81: a typedef definition for int 
+f82: a typedef definition for int 
+f83: a typedef definition for int 
+f84: a typedef definition for int 
+f85: a typedef definition for int 
+f86: a typedef definition for int 
+f87: a typedef definition for int 
+f88: a typedef definition for int 
+f89: a typedef definition for int 
+f90: a typedef definition for int 
+f91: a typedef definition for int 
+f92: a typedef definition for int 
+f93: a typedef definition for int 
+f94: a typedef definition for int 
+f95: a typedef definition for int 
+f96: a typedef definition for int 
+f97: a typedef definition for int 
+f98: a typedef definition for int 
+f99: a typedef definition for int 
+f100: a typedef definition for int 
+f101: a typedef definition for int 
+f102: a typedef definition for int 
+f103: a typedef definition for int 
+f104: a typedef definition for int 
+f105: a typedef definition for int 
+f106: a typedef definition for int 
+f107: a typedef definition for int 
+f108: a typedef definition for int 
+f109: a typedef definition for int 
+f110: a typedef definition for int 
+f111: a typedef definition for int 
+f112: a typedef definition for int 
+f113: a typedef definition for int 
+f114: a typedef definition for int 
+f115: a typedef definition for int 
+f116: a typedef definition for int 
+f117: a typedef definition for int 
+f118: a typedef definition for int 
+f119: a typedef definition for int 
+fred: a function
+  with parameters 
+    f1: a int 
+    f3: a pointer to int 
+    f4: a pointer to pointer to int 
+    f5: a pointer to const pointer to int 
+    f6: a const pointer to const pointer to int 
+    f11: a pointer to int 
+    f12: a pointer to pointer to int 
+    f13: a pointer to const pointer to int 
+    f14: a const pointer to const pointer to int 
+    f15: a open array of int 
+    f16: a array of     10 int 
+    f19: a open array of pointer to int 
+    f20: a array of     10 pointer to int 
+    f21: a open array of pointer to pointer to int 
+    f22: a array of     10 pointer to pointer to int 
+    f23: a open array of pointer to const pointer to int 
+    f24: a array of     10 pointer to const pointer to int 
+    f25: a open array of const pointer to const pointer to int 
+    f26: a array of     10 const pointer to const pointer to int 
+    f35: a open array of pointer to int 
+    f36: a array of     10 pointer to int 
+    f37: a open array of pointer to pointer to int 
+    f38: a array of     10 pointer to pointer to int 
+    f39: a open array of pointer to const pointer to int 
+    f40: a array of     10 pointer to const pointer to int 
+    f41: a open array of const pointer to const pointer to int 
+    f42: a array of     10 const pointer to const pointer to int 
+    f43: a open array of array of     3 int 
+    f44: a array of     3 array of     3 int 
+    f49: a open array of array of     3 pointer to int 
+    f50: a array of     3 array of     3 pointer to int 
+    f51: a open array of array of     3 pointer to pointer to int 
+    f52: a array of     3 array of     3 pointer to pointer to int 
+    f53: a open array of array of     3 pointer to const pointer to int 
+    f54: a array of     3 array of     3 pointer to const pointer to int 
+    f55: a open array of array of     3 const pointer to const pointer to int 
+    f56: a array of     3 array of     3 const pointer to const pointer to int 
+    f57: a open array of array of     3 pointer to int 
+    f58: a array of     3 array of     3 pointer to int 
+    f59: a open array of array of     3 pointer to pointer to int 
+    f60: a array of     3 array of     3 pointer to pointer to int 
+    f61: a open array of array of     3 pointer to const pointer to int 
+    f62: a array of     3 array of     3 pointer to const pointer to int 
+    f63: a open array of array of     3 const pointer to const pointer to int 
+    f64: a array of     3 array of     3 const pointer to const pointer to int 
+    f65: a function
+      with parameters 
+        int 
+      returning int 
+
+    f67: a function
+      with parameters 
+        int 
+      returning pointer to int 
+
+    f68: a function
+      with parameters 
+        int 
+      returning pointer to pointer to int 
+
+    f69: a function
+      with parameters 
+        int 
+      returning pointer to const pointer to int 
+
+    f70: a function
+      with parameters 
+        int 
+      returning const pointer to const pointer to int 
+
+    f75: a pointer to function
+      with parameters 
+        int 
+      returning int 
+
+    f76: a pointer to pointer to function
+      with parameters 
+        int 
+      returning int 
+
+    f77: a pointer to const pointer to function
+      with parameters 
+        int 
+      returning int 
+
+    f78: a const pointer to const pointer to function
+      with parameters 
+        int 
+      returning int 
+
+    f79: a pointer to function
+      with parameters 
+        int 
+      returning pointer to function
+          with no parameters 
+          returning int 
+
+
+    f80: a const pointer to function
+      with parameters 
+        int 
+      returning pointer to function
+          with no parameters 
+          returning int 
+
+
+    f81: a const pointer to function
+      with parameters 
+        int 
+      returning const pointer to function
+          with no parameters 
+          returning int 
+
+
+    f82: a const variable-length array of int 
+    f83: a const array of     3 int 
+    f84: a static array of     3 int 
+    f85: a const static array of     3 int 
+    function
+      with parameters 
+        const variable-length array of instance of type f86
+      returning int 
+
+    function
+      with parameters 
+        const array of         3 instance of type f87
+      returning int 
+
+    function
+      with parameters 
+        static array of         3 instance of type f88
+      returning int 
+
+    function
+      with parameters 
+        const static array of         3 instance of type f89
+      returning int 
+
+    f90: a const variable-length array of pointer to int 
+    f91: a const array of     3 pointer to int 
+    f92: a static array of     3 pointer to pointer to int 
+    f93: a const static array of     3 pointer to const pointer to int 
+    f94: a const static array of     3 const pointer to const pointer to int 
+    function
+      with parameters 
+        const variable-length array of instance of type f95
+      returning pointer to int 
+
+    function
+      with parameters 
+        const array of         3 instance of type f96
+      returning pointer to int 
+
+    function
+      with parameters 
+        static array of         3 instance of type f97
+      returning pointer to pointer to int 
+
+    function
+      with parameters 
+        const static array of         3 instance of type f98
+      returning pointer to const pointer to int 
+
+    function
+      with parameters 
+        const static array of         3 instance of type f99
+      returning const pointer to const pointer to int 
+
+    f100: a const variable-length array of array of     3 int 
+    f101: a const array of     3 array of     3 int 
+    f102: a static array of     3 array of     3 int 
+    f103: a const static array of     3 array of     3 int 
+    function
+      with parameters 
+        const variable-length array of array of         3 instance of type f104
+      returning int 
+
+    function
+      with parameters 
+        const array of         3 array of         3 instance of type f105
+      returning int 
+
+    function
+      with parameters 
+        static array of         3 array of         3 instance of type f106
+      returning int 
+
+    function
+      with parameters 
+        const static array of         3 array of         3 instance of type f107
+      returning int 
+
+    f108: a const variable-length array of array of     3 pointer to int 
+    f109: a const array of     3 array of     3 pointer to int 
+    f110: a static array of     3 array of     3 pointer to pointer to int 
+    f111: a const static array of     3 array of     3 pointer to const pointer to int 
+    f112: a const static array of     3 array of     3 const pointer to const pointer to int 
+    function
+      with parameters 
+        const variable-length array of array of         3 instance of type f113
+      returning pointer to int 
+
+    function
+      with parameters 
+        const array of         3 array of         3 instance of type f114
+      returning pointer to int 
+
+    function
+      with parameters 
+        static array of         3 array of         3 instance of type f115
+      returning pointer to pointer to int 
+
+    function
+      with parameters 
+        const static array of         3 array of         3 instance of type f116
+      returning pointer to const pointer to int 
+
+    function
+      with parameters 
+        const static array of         3 array of         3 instance of type f117
+      returning const pointer to const pointer to int 
+
+  returning int 
+  with body 
+
+  Null Statement:
+
Index: translator/Tests/Parser/Expected/VariableDeclarator.tst
===================================================================
--- translator/Tests/Parser/Expected/VariableDeclarator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Expected/VariableDeclarator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,168 @@
+f1: a int 
+f2: a int 
+f3: a pointer to int 
+f4: a pointer to pointer to int 
+f5: a pointer to const pointer to int 
+f6: a const pointer to const pointer to int 
+f7: a pointer to int 
+f8: a pointer to pointer to int 
+f9: a pointer to const pointer to int 
+f10: a const pointer to const pointer to int 
+f11: a pointer to int 
+f12: a pointer to pointer to int 
+f13: a pointer to const pointer to int 
+f14: a const pointer to const pointer to int 
+f15: a open array of int 
+f16: a array of 10 int 
+f17: a open array of int 
+f18: a array of 10 int 
+f19: a open array of pointer to int 
+f20: a array of 10 pointer to int 
+f21: a open array of pointer to pointer to int 
+f22: a array of 10 pointer to pointer to int 
+f23: a open array of pointer to const pointer to int 
+f24: a array of 10 pointer to const pointer to int 
+f25: a open array of const pointer to const pointer to int 
+f26: a array of 10 const pointer to const pointer to int 
+f27: a open array of pointer to int 
+f28: a array of 10 pointer to int 
+f29: a open array of pointer to pointer to int 
+f30: a array of 10 pointer to pointer to int 
+f31: a open array of pointer to const pointer to int 
+f32: a array of 10 pointer to const pointer to int 
+f33: a open array of const pointer to const pointer to int 
+f34: a array of 10 const pointer to const pointer to int 
+f35: a open array of pointer to int 
+f36: a array of 10 pointer to int 
+f37: a open array of pointer to pointer to int 
+f38: a array of 10 pointer to pointer to int 
+f39: a open array of pointer to const pointer to int 
+f40: a array of 10 pointer to const pointer to int 
+f41: a open array of const pointer to const pointer to int 
+f42: a array of 10 const pointer to const pointer to int 
+f43: a open array of array of 3 int 
+f44: a array of 3 array of 3 int 
+f45: a open array of array of 3 int 
+f46: a array of 3 array of 3 int 
+f47: a open array of array of 3 int 
+f48: a array of 3 array of 3 int 
+f49: a open array of array of 3 pointer to int 
+f50: a array of 3 array of 3 pointer to int 
+f51: a open array of array of 3 pointer to pointer to int 
+f52: a array of 3 array of 3 pointer to pointer to int 
+f53: a open array of array of 3 pointer to const pointer to int 
+f54: a array of 3 array of 3 pointer to const pointer to int 
+f55: a open array of array of 3 const pointer to const pointer to int 
+f56: a array of 3 array of 3 const pointer to const pointer to int 
+f57: a open array of array of 3 pointer to int 
+f58: a array of 3 array of 3 pointer to int 
+f59: a open array of array of 3 pointer to pointer to int 
+f60: a array of 3 array of 3 pointer to pointer to int 
+f61: a open array of array of 3 pointer to const pointer to int 
+f62: a array of 3 array of 3 pointer to const pointer to int 
+f63: a open array of array of 3 const pointer to const pointer to int 
+f64: a array of 3 array of 3 const pointer to const pointer to int 
+f65: a function
+  with parameters 
+    int 
+  returning int 
+
+f66: a function
+  with parameters 
+    int 
+  returning int 
+
+f67: a function
+  with parameters 
+    int 
+  returning pointer to int 
+
+f68: a function
+  with parameters 
+    int 
+  returning pointer to pointer to int 
+
+f69: a function
+  with parameters 
+    int 
+  returning pointer to const pointer to int 
+
+f70: a function
+  with parameters 
+    int 
+  returning const pointer to const pointer to int 
+
+f71: a function
+  with parameters 
+    int 
+  returning pointer to int 
+
+f72: a function
+  with parameters 
+    int 
+  returning pointer to pointer to int 
+
+f73: a function
+  with parameters 
+    int 
+  returning pointer to const pointer to int 
+
+f74: a function
+  with parameters 
+    int 
+  returning const pointer to const pointer to int 
+
+f75: a pointer to function
+  with parameters 
+    int 
+  returning int 
+
+f76: a pointer to pointer to function
+  with parameters 
+    int 
+  returning int 
+
+f77: a pointer to const pointer to function
+  with parameters 
+    int 
+  returning int 
+
+f78: a const pointer to const pointer to function
+  with parameters 
+    int 
+  returning int 
+
+f79: a pointer to function
+  with parameters 
+    int 
+  returning pointer to function
+      with no parameters 
+      returning int 
+
+
+f80: a const pointer to function
+  with parameters 
+    int 
+  returning pointer to function
+      with no parameters 
+      returning int 
+
+
+f81: a const pointer to function
+  with parameters 
+    int 
+  returning const pointer to function
+      with no parameters 
+      returning int 
+
+
+z: a pointer to array of 20 double 
+w: a array of 20 pointer to char 
+v3: a pointer to open array of pointer to open array of pointer to function
+  with parameters 
+    pointer to open array of pointer to open array of int 
+    pointer to open array of pointer to open array of int 
+  returning tuple with members 
+      pointer to open array of pointer to open array of int 
+
+
Index: translator/Tests/Parser/Forall.c
===================================================================
--- translator/Tests/Parser/Forall.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Forall.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,51 @@
+typedef forall ( type T ) int (*f)( int );
+
+forall( type T )
+    void swap( T left, T right ) {
+	T temp = left;
+	left = right;
+	right = temp;
+    }
+
+context sumable( type T ) {
+    const T 0;
+    T ?+?(T, T);
+    T ?++(T);
+    [T] ?+=?(T,T);
+};
+
+type T1 | { const T1 0; T1 ?+?(T1, T1); T1 ?++(T1); [T1] ?+=?(T1,T1); },
+     T2(type P1, type P2 ),
+     T3 | sumable(T3);
+
+type T2(type P1, type P2) | sumable(T2(P1,P2)) = struct { P1 i; P2 j; };
+
+T2(int, int) w1;
+typedef T2(int, int) w2;
+w2 g2;
+type w3 = T2(int, int);
+w3 g3;
+
+forall( type T | sumable( T ) )
+    T sum( int n, T a[] ) {
+	T total = 0;
+	int i;
+	for ( i = 0; i < n; i += 1 )
+	    total = total + a[i];
+	return total;
+    }
+
+forall( type T | { const T 0; T ?+?(T, T); T ?++(T); [T] ?+=?(T,T); } )
+    T twice( T t ) {
+	return t + t;
+    }
+
+int main() {
+    int x = 1, y = 2, a[10];
+    float f;
+
+    swap( x, y );
+    twice( x, y );
+    f = min( 4.0, 3.0 );
+    sum( 10, a );
+}
Index: translator/Tests/Parser/Functions.c
===================================================================
--- translator/Tests/Parser/Functions.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Functions.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,163 @@
+// ANSI function definitions
+
+void h(void) {}
+
+int f (
+    int (void),
+    int (int),
+    int ((void)),
+    int ((int)),
+    void g(void)
+  ) {
+    (*g)();
+    g();
+    g = h;
+}
+
+int f1() {}
+int (f2()) {}
+int (*f3())() {}
+int *((f4())) {}
+int ((*f5()))() {}
+int *f6() {}
+int *(f7)() {}
+int **f8() {}
+int * const *(f9)() {}
+int (*f10())[] {}
+int (*f11())[][3] {}
+int ((*f12())[])[3] {}
+
+// "implicit int" type specifier (not ANSI)
+
+fII1( int i ) {}
+const fII2( int i ) {}
+extern fII3( int i ) {}
+extern const fII4( int i ) {}
+
+*fII5() {}
+const *fII6() {}
+const long *fII7() {}
+static const long *fII8() {}
+const static long *fII9() {}
+
+// K&R function definitions
+
+fO1( i ) int i; {}
+int fO2( i ) int i; {}
+const fO3( i ) int i; {}
+extern fO4( i ) int i; {}
+extern const fO5( i ) int i; {}
+
+// Cforall extensions
+
+[] f( );
+[int] f( );
+[] f(int);
+[int] f(int);
+[] f( ) {}
+[int] f( ) {}
+[] f(int) {}
+[int] f(int) {}
+
+[int x] f( );
+[] f(int x);
+[int x] f(int x);
+[int x] f( ) {}
+[] f(int x) {}
+[int x] f(int x) {}
+
+[int, int x] f( );
+[] f(int, int x);
+[int, int x] f(int, int x);
+[int, int x] f( ) {}
+[] f(int, int x) {}
+[int, int x] f(int, int x) {}
+
+[int, int x, int] f( );
+[] f(int, int x, int);
+[int, int x, int] f(int, int x, int);
+[int, int x, int] f( ) {}
+[] f(int, int x, int) {}
+[int, int x, int] f(int, int x, int) {}
+
+[int, int x, * int y] f( );
+[] f(int, int x, * int y);
+[int, int x, * int y] f(int, int x, * int y);
+[int, int x, * int y] f( ) {}
+[] f(int, int x, * int y) {}
+[int, int x, * int y] f(int, int x, * int y) {}
+
+[ int ] f11( int ), f12;  // => int f11( int ), f12( int );
+
+[int] f(
+	int ( int, int p ),
+	[int](int)
+    ) {
+    int (*(*p)[][10])[][3];
+    * [][10] * [][3] int p;
+    * [] * [int](int) p;
+}
+
+static const int *f1() {}
+static [ const int ] f2() {}
+static inline [ const * int ] f3() {}
+static inline [ const [ * int, int ] ] f4() {}
+static [ const [ * int, const int ] ] f5() {}
+
+// unnamed parameter
+
+int f(
+    int (),
+
+    int *(),
+    int **(),
+    int * const *(),
+    int * const * const (),
+
+    int ([]),
+    int ([10]),
+
+    int *([]),
+    int *([10]),
+    int **([]),
+    int **([10]),
+    int * const *([]),
+    int * const *([10]),
+    int * const * const ([]),
+    int * const * const ([10])
+    );
+
+int f(
+    int (),
+
+    int *(),
+    int **(),
+    int * const *(),
+    int * const * const (),
+
+    int ([]),
+    int ([10]),
+
+    int *([]),
+    int *([10]),
+    int **([]),
+    int **([10]),
+    int * const *([]),
+    int * const *([10]),
+    int * const * const ([]),
+    int * const * const ([10])
+    ) {
+}
+
+typedef int T;
+
+int f( T (T), T T ) {
+    T (T);
+}
+
+// errors
+
+//int f()[] {}
+//int (f[])() {}
+//int f[]() {}
+//int ((*f15())())[] {}
Index: translator/Tests/Parser/IdentFuncDeclarator.c
===================================================================
--- translator/Tests/Parser/IdentFuncDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/IdentFuncDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,105 @@
+int main() {
+    //int f0[]();
+    //int (f0[])();
+    //int f0()[];
+    //int f0()();
+    //int (*f0)()();
+    //int ((*f0())())[];
+    
+    int f1;
+    int (f2);
+
+    int *f3;
+    int **f4;
+    int * const *f5;
+    int * const * const f6;
+
+    int *(f7);
+    int **(f8);
+    int * const *(f9);
+    int * const * const (f10);
+
+    int (*f11);
+    int (**f12);
+    int (* const *f13);
+    int (* const * const f14);
+
+    int f15[];
+    int f16[10];
+    int (f17[]);
+    int (f18[10]);
+
+    int *f19[];
+    int *f20[10];
+    int **f21[];
+    int **f22[10];
+    int * const *f23[];
+    int * const *f24[10];
+    int * const * const f25[];
+    int * const * const f26[10];
+
+    int *(f27[]);
+    int *(f28[10]);
+    int **(f29[]);
+    int **(f30[10]);
+    int * const *(f31[]);
+    int * const *(f32[10]);
+    int * const * const (f33[]);
+    int * const * const (f34[10]);
+
+    int (*f35[]);
+    int (*f36[10]);
+    int (**f37[]);
+    int (**f38[10]);
+    int (* const *f39[]);
+    int (* const *f40[10]);
+    int (* const * const f41[]);
+    int (* const * const f42[10]);
+
+    int f43[][3];
+    int f44[3][3];
+    int (f45[])[3];
+    int (f46[3])[3];
+    int ((f47[]))[3];
+    int ((f48[3]))[3];
+
+    int *f49[][3];
+    int *f50[3][3];
+    int **f51[][3];
+    int **f52[3][3];
+    int * const *f53[][3];
+    int * const *f54[3][3];
+    int * const * const f55[][3];
+    int * const * const f56[3][3];
+
+    int (*f57[][3]);
+    int (*f58[3][3]);
+    int (**f59[][3]);
+    int (**f60[3][3]);
+    int (* const *f61[][3]);
+    int (* const *f62[3][3]);
+    int (* const * const f63[][3]);
+    int (* const * const f64[3][3]);
+
+    int f65(int);
+    int (f66)(int);
+
+    int *f67(int);
+    int **f68(int);
+    int * const *f69(int);
+    int * const * const f70(int);
+
+    int *(f71)(int);
+    int **(f72)(int);
+    int * const *(f73)(int);
+    int * const * const (f74)(int);
+
+    int (*f75)(int);
+    int (**f76)(int);
+    int (* const *f77)(int);
+    int (* const * const f78)(int);
+
+    int (*(*f79)(int))();
+    int (*(* const f80)(int))();
+    int (* const(* const f81)(int))();
+}
Index: translator/Tests/Parser/IdentFuncParamDeclarator.c
===================================================================
--- translator/Tests/Parser/IdentFuncParamDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/IdentFuncParamDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,150 @@
+int fred(
+    //int f0[](),
+    //int (f0[])(),
+    //int f0()[],
+    //int f0()(),
+    //int (*f0)()(),
+    //int ((*f0())())[],
+    
+    int f1,
+    int (f2),
+
+    int *f3,
+    int **f4,
+    int * const *f5,
+    int * const * const f6,
+
+    int *(f7),
+    int **(f8),
+    int * const *(f9),
+    int * const * const (f10),
+
+    int (*f11),
+    int (**f12),
+    int (* const *f13),
+    int (* const * const f14),
+
+    int f15[],
+    int f16[10],
+    int (f17[]),
+    int (f18[10]),
+
+    int *f19[],
+    int *f20[10],
+    int **f21[],
+    int **f22[10],
+    int * const *f23[],
+    int * const *f24[10],
+    int * const * const f25[],
+    int * const * const f26[10],
+
+    int *(f27[]),
+    int *(f28[10]),
+    int **(f29[]),
+    int **(f30[10]),
+    int * const *(f31[]),
+    int * const *(f32[10]),
+    int * const * const (f33[]),
+    int * const * const (f34[10]),
+
+    int (*f35[]),
+    int (*f36[10]),
+    int (**f37[]),
+    int (**f38[10]),
+    int (* const *f39[]),
+    int (* const *f40[10]),
+    int (* const * const f41[]),
+    int (* const * const f42[10]),
+
+    int f43[][3],
+    int f44[3][3],
+    int (f45[])[3],
+    int (f46[3])[3],
+    int ((f47[]))[3],
+    int ((f48[3]))[3],
+
+    int *f49[][3],
+    int *f50[3][3],
+    int **f51[][3],
+    int **f52[3][3],
+    int * const *f53[][3],
+    int * const *f54[3][3],
+    int * const * const f55[][3],
+    int * const * const f56[3][3],
+
+    int (*f57[][3]),
+    int (*f58[3][3]),
+    int (**f59[][3]),
+    int (**f60[3][3]),
+    int (* const *f61[][3]),
+    int (* const *f62[3][3]),
+    int (* const * const f63[][3]),
+    int (* const * const f64[3][3]),
+
+    int f65(int),
+    int (f66)(int),
+
+    int *f67(int),
+    int **f68(int),
+    int * const *f69(int),
+    int * const * const f70(int),
+
+    int *(f71)(int),
+    int **(f72)(int),
+    int * const *(f73)(int),
+    int * const * const (f74)(int),
+
+    int (*f75)(int),
+    int (**f76)(int),
+    int (* const *f77)(int),
+    int (* const * const f78)(int),
+
+    int (*(*f79)(int))(),
+    int (*(* const f80)(int))(),
+    int (* const(* const f81)(int))(),
+
+    int f82[const *],
+    int f83[const 3],
+    int f84[static 3],
+    int f85[static const 3],
+
+    int (f86[const *]),
+    int (f87[const 3]),
+    int (f88[static 3]),
+    int (f89[static const 3]),
+
+    int *f90[const *],
+    int *f91[const 3],
+    int **f92[static 3],
+    int * const *f93[static const 3],
+    int * const * const f94[static const 3],
+
+    int *(f95[const *]),
+    int *(f96[const 3]),
+    int **(f97[static 3]),
+    int * const *(f98[static const 3]),
+    int * const * const (f99[static const 3]),
+
+    int f100[const *][3],
+    int f101[const 3][3],
+    int f102[static 3][3],
+    int f103[static const 3][3],
+
+    int (f104[const *][3]),
+    int (f105[const 3][3]),
+    int (f106[static 3][3]),
+    int (f107[static const 3][3]),
+
+    int *f108[const *][3],
+    int *f109[const 3][3],
+    int **f110[static 3][3],
+    int * const *f111[static const 3][3],
+    int * const * const f112[static const 3][3],
+
+    int *(f113[const *][3]),
+    int *(f114[const 3][3]),
+    int **(f115[static 3][3]),
+    int * const *(f116[static const 3][3]),
+    int * const * const (f117[static const 3][3])
+    ) {
+}
Index: translator/Tests/Parser/Initialization.c
===================================================================
--- translator/Tests/Parser/Initialization.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Initialization.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,27 @@
+// Cforall extensions
+
+int * x21 = 0, x22 = 0;
+int * x21 = 0, x22 = 0;
+
+[20] int y1, y2 = { 1, 2, 3 };
+
+// designators
+
+struct {
+    [int] w;
+} a = { .w : [2] };
+
+struct { int a[3], b; } w [] = { [0].a : {1}, [0].b : 1, [1].a[0] : 2 };
+
+struct {
+    int f1, f2, f3;
+    struct { int g1, g2, g3; } f4[4];
+} v7 = {
+    .f1 : 4,
+    f2 : 3,
+    .f4[2] : {
+	.g1 : 3,
+	g3 : 0,
+    },
+    .f4[3].g3 : 7,
+};
Index: translator/Tests/Parser/Makefile
===================================================================
--- translator/Tests/Parser/Makefile	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Makefile	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,16 @@
+CFA = ../../cfa-cpp
+
+EXPECTED = ${wildcard Expected/*.tst}
+TESTS = $(EXPECTED:Expected/%=%)
+TEST_IN = $(TESTS:.tst=.c)
+DIFF = /software/gnu/bin/diff#diff
+
+%.tst:%.c $(CFA)
+	$(CFA) -nt < $< > $@ 2>&1
+
+report: $(CFA) $(TESTS) $(EXPECTED)
+	rm -f report
+	@for i in $(TESTS); do \
+	  echo "---$$i---" | tee -a report; \
+	  $(DIFF) -B -w Expected/$$i $$i | tee -a report; \
+	done
Index: translator/Tests/Parser/Scope.c
===================================================================
--- translator/Tests/Parser/Scope.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Scope.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,69 @@
+int x;
+typedef double y;
+typedef float t;
+y z;
+type u = struct { int a; double b; };
+int f( int y );
+y q;
+
+y w(y y, u v) {
+  type x | { x t(u); };
+  u u = y;
+  x z = t(u);
+}
+
+y p;
+
+context has_u( type z )
+{
+  z u(z);
+};
+
+forall( type t | has_u( t ) )
+y q( t the_t )
+{
+  t y = u( the_t );
+}
+
+t f( y p ) {
+  int y;
+  typedef char x;
+
+  {
+    x y;
+    typedef x z;
+
+    {
+      z x;
+      typedef z y;
+      y z = x;
+    }
+
+    z x = y;
+  }
+
+  x q = y;
+}
+
+t g( void ) {
+  typedef char x;
+  try {
+    some_func();
+  } catch ( x x ) {
+    t y = x;
+  }
+  x z;
+}
+
+y q(i)
+    int i;
+{
+  switch (i) {
+    y q = i;
+  case 0:
+    return q;
+  default:
+    return i;
+  }
+}
+
Index: translator/Tests/Parser/StructMember.c
===================================================================
--- translator/Tests/Parser/StructMember.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/StructMember.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,40 @@
+typedef int T;
+
+struct S {
+    int m1:3, m2:4;
+    int :2;
+    int :3, :4;
+    int m3;
+    int m4, m5, m6;
+    int *m7, *m8, *m9;
+    int (*m10)();
+    int *(*m11)(int);
+    T T;
+    T (T);
+
+// Cforall extensions
+
+    * int m12, m13;
+    * [ * int ] (int) m14;
+    int ;
+    int , , ;
+    int * , , ;
+    int *, *, *;
+    * int , , ;
+    int (*)();
+    int (**)( int );
+    T ;
+
+// errors
+
+//    void f(void);
+};
+
+struct S s;
+
+union U {
+    [5] int m1;
+    int m2[5];
+    * int m3;
+    int *m4;
+} u;
Index: translator/Tests/Parser/Tuple.c
===================================================================
--- translator/Tests/Parser/Tuple.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Tuple.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,62 @@
+int f( int, int );
+int g( int, int, int );
+static [ int, int *, * int, int ] h( int a, int b, * int c, [] char d );
+
+struct inner {
+    int f2, f3;
+};
+
+struct outer {
+    int f1;
+    struct inner i;
+    double f4;
+} s, *sp;
+
+const volatile [ int, int ] t1;
+static const [ int, const int ] t2;
+const static [ int, const int ] t3;
+
+[ int rc ] printf( * char fmt, ... );
+int printf( char *fmt, ... );
+
+[ short x, unsigned y ] f1( int w ) {
+    [ y, x ] = [ x, y ] = [ w, 23 ];
+}
+
+[ [ int, char, long, int ] r ] g1() {
+    short x, p;
+    unsigned int y;
+    [ int, int ] z;
+
+    [ x, y, z ] = ([short, unsigned int, [int, int]])([ p, f( 17 ), 3 ]);
+    r = [ x, y, z ];
+}
+
+[ int rc ] main( int argc, ** char argv ) {
+    int a, b, c, d;
+    struct outer t = { .[ f1,f4 ] : [ 1,7.0 ] };
+    f( [ 3,5 ] );
+    g( [ 3,5 ], 3 );
+    f( t1 );
+    g( t1, 3 );
+    [ 3,5 ];
+    [ a,b ] = 3;
+    [ a,b ] = [ 4.6 ];
+    [ a,b ] = [ c,d ] = [ 3,5 ];
+    [ a,b,[ c ] ] = [ 2,[ a,b ] ];
+    [ a,b ] = 3 > 4 ? [ b,6 ] : [ 7,8 ];
+
+    t1 = [ a,b ];
+    t1 = t2 = [ a,b ];
+    [ a,b ] = [ c,d ] = d += c += 1;
+    [ a,b ] = [ c,d ] = t1;
+    [ a,b ] = t1 = [ c,d ];
+    [ a,b ] = t1 = t2 = [ c,d ];
+    t1 = [ 3,4 ] = [ 3,4 ] = t1 = [ 3,4 ];
+
+    s.[ f1, i.[ f2, f3 ], f4 ] = [ 11, 12, 13, 3.14159 ];
+    s.[ f1, i.[ f2, f3 ], f4 ] = h( 3, 3, 0, "abc" );
+    sp->[ f4,f1 ] = sp->[ f1,f4 ];
+    printf( "expecting 3, 17, 23, 4; got %d, %d, %d, %d\n", s.[ f4, i.[ f3,f2 ], f1 ] );
+    rc = 0;
+}
Index: translator/Tests/Parser/TypeGenerator.c
===================================================================
--- translator/Tests/Parser/TypeGenerator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/TypeGenerator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,19 @@
+context addable(type T) {
+   T ?+?(T,T);
+};
+
+type List(type T | addable(T) ) | addable(T) = struct { T data; List(T) *next; } *;
+typedef List(int) ListOfIntegers;
+ListOfIntegers li;
+int f( List(int) ((*g))(int) );
+[int] h( * List(int) p ); // new declaration syntax
+
+struct(type T | addable(T) ) node { T data; struct(T) node *next; };
+type List(type T) = struct(T) node *;
+List(int) my_list;
+
+type Complex | addable(Complex);
+
+int main() {
+    (struct(int) node)my_list;
+}
Index: translator/Tests/Parser/Typedef.c
===================================================================
--- translator/Tests/Parser/Typedef.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/Typedef.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,41 @@
+typedef int T;
+
+void f( void ) {
+    int T( T );
+    T( 3 );
+}
+
+struct {
+    T (T);
+} fred = { 3 };
+
+typedef int (*a)(int, char);
+a b;
+
+int g(void) {
+    double a;
+}
+a c;
+
+// typedef x = 3, y = 3;  /* GCC */
+
+// x p;
+// y q;
+
+int main() {
+//    typedef z = p = 3;
+}
+
+/* new-style function definitions */
+
+typedef [10] * int arrayOf10Pointers;
+arrayOf10Pointers x;
+typedef const * int constantPointer;
+typedef * [ int ]( [] int ) funcPtr;
+typedef [ int ] funcProto( []  int );
+typedef [ int, int ] tupleType;
+typedef * [ int, int ] tupleTypePtr;
+typedef * int a, b;
+typedef [ int ] f( * int ), g;
+typedef [ * [static 10] int ] t;
+typedef [ * [static 10] int x ] f();
Index: translator/Tests/Parser/TypedefDeclarator.c
===================================================================
--- translator/Tests/Parser/TypedefDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/TypedefDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,116 @@
+typedef int
+     f0,  f1,  f2,  f3,  f4,  f5,  f6,  f7,  f8,  f9,
+    f10, f11, f12, f13, f14, f15, f16, f17, f18, f19,
+    f20, f21, f22, f23, f24, f25, f26, f27, f28, f29,
+    f30, f31, f32, f33, f34, f35, f36, f37, f38, f39,
+    f40, f41, f42, f43, f44, f45, f46, f47, f48, f49,
+    f50, f51, f52, f53, f54, f55, f56, f57, f58, f59,
+    f60, f61, f62, f63, f64, f65, f66, f67, f68, f69,
+    f70, f71, f72, f73, f74, f75, f76, f77, f78, f79,
+    f80, f81, f82, f83, f84, f85, f86, f87, f88, f89;
+
+int main() {
+    //int f0[]();
+    //int (f0[])();
+    //int f0()[];
+    //int f0()();
+    //int (*f0)()();
+    //int ((*f0())())[];
+    
+    int f1;
+    int (f2);
+
+    int *f3;
+    int **f4;
+    int * const *f5;
+    int * const * const f6;
+
+    int *(f7);
+    int **(f8);
+    int * const *(f9);
+    int * const * const (f10);
+
+    int (*f11);
+    int (**f12);
+    int (* const *f13);
+    int (* const * const f14);
+
+    int f15[];
+    int f16[10];
+    int (f17[]);
+    int (f18[10]);
+
+    int *f19[];
+    int *f20[10];
+    int **f21[];
+    int **f22[10];
+    int * const *f23[];
+    int * const *f24[10];
+    int * const * const f25[];
+    int * const * const f26[10];
+
+    int *(f27[]);
+    int *(f28[10]);
+    int **(f29[]);
+    int **(f30[10]);
+    int * const *(f31[]);
+    int * const *(f32[10]);
+    int * const * const (f33[]);
+    int * const * const (f34[10]);
+
+    int (*f35[]);
+    int (*f36[10]);
+    int (**f37[]);
+    int (**f38[10]);
+    int (* const *f39[]);
+    int (* const *f40[10]);
+    int (* const * const f41[]);
+    int (* const * const f42[10]);
+
+    int f43[][3];
+    int f44[3][3];
+    int (f45[])[3];
+    int (f46[3])[3];
+    int ((f47[]))[3];
+    int ((f48[3]))[3];
+
+    int *f49[][3];
+    int *f50[3][3];
+    int **f51[][3];
+    int **f52[3][3];
+    int * const *f53[][3];
+    int * const *f54[3][3];
+    int * const * const f55[][3];
+    int * const * const f56[3][3];
+
+    int (*f57[][3]);
+    int (*f58[3][3]);
+    int (**f59[][3]);
+    int (**f60[3][3]);
+    int (* const *f61[][3]);
+    int (* const *f62[3][3]);
+    int (* const * const f63[][3]);
+    int (* const * const f64[3][3]);
+
+    int f65(int);
+    int (f66)(int);
+
+    int *f67(int);
+    int **f68(int);
+    int * const *f69(int);
+    int * const * const f70(int);
+
+    int *(f71)(int);
+    int **(f72)(int);
+    int * const *(f73)(int);
+    int * const * const (f74)(int);
+
+    int (*f75)(int);
+    int (**f76)(int);
+    int (* const *f77)(int);
+    int (* const * const f78)(int);
+
+    int (*(*f79)(int))();
+    int (*(* const f80)(int))();
+    int (* const(* const f81)(int))();
+}
Index: translator/Tests/Parser/TypedefParamDeclarator.c
===================================================================
--- translator/Tests/Parser/TypedefParamDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/TypedefParamDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,150 @@
+typedef int
+     f0,   f1,   f2,   f3,   f4,   f5,   f6,   f7,   f8,   f9,
+    f10,  f11,  f12,  f13,  f14,  f15,  f16,  f17,  f18,  f19,
+    f20,  f21,  f22,  f23,  f24,  f25,  f26,  f27,  f28,  f29,
+    f30,  f31,  f32,  f33,  f34,  f35,  f36,  f37,  f38,  f39,
+    f40,  f41,  f42,  f43,  f44,  f45,  f46,  f47,  f48,  f49,
+    f50,  f51,  f52,  f53,  f54,  f55,  f56,  f57,  f58,  f59,
+    f60,  f61,  f62,  f63,  f64,  f65,  f66,  f67,  f68,  f69,
+    f70,  f71,  f72,  f73,  f74,  f75,  f76,  f77,  f78,  f79,
+    f80,  f81,  f82,  f83,  f84,  f85,  f86,  f87,  f88,  f89,
+    f90,  f91,  f92,  f93,  f94,  f95,  f96,  f97,  f98,  f99,
+    f100, f101, f102, f103, f104, f105, f106, f107, f108, f109,
+    f110, f111, f112, f113, f114, f115, f116, f117, f118, f119;
+
+int fred(
+/*
+    //int f0[](),
+    //int (f0[])(),
+    //int f0()[],
+    //int f0()(),
+    //int (*f0)()(),
+    //int ((*f0())())[],
+*/
+    int f1,
+
+    int *f3,
+    int **f4,
+    int * const *f5,
+    int * const * const f6,
+
+    int (*f11),
+    int (**f12),
+    int (* const *f13),
+    int (* const * const f14),
+
+    int f15[],
+    int f16[10],
+
+    int *f19[],
+    int *f20[10],
+    int **f21[],
+    int **f22[10],
+    int * const *f23[],
+    int * const *f24[10],
+    int * const * const f25[],
+    int * const * const f26[10],
+
+    int (*f35[]),
+    int (*f36[10]),
+    int (**f37[]),
+    int (**f38[10]),
+    int (* const *f39[]),
+    int (* const *f40[10]),
+    int (* const * const f41[]),
+    int (* const * const f42[10]),
+
+    int f43[][3],
+    int f44[3][3],
+/*
+    int (f45[])[3],
+    int (f46[3])[3],
+    int ((f47[]))[3],
+    int ((f48[3]))[3],
+*/
+    int *f49[][3],
+    int *f50[3][3],
+    int **f51[][3],
+    int **f52[3][3],
+    int * const *f53[][3],
+    int * const *f54[3][3],
+    int * const * const f55[][3],
+    int * const * const f56[3][3],
+
+    int (*f57[][3]),
+    int (*f58[3][3]),
+    int (**f59[][3]),
+    int (**f60[3][3]),
+    int (* const *f61[][3]),
+    int (* const *f62[3][3]),
+    int (* const * const f63[][3]),
+    int (* const * const f64[3][3]),
+
+    int f65(int),
+/*
+    int (f66)(int),
+*/
+    int *f67(int),
+    int **f68(int),
+    int * const *f69(int),
+    int * const * const f70(int),
+/*
+    int *(f71)(int),
+    int **(f72)(int),
+    int * const *(f73)(int),
+    int * const * const (f74)(int),
+*/
+    int (*f75)(int),
+    int (**f76)(int),
+    int (* const *f77)(int),
+    int (* const * const f78)(int),
+
+    int (*(*f79)(int))(),
+    int (*(* const f80)(int))(),
+    int (* const(* const f81)(int))(),
+
+    int f82[const *],
+    int f83[const 3],
+    int f84[static 3],
+    int f85[static const 3],
+
+    int (f86[const *]),
+    int (f87[const 3]),
+    int (f88[static 3]),
+    int (f89[static const 3]),
+
+    int *f90[const *],
+    int *f91[const 3],
+    int **f92[static 3],
+    int * const *f93[static const 3],
+    int * const * const f94[static const 3],
+
+    int *(f95[const *]),
+    int *(f96[const 3]),
+    int **(f97[static 3]),
+    int * const *(f98[static const 3]),
+    int * const * const (f99[static const 3]),
+
+    int f100[const *][3],
+    int f101[const 3][3],
+    int f102[static 3][3],
+    int f103[static const 3][3],
+
+    int (f104[const *][3]),
+    int (f105[const 3][3]),
+    int (f106[static 3][3]),
+    int (f107[static const 3][3]),
+
+    int *f108[const *][3],
+    int *f109[const 3][3],
+    int **f110[static 3][3],
+    int * const *f111[static const 3][3],
+    int * const * const f112[static const 3][3],
+
+    int *(f113[const *][3]),
+    int *(f114[const 3][3]),
+    int **(f115[static 3][3]),
+    int * const *(f116[static const 3][3]),
+    int * const * const (f117[static const 3][3])
+    ) {
+}
Index: translator/Tests/Parser/VariableDeclarator.c
===================================================================
--- translator/Tests/Parser/VariableDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Parser/VariableDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,115 @@
+int f1;
+int (f2);
+
+int *f3;
+int **f4;
+int * const *f5;
+int * const * const f6;
+
+int *(f7);
+int **(f8);
+int * const *(f9);
+int * const * const (f10);
+
+int (*f11);
+int (**f12);
+int (* const *f13);
+int (* const * const f14);
+
+int f15[];
+int f16[10];
+int (f17[]);
+int (f18[10]);
+
+int *f19[];
+int *f20[10];
+int **f21[];
+int **f22[10];
+int * const *f23[];
+int * const *f24[10];
+int * const * const f25[];
+int * const * const f26[10];
+
+int *(f27[]);
+int *(f28[10]);
+int **(f29[]);
+int **(f30[10]);
+int * const *(f31[]);
+int * const *(f32[10]);
+int * const * const (f33[]);
+int * const * const (f34[10]);
+
+int (*f35[]);
+int (*f36[10]);
+int (**f37[]);
+int (**f38[10]);
+int (* const *f39[]);
+int (* const *f40[10]);
+int (* const * const f41[]);
+int (* const * const f42[10]);
+
+int f43[][3];
+int f44[3][3];
+int (f45[])[3];
+int (f46[3])[3];
+int ((f47[]))[3];
+int ((f48[3]))[3];
+
+int *f49[][3];
+int *f50[3][3];
+int **f51[][3];
+int **f52[3][3];
+int * const *f53[][3];
+int * const *f54[3][3];
+int * const * const f55[][3];
+int * const * const f56[3][3];
+
+int (*f57[][3]);
+int (*f58[3][3]);
+int (**f59[][3]);
+int (**f60[3][3]);
+int (* const *f61[][3]);
+int (* const *f62[3][3]);
+int (* const * const f63[][3]);
+int (* const * const f64[3][3]);
+
+int f65(int);
+int (f66)(int);
+
+int *f67(int);
+int **f68(int);
+int * const *f69(int);
+int * const * const f70(int);
+
+int *(f71)(int);
+int **(f72)(int);
+int * const *(f73)(int);
+
+int * const * const (f74)(int);
+
+int (*f75)(int);
+int (**f76)(int);
+int (* const *f77)(int);
+int (* const * const f78)(int);
+
+int (*(*f79)(int))();
+int (*(* const f80)(int))();
+int (* const(* const f81)(int))();
+
+// errors
+
+//int fe0[]();				// array of functions
+//int (fe1[])();				// array of functions
+//int fe2()[];				// returning an array
+//int fe3()();				// returning a function
+//int (*fe4)()();				// returning a function
+//int ((*fe5())())[];			// returning an array
+
+// Cforall extensions
+
+* [20] double z;
+[20] * char w;
+
+// function pointer
+
+*[]*[]* [ *[]*[] int ]( *[]*[] int, *[]*[] int ) v3;
Index: translator/Tests/ResolvExpr/Abstype.c
===================================================================
--- translator/Tests/ResolvExpr/Abstype.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Abstype.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,28 @@
+// "cfa-cpp -nx Abstype.c"
+
+type T | { T x( T ); };
+
+T y( T t )
+{
+	T t_instance;
+	return x( t );
+}
+
+forall(type T) lvalue T			*?(                T* );
+int		?++( int *);
+int ?=?( int*, int );
+forall(dtype DT) DT* 		   	?=?(                DT *          *,          DT* );
+
+type U = int*;
+
+U x( U u )
+{
+	U u_instance = u;
+	(*u)++;
+	return u;
+}
+
+int *break_abstraction( U u )
+{
+	return u;
+}
Index: translator/Tests/ResolvExpr/Attributes.c
===================================================================
--- translator/Tests/ResolvExpr/Attributes.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Attributes.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,19 @@
+// "cfa-cpp -ne simple.c"
+
+int @voon;
+double @voon;
+
+int @bort(int);
+int @bort(double);
+
+void g( int );
+
+void
+f()
+{
+  float x;
+  double x;
+  @bort(x);
+  @bort(int);
+  g( @voon );
+}
Index: translator/Tests/ResolvExpr/Cast.c
===================================================================
--- translator/Tests/ResolvExpr/Cast.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Cast.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,11 @@
+char f;
+void f()
+{
+  char f;
+  double f;
+  (int)f;
+  short f;
+  (int)f;
+  (void(*)())f;
+  ([long, long double, *[]()])([f, f, f]);
+}
Index: translator/Tests/ResolvExpr/CastError.c
===================================================================
--- translator/Tests/ResolvExpr/CastError.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/CastError.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,8 @@
+int f;
+void f()
+{
+  int f;
+  double f;
+  (char)f;
+  (int(*)())f;
+}
Index: translator/Tests/ResolvExpr/Expected/Abstype.tst
===================================================================
--- translator/Tests/ResolvExpr/Expected/Abstype.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Expected/Abstype.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,215 @@
+T: a type
+  with assertions
+    x: a function
+        with parameters
+          instance of type T 
+        returning 
+          instance of type T 
+
+
+?=?: a automatically generated function
+    with parameters
+      _dst: a pointer to instance of type T 
+      _src: a instance of type T 
+    returning 
+      instance of type T 
+
+y: a function
+    with parameters
+      t: a instance of type T 
+    returning 
+      instance of type T 
+    with body 
+      Declaration of t_instance: a instance of type T 
+      
+        Return Statement, returning: Cast of:
+  Application of
+    Variable Expression: x: a function
+        with parameters
+          instance of type T 
+        returning 
+          instance of type T 
+
+  to arguments
+          Variable Expression: t: a instance of type T 
+
+
+to:
+  instance of type T 
+with environment:
+  Types:
+  Non-types:
+
+
+
+*?: a forall
+      T: a type
+        with assertions
+          ?=?: a pointer to function
+              with parameters
+                pointer to instance of type T 
+                instance of type T 
+              returning 
+                instance of type T 
+
+
+    function
+    with parameters
+      pointer to instance of type T 
+    returning 
+      lvalue instance of type T 
+
+?++: a function
+    with parameters
+      pointer to signed int 
+    returning 
+      signed int 
+
+?=?: a function
+    with parameters
+      pointer to signed int 
+      signed int 
+    returning 
+      signed int 
+
+?=?: a forall
+      DT: a incomplete type
+    function
+    with parameters
+      pointer to pointer to instance of type DT 
+      pointer to instance of type DT 
+    returning 
+      pointer to instance of type DT 
+
+U: a type for pointer to signed int 
+?=?: a automatically generated function
+    with parameters
+      _dst: a pointer to instance of type U 
+      _src: a instance of type U 
+    returning 
+      instance of type U 
+    with body 
+      
+        Return Statement, returning: Cast of:
+  Application of
+    Variable Expression: ?=?: a forall
+          DT: a incomplete type
+        function
+        with parameters
+          pointer to pointer to instance of type DT 
+          pointer to instance of type DT 
+        returning 
+          pointer to instance of type DT 
+
+  to arguments
+          Cast of:
+        Variable Expression: _dst: a pointer to instance of type U 
+
+      to:
+        pointer to pointer to signed int 
+
+          Cast of:
+        Variable Expression: _src: a instance of type U 
+
+      to:
+        pointer to signed int 
+
+
+to:
+  instance of type U 
+with environment:
+  Types:
+    _0_DT -> signed int 
+  Non-types:
+
+
+
+x: a function
+    with parameters
+      u: a instance of type U 
+    returning 
+      instance of type U 
+    with body 
+      Declaration of u_instance: a instance of type U with initializer 
+        Simple Initializer:           Name: u
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: ?++: a function
+                with parameters
+                  pointer to signed int 
+                returning 
+                  signed int 
+
+          to arguments
+                          Address of:
+                Application of
+                  Variable Expression: *?: a forall
+                        T: a type
+                          with assertions
+                            ?=?: a pointer to function
+                                with parameters
+                                  pointer to instance of type T 
+                                  instance of type T 
+                                returning 
+                                  instance of type T 
+
+
+                      function
+                      with parameters
+                        pointer to instance of type T 
+                      returning 
+                        lvalue instance of type T 
+
+                to arguments
+                                      Cast of:
+                      Variable Expression: u: a instance of type U 
+
+                    to:
+                      pointer to signed int 
+
+                with inferred parameters:
+                  ?=?: a function
+                    with parameters
+                      pointer to signed int 
+                      signed int 
+                    returning 
+                      signed int 
+
+
+          with environment:
+            Types:
+              _0_T -> signed int 
+            Non-types:
+
+      
+        Return Statement, returning: Cast of:
+  Variable Expression: u: a instance of type U 
+
+to:
+  instance of type U 
+with environment:
+  Types:
+  Non-types:
+
+
+
+break_abstraction: a function
+    with parameters
+      u: a instance of type U 
+    returning 
+      pointer to signed int 
+    with body 
+      
+        Return Statement, returning: Cast of:
+  Variable Expression: u: a instance of type U 
+
+to:
+  pointer to signed int 
+with environment:
+  Types:
+  Non-types:
+
+
+
Index: translator/Tests/ResolvExpr/Expected/Attributes.tst
===================================================================
--- translator/Tests/ResolvExpr/Expected/Attributes.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Expected/Attributes.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,70 @@
+@voon: a signed int 
+@voon: a double 
+@bort: a function
+    with parameters
+      signed int 
+    returning 
+      signed int 
+
+@bort: a function
+    with parameters
+      double 
+    returning 
+      signed int 
+
+g: a function
+    with parameters
+      signed int 
+    returning 
+      nothing 
+
+f: a function
+      accepting unspecified arguments
+    returning 
+      nothing 
+    with body 
+      Declaration of x: a float 
+      Declaration of x: a double 
+      
+        Expression Statement:
+          Attr             Variable Expression: @bort: a function
+                with parameters
+                  double 
+                returning 
+                  signed int 
+
+applied to: lvalue double 
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Attr             Variable Expression: @bort: a function
+                with parameters
+                  signed int 
+                returning 
+                  signed int 
+
+applied to: signed int 
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: g: a function
+                with parameters
+                  signed int 
+                returning 
+                  nothing 
+
+          to arguments
+                          Variable Expression: @voon: a signed int 
+
+          with environment:
+            Types:
+            Non-types:
+
+
Index: translator/Tests/ResolvExpr/Expected/Cast.tst
===================================================================
--- translator/Tests/ResolvExpr/Expected/Cast.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Expected/Cast.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,78 @@
+f: a char 
+f: a function
+      accepting unspecified arguments
+    returning 
+      nothing 
+    with body 
+      Declaration of f: a char 
+      Declaration of f: a double 
+      
+        Expression Statement:
+          Cast of:
+            Variable Expression: f: a char 
+
+          to:
+            signed int 
+          with environment:
+            Types:
+            Non-types:
+
+      Declaration of f: a short signed int 
+      
+        Expression Statement:
+          Cast of:
+            Variable Expression: f: a short signed int 
+
+          to:
+            signed int 
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Cast of:
+            Variable Expression: f: a function
+                  accepting unspecified arguments
+                returning 
+                  nothing 
+
+
+          to:
+            pointer to function
+                  accepting unspecified arguments
+                returning 
+                  nothing 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Cast of:
+            Tuple:
+                              Variable Expression: f: a short signed int 
+
+                              Variable Expression: f: a double 
+
+                              Variable Expression: f: a function
+                      accepting unspecified arguments
+                    returning 
+                      nothing 
+
+
+
+          to:
+            long signed int 
+            long double 
+            pointer to function
+                  accepting unspecified arguments
+                returning 
+                  nothing 
+
+          with environment:
+            Types:
+            Non-types:
+
+
Index: translator/Tests/ResolvExpr/Expected/CastError.tst
===================================================================
--- translator/Tests/ResolvExpr/Expected/CastError.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Expected/CastError.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,94 @@
+Error: Can't choose between alternatives for expression Cast of:
+  Name: f
+
+to:
+  char 
+Alternatives are:        Cost ( 1, 0, 0 ):         Cast of:
+          Variable Expression: f: a signed int 
+
+        to:
+          char 
+(types:
+            char 
+)
+        Environment: 
+
+        Cost ( 1, 0, 0 ):         Cast of:
+          Variable Expression: f: a double 
+
+        to:
+          char 
+(types:
+            char 
+)
+        Environment: 
+
+
+Error: Can't choose between alternatives for expression Cast of:
+  Name: f
+
+to:
+  pointer to function
+        accepting unspecified arguments
+      returning 
+        signed int 
+
+Alternatives are:        Cost ( 1, 0, 0 ):         Cast of:
+          Variable Expression: f: a function
+                accepting unspecified arguments
+              returning 
+                nothing 
+
+
+        to:
+          pointer to function
+                accepting unspecified arguments
+              returning 
+                signed int 
+
+(types:
+            pointer to function
+                  accepting unspecified arguments
+                returning 
+                  signed int 
+
+)
+        Environment: 
+
+        Cost ( 1, 0, 0 ):         Cast of:
+          Variable Expression: f: a signed int 
+
+        to:
+          pointer to function
+                accepting unspecified arguments
+              returning 
+                signed int 
+
+(types:
+            pointer to function
+                  accepting unspecified arguments
+                returning 
+                  signed int 
+
+)
+        Environment: 
+
+        Cost ( 1, 0, 0 ):         Cast of:
+          Variable Expression: f: a double 
+
+        to:
+          pointer to function
+                accepting unspecified arguments
+              returning 
+                signed int 
+
+(types:
+            pointer to function
+                  accepting unspecified arguments
+                returning 
+                  signed int 
+
+)
+        Environment: 
+
+
Index: translator/Tests/ResolvExpr/Expected/Forall.tst
===================================================================
--- translator/Tests/ResolvExpr/Expected/Forall.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Expected/Forall.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,495 @@
+?=?: a function
+    with parameters
+      pointer to signed int 
+      signed int 
+    returning 
+      signed int 
+
+?=?: a function
+    with parameters
+      pointer to float 
+      float 
+    returning 
+      float 
+
+?=?: a function
+    with parameters
+      pointer to pointer to signed int 
+      pointer to signed int 
+    returning 
+      pointer to signed int 
+
+?=?: a function
+    with parameters
+      pointer to pointer to float 
+      pointer to float 
+    returning 
+      pointer to float 
+
+?=?: a function
+    with parameters
+      pointer to char 
+      char 
+    returning 
+      char 
+
+?=?: a function
+    with parameters
+      pointer to pointer to function
+          returning 
+            nothing 
+
+      pointer to function
+          returning 
+            nothing 
+
+    returning 
+      pointer to function
+          returning 
+            nothing 
+
+
+g1: a function
+      accepting unspecified arguments
+    returning 
+      nothing 
+    with body 
+      Declaration of f: a forall
+            T: a type
+              with assertions
+                ?=?: a pointer to function
+                    with parameters
+                      pointer to instance of type T 
+                      instance of type T 
+                    returning 
+                      instance of type T 
+
+
+          function
+          with parameters
+            instance of type T 
+          returning 
+            instance of type T 
+
+      Declaration of f: a function
+          with parameters
+            signed int 
+          returning 
+            nothing 
+
+      Declaration of h: a function
+          with parameters
+            p: a pointer to function
+                returning 
+                  nothing 
+
+          returning 
+            nothing 
+
+      Declaration of x: a signed int 
+      Declaration of y: a pointer to function
+          returning 
+            nothing 
+
+      Declaration of z: a char 
+      Declaration of w: a float 
+      
+        Expression Statement:
+          Application of
+            Variable Expression: f: a function
+                with parameters
+                  signed int 
+                returning 
+                  nothing 
+
+          to arguments
+                          Variable Expression: x: a signed int 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: f: a forall
+                  T: a type
+                    with assertions
+                      ?=?: a pointer to function
+                          with parameters
+                            pointer to instance of type T 
+                            instance of type T 
+                          returning 
+                            instance of type T 
+
+
+                function
+                with parameters
+                  instance of type T 
+                returning 
+                  instance of type T 
+
+          to arguments
+                          Variable Expression: y: a pointer to function
+                  returning 
+                    nothing 
+
+
+          with inferred parameters:
+            ?=?: a function
+              with parameters
+                pointer to pointer to function
+                    returning 
+                      nothing 
+
+                pointer to function
+                    returning 
+                      nothing 
+
+              returning 
+                pointer to function
+                    returning 
+                      nothing 
+
+
+          with environment:
+            Types:
+              _0_T -> pointer to function
+                  returning 
+                    nothing 
+
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: f: a function
+                with parameters
+                  signed int 
+                returning 
+                  nothing 
+
+          to arguments
+                          Cast of:
+                Variable Expression: z: a char 
+
+              to:
+                signed int 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: f: a forall
+                  T: a type
+                    with assertions
+                      ?=?: a pointer to function
+                          with parameters
+                            pointer to instance of type T 
+                            instance of type T 
+                          returning 
+                            instance of type T 
+
+
+                function
+                with parameters
+                  instance of type T 
+                returning 
+                  instance of type T 
+
+          to arguments
+                          Variable Expression: w: a float 
+
+          with inferred parameters:
+            ?=?: a function
+              with parameters
+                pointer to float 
+                float 
+              returning 
+                float 
+
+          with environment:
+            Types:
+              _0_T -> float 
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: h: a function
+                with parameters
+                  p: a pointer to function
+                      returning 
+                        nothing 
+
+                returning 
+                  nothing 
+
+          to arguments
+                          Application of
+                Variable Expression: f: a forall
+                      T: a type
+                        with assertions
+                          ?=?: a pointer to function
+                              with parameters
+                                pointer to instance of type T 
+                                instance of type T 
+                              returning 
+                                instance of type T 
+
+
+                    function
+                    with parameters
+                      instance of type T 
+                    returning 
+                      instance of type T 
+
+              to arguments
+                                  Variable Expression: y: a pointer to function
+                      returning 
+                        nothing 
+
+
+              with inferred parameters:
+                ?=?: a function
+                  with parameters
+                    pointer to pointer to function
+                        returning 
+                          nothing 
+
+                    pointer to function
+                        returning 
+                          nothing 
+
+                  returning 
+                    pointer to function
+                        returning 
+                          nothing 
+
+
+
+          with environment:
+            Types:
+              _0_T -> pointer to function
+                  returning 
+                    nothing 
+
+            Non-types:
+
+
+g2: a function
+      accepting unspecified arguments
+    returning 
+      nothing 
+    with body 
+      Declaration of f: a forall
+            T: a type
+              with assertions
+                ?=?: a pointer to function
+                    with parameters
+                      pointer to instance of type T 
+                      instance of type T 
+                    returning 
+                      instance of type T 
+
+
+          function
+          with parameters
+            instance of type T 
+            instance of type T 
+          returning 
+            nothing 
+
+      Declaration of f: a forall
+            T: a type
+              with assertions
+                ?=?: a pointer to function
+                    with parameters
+                      pointer to instance of type T 
+                      instance of type T 
+                    returning 
+                      instance of type T 
+
+
+            U: a type
+              with assertions
+                ?=?: a pointer to function
+                    with parameters
+                      pointer to instance of type U 
+                      instance of type U 
+                    returning 
+                      instance of type U 
+
+
+          function
+          with parameters
+            instance of type T 
+            instance of type U 
+          returning 
+            nothing 
+
+      Declaration of x: a signed int 
+      Declaration of y: a float 
+      Declaration of z: a pointer to signed int 
+      Declaration of w: a pointer to float 
+      
+        Expression Statement:
+          Application of
+            Variable Expression: f: a forall
+                  T: a type
+                    with assertions
+                      ?=?: a pointer to function
+                          with parameters
+                            pointer to instance of type T 
+                            instance of type T 
+                          returning 
+                            instance of type T 
+
+
+                function
+                with parameters
+                  instance of type T 
+                  instance of type T 
+                returning 
+                  nothing 
+
+          to arguments
+                          Cast of:
+                Variable Expression: x: a signed int 
+
+              to:
+                float 
+
+                          Variable Expression: y: a float 
+
+          with inferred parameters:
+            ?=?: a function
+              with parameters
+                pointer to float 
+                float 
+              returning 
+                float 
+
+          with environment:
+            Types:
+              _0_T -> float 
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: f: a forall
+                  T: a type
+                    with assertions
+                      ?=?: a pointer to function
+                          with parameters
+                            pointer to instance of type T 
+                            instance of type T 
+                          returning 
+                            instance of type T 
+
+
+                  U: a type
+                    with assertions
+                      ?=?: a pointer to function
+                          with parameters
+                            pointer to instance of type U 
+                            instance of type U 
+                          returning 
+                            instance of type U 
+
+
+                function
+                with parameters
+                  instance of type T 
+                  instance of type U 
+                returning 
+                  nothing 
+
+          to arguments
+                          Variable Expression: z: a pointer to signed int 
+
+                          Variable Expression: w: a pointer to float 
+
+          with inferred parameters:
+            ?=?: a function
+              with parameters
+                pointer to pointer to signed int 
+                pointer to signed int 
+              returning 
+                pointer to signed int 
+
+            ?=?: a function
+              with parameters
+                pointer to pointer to float 
+                pointer to float 
+              returning 
+                pointer to float 
+
+          with environment:
+            Types:
+              _1_T -> pointer to signed int 
+              _2_U -> pointer to float 
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: f: a forall
+                  T: a type
+                    with assertions
+                      ?=?: a pointer to function
+                          with parameters
+                            pointer to instance of type T 
+                            instance of type T 
+                          returning 
+                            instance of type T 
+
+
+                  U: a type
+                    with assertions
+                      ?=?: a pointer to function
+                          with parameters
+                            pointer to instance of type U 
+                            instance of type U 
+                          returning 
+                            instance of type U 
+
+
+                function
+                with parameters
+                  instance of type T 
+                  instance of type U 
+                returning 
+                  nothing 
+
+          to arguments
+                          Variable Expression: x: a signed int 
+
+                          Variable Expression: z: a pointer to signed int 
+
+          with inferred parameters:
+            ?=?: a function
+              with parameters
+                pointer to signed int 
+                signed int 
+              returning 
+                signed int 
+
+            ?=?: a function
+              with parameters
+                pointer to pointer to signed int 
+                pointer to signed int 
+              returning 
+                pointer to signed int 
+
+          with environment:
+            Types:
+              _1_T -> signed int 
+              _2_U -> pointer to signed int 
+            Non-types:
+
+
Index: translator/Tests/ResolvExpr/Expected/Function.tst
===================================================================
--- translator/Tests/ResolvExpr/Expected/Function.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Expected/Function.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,249 @@
+a: a signed int 
+a: a float 
+f: a function
+    with parameters
+      signed int 
+    returning 
+      signed int 
+
+f: a function
+    with parameters
+      float 
+    returning 
+      float 
+
+g: a function
+      accepting unspecified arguments
+    returning 
+      nothing 
+    with body 
+      
+        Expression Statement:
+          Application of
+            Variable Expression: f: a function
+                with parameters
+                  signed int 
+                returning 
+                  signed int 
+
+          to arguments
+                          Cast of:
+                Variable Expression: a: a signed int 
+
+              to:
+                signed int 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Cast of:
+            Application of
+              Variable Expression: f: a function
+                  with parameters
+                    signed int 
+                  returning 
+                    signed int 
+
+            to arguments
+                              Variable Expression: a: a signed int 
+
+
+          to:
+            signed int 
+          with environment:
+            Types:
+            Non-types:
+
+
+p: a tuple of types
+    signed int 
+
+p: a tuple of types
+    signed int 
+    double 
+
+p: a tuple of types
+    signed int 
+    signed int 
+    signed int 
+
+p: a tuple of types
+    signed int 
+    signed int 
+    signed int 
+    signed int 
+
+q: a tuple of types
+    char 
+
+q: a tuple of types
+    signed int 
+    signed int 
+
+q: a tuple of types
+    signed int 
+    signed int 
+    float 
+
+q: a tuple of types
+    signed int 
+    signed int 
+    signed int 
+    signed int 
+
+r: a function
+    with parameters
+      signed int 
+      signed int 
+      signed int 
+      signed int 
+    returning 
+      signed int 
+      signed int 
+
+s: a function
+      accepting unspecified arguments
+    returning 
+      nothing 
+    with body 
+      
+        Expression Statement:
+          Application of
+            Variable Expression: r: a function
+                with parameters
+                  signed int 
+                  signed int 
+                  signed int 
+                  signed int 
+                returning 
+                  signed int 
+                  signed int 
+
+          to arguments
+                          Variable Expression: p: a tuple of types
+                  signed int 
+                  signed int 
+                  signed int 
+
+
+                          Cast of:
+                Variable Expression: q: a tuple of types
+                    char 
+
+
+              to:
+                signed int 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: r: a function
+                with parameters
+                  signed int 
+                  signed int 
+                  signed int 
+                  signed int 
+                returning 
+                  signed int 
+                  signed int 
+
+          to arguments
+                          Cast of:
+                Tuple:
+                                      Variable Expression: q: a tuple of types
+                        char 
+
+
+                                      Variable Expression: p: a tuple of types
+                        signed int 
+                        signed int 
+                        signed int 
+
+
+
+              to:
+                signed int 
+                signed int 
+                signed int 
+                signed int 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: r: a function
+                with parameters
+                  signed int 
+                  signed int 
+                  signed int 
+                  signed int 
+                returning 
+                  signed int 
+                  signed int 
+
+          to arguments
+                          Application of
+                Variable Expression: r: a function
+                    with parameters
+                      signed int 
+                      signed int 
+                      signed int 
+                      signed int 
+                    returning 
+                      signed int 
+                      signed int 
+
+              to arguments
+                                  Variable Expression: p: a tuple of types
+                      signed int 
+                      signed int 
+                      signed int 
+
+
+                                  Cast of:
+                    Variable Expression: q: a tuple of types
+                        char 
+
+
+                  to:
+                    signed int 
+
+
+                          Application of
+                Variable Expression: r: a function
+                    with parameters
+                      signed int 
+                      signed int 
+                      signed int 
+                      signed int 
+                    returning 
+                      signed int 
+                      signed int 
+
+              to arguments
+                                  Variable Expression: q: a tuple of types
+                      signed int 
+                      signed int 
+
+
+                                  Variable Expression: q: a tuple of types
+                      signed int 
+                      signed int 
+
+
+
+          with environment:
+            Types:
+            Non-types:
+
+
Index: translator/Tests/ResolvExpr/Expected/InferParam.tst
===================================================================
--- translator/Tests/ResolvExpr/Expected/InferParam.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Expected/InferParam.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,317 @@
+?=?: a function
+    with parameters
+      pointer to signed int 
+      signed int 
+    returning 
+      signed int 
+
+?=?: a function
+    with parameters
+      pointer to float 
+      float 
+    returning 
+      float 
+
+?=?: a function
+    with parameters
+      pointer to double 
+      double 
+    returning 
+      double 
+
+g: a forall
+      T: a type
+        with assertions
+          ?=?: a pointer to function
+              with parameters
+                pointer to instance of type T 
+                instance of type T 
+              returning 
+                instance of type T 
+
+
+      U: a type
+        with assertions
+          ?=?: a pointer to function
+              with parameters
+                pointer to instance of type U 
+                instance of type U 
+              returning 
+                instance of type U 
+
+          f: a pointer to function
+              with parameters
+                instance of type T 
+              returning 
+                instance of type U 
+
+
+    function
+    with parameters
+      instance of type T 
+    returning 
+      instance of type U 
+
+f: a function
+    with parameters
+      signed int 
+    returning 
+      float 
+
+f: a function
+    with parameters
+      signed int 
+    returning 
+      double 
+
+i: a function
+    with parameters
+      float 
+    returning 
+      nothing 
+
+h: a function
+      accepting unspecified arguments
+    returning 
+      nothing 
+    with body 
+      Declaration of a: a signed int 
+      
+        Expression Statement:
+          Application of
+            Variable Expression: i: a function
+                with parameters
+                  float 
+                returning 
+                  nothing 
+
+          to arguments
+                          Application of
+                Variable Expression: g: a forall
+                      T: a type
+                        with assertions
+                          ?=?: a pointer to function
+                              with parameters
+                                pointer to instance of type T 
+                                instance of type T 
+                              returning 
+                                instance of type T 
+
+
+                      U: a type
+                        with assertions
+                          ?=?: a pointer to function
+                              with parameters
+                                pointer to instance of type U 
+                                instance of type U 
+                              returning 
+                                instance of type U 
+
+                          f: a pointer to function
+                              with parameters
+                                instance of type T 
+                              returning 
+                                instance of type U 
+
+
+                    function
+                    with parameters
+                      instance of type T 
+                    returning 
+                      instance of type U 
+
+              to arguments
+                                  Variable Expression: a: a signed int 
+
+              with inferred parameters:
+                ?=?: a function
+                  with parameters
+                    pointer to signed int 
+                    signed int 
+                  returning 
+                    signed int 
+
+                ?=?: a function
+                  with parameters
+                    pointer to float 
+                    float 
+                  returning 
+                    float 
+
+                f: a function
+                  with parameters
+                    signed int 
+                  returning 
+                    float 
+
+
+          with environment:
+            Types:
+              _0_T -> signed int 
+              _1_U -> float 
+            Non-types:
+
+
+context has_f_and_j
+    with parameters
+      T: a type
+      U: a type
+
+    with members
+      f: a function
+          with parameters
+            instance of type T 
+          returning 
+            instance of type U 
+
+      j: a function
+          with parameters
+            instance of type T 
+            instance of type U 
+          returning 
+            instance of type U 
+
+
+j: a function
+    with parameters
+      signed int 
+      float 
+    returning 
+      float 
+
+k: a forall
+      T: a type
+        with assertions
+          ?=?: a pointer to function
+              with parameters
+                pointer to instance of type T 
+                instance of type T 
+              returning 
+                instance of type T 
+
+
+      U: a type
+        with assertions
+          ?=?: a pointer to function
+              with parameters
+                pointer to instance of type U 
+                instance of type U 
+              returning 
+                instance of type U 
+
+          f: a pointer to function
+              with parameters
+                instance of type T 
+              returning 
+                instance of type U 
+
+          j: a pointer to function
+              with parameters
+                instance of type T 
+                instance of type U 
+              returning 
+                instance of type U 
+
+
+    function
+    with parameters
+      instance of type T 
+    returning 
+      instance of type U 
+
+l: a function
+      accepting unspecified arguments
+    returning 
+      nothing 
+    with body 
+      Declaration of b: a signed int 
+      
+        Expression Statement:
+          Application of
+            Variable Expression: i: a function
+                with parameters
+                  float 
+                returning 
+                  nothing 
+
+          to arguments
+                          Application of
+                Variable Expression: k: a forall
+                      T: a type
+                        with assertions
+                          ?=?: a pointer to function
+                              with parameters
+                                pointer to instance of type T 
+                                instance of type T 
+                              returning 
+                                instance of type T 
+
+
+                      U: a type
+                        with assertions
+                          ?=?: a pointer to function
+                              with parameters
+                                pointer to instance of type U 
+                                instance of type U 
+                              returning 
+                                instance of type U 
+
+                          f: a pointer to function
+                              with parameters
+                                instance of type T 
+                              returning 
+                                instance of type U 
+
+                          j: a pointer to function
+                              with parameters
+                                instance of type T 
+                                instance of type U 
+                              returning 
+                                instance of type U 
+
+
+                    function
+                    with parameters
+                      instance of type T 
+                    returning 
+                      instance of type U 
+
+              to arguments
+                                  Variable Expression: b: a signed int 
+
+              with inferred parameters:
+                ?=?: a function
+                  with parameters
+                    pointer to signed int 
+                    signed int 
+                  returning 
+                    signed int 
+
+                ?=?: a function
+                  with parameters
+                    pointer to float 
+                    float 
+                  returning 
+                    float 
+
+                f: a function
+                  with parameters
+                    signed int 
+                  returning 
+                    float 
+
+                j: a function
+                  with parameters
+                    signed int 
+                    float 
+                  returning 
+                    float 
+
+
+          with environment:
+            Types:
+              _0_T -> signed int 
+              _1_U -> float 
+            Non-types:
+
+
Index: translator/Tests/ResolvExpr/Expected/Members.tst
===================================================================
--- translator/Tests/ResolvExpr/Expected/Members.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Expected/Members.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,666 @@
+?=?: a function
+    with parameters
+      pointer to char 
+      char 
+    returning 
+      char 
+
+?=?: a function
+    with parameters
+      pointer to signed int 
+      signed int 
+    returning 
+      signed int 
+
+?=?: a function
+    with parameters
+      pointer to float 
+      float 
+    returning 
+      float 
+
+?=?: a forall
+      DT: a incomplete type
+    function
+    with parameters
+      pointer to pointer to instance of type DT 
+      pointer to instance of type DT 
+    returning 
+      pointer to instance of type DT 
+
+*?: a forall
+      T: a type
+        with assertions
+          ?=?: a pointer to function
+              with parameters
+                pointer to instance of type T 
+                instance of type T 
+              returning 
+                instance of type T 
+
+
+    function
+    with parameters
+      pointer to instance of type T 
+    returning 
+      lvalue instance of type T 
+
+__builtin_memcpy: a function
+      accepting unspecified arguments
+    returning 
+      pointer to char 
+
+a: a function
+    with parameters
+      char 
+    returning 
+      nothing 
+
+b: a function
+    with parameters
+      signed int 
+    returning 
+      nothing 
+
+c: a function
+    with parameters
+      pointer to signed int 
+    returning 
+      nothing 
+
+d: a function
+    with parameters
+      pointer to float 
+    returning 
+      nothing 
+
+struct a_struct
+    with members
+      a: a signed int 
+      a: a char 
+      a: a float 
+
+?=?: a automatically generated inline static function
+    with parameters
+      _dst: a pointer to instance of struct a_struct 
+      _src: a instance of struct a_struct 
+    returning 
+      instance of struct a_struct 
+    with body 
+      
+        Expression Statement:
+          Application of
+            Variable Expression: ?=?: a function
+                with parameters
+                  pointer to signed int 
+                  signed int 
+                returning 
+                  signed int 
+
+          to arguments
+                          Address of:
+                Member Expression, with field: 
+                  a: a signed int 
+                from aggregate: 
+                  Applying untyped: 
+                      Name: *?
+
+                  ...to: 
+                      Variable Expression: _dst: a pointer to instance of struct a_struct 
+
+                          Member Expression, with field: 
+                a: a signed int 
+              from aggregate: 
+                Variable Expression: _src: a instance of struct a_struct 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: ?=?: a function
+                with parameters
+                  pointer to char 
+                  char 
+                returning 
+                  char 
+
+          to arguments
+                          Address of:
+                Member Expression, with field: 
+                  a: a char 
+                from aggregate: 
+                  Applying untyped: 
+                      Name: *?
+
+                  ...to: 
+                      Variable Expression: _dst: a pointer to instance of struct a_struct 
+
+                          Member Expression, with field: 
+                a: a char 
+              from aggregate: 
+                Variable Expression: _src: a instance of struct a_struct 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: ?=?: a function
+                with parameters
+                  pointer to float 
+                  float 
+                returning 
+                  float 
+
+          to arguments
+                          Address of:
+                Member Expression, with field: 
+                  a: a float 
+                from aggregate: 
+                  Applying untyped: 
+                      Name: *?
+
+                  ...to: 
+                      Variable Expression: _dst: a pointer to instance of struct a_struct 
+
+                          Member Expression, with field: 
+                a: a float 
+              from aggregate: 
+                Variable Expression: _src: a instance of struct a_struct 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Return Statement, returning: Cast of:
+  Variable Expression: _src: a instance of struct a_struct 
+
+to:
+  instance of struct a_struct 
+with environment:
+  Types:
+  Non-types:
+
+
+
+union b_struct
+    with members
+      a: a pointer to signed int 
+      a: a pointer to char 
+      a: a pointer to float 
+
+?=?: a automatically generated inline static function
+    with parameters
+      _dst: a pointer to instance of union b_struct 
+      _src: a instance of union b_struct 
+    returning 
+      instance of union b_struct 
+    with body 
+      
+        Expression Statement:
+          Application of
+            Variable Expression: __builtin_memcpy: a function
+                  accepting unspecified arguments
+                returning 
+                  pointer to char 
+
+          to arguments
+                          Variable Expression: _dst: a pointer to instance of union b_struct 
+
+                          Address of:
+                Variable Expression: _src: a instance of union b_struct 
+
+                          Sizeof Expression on: instance of union b_struct 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Return Statement, returning: Cast of:
+  Variable Expression: _src: a instance of union b_struct 
+
+to:
+  instance of union b_struct 
+with environment:
+  Types:
+  Non-types:
+
+
+
+f: a function
+      accepting unspecified arguments
+    returning 
+      nothing 
+    with body 
+      Declaration of the_struct: a instance of struct a_struct 
+      Declaration of the_struct: a instance of union b_struct 
+      
+        Expression Statement:
+          Application of
+            Variable Expression: a: a function
+                with parameters
+                  char 
+                returning 
+                  nothing 
+
+          to arguments
+                          Member Expression, with field: 
+                a: a char 
+              from aggregate: 
+                Variable Expression: the_struct: a instance of struct a_struct 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: b: a function
+                with parameters
+                  signed int 
+                returning 
+                  nothing 
+
+          to arguments
+                          Member Expression, with field: 
+                a: a signed int 
+              from aggregate: 
+                Variable Expression: the_struct: a instance of struct a_struct 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: c: a function
+                with parameters
+                  pointer to signed int 
+                returning 
+                  nothing 
+
+          to arguments
+                          Member Expression, with field: 
+                a: a pointer to signed int 
+              from aggregate: 
+                Variable Expression: the_struct: a instance of union b_struct 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: d: a function
+                with parameters
+                  pointer to float 
+                returning 
+                  nothing 
+
+          to arguments
+                          Member Expression, with field: 
+                a: a pointer to float 
+              from aggregate: 
+                Variable Expression: the_struct: a instance of union b_struct 
+
+          with environment:
+            Types:
+            Non-types:
+
+
+struct c_struct
+    with members
+      signed int 
+      char 
+      float 
+
+?=?: a automatically generated inline static function
+    with parameters
+      _dst: a pointer to instance of struct c_struct 
+      _src: a instance of struct c_struct 
+    returning 
+      instance of struct c_struct 
+    with body 
+      
+        Expression Statement:
+          Application of
+            Variable Expression: ?=?: a function
+                with parameters
+                  pointer to signed int 
+                  signed int 
+                returning 
+                  signed int 
+
+          to arguments
+                          Address of:
+                Member Expression, with field: 
+                  signed int 
+                from aggregate: 
+                  Applying untyped: 
+                      Name: *?
+
+                  ...to: 
+                      Variable Expression: _dst: a pointer to instance of struct c_struct 
+
+                          Member Expression, with field: 
+                signed int 
+              from aggregate: 
+                Variable Expression: _src: a instance of struct c_struct 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: ?=?: a function
+                with parameters
+                  pointer to char 
+                  char 
+                returning 
+                  char 
+
+          to arguments
+                          Address of:
+                Member Expression, with field: 
+                  char 
+                from aggregate: 
+                  Applying untyped: 
+                      Name: *?
+
+                  ...to: 
+                      Variable Expression: _dst: a pointer to instance of struct c_struct 
+
+                          Member Expression, with field: 
+                char 
+              from aggregate: 
+                Variable Expression: _src: a instance of struct c_struct 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: ?=?: a function
+                with parameters
+                  pointer to float 
+                  float 
+                returning 
+                  float 
+
+          to arguments
+                          Address of:
+                Member Expression, with field: 
+                  float 
+                from aggregate: 
+                  Applying untyped: 
+                      Name: *?
+
+                  ...to: 
+                      Variable Expression: _dst: a pointer to instance of struct c_struct 
+
+                          Member Expression, with field: 
+                float 
+              from aggregate: 
+                Variable Expression: _src: a instance of struct c_struct 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Return Statement, returning: Cast of:
+  Variable Expression: _src: a instance of struct c_struct 
+
+to:
+  instance of struct c_struct 
+with environment:
+  Types:
+  Non-types:
+
+
+
+union d_struct
+    with members
+      pointer to signed int 
+      pointer to char 
+      pointer to float 
+
+?=?: a automatically generated inline static function
+    with parameters
+      _dst: a pointer to instance of union d_struct 
+      _src: a instance of union d_struct 
+    returning 
+      instance of union d_struct 
+    with body 
+      
+        Expression Statement:
+          Application of
+            Variable Expression: __builtin_memcpy: a function
+                  accepting unspecified arguments
+                returning 
+                  pointer to char 
+
+          to arguments
+                          Variable Expression: _dst: a pointer to instance of union d_struct 
+
+                          Address of:
+                Variable Expression: _src: a instance of union d_struct 
+
+                          Sizeof Expression on: instance of union d_struct 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Return Statement, returning: Cast of:
+  Variable Expression: _src: a instance of union d_struct 
+
+to:
+  instance of union d_struct 
+with environment:
+  Types:
+  Non-types:
+
+
+
+g: a function
+      accepting unspecified arguments
+    returning 
+      nothing 
+    with body 
+      Declaration of x: a short unsigned int 
+      Declaration of x: a instance of struct c_struct 
+      Declaration of x: a instance of union d_struct 
+      
+        Expression Statement:
+          Application of
+            Variable Expression: a: a function
+                with parameters
+                  char 
+                returning 
+                  nothing 
+
+          to arguments
+                          Cast of:
+                Variable Expression: x: a short unsigned int 
+
+              to:
+                char 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: b: a function
+                with parameters
+                  signed int 
+                returning 
+                  nothing 
+
+          to arguments
+                          Cast of:
+                Variable Expression: x: a short unsigned int 
+
+              to:
+                signed int 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: c: a function
+                with parameters
+                  pointer to signed int 
+                returning 
+                  nothing 
+
+          to arguments
+                          Member Expression, with field: 
+                pointer to signed int 
+              from aggregate: 
+                Variable Expression: x: a instance of union d_struct 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: d: a function
+                with parameters
+                  pointer to float 
+                returning 
+                  nothing 
+
+          to arguments
+                          Member Expression, with field: 
+                pointer to float 
+              from aggregate: 
+                Variable Expression: x: a instance of union d_struct 
+
+          with environment:
+            Types:
+            Non-types:
+
+
+struct forward
+q: a pointer to instance of struct forward 
+struct forward
+    with members
+      y: a signed int 
+
+?=?: a automatically generated inline static function
+    with parameters
+      _dst: a pointer to instance of struct forward 
+      _src: a instance of struct forward 
+    returning 
+      instance of struct forward 
+    with body 
+      
+        Expression Statement:
+          Application of
+            Variable Expression: ?=?: a function
+                with parameters
+                  pointer to signed int 
+                  signed int 
+                returning 
+                  signed int 
+
+          to arguments
+                          Address of:
+                Member Expression, with field: 
+                  y: a signed int 
+                from aggregate: 
+                  Applying untyped: 
+                      Name: *?
+
+                  ...to: 
+                      Variable Expression: _dst: a pointer to instance of struct forward 
+
+                          Member Expression, with field: 
+                y: a signed int 
+              from aggregate: 
+                Variable Expression: _src: a instance of struct forward 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Return Statement, returning: Cast of:
+  Variable Expression: _src: a instance of struct forward 
+
+to:
+  instance of struct forward 
+with environment:
+  Types:
+  Non-types:
+
+
+
+h: a function
+      accepting unspecified arguments
+    returning 
+      nothing 
+    with body 
+      
+        Expression Statement:
+          Member Expression, with field: 
+            y: a signed int 
+          from aggregate: 
+            Application of
+              Variable Expression: *?: a forall
+                    T: a type
+                      with assertions
+                        ?=?: a pointer to function
+                            with parameters
+                              pointer to instance of type T 
+                              instance of type T 
+                            returning 
+                              instance of type T 
+
+
+                  function
+                  with parameters
+                    pointer to instance of type T 
+                  returning 
+                    lvalue instance of type T 
+
+            to arguments
+                              Variable Expression: q: a pointer to instance of struct forward 
+
+            with inferred parameters:
+              ?=?: a inline static function
+                with parameters
+                  _dst: a pointer to instance of struct forward 
+                  _src: a instance of struct forward 
+                returning 
+                  instance of struct forward 
+
+          with environment:
+            Types:
+            Non-types:
+
+
Index: translator/Tests/ResolvExpr/Expected/Misc.tst
===================================================================
--- translator/Tests/ResolvExpr/Expected/Misc.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Expected/Misc.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,94 @@
+a: a signed int 
+b: a signed int 
+b: a float 
+g: a function
+    with parameters
+      signed int 
+    returning 
+      nothing 
+
+g: a function
+    with parameters
+      unsigned int 
+    returning 
+      nothing 
+
+f: a function
+    returning 
+      nothing 
+    with body 
+      
+        Expression Statement:
+          Application of
+            Variable Expression: g: a function
+                with parameters
+                  signed int 
+                returning 
+                  nothing 
+
+          to arguments
+                          Comma Expression:
+                Variable Expression: a: a signed int 
+
+                Variable Expression: b: a signed int 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: g: a function
+                with parameters
+                  signed int 
+                returning 
+                  nothing 
+
+          to arguments
+                          Comma Expression:
+                Comma Expression:
+                  Variable Expression: a: a signed int 
+
+                  Variable Expression: a: a signed int 
+
+                Variable Expression: b: a signed int 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: g: a function
+                with parameters
+                  unsigned int 
+                returning 
+                  nothing 
+
+          to arguments
+                          Sizeof Expression on:                 Variable Expression: a: a signed int 
+
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: g: a function
+                with parameters
+                  unsigned int 
+                returning 
+                  nothing 
+
+          to arguments
+                          Sizeof Expression on: signed int 
+
+          with environment:
+            Types:
+            Non-types:
+
+
Index: translator/Tests/ResolvExpr/Expected/MiscError.tst
===================================================================
--- translator/Tests/ResolvExpr/Expected/MiscError.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Expected/MiscError.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,83 @@
+Error: Can't choose between alternatives for expression Cast of:
+  Name: b
+
+to:
+  nothing
+Alternatives are:        Cost ( 0, 0, 1 ):         Cast of:
+          Variable Expression: b: a signed int 
+
+        to:
+          nothing
+(types:
+)
+        Environment: 
+
+        Cost ( 0, 0, 1 ):         Cast of:
+          Variable Expression: b: a float 
+
+        to:
+          nothing
+(types:
+)
+        Environment: 
+
+
+Error: Can't choose between alternatives for expression Cast of:
+  Name: b
+
+to:
+  nothing
+Alternatives are:        Cost ( 0, 0, 1 ):         Cast of:
+          Variable Expression: b: a signed int 
+
+        to:
+          nothing
+(types:
+)
+        Environment: 
+
+        Cost ( 0, 0, 1 ):         Cast of:
+          Variable Expression: b: a float 
+
+        to:
+          nothing
+(types:
+)
+        Environment: 
+
+
+Error: Can't choose between alternatives for expression Cast of:
+  Comma Expression:
+    Name: a
+
+    Name: b
+
+to:
+  nothing
+Alternatives are:        Cost ( 0, 0, 1 ):         Cast of:
+          Comma Expression:
+            Variable Expression: a: a signed int 
+
+            Variable Expression: b: a signed int 
+
+        to:
+          nothing
+(types:
+)
+        Environment: 
+
+        Cost ( 0, 0, 1 ):         Cast of:
+          Comma Expression:
+            Variable Expression: a: a signed int 
+
+            Variable Expression: b: a float 
+
+        to:
+          nothing
+(types:
+)
+        Environment: 
+
+
+Error: Ambiguous expression in sizeof operand: Name: b
+
Index: translator/Tests/ResolvExpr/Expected/OccursError.tst
===================================================================
--- translator/Tests/ResolvExpr/Expected/OccursError.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Expected/OccursError.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,6 @@
+Error: No reasonable alternatives for expression Applying untyped: 
+    Name: f
+
+...to: 
+    Name: g
+
Index: translator/Tests/ResolvExpr/Expected/Operators.tst
===================================================================
--- translator/Tests/ResolvExpr/Expected/Operators.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Expected/Operators.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,224 @@
+?*?: a function
+    with parameters
+      signed int 
+      signed int 
+    returning 
+      signed int 
+
+?(): a function
+    with parameters
+      number1: a signed int 
+      number2: a signed int 
+    returning 
+      signed int 
+    with body 
+      
+        Return Statement, returning: Cast of:
+  Application of
+    Variable Expression: ?*?: a function
+        with parameters
+          signed int 
+          signed int 
+        returning 
+          signed int 
+
+  to arguments
+          Variable Expression: number1: a signed int 
+
+          Variable Expression: number2: a signed int 
+
+
+to:
+  signed int 
+with environment:
+  Types:
+  Non-types:
+
+
+
+?+?: a function
+    with parameters
+      signed int 
+      signed int 
+    returning 
+      signed int 
+
+?=?: a function
+    with parameters
+      pointer to signed int 
+      signed int 
+    returning 
+      signed int 
+
+struct accumulator
+    with members
+      total: a signed int 
+
+?=?: a automatically generated inline static function
+    with parameters
+      _dst: a pointer to instance of struct accumulator 
+      _src: a instance of struct accumulator 
+    returning 
+      instance of struct accumulator 
+    with body 
+      
+        Expression Statement:
+          Application of
+            Variable Expression: ?=?: a function
+                with parameters
+                  pointer to signed int 
+                  signed int 
+                returning 
+                  signed int 
+
+          to arguments
+                          Address of:
+                Member Expression, with field: 
+                  total: a signed int 
+                from aggregate: 
+                  Applying untyped: 
+                      Name: *?
+
+                  ...to: 
+                      Variable Expression: _dst: a pointer to instance of struct accumulator 
+
+                          Member Expression, with field: 
+                total: a signed int 
+              from aggregate: 
+                Variable Expression: _src: a instance of struct accumulator 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Return Statement, returning: Cast of:
+  Variable Expression: _src: a instance of struct accumulator 
+
+to:
+  instance of struct accumulator 
+with environment:
+  Types:
+  Non-types:
+
+
+
+?(): a function
+    with parameters
+      a: a instance of struct accumulator 
+      number1: a char 
+      number2: a char 
+    returning 
+      char 
+
+f: a function
+    returning 
+      nothing 
+    with body 
+      Declaration of a: a char 
+      Declaration of b: a char 
+      
+        Expression Statement:
+          Application of
+            Variable Expression: ?(): a function
+                with parameters
+                  number1: a signed int 
+                  number2: a signed int 
+                returning 
+                  signed int 
+
+          to arguments
+                          Cast of:
+                Variable Expression: a: a char 
+
+              to:
+                signed int 
+
+                          Cast of:
+                Variable Expression: b: a char 
+
+              to:
+                signed int 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: ?(): a function
+                with parameters
+                  number1: a signed int 
+                  number2: a signed int 
+                returning 
+                  signed int 
+
+          to arguments
+                          Cast of:
+                Variable Expression: a: a char 
+
+              to:
+                signed int 
+
+                          Cast of:
+                Variable Expression: b: a char 
+
+              to:
+                signed int 
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: ?+?: a function
+                with parameters
+                  signed int 
+                  signed int 
+                returning 
+                  signed int 
+
+          to arguments
+                          Cast of:
+                Variable Expression: a: a char 
+
+              to:
+                signed int 
+
+                          Cast of:
+                Variable Expression: b: a char 
+
+              to:
+                signed int 
+
+          with environment:
+            Types:
+            Non-types:
+
+      Declaration of ?+?: a instance of struct accumulator 
+      
+        Expression Statement:
+          Application of
+            Variable Expression: ?(): a function
+                with parameters
+                  a: a instance of struct accumulator 
+                  number1: a char 
+                  number2: a char 
+                returning 
+                  char 
+
+          to arguments
+                          Variable Expression: ?+?: a instance of struct accumulator 
+
+                          Variable Expression: a: a char 
+
+                          Variable Expression: b: a char 
+
+          with environment:
+            Types:
+            Non-types:
+
+
Index: translator/Tests/ResolvExpr/Expected/Quad.tst
===================================================================
--- translator/Tests/ResolvExpr/Expected/Quad.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Expected/Quad.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,201 @@
+?=?: a function
+    with parameters
+      pointer to signed int 
+      signed int 
+    returning 
+      signed int 
+
+?*?: a function
+    with parameters
+      signed int 
+      signed int 
+    returning 
+      signed int 
+
+square: a forall
+      T: a type
+        with assertions
+          ?=?: a pointer to function
+              with parameters
+                pointer to instance of type T 
+                instance of type T 
+              returning 
+                instance of type T 
+
+          ?*?: a pointer to function
+              with parameters
+                instance of type T 
+                instance of type T 
+              returning 
+                instance of type T 
+
+
+    function
+    with parameters
+      t: a instance of type T 
+    returning 
+      instance of type T 
+    with body 
+      
+        Return Statement, returning: Cast of:
+  Application of
+    Variable Expression: ?*?: a pointer to function
+        with parameters
+          instance of type T 
+          instance of type T 
+        returning 
+          instance of type T 
+
+  to arguments
+          Variable Expression: t: a instance of type T 
+
+          Variable Expression: t: a instance of type T 
+
+
+to:
+  instance of type T 
+with environment:
+  Types:
+  Non-types:
+
+
+
+quad: a forall
+      U: a type
+        with assertions
+          ?=?: a pointer to function
+              with parameters
+                pointer to instance of type U 
+                instance of type U 
+              returning 
+                instance of type U 
+
+          square: a pointer to function
+              with parameters
+                instance of type U 
+              returning 
+                instance of type U 
+
+
+    function
+    with parameters
+      u: a instance of type U 
+    returning 
+      instance of type U 
+    with body 
+      
+        Return Statement, returning: Cast of:
+  Application of
+    Variable Expression: square: a pointer to function
+        with parameters
+          instance of type U 
+        returning 
+          instance of type U 
+
+  to arguments
+          Application of
+        Variable Expression: square: a pointer to function
+            with parameters
+              instance of type U 
+            returning 
+              instance of type U 
+
+      to arguments
+                  Variable Expression: u: a instance of type U 
+
+
+
+to:
+  instance of type U 
+with environment:
+  Types:
+  Non-types:
+
+
+
+f: a function
+      accepting unspecified arguments
+    returning 
+      nothing 
+    with body 
+      
+        Expression Statement:
+          Application of
+            Variable Expression: quad: a forall
+                  U: a type
+                    with assertions
+                      ?=?: a pointer to function
+                          with parameters
+                            pointer to instance of type U 
+                            instance of type U 
+                          returning 
+                            instance of type U 
+
+                      square: a pointer to function
+                          with parameters
+                            instance of type U 
+                          returning 
+                            instance of type U 
+
+
+                function
+                with parameters
+                  u: a instance of type U 
+                returning 
+                  instance of type U 
+
+          to arguments
+                          Constant Expression: 7 (type: signed int )
+          with inferred parameters:
+            ?=?: a function
+              with parameters
+                pointer to signed int 
+                signed int 
+              returning 
+                signed int 
+
+            ?*?: a function
+              with parameters
+                signed int 
+                signed int 
+              returning 
+                signed int 
+
+            ?=?: a function
+              with parameters
+                pointer to signed int 
+                signed int 
+              returning 
+                signed int 
+
+            square: a forall
+                T: a type
+                  with assertions
+                    ?=?: a pointer to function
+                        with parameters
+                          pointer to instance of type T 
+                          instance of type T 
+                        returning 
+                          instance of type T 
+
+                    ?*?: a pointer to function
+                        with parameters
+                          instance of type T 
+                          instance of type T 
+                        returning 
+                          instance of type T 
+
+
+              function
+              with parameters
+                t: a instance of type T 
+              returning 
+                instance of type T 
+
+          with environment:
+            Types:
+              _0_U -> signed int 
+              _1_T -> signed int 
+            Non-types:
+
+
Index: translator/Tests/ResolvExpr/Expected/Rank2.tst
===================================================================
--- translator/Tests/ResolvExpr/Expected/Rank2.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Expected/Rank2.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,272 @@
+?=?: a function
+    with parameters
+      pointer to signed int 
+      signed int 
+    returning 
+      signed int 
+
+?=?: a forall
+      DT: a incomplete type
+    function
+    with parameters
+      pointer to pointer to instance of type DT 
+      pointer to instance of type DT 
+    returning 
+      pointer to instance of type DT 
+
+a: a function
+      accepting unspecified arguments
+    returning 
+      nothing 
+    with body 
+      Declaration of f: a forall
+            T: a type
+              with assertions
+                ?=?: a pointer to function
+                    with parameters
+                      pointer to instance of type T 
+                      instance of type T 
+                    returning 
+                      instance of type T 
+
+
+          function
+          with parameters
+            instance of type T 
+          returning 
+            nothing 
+
+      Declaration of g: a function
+          with parameters
+            p: a pointer to forall
+                  U: a type
+                    with assertions
+                      ?=?: a pointer to function
+                          with parameters
+                            pointer to instance of type U 
+                            instance of type U 
+                          returning 
+                            instance of type U 
+
+
+                function
+                with parameters
+                  instance of type U 
+                returning 
+                  nothing 
+
+          returning 
+            nothing 
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: g: a function
+                with parameters
+                  p: a pointer to forall
+                        U: a type
+                          with assertions
+                            ?=?: a pointer to function
+                                with parameters
+                                  pointer to instance of type U 
+                                  instance of type U 
+                                returning 
+                                  instance of type U 
+
+
+                      function
+                      with parameters
+                        instance of type U 
+                      returning 
+                        nothing 
+
+                returning 
+                  nothing 
+
+          to arguments
+                          Variable Expression: f: a forall
+                    T: a type
+                      with assertions
+                        ?=?: a pointer to function
+                            with parameters
+                              pointer to instance of type T 
+                              instance of type T 
+                            returning 
+                              instance of type T 
+
+
+                  function
+                  with parameters
+                    instance of type T 
+                  returning 
+                    nothing 
+
+
+          with inferred parameters:
+            ?=?: a pointer to function
+              with parameters
+                pointer to instance of type U 
+                instance of type U 
+              returning 
+                instance of type U 
+
+          with environment:
+            Types:
+              _1_T -> instance of type _0_U 
+            Non-types:
+
+
+g: a function
+      accepting unspecified arguments
+    returning 
+      nothing 
+    with body 
+      Declaration of h: a function
+          with parameters
+            null: a pointer to signed int 
+          returning 
+            nothing 
+
+      Declaration of id: a forall
+            T: a type
+              with assertions
+                ?=?: a pointer to function
+                    with parameters
+                      pointer to instance of type T 
+                      instance of type T 
+                    returning 
+                      instance of type T 
+
+
+          function
+          with parameters
+            instance of type T 
+          returning 
+            instance of type T 
+
+      Declaration of 0: a forall
+            T: a incomplete type
+          pointer to instance of type T 
+      Declaration of 0: a signed int 
+      
+        Expression Statement:
+          Application of
+            Variable Expression: h: a function
+                with parameters
+                  null: a pointer to signed int 
+                returning 
+                  nothing 
+
+          to arguments
+                          Application of
+                Variable Expression: id: a forall
+                      T: a type
+                        with assertions
+                          ?=?: a pointer to function
+                              with parameters
+                                pointer to instance of type T 
+                                instance of type T 
+                              returning 
+                                instance of type T 
+
+
+                    function
+                    with parameters
+                      instance of type T 
+                    returning 
+                      instance of type T 
+
+              to arguments
+                                  Application of
+                    Variable Expression: id: a forall
+                          T: a type
+                            with assertions
+                              ?=?: a pointer to function
+                                  with parameters
+                                    pointer to instance of type T 
+                                    instance of type T 
+                                  returning 
+                                    instance of type T 
+
+
+                        function
+                        with parameters
+                          instance of type T 
+                        returning 
+                          instance of type T 
+
+                  to arguments
+                                          Application of
+                        Variable Expression: id: a forall
+                              T: a type
+                                with assertions
+                                  ?=?: a pointer to function
+                                      with parameters
+                                        pointer to instance of type T 
+                                        instance of type T 
+                                      returning 
+                                        instance of type T 
+
+
+                            function
+                            with parameters
+                              instance of type T 
+                            returning 
+                              instance of type T 
+
+                      to arguments
+                                                  Variable Expression: 0: a forall
+                                T: a incomplete type
+                              pointer to instance of type T 
+
+                      with inferred parameters:
+                        ?=?: a forall
+                            DT: a incomplete type
+                          function
+                          with parameters
+                            pointer to pointer to instance of type DT 
+                            pointer to instance of type DT 
+                          returning 
+                            pointer to instance of type DT 
+
+
+                  with inferred parameters:
+                    ?=?: a forall
+                        DT: a incomplete type
+                      function
+                      with parameters
+                        pointer to pointer to instance of type DT 
+                        pointer to instance of type DT 
+                      returning 
+                        pointer to instance of type DT 
+
+
+              with inferred parameters:
+                ?=?: a forall
+                    DT: a incomplete type
+                  function
+                  with parameters
+                    pointer to pointer to instance of type DT 
+                    pointer to instance of type DT 
+                  returning 
+                    pointer to instance of type DT 
+
+
+          with environment:
+            Types:
+              _0_T -> forall
+                    _3_T: a incomplete type
+                  pointer to instance of type _3_T 
+              _1_T -> forall
+                    _3_T: a incomplete type
+                  pointer to instance of type _3_T 
+              _2_T -> forall
+                    _3_T: a incomplete type
+                  pointer to instance of type _3_T 
+              _3_T -> signed int 
+              _5_DT -> signed int 
+              _7_DT -> signed int 
+              _9_DT -> signed int 
+            Non-types:
+
+
Index: translator/Tests/ResolvExpr/Expected/ShortCircuit.tst
===================================================================
--- translator/Tests/ResolvExpr/Expected/ShortCircuit.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Expected/ShortCircuit.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,178 @@
+?!=?: a function
+    with parameters
+      signed int 
+      signed int 
+    returning 
+      signed int 
+
+?!=?: a function
+    with parameters
+      float 
+      float 
+    returning 
+      signed int 
+
+0: a signed int 
+g: a function
+    with parameters
+      float 
+    returning 
+      nothing 
+
+g: a function
+    with parameters
+      signed int 
+    returning 
+      nothing 
+
+f: a function
+    with parameters
+      a: a signed int 
+    returning 
+      nothing 
+    with body 
+      Declaration of b: a signed int 
+      Declaration of c: a float 
+      
+        Expression Statement:
+          Application of
+            Variable Expression: g: a function
+                with parameters
+                  float 
+                returning 
+                  nothing 
+
+          to arguments
+                          Conditional expression on: 
+                Cast of:
+                  Application of
+                    Variable Expression: ?!=?: a function
+                        with parameters
+                          signed int 
+                          signed int 
+                        returning 
+                          signed int 
+
+                  to arguments
+                                          Variable Expression: a: a signed int 
+
+                                          Variable Expression: 0: a signed int 
+
+
+                to:
+                  signed int 
+              First alternative:
+                Variable Expression: b: a signed int 
+              Second alternative:
+                Variable Expression: c: a float 
+
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: g: a function
+                with parameters
+                  signed int 
+                returning 
+                  nothing 
+
+          to arguments
+                          Short-circuited operation (and) on: Cast of:
+  Application of
+    Variable Expression: ?!=?: a function
+        with parameters
+          signed int 
+          signed int 
+        returning 
+          signed int 
+
+  to arguments
+          Variable Expression: a: a signed int 
+
+          Variable Expression: 0: a signed int 
+
+
+to:
+  signed int 
+ and Cast of:
+  Application of
+    Variable Expression: ?!=?: a function
+        with parameters
+          float 
+          float 
+        returning 
+          signed int 
+
+  to arguments
+          Variable Expression: c: a float 
+
+          Cast of:
+        Variable Expression: 0: a signed int 
+
+      to:
+        float 
+
+
+to:
+  signed int 
+
+
+          with environment:
+            Types:
+            Non-types:
+
+      
+        Expression Statement:
+          Application of
+            Variable Expression: g: a function
+                with parameters
+                  signed int 
+                returning 
+                  nothing 
+
+          to arguments
+                          Short-circuited operation (or) on: Cast of:
+  Application of
+    Variable Expression: ?!=?: a function
+        with parameters
+          signed int 
+          signed int 
+        returning 
+          signed int 
+
+  to arguments
+          Variable Expression: a: a signed int 
+
+          Variable Expression: 0: a signed int 
+
+
+to:
+  signed int 
+ and Cast of:
+  Application of
+    Variable Expression: ?!=?: a function
+        with parameters
+          signed int 
+          signed int 
+        returning 
+          signed int 
+
+  to arguments
+          Variable Expression: b: a signed int 
+
+          Variable Expression: 0: a signed int 
+
+
+to:
+  signed int 
+
+
+          with environment:
+            Types:
+            Non-types:
+
+
Index: translator/Tests/ResolvExpr/Expected/Statement.tst
===================================================================
--- translator/Tests/ResolvExpr/Expected/Statement.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Expected/Statement.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,170 @@
+?=?: a function
+    with parameters
+      pointer to signed int 
+      signed int 
+    returning 
+      signed int 
+
+?!=?: a function
+    with parameters
+      signed int 
+      signed int 
+    returning 
+      signed int 
+
+0: a signed int 
+f: a function
+      accepting unspecified arguments
+    returning 
+      nothing 
+    with body 
+      Declaration of a: a signed int 
+      Declaration of struct __anonymous0
+          with members
+            b: a signed int 
+
+      Declaration of ?=?: a automatically generated inline static function
+          with parameters
+            _dst: a pointer to instance of struct __anonymous0 
+            _src: a instance of struct __anonymous0 
+          returning 
+            instance of struct __anonymous0 
+          with body 
+            
+              Expression Statement:
+                Application of
+                  Variable Expression: ?=?: a function
+                      with parameters
+                        pointer to signed int 
+                        signed int 
+                      returning 
+                        signed int 
+
+                to arguments
+                                      Address of:
+                      Member Expression, with field: 
+                        b: a signed int 
+                      from aggregate: 
+                        Applying untyped: 
+                            Name: *?
+
+                        ...to: 
+                            Variable Expression: _dst: a pointer to instance of struct __anonymous0 
+
+                                      Member Expression, with field: 
+                      b: a signed int 
+                    from aggregate: 
+                      Variable Expression: _src: a instance of struct __anonymous0 
+
+                with environment:
+                  Types:
+                  Non-types:
+
+            
+              Return Statement, returning: Cast of:
+  Variable Expression: _src: a instance of struct __anonymous0 
+
+to:
+  instance of struct __anonymous0 
+with environment:
+  Types:
+  Non-types:
+
+
+
+      Declaration of a: a instance of struct __anonymous0 
+      
+        If on condition: 
+            Cast of:
+              Application of
+                Variable Expression: ?!=?: a function
+                    with parameters
+                      signed int 
+                      signed int 
+                    returning 
+                      signed int 
+
+              to arguments
+                                  Variable Expression: a: a signed int 
+
+                                  Variable Expression: 0: a signed int 
+
+
+            to:
+              signed int 
+            with environment:
+              Types:
+              Non-types:
+        .... and branches: 
+            
+              While on condition: 
+                  Cast of:
+                    Application of
+                      Variable Expression: ?!=?: a function
+                          with parameters
+                            signed int 
+                            signed int 
+                          returning 
+                            signed int 
+
+                    to arguments
+                                              Variable Expression: a: a signed int 
+
+                                              Variable Expression: 0: a signed int 
+
+
+                  to:
+                    signed int 
+                  with environment:
+                    Types:
+                    Non-types:
+              .... with body: 
+                  Declaration of b: a pointer to signed int 
+                  
+                    For Statement
+
+                      initialization: 
+
+                        Expression Statement:
+                          Variable Expression: b: a pointer to signed int 
+                          with environment:
+                            Types:
+                            Non-types:
+
+
+                      condition: 
+                        Cast of:
+                          Application of
+                            Variable Expression: ?!=?: a function
+                                with parameters
+                                  signed int 
+                                  signed int 
+                                returning 
+                                  signed int 
+
+                          to arguments
+                                                          Variable Expression: a: a signed int 
+
+                                                          Variable Expression: 0: a signed int 
+
+
+                        to:
+                          signed int 
+                        with environment:
+                          Types:
+                          Non-types:
+
+
+                      increment: 
+                        Variable Expression: b: a pointer to signed int 
+                        with environment:
+                          Types:
+                          Non-types:
+
+
+                      statement block: 
+
+
+
+
+
Index: translator/Tests/ResolvExpr/Forall.c
===================================================================
--- translator/Tests/ResolvExpr/Forall.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Forall.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,39 @@
+int ?=?( int*, int );
+float ?=?( float*, float );
+int * ?=?( int **, int * );
+float * ?=?( float **, float * );
+char ?=?( char*, char );
+void (* ?=?( void (**)(void), void (*)(void) ))(void);
+
+void g1()
+{
+  forall( type T ) T f( T );
+  void f( int );
+  void h( void (*p)(void) );
+  
+  int x;
+  void (*y)(void);
+  char z;
+  float w;
+  
+  f( x );
+  f( y );
+  f( z );
+  f( w );
+  h( f( y ) );
+}
+
+void g2()
+{
+  forall( type T ) void f( T, T );
+  forall( type T, type U ) void f( T, U );
+  
+  int x;
+  float y;
+  int *z;
+  float *w;
+  
+  f( x, y );
+  f( z, w );
+  f( x, z );
+}
Index: translator/Tests/ResolvExpr/Function.c
===================================================================
--- translator/Tests/ResolvExpr/Function.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Function.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,31 @@
+int a;
+float a;
+int f( int );
+float f( float );
+
+void g()
+{
+  // selects the same f and a each time
+  // but without a cast would be ambiguous
+  f( (int)a );
+  (int)f( a );
+}
+
+[ int ] p;
+[ int, double ] p;
+[ int, int, int ] p;
+[ int, int, int, int ] p;
+
+[ char ] q;
+[ int, int ] q;
+[ int, int, float ] q;
+[ int, int, int, int ] q;
+
+[ int, int ] r( int, int, int, int );
+
+void s()
+{
+  r( p, q );
+  r( [ q, p ] );
+  r( r( p, q ), r( q, q ) );
+}
Index: translator/Tests/ResolvExpr/InferParam.c
===================================================================
--- translator/Tests/ResolvExpr/InferParam.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/InferParam.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,29 @@
+int ?=?( int*, int );
+float ?=?( float*, float );
+double ?=?( double*, double );
+
+forall( type T, type U | { U f(T); } ) U g(T);
+float f( int );
+double f( int );
+void i( float );
+
+void h()
+{
+  int a;
+  i( g( a ) );
+}
+
+context has_f_and_j( type T, type U )
+{
+  U f( T );
+  U j( T, U );
+};
+
+float j( int, float );
+forall( type T, type U | has_f_and_j( T, U ) ) U k( T );
+
+void l()
+{
+  int b;
+  i( k( b ) );
+}
Index: translator/Tests/ResolvExpr/Makefile
===================================================================
--- translator/Tests/ResolvExpr/Makefile	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Makefile	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,2 @@
+all:
+	sh run-tests.sh
Index: translator/Tests/ResolvExpr/Members.c
===================================================================
--- translator/Tests/ResolvExpr/Members.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Members.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,77 @@
+// "../../cfa-cpp -nc Members.c"
+
+char ?=?( char*, char );
+int ?=?( int*, int );
+float ?=?( float*, float );
+forall( dtype DT ) DT * ?=?( DT**, DT* );
+forall(type T) lvalue T *?( T* );
+char *__builtin_memcpy();
+
+void a( char );
+void b( int );
+void c( int* );
+void d( float* );
+
+struct a_struct
+{
+  int a;
+  char a;
+  float a;
+};
+
+union b_struct
+{
+  int *a;
+  char *a;
+  float *a;
+};
+
+void f()
+{
+  struct a_struct the_struct;
+  union b_struct the_struct;
+  
+  a( the_struct.a );
+  b( the_struct.a );
+  c( the_struct.a );
+  d( the_struct.a );
+}
+
+struct c_struct
+{
+  int;
+  char;
+  float;
+};
+
+union d_struct
+{
+  int*;
+  char*;
+  float*;
+};
+
+void g()
+{
+  unsigned short x;
+  struct c_struct x;
+  union d_struct x;
+  
+  a( x );	// the 'a' and 'b' calls resolve to the ushort
+  b( x );	// it's debatable whether this is good
+  c( x );
+  d( x );
+}
+
+// make sure that forward declarations work
+
+struct forward;
+
+struct forward *q;
+
+struct forward { int y; };
+
+void h()
+{
+	q->y;
+}
Index: translator/Tests/ResolvExpr/Misc.c
===================================================================
--- translator/Tests/ResolvExpr/Misc.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Misc.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,15 @@
+int a;
+int b;
+float b;
+
+void g( int );
+void g( unsigned );
+
+void
+f( void )
+{
+  g( (a, b) );
+  g( (a, a, b) );
+  g( sizeof a );
+  g( sizeof( int ) );
+}
Index: translator/Tests/ResolvExpr/MiscError.c
===================================================================
--- translator/Tests/ResolvExpr/MiscError.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/MiscError.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,14 @@
+int a;
+int b;
+float b;
+
+void g( int );
+
+void
+f( void )
+{
+  g( (b, a) );
+  g( (b, a, b) );
+  g( (a, b, b) );
+  sizeof b;
+}
Index: translator/Tests/ResolvExpr/OccursError.c
===================================================================
--- translator/Tests/ResolvExpr/OccursError.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/OccursError.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,11 @@
+// "./cfa-cpp -c simple.c"
+// "./cfa -v simple.c"
+// "./cfa -CFA simple.c > simple_out.c"
+
+forall( type T ) void f( void (*)( T, T* ) );
+forall( type U ) void g( U*, U );
+
+void test()
+{
+  f( g );
+}
Index: translator/Tests/ResolvExpr/Operators.c
===================================================================
--- translator/Tests/ResolvExpr/Operators.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Operators.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,28 @@
+int ?*?( int, int );
+
+int
+?()( int number1, int number2 )
+{
+  return number1 * number2;
+}
+
+int ?+?( int, int );
+
+int ?=?( int*, int );
+struct accumulator
+{
+  int total;
+};
+
+char ?()( struct accumulator a, char number1, char number2 );
+
+void
+f( void )
+{
+  char a, b;
+  ?()( a, b );
+  a(b);
+  a + b;
+  struct accumulator ?+?;	// why not, eh?
+  a + b;
+}
Index: translator/Tests/ResolvExpr/Quad.c
===================================================================
--- translator/Tests/ResolvExpr/Quad.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Quad.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,19 @@
+int ?=?( int*, int );
+int ?*?( int, int );
+
+forall( type T | { T ?*?( T, T ); } )
+T square( T t )
+{
+  return t * t;
+}
+
+forall( type U | { U square( U ); } )
+U quad( U u )
+{
+  return square( square( u ) );
+}
+
+void f()
+{
+  quad( 7 );
+}
Index: translator/Tests/ResolvExpr/Rank2.c
===================================================================
--- translator/Tests/ResolvExpr/Rank2.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Rank2.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,18 @@
+int ?=?( int*, int );
+forall(dtype DT) DT* 	   	?=?( DT *          *,            DT* );
+
+void a()
+{
+  forall( type T ) void f( T );
+  void g( forall( type U ) void p( U ) );
+  g( f );
+}
+
+void g()
+{
+  void h( int *null );
+  forall( type T ) T id( T );
+  forall( dtype T ) T *0;
+  int 0;
+  h( id( id( id( 0 ) ) ) );
+}
Index: translator/Tests/ResolvExpr/ShortCircuit.c
===================================================================
--- translator/Tests/ResolvExpr/ShortCircuit.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/ShortCircuit.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,15 @@
+int ?!=?( int, int );
+int ?!=?( float, float );
+int 0;
+
+void g( float );
+void g( int );
+
+void f( int a )
+{
+  int b;
+  float c;
+  g( a ? b : c );
+  g( a && c );
+  g( a || b );
+}
Index: translator/Tests/ResolvExpr/Statement.c
===================================================================
--- translator/Tests/ResolvExpr/Statement.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/Statement.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,16 @@
+int ?=?( int*, int );
+int ?!=?( int, int );
+int 0;
+
+void f()
+{
+    int a;
+    struct { int b; } a;
+    if( a ) {
+      while( a ) {
+        int *b;
+        for( b; a; b ) {
+        }
+      }
+    }
+}
Index: translator/Tests/ResolvExpr/make-rules
===================================================================
--- translator/Tests/ResolvExpr/make-rules	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/make-rules	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,21 @@
+CFA = ../../cfa-cpp
+
+DIFF = /software/gnu/bin/diff
+
+# Basic SynTree printing
+EXPECTED := ${wildcard $(EXPECTDIR)/*.tst}
+TESTS := $(EXPECTED:$(EXPECTDIR)/%=$(OUTPUTDIR)/%)
+TEST_IN := $(TESTS:.tst=.c)
+
+$(OUTPUTDIR)/%.tst:%.c $(CFA)
+	-$(CFA) $(CFAOPT) < $< > $@ 2>&1
+
+$(OUTPUTDIR)/report: $(TESTS) $(EXPECTED)
+	rm -f $@
+	@for i in $(TESTS); do \
+	  echo "---"`basename $$i`"---" | tee -a $@; \
+	  $(DIFF) -B -w -u $(EXPECTDIR)/`basename $$i` $$i | tee -a $@; \
+	done
+
+clean:
+	rm -rf $(OUTPUTDIR)
Index: translator/Tests/ResolvExpr/run-tests.sh
===================================================================
--- translator/Tests/ResolvExpr/run-tests.sh	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/ResolvExpr/run-tests.sh	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,8 @@
+#!/bin/sh -v
+
+dotest() {
+  mkdir -p Output$1
+  OUTPUTDIR=Output$1 EXPECTDIR=Expected$1 CFAOPT=$2 gmake -f make-rules $3
+}
+
+dotest "" -ne "$*"
Index: translator/Tests/SynTree/Array.c
===================================================================
--- translator/Tests/SynTree/Array.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Array.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,33 @@
+int a1[];
+int a2[*];
+int a4[3];
+
+int m1[][3];
+int m2[*][*];
+int m4[3][3];
+
+typedef int T;
+
+int fred() {
+    int a1[];
+    int a2[*];
+    int a4[3];
+    int T[3];
+}
+
+int mary( int T[3],
+	  int p1[const 3],
+	  int p2[static 3],
+	  int p3[static const 3]
+    ) {
+}
+
+int (*tom())[3] {
+}
+
+int (*(jane)())( int T[3],
+		 int p1[const 3],
+		 int p2[static 3],
+		 int p3[static const 3]
+    ) {
+}
Index: translator/Tests/SynTree/Constant0-1.c
===================================================================
--- translator/Tests/SynTree/Constant0-1.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Constant0-1.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,35 @@
+// Cforall extension
+
+// value
+
+int 0;
+const int 0;
+static const int 0;
+int 1;
+const int 1;
+static const int 1;
+int 0, 1;
+const int 0, 1;
+static const int 0, 1;
+struct { int i; } 0;
+const struct { int i; } 1;
+static const struct { int i; } 1;
+
+// pointer
+
+int 1, * 0;
+int (1), ((1)), * (0), (* 0), ((* 0));
+int * const (0), (* const 0), ((* const 0));
+struct { int i; } * 0;
+
+// Cforall style
+
+* int x, 0;
+const * int x, 0;
+static const * int x, 0;
+* struct { int i; } 0;
+const * struct { int i; } 0;
+static const * struct { int i; } 0;
+static * int x, 0;
+static const * int x, 0;
+const * * int x, 0;
Index: translator/Tests/SynTree/Context.c
===================================================================
--- translator/Tests/SynTree/Context.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Context.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,16 @@
+context has_q( type T )
+{
+  T q( T );
+};
+
+forall( type z | has_q( z ) )
+void f()
+{
+  context has_r( type T, type U )
+  {
+    T r( T, T (T,U) );
+  };
+  
+  extern type x, y | has_r( x, y );
+  
+}
Index: translator/Tests/SynTree/DeclarationErrors.c
===================================================================
--- translator/Tests/SynTree/DeclarationErrors.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/DeclarationErrors.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,5 @@
+static short int volatile static const x9;		// duplicate static
+struct { int i; } const static volatile static x18;	// duplicate static
+struct { int i; } const static volatile static volatile x19; // duplicate static & volatile
+typedef int Int;
+static Int volatile static const x28;			// duplicate static
Index: translator/Tests/SynTree/DeclarationSpecifier.c
===================================================================
--- translator/Tests/SynTree/DeclarationSpecifier.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/DeclarationSpecifier.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,86 @@
+typedef short int Int;
+
+
+const short int volatile x1;
+static const short int volatile x2;
+const static short int volatile x3;
+const short static int volatile x4;
+const static volatile short int x4;
+const short int static volatile x5;
+const short int volatile static x6;
+const short volatile int static x7;
+short int volatile static const x8;
+
+const volatile struct { int i; } x10;
+const struct { int i; } volatile x11;
+struct { int i; } const volatile x12;
+static const volatile struct { int i; } x13;
+const static struct { int i; } volatile x14;
+struct { int i; } static const volatile x15;
+struct { int i; } const static volatile x16;
+struct { int i; } const volatile static x17;
+
+const Int volatile x20;
+static const Int volatile x21;
+const static Int volatile x22;
+const static Int volatile x23;
+const Int static volatile x24;
+const Int volatile static x25;
+const volatile Int static x26;
+Int volatile static const x27;
+
+const volatile struct { Int i; } x29;
+const struct { Int i; } volatile x30;
+struct { Int i; } const volatile x31;
+static const volatile struct { Int i; } x32;
+const static struct { Int i; } volatile x33;
+struct { Int i; } static const volatile x34;
+struct { Int i; } const static volatile x35;
+struct { Int i; } const volatile static x36;
+
+
+const static inline const volatile int f01();		// duplicate const
+volatile inline const volatile static int f02();	// duplicate volatile
+const inline const volatile int static f03();		// duplicate const
+volatile inline static const volatile int f04();	// duplicate volatile
+const static const inline volatile int f05();		// duplicate const
+volatile static const volatile inline int f06();	// duplicate volatile
+const static const volatile int inline f07();		// duplicate const
+volatile static const int inline volatile f08();	// duplicate volatile
+
+static inline const volatile int f11();
+inline const volatile static int f12();
+inline const volatile int static f13();
+inline static const volatile int f14();
+static const inline volatile int f15();
+static const volatile inline int f16();
+static const volatile int inline f17();
+static const int inline volatile f18();
+
+short static inline const volatile int f21();
+inline short const volatile static int f22();
+inline const short volatile int static f23();
+inline static const short volatile int f24();
+static const inline volatile short int f25();
+static const volatile inline int short f26();
+static const volatile int inline short f27();
+static const int inline volatile short f28();
+
+static inline const volatile struct { int i; } f31();
+inline const volatile static struct { int i; } f32();
+inline const volatile struct { int i; } static f33();
+inline static const volatile struct { int i; } f34();
+static const inline volatile struct { int i; } f35();
+static const volatile inline struct { int i; } f36();
+static const volatile struct { int i; } inline f37();
+static const struct { int i; } inline volatile f38();
+
+static inline const volatile Int f41();
+inline const volatile static Int f42();
+inline const volatile Int static f43();
+inline static const volatile Int f44();
+static const inline volatile Int f45();
+static const volatile inline Int f46();
+static const volatile Int inline f47();
+static const Int inline volatile f48();
+
Index: translator/Tests/SynTree/Enum.c
===================================================================
--- translator/Tests/SynTree/Enum.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Enum.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,20 @@
+enum Colors {
+  Red,
+  Yellow,
+  Pink,
+  Blue,
+  Purple,
+  Orange,
+  Green
+};
+
+
+void f( void )
+{
+  enum Fruits {
+    Apple,
+    Banana,
+    Pear,
+    Mango
+  } fruit = Mango;
+}
Index: translator/Tests/SynTree/Expected-SymTab/Array.tst
===================================================================
--- translator/Tests/SynTree/Expected-SymTab/Array.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected-SymTab/Array.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,53 @@
+Adding object a1
+Adding object a2
+Adding object a4
+Adding object m1
+Adding object m2
+Adding object m4
+Adding typedef T
+--- Entering scope
+--- Leaving scope containing
+Adding function fred
+--- Entering scope
+--- Entering scope
+Adding object a1
+Adding object a2
+Adding object a4
+Adding object T
+--- Leaving scope containing
+T (__T__A0i) (2)
+a1 (__a1__A0i) (2)
+a2 (__a2__A0i) (2)
+a4 (__a4__A0i) (2)
+--- Leaving scope containing
+Adding function mary
+--- Entering scope
+Adding object T
+Adding object p1
+Adding object p2
+Adding object p3
+--- Entering scope
+--- Leaving scope containing
+--- Leaving scope containing
+T (__T__Pi) (1)
+p1 (__p1__CPi) (1)
+p2 (__p2__Pi) (1)
+p3 (__p3__CPi) (1)
+Adding function tom
+--- Entering scope
+--- Entering scope
+--- Leaving scope containing
+--- Leaving scope containing
+Adding function jane
+--- Entering scope
+Adding object T
+Adding object p1
+Adding object p2
+Adding object p3
+--- Entering scope
+--- Leaving scope containing
+--- Leaving scope containing
+T (__T__Pi) (1)
+p1 (__p1__CPi) (1)
+p2 (__p2__Pi) (1)
+p3 (__p3__CPi) (1)
Index: translator/Tests/SynTree/Expected-SymTab/Context.tst
===================================================================
--- translator/Tests/SynTree/Expected-SymTab/Context.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected-SymTab/Context.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,52 @@
+Adding context has_q
+--- Entering scope
+Adding type T
+--- Entering scope
+--- Leaving scope containing
+Adding function q
+--- Entering scope
+--- Leaving scope containing
+--- Leaving scope containing
+q (__q__F_2tT_2tT_) (1)
+T
+Adding function f
+--- Entering scope
+Adding type z
+--- Entering scope
+--- Leaving scope containing
+Adding function q
+--- Entering scope
+--- Leaving scope containing
+--- Entering scope
+Adding context has_r
+--- Entering scope
+Adding type T
+--- Entering scope
+--- Leaving scope containing
+Adding type U
+--- Entering scope
+--- Leaving scope containing
+Adding function r
+--- Entering scope
+--- Leaving scope containing
+--- Leaving scope containing
+r (__r__F_2tT_2tTPF_2tT_2tT2tU__) (3)
+T
+U
+Adding type x
+--- Entering scope
+--- Leaving scope containing
+Adding type y
+--- Entering scope
+--- Leaving scope containing
+Adding function r
+--- Entering scope
+--- Leaving scope containing
+--- Leaving scope containing
+r (__r__F_2tx_2txPF_2tx_2tx2ty__) (2)
+x
+y
+has_r
+--- Leaving scope containing
+q (__q__F_2tz_2tz_) (1)
+z
Index: translator/Tests/SynTree/Expected-SymTab/Enum.tst
===================================================================
--- translator/Tests/SynTree/Expected-SymTab/Enum.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected-SymTab/Enum.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,25 @@
+Adding enum Colors
+Adding object Red
+Adding object Yellow
+Adding object Pink
+Adding object Blue
+Adding object Purple
+Adding object Orange
+Adding object Green
+Adding function f
+--- Entering scope
+--- Entering scope
+Adding enum Fruits
+Adding object Apple
+Adding object Banana
+Adding object Pear
+Adding object Mango
+Adding object fruit
+--- Leaving scope containing
+Apple (__Apple__C7eFruits) (2)
+Banana (__Banana__C7eFruits) (2)
+Mango (__Mango__C7eFruits) (2)
+Pear (__Pear__C7eFruits) (2)
+fruit (__fruit__7eFruits) (2)
+Fruits
+--- Leaving scope containing
Index: translator/Tests/SynTree/Expected-SymTab/Forall.tst
===================================================================
--- translator/Tests/SynTree/Expected-SymTab/Forall.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected-SymTab/Forall.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,188 @@
+in default case, (shouldn't be here)
+in default case, (shouldn't be here)
+Adding typedef f
+--- Entering scope
+Adding type T
+--- Entering scope
+--- Leaving scope containing
+--- Leaving scope containing
+T
+Adding function swap
+--- Entering scope
+Adding type T
+--- Entering scope
+--- Leaving scope containing
+Adding object left
+Adding object right
+--- Entering scope
+Adding object temp
+--- Leaving scope containing
+temp (__temp__2tT) (2)
+--- Leaving scope containing
+left (__left__2tT) (1)
+right (__right__2tT) (1)
+T
+Adding context sumable
+--- Entering scope
+Adding type T
+--- Entering scope
+--- Leaving scope containing
+Adding object 0
+Adding function ?+?
+--- Entering scope
+--- Leaving scope containing
+Adding function ?++
+--- Entering scope
+--- Leaving scope containing
+Adding function ?+=?
+--- Entering scope
+--- Leaving scope containing
+--- Leaving scope containing
+0 (__0__C2tT) (1)
+?++ (__?++__F_2tT_2tT_) (1)
+?+=? (__?+=?__F_2tT_2tT2tT_) (1)
+?+? (__?+?__F_2tT_2tT2tT_) (1)
+T
+Adding type T1
+--- Entering scope
+--- Leaving scope containing
+Adding object 0
+Adding function ?+?
+--- Entering scope
+--- Leaving scope containing
+Adding function ?++
+--- Entering scope
+--- Leaving scope containing
+Adding function ?+=?
+--- Entering scope
+--- Leaving scope containing
+Adding type T2
+--- Entering scope
+Adding type P1
+--- Entering scope
+--- Leaving scope containing
+Adding type P2
+--- Entering scope
+--- Leaving scope containing
+--- Leaving scope containing
+P1
+P2
+Adding type T3
+--- Entering scope
+--- Leaving scope containing
+Adding object 0
+Adding function ?+?
+--- Entering scope
+--- Leaving scope containing
+Adding function ?++
+--- Entering scope
+--- Leaving scope containing
+Adding function ?+=?
+--- Entering scope
+--- Leaving scope containing
+Adding struct __anonymous0
+--- Entering scope
+Adding object i
+Adding object j
+--- Leaving scope containing
+i (__i__3tP1) (1)
+j (__j__3tP2) (1)
+Adding type T2
+--- Entering scope
+Adding type P1
+--- Entering scope
+--- Leaving scope containing
+Adding type P2
+--- Entering scope
+--- Leaving scope containing
+--- Leaving scope containing
+P1
+P2
+Adding object 0
+Adding function ?+?
+--- Entering scope
+--- Leaving scope containing
+Adding function ?++
+--- Entering scope
+--- Leaving scope containing
+Adding function ?+=?
+--- Entering scope
+--- Leaving scope containing
+Adding object w1
+Adding typedef w2
+--- Entering scope
+--- Leaving scope containing
+Adding object g2
+Adding type w3
+--- Entering scope
+--- Leaving scope containing
+Adding object g3
+Adding function sum
+--- Entering scope
+Adding type T
+--- Entering scope
+--- Leaving scope containing
+Adding object 0
+Adding function ?+?
+--- Entering scope
+--- Leaving scope containing
+Adding function ?++
+--- Entering scope
+--- Leaving scope containing
+Adding function ?+=?
+--- Entering scope
+--- Leaving scope containing
+Adding object n
+Adding object a
+--- Entering scope
+Adding object total
+Adding object i
+--- Leaving scope containing
+i (__i__i) (2)
+total (__total__2tT) (2)
+--- Leaving scope containing
+0 (__0__2tT) (1)
+?++ (__?++__F_2tT_2tT_) (1)
+?+=? (__?+=?__F_2tT_2tT2tT_) (1)
+?+? (__?+?__F_2tT_2tT2tT_) (1)
+a (__a__P2tT) (1)
+n (__n__i) (1)
+T
+Adding function twice
+--- Entering scope
+Adding type T
+--- Entering scope
+--- Leaving scope containing
+Adding object 0
+Adding function ?+?
+--- Entering scope
+--- Leaving scope containing
+Adding function ?++
+--- Entering scope
+--- Leaving scope containing
+Adding function ?+=?
+--- Entering scope
+--- Leaving scope containing
+Adding object t
+--- Entering scope
+--- Leaving scope containing
+--- Leaving scope containing
+0 (__0__C2tT) (1)
+?++ (__?++__F_2tT_2tT_) (1)
+?+=? (__?+=?__F_2tT_2tT2tT_) (1)
+?+? (__?+?__F_2tT_2tT2tT_) (1)
+t (__t__2tT) (1)
+T
+Adding function main
+--- Entering scope
+--- Entering scope
+Adding object x
+Adding object y
+Adding object a
+Adding object f
+--- Leaving scope containing
+a (__a__A0i) (2)
+f (__f__f) (2)
+x (__x__i) (2)
+y (__y__i) (2)
+--- Leaving scope containing
Index: translator/Tests/SynTree/Expected-SymTab/Scope.tst
===================================================================
--- translator/Tests/SynTree/Expected-SymTab/Scope.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected-SymTab/Scope.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,130 @@
+in default case, (shouldn't be here)
+in default case, (shouldn't be here)
+in default case, (shouldn't be here)
+Adding object x
+Adding typedef y
+--- Entering scope
+--- Leaving scope containing
+Adding typedef t
+--- Entering scope
+--- Leaving scope containing
+Adding object z
+Adding struct __anonymous0
+--- Entering scope
+Adding object a
+Adding object b
+--- Leaving scope containing
+a (__a__i) (1)
+b (__b__d) (1)
+Adding type u
+--- Entering scope
+--- Leaving scope containing
+Adding function f
+--- Entering scope
+Adding object y
+--- Leaving scope containing
+y (__y__i) (1)
+Adding object q
+Adding function w
+--- Entering scope
+Adding object y
+Adding object v
+--- Entering scope
+Adding type x
+--- Entering scope
+--- Leaving scope containing
+Adding function t
+--- Entering scope
+--- Leaving scope containing
+Adding object u
+Adding object z
+--- Leaving scope containing
+t (__t__F_2tx_2tu_) (2)
+u (__u__2tu) (2)
+z (__z__2tx) (2)
+x
+--- Leaving scope containing
+v (__v__2tu) (1)
+y (__y__2ty) (1)
+Adding object p
+Adding context has_u
+--- Entering scope
+Adding type z
+--- Entering scope
+--- Leaving scope containing
+Adding function u
+--- Entering scope
+--- Leaving scope containing
+--- Leaving scope containing
+u (__u__F_2tz_2tz_) (1)
+z
+Adding function q
+--- Entering scope
+Adding type t
+--- Entering scope
+--- Leaving scope containing
+Adding function u
+--- Entering scope
+--- Leaving scope containing
+Adding object the_t
+--- Entering scope
+Adding object y
+--- Leaving scope containing
+y (__y__2tt) (2)
+--- Leaving scope containing
+the_t (__the_t__2tt) (1)
+u (__u__F_2tt_2tt_) (1)
+t
+Adding function f
+--- Entering scope
+Adding object p
+--- Entering scope
+Adding object y
+Adding typedef x
+--- Entering scope
+--- Leaving scope containing
+--- Entering scope
+Adding object y
+Adding typedef z
+--- Entering scope
+--- Leaving scope containing
+--- Entering scope
+Adding object x
+Adding typedef y
+--- Entering scope
+--- Leaving scope containing
+Adding object z
+--- Leaving scope containing
+x (__x__2tz) (4)
+z (__z__2ty) (4)
+y
+Adding object x
+--- Leaving scope containing
+x (__x__2tz) (3)
+y (__y__2tx) (3)
+z
+Adding object q
+--- Leaving scope containing
+q (__q__2tx) (2)
+y (__y__i) (2)
+x
+--- Leaving scope containing
+p (__p__2ty) (1)
+Adding function g
+--- Entering scope
+--- Entering scope
+Adding typedef x
+--- Entering scope
+--- Leaving scope containing
+Adding object z
+--- Leaving scope containing
+z (__z__2tx) (2)
+x
+--- Leaving scope containing
+Adding function q
+--- Entering scope
+Adding object i
+--- Entering scope
+--- Leaving scope containing
+--- Leaving scope containing
+i (__i__i) (1)
Index: translator/Tests/SynTree/Expected-SymTab/ScopeErrors.tst
===================================================================
--- translator/Tests/SynTree/Expected-SymTab/ScopeErrors.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected-SymTab/ScopeErrors.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,38 @@
+Adding object thisIsAnError
+Adding object thisIsAnError
+Adding object thisIsNotAnError
+Adding object thisIsNotAnError
+Adding function thisIsAlsoNotAnError
+--- Entering scope
+--- Entering scope
+Adding object thisIsNotAnError
+--- Leaving scope containing
+thisIsNotAnError (__thisIsNotAnError__i) (2)
+--- Leaving scope containing
+Adding function thisIsAlsoNotAnError
+--- Entering scope
+Adding object x
+--- Entering scope
+--- Leaving scope containing
+--- Leaving scope containing
+x (__x__d) (1)
+Adding function thisIsStillNotAnError
+--- Entering scope
+--- Leaving scope containing
+Adding function thisIsStillNotAnError
+--- Entering scope
+--- Leaving scope containing
+Adding function butThisIsAnError
+--- Entering scope
+--- Entering scope
+--- Leaving scope containing
+--- Leaving scope containing
+Adding function butThisIsAnError
+Error: duplicate definition for thisIsAnError: a signed int 
+Error: duplicate function definition for butThisIsAnError: a function
+  with parameters
+    double 
+  returning 
+    double 
+  with body 
+
Index: translator/Tests/SynTree/Expected-SymTab/Tuple.tst
===================================================================
--- translator/Tests/SynTree/Expected-SymTab/Tuple.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected-SymTab/Tuple.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,97 @@
+Adding function f
+--- Entering scope
+--- Leaving scope containing
+Adding function g
+--- Entering scope
+--- Leaving scope containing
+Adding function h
+--- Entering scope
+Adding object a
+Adding object b
+Adding object c
+Adding object d
+--- Leaving scope containing
+a (__a__i) (1)
+b (__b__i) (1)
+c (__c__Pi) (1)
+d (__d__Pc) (1)
+Adding struct inner
+--- Entering scope
+Adding object f2
+Adding object f3
+--- Leaving scope containing
+f2 (__f2__i) (1)
+f3 (__f3__i) (1)
+Adding struct outer
+--- Entering scope
+Adding object f1
+Adding object i
+Adding object f4
+--- Leaving scope containing
+f1 (__f1__i) (1)
+f4 (__f4__d) (1)
+i (__i__6sinner) (1)
+Adding object s
+Adding object sp
+Adding object t1
+Adding object t2
+Adding object t3
+Adding function printf
+--- Entering scope
+Adding object rc
+Adding object fmt
+--- Leaving scope containing
+fmt (__fmt__Pc) (1)
+rc (__rc__i) (1)
+Adding function printf
+--- Entering scope
+Adding object fmt
+--- Leaving scope containing
+fmt (__fmt__Pc) (1)
+Adding function f1
+--- Entering scope
+Adding object x
+Adding object y
+Adding object w
+--- Entering scope
+--- Leaving scope containing
+--- Leaving scope containing
+w (__w__i) (1)
+x (__x__s) (1)
+y (__y__Ui) (1)
+Adding function g1
+--- Entering scope
+Adding object r
+--- Entering scope
+Adding object x
+Adding object p
+Adding object y
+Adding object z
+--- Leaving scope containing
+p (__p__s) (2)
+x (__x__s) (2)
+y (__y__Ui) (2)
+z (__z__Tii_) (2)
+--- Leaving scope containing
+r (__r__Ticli_) (1)
+Adding function main
+--- Entering scope
+Adding object rc
+Adding object argc
+Adding object argv
+--- Entering scope
+Adding object a
+Adding object b
+Adding object c
+Adding object d
+Adding object t
+--- Leaving scope containing
+a (__a__i) (2)
+b (__b__i) (2)
+c (__c__i) (2)
+d (__d__i) (2)
+t (__t__6souter) (2)
+--- Leaving scope containing
+argc (__argc__i) (1)
+argv (__argv__PPc) (1)
+rc (__rc__i) (1)
Index: translator/Tests/SynTree/Expected/Array.tst
===================================================================
--- translator/Tests/SynTree/Expected/Array.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected/Array.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,50 @@
+a1: a open array of signed int 
+a2: a variable length array of signed int 
+a4: a array of   Constant Expression: 3signed int 
+m1: a open array of array of   Constant Expression: 3signed int 
+m2: a variable length array of variable length array of signed int 
+m4: a array of   Constant Expression: 3array of   Constant Expression: 3signed int 
+T: a typedef for signed int 
+fred: a function
+    returning 
+      signed int 
+    with body 
+      Declaration of a1: a open array of signed int 
+      Declaration of a2: a variable length array of signed int 
+      Declaration of a4: a array of         Constant Expression: 3signed int 
+      Declaration of T: a array of         Constant Expression: 3signed int 
+
+mary: a function
+    with parameters
+      T: a array of         Constant Expression: 3signed int 
+      p1: a const array of         Constant Expression: 3signed int 
+      p2: a static array of         Constant Expression: 3signed int 
+      p3: a const static array of         Constant Expression: 3signed int 
+    returning 
+      signed int 
+    with body 
+
+      Null Statement
+
+tom: a function
+    returning 
+      pointer to array of         Constant Expression: 3signed int 
+    with body 
+
+      Null Statement
+
+jane: a function
+    returning 
+      pointer to function
+          with parameters
+            T: a array of               Constant Expression: 3signed int 
+            p1: a const array of               Constant Expression: 3signed int 
+            p2: a static array of               Constant Expression: 3signed int 
+            p3: a const static array of               Constant Expression: 3signed int 
+          returning 
+            signed int 
+
+    with body 
+
+      Null Statement
+
Index: translator/Tests/SynTree/Expected/Constant0-1.tst
===================================================================
--- translator/Tests/SynTree/Expected/Constant0-1.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected/Constant0-1.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,69 @@
+0: a signed int 
+0: a const signed int 
+0: a static const signed int 
+1: a signed int 
+1: a const signed int 
+1: a static const signed int 
+0: a signed int 
+1: a signed int 
+0: a const signed int 
+1: a const signed int 
+0: a static const signed int 
+1: a static const signed int 
+struct __anonymous0
+    with members
+      i: a signed int 
+
+0: a instance of struct __anonymous0 
+struct __anonymous1
+    with members
+      i: a signed int 
+
+1: a const instance of struct __anonymous1 
+struct __anonymous2
+    with members
+      i: a signed int 
+
+1: a static const instance of struct __anonymous2 
+1: a signed int 
+0: a pointer to signed int 
+1: a signed int 
+1: a signed int 
+0: a pointer to signed int 
+0: a pointer to signed int 
+0: a pointer to signed int 
+0: a const pointer to signed int 
+0: a const pointer to signed int 
+0: a const pointer to signed int 
+struct __anonymous3
+    with members
+      i: a signed int 
+
+0: a pointer to instance of struct __anonymous3 
+x: a pointer to signed int 
+0: a pointer to signed int 
+x: a const pointer to signed int 
+0: a const pointer to signed int 
+x: a static const pointer to signed int 
+0: a static const pointer to signed int 
+struct __anonymous4
+    with members
+      i: a signed int 
+
+0: a pointer to instance of struct __anonymous4 
+struct __anonymous5
+    with members
+      i: a signed int 
+
+0: a const pointer to instance of struct __anonymous5 
+struct __anonymous6
+    with members
+      i: a signed int 
+
+0: a static const pointer to instance of struct __anonymous6 
+x: a static pointer to signed int 
+0: a static pointer to signed int 
+x: a static const pointer to signed int 
+0: a static const pointer to signed int 
+x: a const pointer to pointer to signed int 
+0: a const pointer to pointer to signed int 
Index: translator/Tests/SynTree/Expected/Context.tst
===================================================================
--- translator/Tests/SynTree/Expected/Context.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected/Context.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,54 @@
+context has_q
+    with parameters
+      T: a type
+
+    with members
+      q: a function
+          with parameters
+            instance of type T 
+          returning 
+            instance of type T 
+
+
+f: a function
+    with forall
+      z: a type
+        with assertions
+          instance of context has_q 
+            with parameters
+              instance of type z 
+
+
+    returning 
+      void 
+    with body 
+      Declaration of context has_r
+          with parameters
+            T: a type
+            U: a type
+
+          with members
+            r: a function
+                with parameters
+                  instance of type T 
+                  function
+                      with parameters
+                        instance of type T 
+                        instance of type U 
+                      returning 
+                        instance of type T 
+
+                returning 
+                  instance of type T 
+
+
+      Declaration of x: a extern type
+      Declaration of y: a extern type
+        with assertions
+          instance of context has_r 
+            with parameters
+              instance of type x 
+              instance of type y 
+
+
+
Index: translator/Tests/SynTree/Expected/DeclarationSpecifier.tst
===================================================================
--- translator/Tests/SynTree/Expected/DeclarationSpecifier.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected/DeclarationSpecifier.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,290 @@
+Int: a typedef for short signed int 
+x1: a const volatile short signed int 
+x2: a static const volatile short signed int 
+x3: a static const volatile short signed int 
+x4: a static const volatile short signed int 
+x4: a static const volatile short signed int 
+x5: a static const volatile short signed int 
+x6: a static const volatile short signed int 
+x7: a static const volatile short signed int 
+x8: a static const volatile short signed int 
+struct __anonymous0
+    with members
+      i: a signed int 
+
+x10: a const volatile instance of struct __anonymous0 
+struct __anonymous1
+    with members
+      i: a signed int 
+
+x11: a const volatile instance of struct __anonymous1 
+struct __anonymous2
+    with members
+      i: a signed int 
+
+x12: a const volatile instance of struct __anonymous2 
+struct __anonymous3
+    with members
+      i: a signed int 
+
+x13: a static const volatile instance of struct __anonymous3 
+struct __anonymous4
+    with members
+      i: a signed int 
+
+x14: a static const volatile instance of struct __anonymous4 
+struct __anonymous5
+    with members
+      i: a signed int 
+
+x15: a static const volatile instance of struct __anonymous5 
+struct __anonymous6
+    with members
+      i: a signed int 
+
+x16: a static const volatile instance of struct __anonymous6 
+struct __anonymous7
+    with members
+      i: a signed int 
+
+x17: a static const volatile instance of struct __anonymous7 
+x20: a const volatile instance of type Int 
+x21: a static const volatile instance of type Int 
+x22: a static const volatile instance of type Int 
+x23: a static const volatile instance of type Int 
+x24: a static const volatile instance of type Int 
+x25: a static const volatile instance of type Int 
+x26: a static const volatile instance of type Int 
+x27: a static const volatile instance of type Int 
+struct __anonymous8
+    with members
+      i: a instance of type Int 
+
+x29: a const volatile instance of struct __anonymous8 
+struct __anonymous9
+    with members
+      i: a instance of type Int 
+
+x30: a const volatile instance of struct __anonymous9 
+struct __anonymous10
+    with members
+      i: a instance of type Int 
+
+x31: a const volatile instance of struct __anonymous10 
+struct __anonymous11
+    with members
+      i: a instance of type Int 
+
+x32: a static const volatile instance of struct __anonymous11 
+struct __anonymous12
+    with members
+      i: a instance of type Int 
+
+x33: a static const volatile instance of struct __anonymous12 
+struct __anonymous13
+    with members
+      i: a instance of type Int 
+
+x34: a static const volatile instance of struct __anonymous13 
+struct __anonymous14
+    with members
+      i: a instance of type Int 
+
+x35: a static const volatile instance of struct __anonymous14 
+struct __anonymous15
+    with members
+      i: a instance of type Int 
+
+x36: a static const volatile instance of struct __anonymous15 
+f01: a inline static function
+    returning 
+      const volatile signed int 
+
+f02: a inline static function
+    returning 
+      const volatile signed int 
+
+f03: a inline static function
+    returning 
+      const volatile signed int 
+
+f04: a inline static function
+    returning 
+      const volatile signed int 
+
+f05: a inline static function
+    returning 
+      const volatile signed int 
+
+f06: a inline static function
+    returning 
+      const volatile signed int 
+
+f07: a inline static function
+    returning 
+      const volatile signed int 
+
+f08: a inline static function
+    returning 
+      const volatile signed int 
+
+f11: a inline static function
+    returning 
+      const volatile signed int 
+
+f12: a inline static function
+    returning 
+      const volatile signed int 
+
+f13: a inline static function
+    returning 
+      const volatile signed int 
+
+f14: a inline static function
+    returning 
+      const volatile signed int 
+
+f15: a inline static function
+    returning 
+      const volatile signed int 
+
+f16: a inline static function
+    returning 
+      const volatile signed int 
+
+f17: a inline static function
+    returning 
+      const volatile signed int 
+
+f18: a inline static function
+    returning 
+      const volatile signed int 
+
+f21: a inline static function
+    returning 
+      const volatile short signed int 
+
+f22: a inline static function
+    returning 
+      const volatile short signed int 
+
+f23: a inline static function
+    returning 
+      const volatile short signed int 
+
+f24: a inline static function
+    returning 
+      const volatile short signed int 
+
+f25: a inline static function
+    returning 
+      const volatile short signed int 
+
+f26: a inline static function
+    returning 
+      const volatile short signed int 
+
+f27: a inline static function
+    returning 
+      const volatile short signed int 
+
+f28: a inline static function
+    returning 
+      const volatile short signed int 
+
+struct __anonymous16
+    with members
+      i: a signed int 
+
+f31: a inline static function
+    returning 
+      const volatile instance of struct __anonymous16 
+
+struct __anonymous17
+    with members
+      i: a signed int 
+
+f32: a inline static function
+    returning 
+      const volatile instance of struct __anonymous17 
+
+struct __anonymous18
+    with members
+      i: a signed int 
+
+f33: a inline static function
+    returning 
+      const volatile instance of struct __anonymous18 
+
+struct __anonymous19
+    with members
+      i: a signed int 
+
+f34: a inline static function
+    returning 
+      const volatile instance of struct __anonymous19 
+
+struct __anonymous20
+    with members
+      i: a signed int 
+
+f35: a inline static function
+    returning 
+      const volatile instance of struct __anonymous20 
+
+struct __anonymous21
+    with members
+      i: a signed int 
+
+f36: a inline static function
+    returning 
+      const volatile instance of struct __anonymous21 
+
+struct __anonymous22
+    with members
+      i: a signed int 
+
+f37: a inline static function
+    returning 
+      const volatile instance of struct __anonymous22 
+
+struct __anonymous23
+    with members
+      i: a signed int 
+
+f38: a inline static function
+    returning 
+      const volatile instance of struct __anonymous23 
+
+f41: a inline static function
+    returning 
+      const volatile instance of type Int 
+
+f42: a inline static function
+    returning 
+      const volatile instance of type Int 
+
+f43: a inline static function
+    returning 
+      const volatile instance of type Int 
+
+f44: a inline static function
+    returning 
+      const volatile instance of type Int 
+
+f45: a inline static function
+    returning 
+      const volatile instance of type Int 
+
+f46: a inline static function
+    returning 
+      const volatile instance of type Int 
+
+f47: a inline static function
+    returning 
+      const volatile instance of type Int 
+
+f48: a inline static function
+    returning 
+      const volatile instance of type Int 
+
Index: translator/Tests/SynTree/Expected/Enum.tst
===================================================================
--- translator/Tests/SynTree/Expected/Enum.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected/Enum.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,25 @@
+enum Colors
+    with members
+      Red: a untyped entity 
+      Yellow: a untyped entity 
+      Pink: a untyped entity 
+      Blue: a untyped entity 
+      Purple: a untyped entity 
+      Orange: a untyped entity 
+      Green: a untyped entity 
+
+f: a function
+    with parameters
+      void 
+    returning 
+      void 
+    with body 
+      Declaration of enum Fruits
+          with members
+            Apple: a untyped entity 
+            Banana: a untyped entity 
+            Pear: a untyped entity 
+            Mango: a untyped entity 
+
+      Declaration of fruit: a instance of enum Fruits 
+
Index: translator/Tests/SynTree/Expected/Forall.tst
===================================================================
--- translator/Tests/SynTree/Expected/Forall.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected/Forall.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,229 @@
+in default case, (shouldn't be here)
+in default case, (shouldn't be here)
+f: a typedef for pointer to function
+    with parameters
+      signed int 
+    with forall
+      T: a type
+    returning 
+      signed int 
+
+swap: a function
+    with parameters
+      left: a instance of type T 
+      right: a instance of type T 
+    with forall
+      T: a type
+    returning 
+      void 
+    with body 
+      Declaration of temp: a instance of type T 
+      
+        Expression Statement:
+          Applying untyped: 
+              Name: ?=?
+ to: 
+              Name: left
+              Name: right
+
+      
+        Expression Statement:
+          Applying untyped: 
+              Name: ?=?
+ to: 
+              Name: right
+              Name: temp
+
+
+context sumable
+    with parameters
+      T: a type
+
+    with members
+      0: a const instance of type T 
+      ?+?: a function
+          with parameters
+            instance of type T 
+            instance of type T 
+          returning 
+            instance of type T 
+
+      ?++: a function
+          with parameters
+            instance of type T 
+          returning 
+            instance of type T 
+
+      ?+=?: a function
+          with parameters
+            instance of type T 
+            instance of type T 
+          returning 
+            instance of type T 
+
+
+T1: a type
+  with assertions
+    0: a const instance of type T1 
+    ?+?: a function
+        with parameters
+          instance of type T1 
+          instance of type T1 
+        returning 
+          instance of type T1 
+
+    ?++: a function
+        with parameters
+          instance of type T1 
+        returning 
+          instance of type T1 
+
+    ?+=?: a function
+        with parameters
+          instance of type T1 
+          instance of type T1 
+        returning 
+          instance of type T1 
+
+
+T2: a type
+  with parameters
+    P1: a type
+    P2: a type
+
+T3: a type
+  with assertions
+    instance of context sumable 
+      with parameters
+        instance of type T3 
+
+
+struct __anonymous0
+    with members
+      i: a instance of type P1 
+      j: a instance of type P2 
+
+T2: a type for instance of struct __anonymous0 
+  with parameters
+    P1: a type
+    P2: a type
+
+  with assertions
+    instance of context sumable 
+      with parameters
+        instance of type T2 
+          with parameters
+            instance of type P1 
+            instance of type P2 
+
+
+
+w1: a instance of type T2 
+  with parameters
+    signed int 
+    signed int 
+
+w2: a typedef for instance of type T2 
+  with parameters
+    signed int 
+    signed int 
+
+g2: a instance of type w2 
+w3: a type for instance of type T2 
+  with parameters
+    signed int 
+    signed int 
+
+g3: a instance of type w3 
+sum: a function
+    with parameters
+      n: a signed int 
+      a: a open array of instance of type T 
+    with forall
+      T: a type
+        with assertions
+          instance of context sumable 
+            with parameters
+              instance of type T 
+
+
+    returning 
+      instance of type T 
+    with body 
+      Declaration of total: a instance of type T 
+      Declaration of i: a signed int 
+
+twice: a function
+    with parameters
+      t: a instance of type T 
+    with forall
+      T: a type
+        with assertions
+          0: a const instance of type T 
+          ?+?: a function
+              with parameters
+                instance of type T 
+                instance of type T 
+              returning 
+                instance of type T 
+
+          ?++: a function
+              with parameters
+                instance of type T 
+              returning 
+                instance of type T 
+
+          ?+=?: a function
+              with parameters
+                instance of type T 
+                instance of type T 
+              returning 
+                instance of type T 
+
+
+    returning 
+      instance of type T 
+    with body 
+
+main: a function
+    returning 
+      signed int 
+    with body 
+      Declaration of x: a signed int 
+      Declaration of y: a signed int 
+      Declaration of a: a array of         Constant Expression: 10signed int 
+      Declaration of f: a float 
+      
+        Expression Statement:
+          Applying untyped: 
+              Name: swap
+ to: 
+              Name: x
+              Name: y
+
+      
+        Expression Statement:
+          Applying untyped: 
+              Name: twice
+ to: 
+              Name: x
+              Name: y
+
+      
+        Expression Statement:
+          Applying untyped: 
+              Name: ?=?
+ to: 
+              Name: f
+              Applying untyped: 
+                  Name: min
+ to: 
+                  Constant Expression: 4.0                  Constant Expression: 3.0
+      
+        Expression Statement:
+          Applying untyped: 
+              Name: sum
+ to: 
+              Constant Expression: 10              Name: a
+
+
Index: translator/Tests/SynTree/Expected/Functions.tst
===================================================================
--- translator/Tests/SynTree/Expected/Functions.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected/Functions.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,586 @@
+h: a function
+    with parameters
+      void 
+    returning 
+      void 
+    with body 
+
+f: a function
+    with parameters
+      function
+          with parameters
+            void 
+          returning 
+            signed int 
+
+      function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+      function
+          with parameters
+            void 
+          returning 
+            signed int 
+
+      function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+      g: a function
+          with parameters
+            void 
+          returning 
+            void 
+
+    returning 
+      signed int 
+    with body 
+
+f1: a function
+    returning 
+      signed int 
+    with body 
+
+f2: a function
+    returning 
+      signed int 
+    with body 
+
+f3: a function
+    returning 
+      pointer to function
+          returning 
+            signed int 
+
+    with body 
+
+f4: a function
+    returning 
+      pointer to signed int 
+    with body 
+
+f5: a function
+    returning 
+      pointer to function
+          returning 
+            signed int 
+
+    with body 
+
+f6: a function
+    returning 
+      pointer to signed int 
+    with body 
+
+f7: a function
+    returning 
+      pointer to signed int 
+    with body 
+
+f8: a function
+    returning 
+      pointer to pointer to signed int 
+    with body 
+
+f9: a function
+    returning 
+      pointer to const pointer to signed int 
+    with body 
+
+f10: a function
+    returning 
+      pointer to open array of signed int 
+    with body 
+
+f11: a function
+    returning 
+      pointer to open array of open array of signed int 
+    with body 
+
+f12: a function
+    returning 
+      pointer to open array of open array of signed int 
+    with body 
+
+fII1: a function
+    with parameters
+      i: a signed int 
+    returning 
+      signed int 
+    with body 
+
+fII2: a function
+    with parameters
+      i: a signed int 
+    returning 
+      const signed int 
+    with body 
+
+fII3: a extern function
+    with parameters
+      i: a signed int 
+    returning 
+      signed int 
+    with body 
+
+fII4: a extern function
+    with parameters
+      i: a signed int 
+    returning 
+      const signed int 
+    with body 
+
+fII5: a function
+    returning 
+      pointer to signed int 
+    with body 
+
+fII6: a function
+    returning 
+      const pointer to signed int 
+    with body 
+
+fII7: a function
+    returning 
+      pointer to const long signed int 
+    with body 
+
+fII8: a static function
+    returning 
+      pointer to const long signed int 
+    with body 
+
+fII9: a static function
+    returning 
+      pointer to const long signed int 
+    with body 
+
+fO1: a function
+    returning 
+      signed int 
+    with parameter names
+      i
+    with parameter declarations
+      i: a signed int 
+    with body 
+
+fO2: a function
+    returning 
+      signed int 
+    with parameter names
+      i
+    with parameter declarations
+      i: a signed int 
+    with body 
+
+fO3: a function
+    returning 
+      const signed int 
+    with parameter names
+      i
+    with parameter declarations
+      i: a signed int 
+    with body 
+
+fO4: a extern function
+    returning 
+      signed int 
+    with parameter names
+      i
+    with parameter declarations
+      i: a signed int 
+    with body 
+
+fO5: a extern function
+    returning 
+      const signed int 
+    with parameter names
+      i
+    with parameter declarations
+      i: a signed int 
+    with body 
+
+f: a function
+    returning 
+      nothing 
+
+f: a function
+    returning 
+      signed int 
+
+f: a function
+    with parameters
+      signed int 
+    returning 
+      nothing 
+
+f: a function
+    with parameters
+      signed int 
+    returning 
+      signed int 
+
+f: a function
+    returning 
+      nothing 
+    with body 
+
+f: a function
+    returning 
+      signed int 
+    with body 
+
+f: a function
+    with parameters
+      signed int 
+    returning 
+      nothing 
+    with body 
+
+f: a function
+    with parameters
+      signed int 
+    returning 
+      signed int 
+    with body 
+
+f: a function
+    returning 
+      x: a signed int 
+
+f: a function
+    with parameters
+      x: a signed int 
+    returning 
+      nothing 
+
+f: a function
+    with parameters
+      x: a signed int 
+    returning 
+      x: a signed int 
+
+f: a function
+    returning 
+      x: a signed int 
+    with body 
+
+f: a function
+    with parameters
+      x: a signed int 
+    returning 
+      nothing 
+    with body 
+
+f: a function
+    with parameters
+      x: a signed int 
+    returning 
+      x: a signed int 
+    with body 
+
+f: a function
+    returning 
+      signed int 
+      x: a signed int 
+
+f: a function
+    with parameters
+      signed int 
+      x: a signed int 
+    returning 
+      nothing 
+
+f: a function
+    with parameters
+      signed int 
+      x: a signed int 
+    returning 
+      signed int 
+      x: a signed int 
+
+f: a function
+    returning 
+      signed int 
+      x: a signed int 
+    with body 
+
+f: a function
+    with parameters
+      signed int 
+      x: a signed int 
+    returning 
+      nothing 
+    with body 
+
+f: a function
+    with parameters
+      signed int 
+      x: a signed int 
+    returning 
+      signed int 
+      x: a signed int 
+    with body 
+
+f: a function
+    returning 
+      signed int 
+      x: a signed int 
+      signed int 
+
+f: a function
+    with parameters
+      signed int 
+      x: a signed int 
+      signed int 
+    returning 
+      nothing 
+
+f: a function
+    with parameters
+      signed int 
+      x: a signed int 
+      signed int 
+    returning 
+      signed int 
+      x: a signed int 
+      signed int 
+
+f: a function
+    returning 
+      signed int 
+      x: a signed int 
+      signed int 
+    with body 
+
+f: a function
+    with parameters
+      signed int 
+      x: a signed int 
+      signed int 
+    returning 
+      nothing 
+    with body 
+
+f: a function
+    with parameters
+      signed int 
+      x: a signed int 
+      signed int 
+    returning 
+      signed int 
+      x: a signed int 
+      signed int 
+    with body 
+
+f: a function
+    returning 
+      signed int 
+      x: a signed int 
+      y: a pointer to signed int 
+
+f: a function
+    with parameters
+      signed int 
+      x: a signed int 
+      y: a pointer to signed int 
+    returning 
+      nothing 
+
+f: a function
+    with parameters
+      signed int 
+      x: a signed int 
+      y: a pointer to signed int 
+    returning 
+      signed int 
+      x: a signed int 
+      y: a pointer to signed int 
+
+f: a function
+    returning 
+      signed int 
+      x: a signed int 
+      y: a pointer to signed int 
+    with body 
+
+f: a function
+    with parameters
+      signed int 
+      x: a signed int 
+      y: a pointer to signed int 
+    returning 
+      nothing 
+    with body 
+
+f: a function
+    with parameters
+      signed int 
+      x: a signed int 
+      y: a pointer to signed int 
+    returning 
+      signed int 
+      x: a signed int 
+      y: a pointer to signed int 
+    with body 
+
+f11: a function
+    with parameters
+      signed int 
+    returning 
+      signed int 
+
+f12: a function
+    with parameters
+      signed int 
+    returning 
+      signed int 
+
+f: a function
+    with parameters
+      function
+          with parameters
+            signed int 
+            p: a signed int 
+          returning 
+            signed int 
+
+      function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+    returning 
+      signed int 
+    with body 
+      Declaration of p: a pointer to open array of open array of pointer to open array of open array of signed int 
+      Declaration of p: a pointer to open array of open array of pointer to open array of open array of signed int 
+      Declaration of p: a pointer to open array of pointer to function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+
+f1: a static function
+    returning 
+      pointer to const signed int 
+    with body 
+
+f2: a static function
+    returning 
+      const signed int 
+    with body 
+
+f3: a inline static function
+    returning 
+      const pointer to signed int 
+    with body 
+
+f4: a inline static function
+    returning 
+      const tuple of types
+          pointer to signed int 
+          signed int 
+
+    with body 
+
+f5: a static function
+    returning 
+      const tuple of types
+          pointer to signed int 
+          const signed int 
+
+    with body 
+
+f: a function
+    with parameters
+      function
+          returning 
+            signed int 
+
+      function
+          returning 
+            pointer to signed int 
+
+      function
+          returning 
+            pointer to pointer to signed int 
+
+      function
+          returning 
+            pointer to const pointer to signed int 
+
+      function
+          returning 
+            const pointer to const pointer to signed int 
+
+      open array of signed int 
+      open array of signed int 
+      open array of pointer to signed int 
+      open array of pointer to signed int 
+      open array of pointer to pointer to signed int 
+      open array of pointer to pointer to signed int 
+      open array of pointer to const pointer to signed int 
+      open array of pointer to const pointer to signed int 
+      open array of const pointer to const pointer to signed int 
+      open array of const pointer to const pointer to signed int 
+    returning 
+      signed int 
+
+f: a function
+    with parameters
+      function
+          returning 
+            signed int 
+
+      function
+          returning 
+            pointer to signed int 
+
+      function
+          returning 
+            pointer to pointer to signed int 
+
+      function
+          returning 
+            pointer to const pointer to signed int 
+
+      function
+          returning 
+            const pointer to const pointer to signed int 
+
+      open array of signed int 
+      open array of signed int 
+      open array of pointer to signed int 
+      open array of pointer to signed int 
+      open array of pointer to pointer to signed int 
+      open array of pointer to pointer to signed int 
+      open array of pointer to const pointer to signed int 
+      open array of pointer to const pointer to signed int 
+      open array of const pointer to const pointer to signed int 
+      open array of const pointer to const pointer to signed int 
+    returning 
+      signed int 
+    with body 
+
+T: a typedef for signed int 
+f: a function
+    with parameters
+      function
+          with parameters
+            instance of type T 
+          returning 
+            instance of type T 
+
+      T: a instance of type T 
+    returning 
+      signed int 
+    with body 
+
Index: translator/Tests/SynTree/Expected/IdentFuncDeclarator.tst
===================================================================
--- translator/Tests/SynTree/Expected/IdentFuncDeclarator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected/IdentFuncDeclarator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,180 @@
+main: a function
+    returning 
+      signed int 
+    with body 
+      Declaration of f1: a signed int 
+      Declaration of f2: a signed int 
+      Declaration of f3: a pointer to signed int 
+      Declaration of f4: a pointer to pointer to signed int 
+      Declaration of f5: a pointer to const pointer to signed int 
+      Declaration of f6: a const pointer to const pointer to signed int 
+      Declaration of f7: a pointer to signed int 
+      Declaration of f8: a pointer to pointer to signed int 
+      Declaration of f9: a pointer to const pointer to signed int 
+      Declaration of f10: a const pointer to const pointer to signed int 
+      Declaration of f11: a pointer to signed int 
+      Declaration of f12: a pointer to pointer to signed int 
+      Declaration of f13: a pointer to const pointer to signed int 
+      Declaration of f14: a const pointer to const pointer to signed int 
+      Declaration of f15: a open array of signed int 
+      Declaration of f16: a open array of signed int 
+      Declaration of f17: a open array of signed int 
+      Declaration of f18: a open array of signed int 
+      Declaration of f19: a open array of pointer to signed int 
+      Declaration of f20: a open array of pointer to signed int 
+      Declaration of f21: a open array of pointer to pointer to signed int 
+      Declaration of f22: a open array of pointer to pointer to signed int 
+      Declaration of f23: a open array of pointer to const pointer to signed int 
+      Declaration of f24: a open array of pointer to const pointer to signed int 
+      Declaration of f25: a open array of const pointer to const pointer to signed int 
+      Declaration of f26: a open array of const pointer to const pointer to signed int 
+      Declaration of f27: a open array of pointer to signed int 
+      Declaration of f28: a open array of pointer to signed int 
+      Declaration of f29: a open array of pointer to pointer to signed int 
+      Declaration of f30: a open array of pointer to pointer to signed int 
+      Declaration of f31: a open array of pointer to const pointer to signed int 
+      Declaration of f32: a open array of pointer to const pointer to signed int 
+      Declaration of f33: a open array of const pointer to const pointer to signed int 
+      Declaration of f34: a open array of const pointer to const pointer to signed int 
+      Declaration of f35: a open array of pointer to signed int 
+      Declaration of f36: a open array of pointer to signed int 
+      Declaration of f37: a open array of pointer to pointer to signed int 
+      Declaration of f38: a open array of pointer to pointer to signed int 
+      Declaration of f39: a open array of pointer to const pointer to signed int 
+      Declaration of f40: a open array of pointer to const pointer to signed int 
+      Declaration of f41: a open array of const pointer to const pointer to signed int 
+      Declaration of f42: a open array of const pointer to const pointer to signed int 
+      Declaration of f43: a open array of open array of signed int 
+      Declaration of f44: a open array of open array of signed int 
+      Declaration of f45: a open array of open array of signed int 
+      Declaration of f46: a open array of open array of signed int 
+      Declaration of f47: a open array of open array of signed int 
+      Declaration of f48: a open array of open array of signed int 
+      Declaration of f49: a open array of open array of pointer to signed int 
+      Declaration of f50: a open array of open array of pointer to signed int 
+      Declaration of f51: a open array of open array of pointer to pointer to signed int 
+      Declaration of f52: a open array of open array of pointer to pointer to signed int 
+      Declaration of f53: a open array of open array of pointer to const pointer to signed int 
+      Declaration of f54: a open array of open array of pointer to const pointer to signed int 
+      Declaration of f55: a open array of open array of const pointer to const pointer to signed int 
+      Declaration of f56: a open array of open array of const pointer to const pointer to signed int 
+      Declaration of f57: a open array of open array of pointer to signed int 
+      Declaration of f58: a open array of open array of pointer to signed int 
+      Declaration of f59: a open array of open array of pointer to pointer to signed int 
+      Declaration of f60: a open array of open array of pointer to pointer to signed int 
+      Declaration of f61: a open array of open array of pointer to const pointer to signed int 
+      Declaration of f62: a open array of open array of pointer to const pointer to signed int 
+      Declaration of f63: a open array of open array of const pointer to const pointer to signed int 
+      Declaration of f64: a open array of open array of const pointer to const pointer to signed int 
+      Declaration of f65: a function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+      Declaration of f66: a function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+      Declaration of f67: a function
+          with parameters
+            signed int 
+          returning 
+            pointer to signed int 
+
+      Declaration of f68: a function
+          with parameters
+            signed int 
+          returning 
+            pointer to pointer to signed int 
+
+      Declaration of f69: a function
+          with parameters
+            signed int 
+          returning 
+            pointer to const pointer to signed int 
+
+      Declaration of f70: a function
+          with parameters
+            signed int 
+          returning 
+            const pointer to const pointer to signed int 
+
+      Declaration of f71: a function
+          with parameters
+            signed int 
+          returning 
+            pointer to signed int 
+
+      Declaration of f72: a function
+          with parameters
+            signed int 
+          returning 
+            pointer to pointer to signed int 
+
+      Declaration of f73: a function
+          with parameters
+            signed int 
+          returning 
+            pointer to const pointer to signed int 
+
+      Declaration of f74: a function
+          with parameters
+            signed int 
+          returning 
+            const pointer to const pointer to signed int 
+
+      Declaration of f75: a pointer to function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+      Declaration of f76: a pointer to pointer to function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+      Declaration of f77: a pointer to const pointer to function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+      Declaration of f78: a const pointer to const pointer to function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+      Declaration of f79: a pointer to function
+          with parameters
+            signed int 
+          returning 
+            pointer to function
+                returning 
+                  signed int 
+
+
+      Declaration of f80: a const pointer to function
+          with parameters
+            signed int 
+          returning 
+            pointer to function
+                returning 
+                  signed int 
+
+
+      Declaration of f81: a const pointer to function
+          with parameters
+            signed int 
+          returning 
+            const pointer to function
+                returning 
+                  signed int 
+
+
+
Index: translator/Tests/SynTree/Expected/Initialization.tst
===================================================================
--- translator/Tests/SynTree/Expected/Initialization.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected/Initialization.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,33 @@
+x21: a pointer to signed int 
+x22: a signed int 
+x21: a pointer to signed int 
+x22: a signed int 
+y1: a open array of signed int 
+y2: a open array of signed int 
+struct __anonymous0
+    with members
+      w: a tuple of types
+          signed int 
+
+
+a: a instance of struct __anonymous0 
+struct __anonymous1
+    with members
+      a: a open array of signed int 
+      b: a signed int 
+
+w: a open array of instance of struct __anonymous1 
+struct __anonymous3
+    with members
+      f1: a signed int 
+      f2: a signed int 
+      f3: a signed int 
+      struct __anonymous2
+          with members
+            g1: a signed int 
+            g2: a signed int 
+            g3: a signed int 
+
+      f4: a open array of instance of struct __anonymous2 
+
+v7: a instance of struct __anonymous3 
Index: translator/Tests/SynTree/Expected/Scope.tst
===================================================================
--- translator/Tests/SynTree/Expected/Scope.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected/Scope.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,115 @@
+in default case, (shouldn't be here)
+in default case, (shouldn't be here)
+in default case, (shouldn't be here)
+x: a signed int 
+y: a typedef for double 
+t: a typedef for float 
+z: a instance of type y 
+struct __anonymous0
+    with members
+      a: a signed int 
+      b: a double 
+
+u: a type for instance of struct __anonymous0 
+f: a function
+    with parameters
+      y: a signed int 
+    returning 
+      signed int 
+
+q: a instance of type y 
+w: a function
+    with parameters
+      y: a instance of type y 
+      v: a instance of type u 
+    returning 
+      instance of type y 
+    with body 
+      Declaration of x: a type
+        with assertions
+          t: a function
+              with parameters
+                instance of type u 
+              returning 
+                instance of type x 
+
+
+      Declaration of u: a instance of type u 
+      Declaration of z: a instance of type x 
+
+p: a instance of type y 
+context has_u
+    with parameters
+      z: a type
+
+    with members
+      u: a function
+          with parameters
+            instance of type z 
+          returning 
+            instance of type z 
+
+
+q: a function
+    with parameters
+      the_t: a instance of type t 
+    with forall
+      t: a type
+        with assertions
+          instance of context has_u 
+            with parameters
+              instance of type t 
+
+
+    returning 
+      instance of type y 
+    with body 
+      Declaration of y: a instance of type t 
+
+f: a function
+    with parameters
+      p: a instance of type y 
+    returning 
+      instance of type t 
+    with body 
+      Declaration of y: a signed int 
+      Declaration of x: a typedef for char 
+              Declaration of y: a instance of type x 
+        Declaration of z: a typedef for instance of type x 
+                  Declaration of x: a instance of type z 
+          Declaration of y: a typedef for instance of type z 
+          Declaration of z: a instance of type y 
+
+        Declaration of x: a instance of type z 
+
+      Declaration of q: a instance of type x 
+
+g: a function
+    with parameters
+      void 
+    returning 
+      instance of type t 
+    with body 
+      Declaration of x: a typedef for char 
+      Declaration of z: a instance of type x 
+
+q: a function
+    returning 
+      instance of type y 
+    with parameter names
+      i
+    with parameter declarations
+      i: a signed int 
+    with body 
+      
+        Switch on condition: 
+            Name: i
+
+            Case: 
+            .... and 1 conditions 
+                Name: 0
+
+            Case: 
+            .... and 0 conditions 
+
+
Index: translator/Tests/SynTree/Expected/StructMember.tst
===================================================================
--- translator/Tests/SynTree/Expected/StructMember.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected/StructMember.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,69 @@
+T: a typedef for signed int 
+struct S
+    with members
+      m1: a signed int 
+      m2: a signed int 
+      signed int 
+      signed int 
+      signed int 
+      m3: a signed int 
+      m4: a signed int 
+      m5: a signed int 
+      m6: a signed int 
+      m7: a pointer to signed int 
+      m8: a pointer to signed int 
+      m9: a pointer to signed int 
+      m10: a pointer to function
+          returning 
+            signed int 
+
+      m11: a pointer to function
+          with parameters
+            signed int 
+          returning 
+            pointer to signed int 
+
+      T: a instance of type T 
+      T: a instance of type T 
+      m12: a pointer to signed int 
+      m13: a pointer to signed int 
+      m14: a pointer to function
+          with parameters
+            signed int 
+          returning 
+            pointer to signed int 
+
+      signed int 
+      signed int 
+      signed int 
+      signed int 
+      pointer to signed int 
+      signed int 
+      signed int 
+      pointer to signed int 
+      pointer to signed int 
+      pointer to signed int 
+      pointer to signed int 
+      pointer to signed int 
+      pointer to signed int 
+      pointer to function
+          returning 
+            signed int 
+
+      pointer to pointer to function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+      instance of type T 
+
+s: a instance of struct S 
+union U
+    with members
+      m1: a open array of signed int 
+      m2: a open array of signed int 
+      m3: a pointer to signed int 
+      m4: a pointer to signed int 
+
+u: a instance of union U 
Index: translator/Tests/SynTree/Expected/Tuple.tst
===================================================================
--- translator/Tests/SynTree/Expected/Tuple.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected/Tuple.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,104 @@
+f: a function
+    with parameters
+      signed int 
+      signed int 
+    returning 
+      signed int 
+
+g: a function
+    with parameters
+      signed int 
+      signed int 
+      signed int 
+    returning 
+      signed int 
+
+h: a static function
+    with parameters
+      a: a signed int 
+      b: a signed int 
+      c: a pointer to signed int 
+      d: a open array of char 
+    returning 
+      signed int 
+      signed int 
+      signed int 
+      signed int 
+
+struct inner
+    with members
+      f2: a signed int 
+      f3: a signed int 
+
+struct outer
+    with members
+      f1: a signed int 
+      i: a instance of struct inner 
+      f4: a double 
+
+s: a instance of struct outer 
+sp: a pointer to instance of struct outer 
+t1: a const volatile tuple of types
+    signed int 
+    signed int 
+
+t2: a static const tuple of types
+    signed int 
+    const signed int 
+
+t3: a static const tuple of types
+    signed int 
+    const signed int 
+
+printf: a function
+    with parameters
+      fmt: a pointer to char 
+      and a variable number of other arguments
+    returning 
+      rc: a signed int 
+
+printf: a function
+    with parameters
+      fmt: a pointer to char 
+      and a variable number of other arguments
+    returning 
+      signed int 
+
+f1: a function
+    with parameters
+      w: a signed int 
+    returning 
+      x: a short signed int 
+      y: a unsigned int 
+    with body 
+
+g1: a function
+    returning 
+      r: a tuple of types
+          signed int 
+          char 
+          long signed int 
+          signed int 
+
+    with body 
+      Declaration of x: a short signed int 
+      Declaration of p: a short signed int 
+      Declaration of y: a unsigned int 
+      Declaration of z: a tuple of types
+          signed int 
+          signed int 
+
+
+main: a function
+    with parameters
+      argc: a signed int 
+      argv: a pointer to pointer to char 
+    returning 
+      rc: a signed int 
+    with body 
+      Declaration of a: a signed int 
+      Declaration of b: a signed int 
+      Declaration of c: a signed int 
+      Declaration of d: a signed int 
+      Declaration of t: a instance of struct outer 
+
Index: translator/Tests/SynTree/Expected/TypeGenerator.tst
===================================================================
--- translator/Tests/SynTree/Expected/TypeGenerator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected/TypeGenerator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,116 @@
+context addable
+    with parameters
+      T: a type
+
+    with members
+      ?+?: a function
+          with parameters
+            instance of type T 
+            instance of type T 
+          returning 
+            instance of type T 
+
+
+struct __anonymous0
+    with members
+      data: a instance of type T 
+      next: a pointer to instance of type List 
+        with parameters
+          instance of type T 
+
+
+List: a type for pointer to instance of struct __anonymous0 
+  with parameters
+    T: a type
+      with assertions
+        instance of context addable 
+          with parameters
+            instance of type T 
+
+
+
+  with assertions
+    instance of context addable 
+      with parameters
+        instance of type T 
+
+
+ListOfIntegers: a typedef for instance of type List 
+  with parameters
+    signed int 
+
+li: a instance of type ListOfIntegers 
+f: a function
+    with parameters
+      g: a pointer to function
+          with parameters
+            signed int 
+          returning 
+            instance of type List 
+              with parameters
+                signed int 
+
+
+    returning 
+      signed int 
+
+h: a function
+    with parameters
+      p: a pointer to instance of type List 
+        with parameters
+          signed int 
+
+    returning 
+      signed int 
+
+struct node
+    with parameters
+      T: a type
+        with assertions
+          instance of context addable 
+            with parameters
+              instance of type T 
+
+
+
+    with members
+      data: a instance of type T 
+      next: a pointer to instance of struct node 
+        with parameters
+          instance of type T 
+
+
+List: a type for pointer to instance of struct node 
+  with parameters
+    instance of type T 
+
+  with parameters
+    T: a type
+
+my_list: a instance of type List 
+  with parameters
+    signed int 
+
+Complex: a type
+  with assertions
+    instance of context addable 
+      with parameters
+        instance of type Complex 
+
+
+main: a function
+    returning 
+      signed int 
+    with body 
+      
+        Expression Statement:
+          Cast of:
+            Name: my_list
+
+          to:
+            instance of struct node 
+              with parameters
+                signed int 
+
+
+
Index: translator/Tests/SynTree/Expected/Typedef.tst
===================================================================
--- translator/Tests/SynTree/Expected/Typedef.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected/Typedef.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,85 @@
+T: a typedef for signed int 
+f: a function
+    with parameters
+      void 
+    returning 
+      void 
+    with body 
+      Declaration of T: a function
+          with parameters
+            instance of type T 
+          returning 
+            signed int 
+
+
+struct __anonymous0
+    with members
+      T: a instance of type T 
+
+fred: a instance of struct __anonymous0 
+a: a typedef for pointer to function
+    with parameters
+      signed int 
+      char 
+    returning 
+      signed int 
+
+b: a instance of type a 
+g: a function
+    with parameters
+      void 
+    returning 
+      signed int 
+    with body 
+      Declaration of a: a double 
+
+c: a instance of type a 
+main: a function
+    returning 
+      signed int 
+    with body 
+
+arrayOf10Pointers: a typedef for open array of pointer to signed int 
+x: a instance of type arrayOf10Pointers 
+constantPointer: a typedef for const pointer to signed int 
+funcPtr: a typedef for pointer to function
+    with parameters
+      open array of signed int 
+    returning 
+      signed int 
+
+funcProto: a typedef for function
+    with parameters
+      open array of signed int 
+    returning 
+      signed int 
+
+tupleType: a typedef for tuple of types
+    signed int 
+    signed int 
+
+tupleTypePtr: a typedef for pointer to tuple of types
+    signed int 
+    signed int 
+
+a: a typedef for pointer to signed int 
+b: a typedef for pointer to signed int 
+f: a typedef for function
+    with parameters
+      pointer to signed int 
+    returning 
+      signed int 
+
+g: a typedef for function
+    with parameters
+      pointer to signed int 
+    returning 
+      signed int 
+
+t: a typedef for tuple of types
+    pointer to static open array of signed int 
+
+f: a typedef for function
+    returning 
+      x: a pointer to static open array of signed int 
+
Index: translator/Tests/SynTree/Expected/TypedefDeclarator.tst
===================================================================
--- translator/Tests/SynTree/Expected/TypedefDeclarator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected/TypedefDeclarator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,270 @@
+f0: a typedef for signed int 
+f1: a typedef for signed int 
+f2: a typedef for signed int 
+f3: a typedef for signed int 
+f4: a typedef for signed int 
+f5: a typedef for signed int 
+f6: a typedef for signed int 
+f7: a typedef for signed int 
+f8: a typedef for signed int 
+f9: a typedef for signed int 
+f10: a typedef for signed int 
+f11: a typedef for signed int 
+f12: a typedef for signed int 
+f13: a typedef for signed int 
+f14: a typedef for signed int 
+f15: a typedef for signed int 
+f16: a typedef for signed int 
+f17: a typedef for signed int 
+f18: a typedef for signed int 
+f19: a typedef for signed int 
+f20: a typedef for signed int 
+f21: a typedef for signed int 
+f22: a typedef for signed int 
+f23: a typedef for signed int 
+f24: a typedef for signed int 
+f25: a typedef for signed int 
+f26: a typedef for signed int 
+f27: a typedef for signed int 
+f28: a typedef for signed int 
+f29: a typedef for signed int 
+f30: a typedef for signed int 
+f31: a typedef for signed int 
+f32: a typedef for signed int 
+f33: a typedef for signed int 
+f34: a typedef for signed int 
+f35: a typedef for signed int 
+f36: a typedef for signed int 
+f37: a typedef for signed int 
+f38: a typedef for signed int 
+f39: a typedef for signed int 
+f40: a typedef for signed int 
+f41: a typedef for signed int 
+f42: a typedef for signed int 
+f43: a typedef for signed int 
+f44: a typedef for signed int 
+f45: a typedef for signed int 
+f46: a typedef for signed int 
+f47: a typedef for signed int 
+f48: a typedef for signed int 
+f49: a typedef for signed int 
+f50: a typedef for signed int 
+f51: a typedef for signed int 
+f52: a typedef for signed int 
+f53: a typedef for signed int 
+f54: a typedef for signed int 
+f55: a typedef for signed int 
+f56: a typedef for signed int 
+f57: a typedef for signed int 
+f58: a typedef for signed int 
+f59: a typedef for signed int 
+f60: a typedef for signed int 
+f61: a typedef for signed int 
+f62: a typedef for signed int 
+f63: a typedef for signed int 
+f64: a typedef for signed int 
+f65: a typedef for signed int 
+f66: a typedef for signed int 
+f67: a typedef for signed int 
+f68: a typedef for signed int 
+f69: a typedef for signed int 
+f70: a typedef for signed int 
+f71: a typedef for signed int 
+f72: a typedef for signed int 
+f73: a typedef for signed int 
+f74: a typedef for signed int 
+f75: a typedef for signed int 
+f76: a typedef for signed int 
+f77: a typedef for signed int 
+f78: a typedef for signed int 
+f79: a typedef for signed int 
+f80: a typedef for signed int 
+f81: a typedef for signed int 
+f82: a typedef for signed int 
+f83: a typedef for signed int 
+f84: a typedef for signed int 
+f85: a typedef for signed int 
+f86: a typedef for signed int 
+f87: a typedef for signed int 
+f88: a typedef for signed int 
+f89: a typedef for signed int 
+main: a function
+    returning 
+      signed int 
+    with body 
+      Declaration of f1: a signed int 
+      Declaration of f2: a signed int 
+      Declaration of f3: a pointer to signed int 
+      Declaration of f4: a pointer to pointer to signed int 
+      Declaration of f5: a pointer to const pointer to signed int 
+      Declaration of f6: a const pointer to const pointer to signed int 
+      Declaration of f7: a pointer to signed int 
+      Declaration of f8: a pointer to pointer to signed int 
+      Declaration of f9: a pointer to const pointer to signed int 
+      Declaration of f10: a const pointer to const pointer to signed int 
+      Declaration of f11: a pointer to signed int 
+      Declaration of f12: a pointer to pointer to signed int 
+      Declaration of f13: a pointer to const pointer to signed int 
+      Declaration of f14: a const pointer to const pointer to signed int 
+      Declaration of f15: a open array of signed int 
+      Declaration of f16: a open array of signed int 
+      Declaration of f17: a open array of signed int 
+      Declaration of f18: a open array of signed int 
+      Declaration of f19: a open array of pointer to signed int 
+      Declaration of f20: a open array of pointer to signed int 
+      Declaration of f21: a open array of pointer to pointer to signed int 
+      Declaration of f22: a open array of pointer to pointer to signed int 
+      Declaration of f23: a open array of pointer to const pointer to signed int 
+      Declaration of f24: a open array of pointer to const pointer to signed int 
+      Declaration of f25: a open array of const pointer to const pointer to signed int 
+      Declaration of f26: a open array of const pointer to const pointer to signed int 
+      Declaration of f27: a open array of pointer to signed int 
+      Declaration of f28: a open array of pointer to signed int 
+      Declaration of f29: a open array of pointer to pointer to signed int 
+      Declaration of f30: a open array of pointer to pointer to signed int 
+      Declaration of f31: a open array of pointer to const pointer to signed int 
+      Declaration of f32: a open array of pointer to const pointer to signed int 
+      Declaration of f33: a open array of const pointer to const pointer to signed int 
+      Declaration of f34: a open array of const pointer to const pointer to signed int 
+      Declaration of f35: a open array of pointer to signed int 
+      Declaration of f36: a open array of pointer to signed int 
+      Declaration of f37: a open array of pointer to pointer to signed int 
+      Declaration of f38: a open array of pointer to pointer to signed int 
+      Declaration of f39: a open array of pointer to const pointer to signed int 
+      Declaration of f40: a open array of pointer to const pointer to signed int 
+      Declaration of f41: a open array of const pointer to const pointer to signed int 
+      Declaration of f42: a open array of const pointer to const pointer to signed int 
+      Declaration of f43: a open array of open array of signed int 
+      Declaration of f44: a open array of open array of signed int 
+      Declaration of f45: a open array of open array of signed int 
+      Declaration of f46: a open array of open array of signed int 
+      Declaration of f47: a open array of open array of signed int 
+      Declaration of f48: a open array of open array of signed int 
+      Declaration of f49: a open array of open array of pointer to signed int 
+      Declaration of f50: a open array of open array of pointer to signed int 
+      Declaration of f51: a open array of open array of pointer to pointer to signed int 
+      Declaration of f52: a open array of open array of pointer to pointer to signed int 
+      Declaration of f53: a open array of open array of pointer to const pointer to signed int 
+      Declaration of f54: a open array of open array of pointer to const pointer to signed int 
+      Declaration of f55: a open array of open array of const pointer to const pointer to signed int 
+      Declaration of f56: a open array of open array of const pointer to const pointer to signed int 
+      Declaration of f57: a open array of open array of pointer to signed int 
+      Declaration of f58: a open array of open array of pointer to signed int 
+      Declaration of f59: a open array of open array of pointer to pointer to signed int 
+      Declaration of f60: a open array of open array of pointer to pointer to signed int 
+      Declaration of f61: a open array of open array of pointer to const pointer to signed int 
+      Declaration of f62: a open array of open array of pointer to const pointer to signed int 
+      Declaration of f63: a open array of open array of const pointer to const pointer to signed int 
+      Declaration of f64: a open array of open array of const pointer to const pointer to signed int 
+      Declaration of f65: a function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+      Declaration of f66: a function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+      Declaration of f67: a function
+          with parameters
+            signed int 
+          returning 
+            pointer to signed int 
+
+      Declaration of f68: a function
+          with parameters
+            signed int 
+          returning 
+            pointer to pointer to signed int 
+
+      Declaration of f69: a function
+          with parameters
+            signed int 
+          returning 
+            pointer to const pointer to signed int 
+
+      Declaration of f70: a function
+          with parameters
+            signed int 
+          returning 
+            const pointer to const pointer to signed int 
+
+      Declaration of f71: a function
+          with parameters
+            signed int 
+          returning 
+            pointer to signed int 
+
+      Declaration of f72: a function
+          with parameters
+            signed int 
+          returning 
+            pointer to pointer to signed int 
+
+      Declaration of f73: a function
+          with parameters
+            signed int 
+          returning 
+            pointer to const pointer to signed int 
+
+      Declaration of f74: a function
+          with parameters
+            signed int 
+          returning 
+            const pointer to const pointer to signed int 
+
+      Declaration of f75: a pointer to function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+      Declaration of f76: a pointer to pointer to function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+      Declaration of f77: a pointer to const pointer to function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+      Declaration of f78: a const pointer to const pointer to function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+      Declaration of f79: a pointer to function
+          with parameters
+            signed int 
+          returning 
+            pointer to function
+                returning 
+                  signed int 
+
+
+      Declaration of f80: a const pointer to function
+          with parameters
+            signed int 
+          returning 
+            pointer to function
+                returning 
+                  signed int 
+
+
+      Declaration of f81: a const pointer to function
+          with parameters
+            signed int 
+          returning 
+            const pointer to function
+                returning 
+                  signed int 
+
+
+
Index: translator/Tests/SynTree/Expected/TypedefParamDeclarator.tst
===================================================================
--- translator/Tests/SynTree/Expected/TypedefParamDeclarator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected/TypedefParamDeclarator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,378 @@
+f0: a typedef for signed int 
+f1: a typedef for signed int 
+f2: a typedef for signed int 
+f3: a typedef for signed int 
+f4: a typedef for signed int 
+f5: a typedef for signed int 
+f6: a typedef for signed int 
+f7: a typedef for signed int 
+f8: a typedef for signed int 
+f9: a typedef for signed int 
+f10: a typedef for signed int 
+f11: a typedef for signed int 
+f12: a typedef for signed int 
+f13: a typedef for signed int 
+f14: a typedef for signed int 
+f15: a typedef for signed int 
+f16: a typedef for signed int 
+f17: a typedef for signed int 
+f18: a typedef for signed int 
+f19: a typedef for signed int 
+f20: a typedef for signed int 
+f21: a typedef for signed int 
+f22: a typedef for signed int 
+f23: a typedef for signed int 
+f24: a typedef for signed int 
+f25: a typedef for signed int 
+f26: a typedef for signed int 
+f27: a typedef for signed int 
+f28: a typedef for signed int 
+f29: a typedef for signed int 
+f30: a typedef for signed int 
+f31: a typedef for signed int 
+f32: a typedef for signed int 
+f33: a typedef for signed int 
+f34: a typedef for signed int 
+f35: a typedef for signed int 
+f36: a typedef for signed int 
+f37: a typedef for signed int 
+f38: a typedef for signed int 
+f39: a typedef for signed int 
+f40: a typedef for signed int 
+f41: a typedef for signed int 
+f42: a typedef for signed int 
+f43: a typedef for signed int 
+f44: a typedef for signed int 
+f45: a typedef for signed int 
+f46: a typedef for signed int 
+f47: a typedef for signed int 
+f48: a typedef for signed int 
+f49: a typedef for signed int 
+f50: a typedef for signed int 
+f51: a typedef for signed int 
+f52: a typedef for signed int 
+f53: a typedef for signed int 
+f54: a typedef for signed int 
+f55: a typedef for signed int 
+f56: a typedef for signed int 
+f57: a typedef for signed int 
+f58: a typedef for signed int 
+f59: a typedef for signed int 
+f60: a typedef for signed int 
+f61: a typedef for signed int 
+f62: a typedef for signed int 
+f63: a typedef for signed int 
+f64: a typedef for signed int 
+f65: a typedef for signed int 
+f66: a typedef for signed int 
+f67: a typedef for signed int 
+f68: a typedef for signed int 
+f69: a typedef for signed int 
+f70: a typedef for signed int 
+f71: a typedef for signed int 
+f72: a typedef for signed int 
+f73: a typedef for signed int 
+f74: a typedef for signed int 
+f75: a typedef for signed int 
+f76: a typedef for signed int 
+f77: a typedef for signed int 
+f78: a typedef for signed int 
+f79: a typedef for signed int 
+f80: a typedef for signed int 
+f81: a typedef for signed int 
+f82: a typedef for signed int 
+f83: a typedef for signed int 
+f84: a typedef for signed int 
+f85: a typedef for signed int 
+f86: a typedef for signed int 
+f87: a typedef for signed int 
+f88: a typedef for signed int 
+f89: a typedef for signed int 
+f90: a typedef for signed int 
+f91: a typedef for signed int 
+f92: a typedef for signed int 
+f93: a typedef for signed int 
+f94: a typedef for signed int 
+f95: a typedef for signed int 
+f96: a typedef for signed int 
+f97: a typedef for signed int 
+f98: a typedef for signed int 
+f99: a typedef for signed int 
+f100: a typedef for signed int 
+f101: a typedef for signed int 
+f102: a typedef for signed int 
+f103: a typedef for signed int 
+f104: a typedef for signed int 
+f105: a typedef for signed int 
+f106: a typedef for signed int 
+f107: a typedef for signed int 
+f108: a typedef for signed int 
+f109: a typedef for signed int 
+f110: a typedef for signed int 
+f111: a typedef for signed int 
+f112: a typedef for signed int 
+f113: a typedef for signed int 
+f114: a typedef for signed int 
+f115: a typedef for signed int 
+f116: a typedef for signed int 
+f117: a typedef for signed int 
+f118: a typedef for signed int 
+f119: a typedef for signed int 
+fred: a function
+    with parameters
+      f1: a signed int 
+      f3: a pointer to signed int 
+      f4: a pointer to pointer to signed int 
+      f5: a pointer to const pointer to signed int 
+      f6: a const pointer to const pointer to signed int 
+      f11: a pointer to signed int 
+      f12: a pointer to pointer to signed int 
+      f13: a pointer to const pointer to signed int 
+      f14: a const pointer to const pointer to signed int 
+      f15: a open array of signed int 
+      f16: a open array of signed int 
+      f19: a open array of pointer to signed int 
+      f20: a open array of pointer to signed int 
+      f21: a open array of pointer to pointer to signed int 
+      f22: a open array of pointer to pointer to signed int 
+      f23: a open array of pointer to const pointer to signed int 
+      f24: a open array of pointer to const pointer to signed int 
+      f25: a open array of const pointer to const pointer to signed int 
+      f26: a open array of const pointer to const pointer to signed int 
+      f35: a open array of pointer to signed int 
+      f36: a open array of pointer to signed int 
+      f37: a open array of pointer to pointer to signed int 
+      f38: a open array of pointer to pointer to signed int 
+      f39: a open array of pointer to const pointer to signed int 
+      f40: a open array of pointer to const pointer to signed int 
+      f41: a open array of const pointer to const pointer to signed int 
+      f42: a open array of const pointer to const pointer to signed int 
+      f43: a open array of open array of signed int 
+      f44: a open array of open array of signed int 
+      f49: a open array of open array of pointer to signed int 
+      f50: a open array of open array of pointer to signed int 
+      f51: a open array of open array of pointer to pointer to signed int 
+      f52: a open array of open array of pointer to pointer to signed int 
+      f53: a open array of open array of pointer to const pointer to signed int 
+      f54: a open array of open array of pointer to const pointer to signed int 
+      f55: a open array of open array of const pointer to const pointer to signed int 
+      f56: a open array of open array of const pointer to const pointer to signed int 
+      f57: a open array of open array of pointer to signed int 
+      f58: a open array of open array of pointer to signed int 
+      f59: a open array of open array of pointer to pointer to signed int 
+      f60: a open array of open array of pointer to pointer to signed int 
+      f61: a open array of open array of pointer to const pointer to signed int 
+      f62: a open array of open array of pointer to const pointer to signed int 
+      f63: a open array of open array of const pointer to const pointer to signed int 
+      f64: a open array of open array of const pointer to const pointer to signed int 
+      f65: a function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+      f67: a function
+          with parameters
+            signed int 
+          returning 
+            pointer to signed int 
+
+      f68: a function
+          with parameters
+            signed int 
+          returning 
+            pointer to pointer to signed int 
+
+      f69: a function
+          with parameters
+            signed int 
+          returning 
+            pointer to const pointer to signed int 
+
+      f70: a function
+          with parameters
+            signed int 
+          returning 
+            const pointer to const pointer to signed int 
+
+      f75: a pointer to function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+      f76: a pointer to pointer to function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+      f77: a pointer to const pointer to function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+      f78: a const pointer to const pointer to function
+          with parameters
+            signed int 
+          returning 
+            signed int 
+
+      f79: a pointer to function
+          with parameters
+            signed int 
+          returning 
+            pointer to function
+                returning 
+                  signed int 
+
+
+      f80: a const pointer to function
+          with parameters
+            signed int 
+          returning 
+            pointer to function
+                returning 
+                  signed int 
+
+
+      f81: a const pointer to function
+          with parameters
+            signed int 
+          returning 
+            const pointer to function
+                returning 
+                  signed int 
+
+
+      f82: a const variable length array of signed int 
+      f83: a const open array of signed int 
+      f84: a static open array of signed int 
+      f85: a const static open array of signed int 
+      function
+          with parameters
+            const variable length array of instance of type f86 
+          returning 
+            signed int 
+
+      function
+          with parameters
+            const open array of instance of type f87 
+          returning 
+            signed int 
+
+      function
+          with parameters
+            static open array of instance of type f88 
+          returning 
+            signed int 
+
+      function
+          with parameters
+            const static open array of instance of type f89 
+          returning 
+            signed int 
+
+      f90: a const variable length array of pointer to signed int 
+      f91: a const open array of pointer to signed int 
+      f92: a static open array of pointer to pointer to signed int 
+      f93: a const static open array of pointer to const pointer to signed int 
+      f94: a const static open array of const pointer to const pointer to signed int 
+      function
+          with parameters
+            const variable length array of instance of type f95 
+          returning 
+            pointer to signed int 
+
+      function
+          with parameters
+            const open array of instance of type f96 
+          returning 
+            pointer to signed int 
+
+      function
+          with parameters
+            static open array of instance of type f97 
+          returning 
+            pointer to pointer to signed int 
+
+      function
+          with parameters
+            const static open array of instance of type f98 
+          returning 
+            pointer to const pointer to signed int 
+
+      function
+          with parameters
+            const static open array of instance of type f99 
+          returning 
+            const pointer to const pointer to signed int 
+
+      f100: a const variable length array of open array of signed int 
+      f101: a const open array of open array of signed int 
+      f102: a static open array of open array of signed int 
+      f103: a const static open array of open array of signed int 
+      function
+          with parameters
+            const variable length array of open array of instance of type f104 
+          returning 
+            signed int 
+
+      function
+          with parameters
+            const open array of open array of instance of type f105 
+          returning 
+            signed int 
+
+      function
+          with parameters
+            static open array of open array of instance of type f106 
+          returning 
+            signed int 
+
+      function
+          with parameters
+            const static open array of open array of instance of type f107 
+          returning 
+            signed int 
+
+      f108: a const variable length array of open array of pointer to signed int 
+      f109: a const open array of open array of pointer to signed int 
+      f110: a static open array of open array of pointer to pointer to signed int 
+      f111: a const static open array of open array of pointer to const pointer to signed int 
+      f112: a const static open array of open array of const pointer to const pointer to signed int 
+      function
+          with parameters
+            const variable length array of open array of instance of type f113 
+          returning 
+            pointer to signed int 
+
+      function
+          with parameters
+            const open array of open array of instance of type f114 
+          returning 
+            pointer to signed int 
+
+      function
+          with parameters
+            static open array of open array of instance of type f115 
+          returning 
+            pointer to pointer to signed int 
+
+      function
+          with parameters
+            const static open array of open array of instance of type f116 
+          returning 
+            pointer to const pointer to signed int 
+
+      function
+          with parameters
+            const static open array of open array of instance of type f117 
+          returning 
+            const pointer to const pointer to signed int 
+
+    returning 
+      signed int 
+    with body 
+
Index: translator/Tests/SynTree/Expected/VariableDeclarator.tst
===================================================================
--- translator/Tests/SynTree/Expected/VariableDeclarator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Expected/VariableDeclarator.tst	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,184 @@
+f1: a signed int 
+f2: a signed int 
+f3: a pointer to signed int 
+f4: a pointer to pointer to signed int 
+f5: a pointer to const pointer to signed int 
+f6: a const pointer to const pointer to signed int 
+f7: a pointer to signed int 
+f8: a pointer to pointer to signed int 
+f9: a pointer to const pointer to signed int 
+f10: a const pointer to const pointer to signed int 
+f11: a pointer to signed int 
+f12: a pointer to pointer to signed int 
+f13: a pointer to const pointer to signed int 
+f14: a const pointer to const pointer to signed int 
+f15: a open array of signed int 
+f16: a open array of signed int 
+f17: a open array of signed int 
+f18: a open array of signed int 
+f19: a open array of pointer to signed int 
+f20: a open array of pointer to signed int 
+f21: a open array of pointer to pointer to signed int 
+f22: a open array of pointer to pointer to signed int 
+f23: a open array of pointer to const pointer to signed int 
+f24: a open array of pointer to const pointer to signed int 
+f25: a open array of const pointer to const pointer to signed int 
+f26: a open array of const pointer to const pointer to signed int 
+f27: a open array of pointer to signed int 
+f28: a open array of pointer to signed int 
+f29: a open array of pointer to pointer to signed int 
+f30: a open array of pointer to pointer to signed int 
+f31: a open array of pointer to const pointer to signed int 
+f32: a open array of pointer to const pointer to signed int 
+f33: a open array of const pointer to const pointer to signed int 
+f34: a open array of const pointer to const pointer to signed int 
+f35: a open array of pointer to signed int 
+f36: a open array of pointer to signed int 
+f37: a open array of pointer to pointer to signed int 
+f38: a open array of pointer to pointer to signed int 
+f39: a open array of pointer to const pointer to signed int 
+f40: a open array of pointer to const pointer to signed int 
+f41: a open array of const pointer to const pointer to signed int 
+f42: a open array of const pointer to const pointer to signed int 
+f43: a open array of open array of signed int 
+f44: a open array of open array of signed int 
+f45: a open array of open array of signed int 
+f46: a open array of open array of signed int 
+f47: a open array of open array of signed int 
+f48: a open array of open array of signed int 
+f49: a open array of open array of pointer to signed int 
+f50: a open array of open array of pointer to signed int 
+f51: a open array of open array of pointer to pointer to signed int 
+f52: a open array of open array of pointer to pointer to signed int 
+f53: a open array of open array of pointer to const pointer to signed int 
+f54: a open array of open array of pointer to const pointer to signed int 
+f55: a open array of open array of const pointer to const pointer to signed int 
+f56: a open array of open array of const pointer to const pointer to signed int 
+f57: a open array of open array of pointer to signed int 
+f58: a open array of open array of pointer to signed int 
+f59: a open array of open array of pointer to pointer to signed int 
+f60: a open array of open array of pointer to pointer to signed int 
+f61: a open array of open array of pointer to const pointer to signed int 
+f62: a open array of open array of pointer to const pointer to signed int 
+f63: a open array of open array of const pointer to const pointer to signed int 
+f64: a open array of open array of const pointer to const pointer to signed int 
+f65: a function
+    with parameters
+      signed int 
+    returning 
+      signed int 
+
+f66: a function
+    with parameters
+      signed int 
+    returning 
+      signed int 
+
+f67: a function
+    with parameters
+      signed int 
+    returning 
+      pointer to signed int 
+
+f68: a function
+    with parameters
+      signed int 
+    returning 
+      pointer to pointer to signed int 
+
+f69: a function
+    with parameters
+      signed int 
+    returning 
+      pointer to const pointer to signed int 
+
+f70: a function
+    with parameters
+      signed int 
+    returning 
+      const pointer to const pointer to signed int 
+
+f71: a function
+    with parameters
+      signed int 
+    returning 
+      pointer to signed int 
+
+f72: a function
+    with parameters
+      signed int 
+    returning 
+      pointer to pointer to signed int 
+
+f73: a function
+    with parameters
+      signed int 
+    returning 
+      pointer to const pointer to signed int 
+
+f74: a function
+    with parameters
+      signed int 
+    returning 
+      const pointer to const pointer to signed int 
+
+f75: a pointer to function
+    with parameters
+      signed int 
+    returning 
+      signed int 
+
+f76: a pointer to pointer to function
+    with parameters
+      signed int 
+    returning 
+      signed int 
+
+f77: a pointer to const pointer to function
+    with parameters
+      signed int 
+    returning 
+      signed int 
+
+f78: a const pointer to const pointer to function
+    with parameters
+      signed int 
+    returning 
+      signed int 
+
+f79: a pointer to function
+    with parameters
+      signed int 
+    returning 
+      pointer to function
+          returning 
+            signed int 
+
+
+f80: a const pointer to function
+    with parameters
+      signed int 
+    returning 
+      pointer to function
+          returning 
+            signed int 
+
+
+f81: a const pointer to function
+    with parameters
+      signed int 
+    returning 
+      const pointer to function
+          returning 
+            signed int 
+
+
+z: a pointer to open array of double 
+w: a open array of pointer to char 
+v3: a pointer to open array of pointer to open array of pointer to function
+    with parameters
+      pointer to open array of pointer to open array of signed int 
+      pointer to open array of pointer to open array of signed int 
+    returning 
+      pointer to open array of pointer to open array of signed int 
+
Index: translator/Tests/SynTree/Forall.c
===================================================================
--- translator/Tests/SynTree/Forall.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Forall.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,51 @@
+typedef forall ( type T ) int (*f)( int );
+
+forall( type T )
+    void swap( T left, T right ) {
+	T temp = left;
+	left = right;
+	right = temp;
+    }
+
+context sumable( type T ) {
+    const T 0;
+    T ?+?(T, T);
+    T ?++(T);
+    [T] ?+=?(T,T);
+};
+
+type T1 | { const T1 0; T1 ?+?(T1, T1); T1 ?++(T1); [T1] ?+=?(T1,T1); },
+     T2(type P1, type P2 ),
+     T3 | sumable(T3);
+
+type T2(type P1, type P2) | sumable(T2(P1,P2)) = struct { P1 i; P2 j; };
+
+T2(int, int) w1;
+typedef T2(int, int) w2;
+w2 g2;
+type w3 = T2(int, int);
+w3 g3;
+
+forall( type T | sumable( T ) )
+    T sum( int n, T a[] ) {
+	T total = 0;
+	int i;
+	for ( i = 0; i < n; i += 1 )
+	    total = total + a[i];
+	return total;
+    }
+
+forall( type T | { const T 0; T ?+?(T, T); T ?++(T); [T] ?+=?(T,T); } )
+    T twice( T t ) {
+	return t + t;
+    }
+
+int main() {
+    int x = 1, y = 2, a[10];
+    float f;
+
+    swap( x, y );
+    twice( x, y );
+    f = min( 4.0, 3.0 );
+    sum( 10, a );
+}
Index: translator/Tests/SynTree/Functions.c
===================================================================
--- translator/Tests/SynTree/Functions.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Functions.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,163 @@
+// ANSI function definitions
+
+void h(void) {}
+
+int f (
+    int (void),
+    int (int),
+    int ((void)),
+    int ((int)),
+    void g(void)
+  ) {
+    (*g)();
+    g();
+    g = h;
+}
+
+int f1() {}
+int (f2()) {}
+int (*f3())() {}
+int *((f4())) {}
+int ((*f5()))() {}
+int *f6() {}
+int *(f7)() {}
+int **f8() {}
+int * const *(f9)() {}
+int (*f10())[] {}
+int (*f11())[][3] {}
+int ((*f12())[])[3] {}
+
+// "implicit int" type specifier (not ANSI)
+
+fII1( int i ) {}
+const fII2( int i ) {}
+extern fII3( int i ) {}
+extern const fII4( int i ) {}
+
+*fII5() {}
+const *fII6() {}
+const long *fII7() {}
+static const long *fII8() {}
+const static long *fII9() {}
+
+// K&R function definitions
+
+fO1( i ) int i; {}
+int fO2( i ) int i; {}
+const fO3( i ) int i; {}
+extern fO4( i ) int i; {}
+extern const fO5( i ) int i; {}
+
+// Cforall extensions
+
+[] f( );
+[int] f( );
+[] f(int);
+[int] f(int);
+[] f( ) {}
+[int] f( ) {}
+[] f(int) {}
+[int] f(int) {}
+
+[int x] f( );
+[] f(int x);
+[int x] f(int x);
+[int x] f( ) {}
+[] f(int x) {}
+[int x] f(int x) {}
+
+[int, int x] f( );
+[] f(int, int x);
+[int, int x] f(int, int x);
+[int, int x] f( ) {}
+[] f(int, int x) {}
+[int, int x] f(int, int x) {}
+
+[int, int x, int] f( );
+[] f(int, int x, int);
+[int, int x, int] f(int, int x, int);
+[int, int x, int] f( ) {}
+[] f(int, int x, int) {}
+[int, int x, int] f(int, int x, int) {}
+
+[int, int x, * int y] f( );
+[] f(int, int x, * int y);
+[int, int x, * int y] f(int, int x, * int y);
+[int, int x, * int y] f( ) {}
+[] f(int, int x, * int y) {}
+[int, int x, * int y] f(int, int x, * int y) {}
+
+[ int ] f11( int ), f12;  // => int f11( int ), f12( int );
+
+[int] f(
+	int ( int, int p ),
+	[int](int)
+    ) {
+    int (*(*p)[][10])[][3];
+    * [][10] * [][3] int p;
+    * [] * [int](int) p;
+}
+
+static const int *f1() {}
+static [ const int ] f2() {}
+static inline [ const * int ] f3() {}
+static inline [ const [ * int, int ] ] f4() {}
+static [ const [ * int, const int ] ] f5() {}
+
+// unnamed parameter
+
+int f(
+    int (),
+
+    int *(),
+    int **(),
+    int * const *(),
+    int * const * const (),
+
+    int ([]),
+    int ([10]),
+
+    int *([]),
+    int *([10]),
+    int **([]),
+    int **([10]),
+    int * const *([]),
+    int * const *([10]),
+    int * const * const ([]),
+    int * const * const ([10])
+    );
+
+int f(
+    int (),
+
+    int *(),
+    int **(),
+    int * const *(),
+    int * const * const (),
+
+    int ([]),
+    int ([10]),
+
+    int *([]),
+    int *([10]),
+    int **([]),
+    int **([10]),
+    int * const *([]),
+    int * const *([10]),
+    int * const * const ([]),
+    int * const * const ([10])
+    ) {
+}
+
+typedef int T;
+
+int f( T (T), T T ) {
+    T (T);
+}
+
+// errors
+
+//int f()[] {}
+//int (f[])() {}
+//int f[]() {}
+//int ((*f15())())[] {}
Index: translator/Tests/SynTree/IdentFuncDeclarator.c
===================================================================
--- translator/Tests/SynTree/IdentFuncDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/IdentFuncDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,105 @@
+int main() {
+    //int f0[]();
+    //int (f0[])();
+    //int f0()[];
+    //int f0()();
+    //int (*f0)()();
+    //int ((*f0())())[];
+    
+    int f1;
+    int (f2);
+
+    int *f3;
+    int **f4;
+    int * const *f5;
+    int * const * const f6;
+
+    int *(f7);
+    int **(f8);
+    int * const *(f9);
+    int * const * const (f10);
+
+    int (*f11);
+    int (**f12);
+    int (* const *f13);
+    int (* const * const f14);
+
+    int f15[];
+    int f16[10];
+    int (f17[]);
+    int (f18[10]);
+
+    int *f19[];
+    int *f20[10];
+    int **f21[];
+    int **f22[10];
+    int * const *f23[];
+    int * const *f24[10];
+    int * const * const f25[];
+    int * const * const f26[10];
+
+    int *(f27[]);
+    int *(f28[10]);
+    int **(f29[]);
+    int **(f30[10]);
+    int * const *(f31[]);
+    int * const *(f32[10]);
+    int * const * const (f33[]);
+    int * const * const (f34[10]);
+
+    int (*f35[]);
+    int (*f36[10]);
+    int (**f37[]);
+    int (**f38[10]);
+    int (* const *f39[]);
+    int (* const *f40[10]);
+    int (* const * const f41[]);
+    int (* const * const f42[10]);
+
+    int f43[][3];
+    int f44[3][3];
+    int (f45[])[3];
+    int (f46[3])[3];
+    int ((f47[]))[3];
+    int ((f48[3]))[3];
+
+    int *f49[][3];
+    int *f50[3][3];
+    int **f51[][3];
+    int **f52[3][3];
+    int * const *f53[][3];
+    int * const *f54[3][3];
+    int * const * const f55[][3];
+    int * const * const f56[3][3];
+
+    int (*f57[][3]);
+    int (*f58[3][3]);
+    int (**f59[][3]);
+    int (**f60[3][3]);
+    int (* const *f61[][3]);
+    int (* const *f62[3][3]);
+    int (* const * const f63[][3]);
+    int (* const * const f64[3][3]);
+
+    int f65(int);
+    int (f66)(int);
+
+    int *f67(int);
+    int **f68(int);
+    int * const *f69(int);
+    int * const * const f70(int);
+
+    int *(f71)(int);
+    int **(f72)(int);
+    int * const *(f73)(int);
+    int * const * const (f74)(int);
+
+    int (*f75)(int);
+    int (**f76)(int);
+    int (* const *f77)(int);
+    int (* const * const f78)(int);
+
+    int (*(*f79)(int))();
+    int (*(* const f80)(int))();
+    int (* const(* const f81)(int))();
+}
Index: translator/Tests/SynTree/IdentFuncParamDeclarator.c
===================================================================
--- translator/Tests/SynTree/IdentFuncParamDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/IdentFuncParamDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,150 @@
+int fred(
+    //int f0[](),
+    //int (f0[])(),
+    //int f0()[],
+    //int f0()(),
+    //int (*f0)()(),
+    //int ((*f0())())[],
+    
+    int f1,
+    int (f2),
+
+    int *f3,
+    int **f4,
+    int * const *f5,
+    int * const * const f6,
+
+    int *(f7),
+    int **(f8),
+    int * const *(f9),
+    int * const * const (f10),
+
+    int (*f11),
+    int (**f12),
+    int (* const *f13),
+    int (* const * const f14),
+
+    int f15[],
+    int f16[10],
+    int (f17[]),
+    int (f18[10]),
+
+    int *f19[],
+    int *f20[10],
+    int **f21[],
+    int **f22[10],
+    int * const *f23[],
+    int * const *f24[10],
+    int * const * const f25[],
+    int * const * const f26[10],
+
+    int *(f27[]),
+    int *(f28[10]),
+    int **(f29[]),
+    int **(f30[10]),
+    int * const *(f31[]),
+    int * const *(f32[10]),
+    int * const * const (f33[]),
+    int * const * const (f34[10]),
+
+    int (*f35[]),
+    int (*f36[10]),
+    int (**f37[]),
+    int (**f38[10]),
+    int (* const *f39[]),
+    int (* const *f40[10]),
+    int (* const * const f41[]),
+    int (* const * const f42[10]),
+
+    int f43[][3],
+    int f44[3][3],
+    int (f45[])[3],
+    int (f46[3])[3],
+    int ((f47[]))[3],
+    int ((f48[3]))[3],
+
+    int *f49[][3],
+    int *f50[3][3],
+    int **f51[][3],
+    int **f52[3][3],
+    int * const *f53[][3],
+    int * const *f54[3][3],
+    int * const * const f55[][3],
+    int * const * const f56[3][3],
+
+    int (*f57[][3]),
+    int (*f58[3][3]),
+    int (**f59[][3]),
+    int (**f60[3][3]),
+    int (* const *f61[][3]),
+    int (* const *f62[3][3]),
+    int (* const * const f63[][3]),
+    int (* const * const f64[3][3]),
+
+    int f65(int),
+    int (f66)(int),
+
+    int *f67(int),
+    int **f68(int),
+    int * const *f69(int),
+    int * const * const f70(int),
+
+    int *(f71)(int),
+    int **(f72)(int),
+    int * const *(f73)(int),
+    int * const * const (f74)(int),
+
+    int (*f75)(int),
+    int (**f76)(int),
+    int (* const *f77)(int),
+    int (* const * const f78)(int),
+
+    int (*(*f79)(int))(),
+    int (*(* const f80)(int))(),
+    int (* const(* const f81)(int))(),
+
+    int f82[const *],
+    int f83[const 3],
+    int f84[static 3],
+    int f85[static const 3],
+
+    int (f86[const *]),
+    int (f87[const 3]),
+    int (f88[static 3]),
+    int (f89[static const 3]),
+
+    int *f90[const *],
+    int *f91[const 3],
+    int **f92[static 3],
+    int * const *f93[static const 3],
+    int * const * const f94[static const 3],
+
+    int *(f95[const *]),
+    int *(f96[const 3]),
+    int **(f97[static 3]),
+    int * const *(f98[static const 3]),
+    int * const * const (f99[static const 3]),
+
+    int f100[const *][3],
+    int f101[const 3][3],
+    int f102[static 3][3],
+    int f103[static const 3][3],
+
+    int (f104[const *][3]),
+    int (f105[const 3][3]),
+    int (f106[static 3][3]),
+    int (f107[static const 3][3]),
+
+    int *f108[const *][3],
+    int *f109[const 3][3],
+    int **f110[static 3][3],
+    int * const *f111[static const 3][3],
+    int * const * const f112[static const 3][3],
+
+    int *(f113[const *][3]),
+    int *(f114[const 3][3]),
+    int **(f115[static 3][3]),
+    int * const *(f116[static const 3][3]),
+    int * const * const (f117[static const 3][3])
+    ) {
+}
Index: translator/Tests/SynTree/Initialization.c
===================================================================
--- translator/Tests/SynTree/Initialization.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Initialization.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,27 @@
+// Cforall extensions
+
+int * x21 = 0, x22 = 0;
+int * x21 = 0, x22 = 0;
+
+[20] int y1, y2 = { 1, 2, 3 };
+
+// designators
+
+struct {
+    [int] w;
+} a = { .w : [2] };
+
+struct { int a[3], b; } w [] = { [0].a : {1}, [0].b : 1, [1].a[0] : 2 };
+
+struct {
+    int f1, f2, f3;
+    struct { int g1, g2, g3; } f4[4];
+} v7 = {
+    .f1 : 4,
+    f2 : 3,
+    .f4[2] : {
+	.g1 : 3,
+	g3 : 0,
+    },
+    .f4[3].g3 : 7,
+};
Index: translator/Tests/SynTree/Makefile
===================================================================
--- translator/Tests/SynTree/Makefile	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Makefile	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,2 @@
+all:
+	sh run-tests.sh
Index: translator/Tests/SynTree/Scope.c
===================================================================
--- translator/Tests/SynTree/Scope.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Scope.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,69 @@
+int x;
+typedef double y;
+typedef float t;
+y z;
+type u = struct { int a; double b; };
+int f( int y );
+y q;
+
+y w(y y, u v) {
+  type x | { x t(u); };
+  u u = y;
+  x z = t(u);
+}
+
+y p;
+
+context has_u( type z )
+{
+  z u(z);
+};
+
+forall( type t | has_u( t ) )
+y q( t the_t )
+{
+  t y = u( the_t );
+}
+
+t f( y p ) {
+  int y;
+  typedef char x;
+
+  {
+    x y;
+    typedef x z;
+
+    {
+      z x;
+      typedef z y;
+      y z = x;
+    }
+
+    z x = y;
+  }
+
+  x q = y;
+}
+
+t g( void ) {
+  typedef char x;
+  try {
+    some_func();
+  } catch ( x x ) {
+    t y = x;
+  }
+  x z;
+}
+
+y q(i)
+    int i;
+{
+  switch (i) {
+    y q = i;
+  case 0:
+    return q;
+  default:
+    return i;
+  }
+}
+
Index: translator/Tests/SynTree/ScopeErrors.c
===================================================================
--- translator/Tests/SynTree/ScopeErrors.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/ScopeErrors.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,26 @@
+int thisIsAnError;
+int thisIsAnError;
+
+int thisIsNotAnError;
+float thisIsNotAnError;
+
+int thisIsAlsoNotAnError()
+{
+  int thisIsNotAnError;
+}
+
+int thisIsAlsoNotAnError( double x )
+{
+}
+
+double thisIsStillNotAnError( double );
+double thisIsStillNotAnError( double );
+
+double butThisIsAnError( double )
+{
+}
+
+double butThisIsAnError( double )
+{
+}
+
Index: translator/Tests/SynTree/StructMember.c
===================================================================
--- translator/Tests/SynTree/StructMember.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/StructMember.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,40 @@
+typedef int T;
+
+struct S {
+    int m1:3, m2:4;
+    int :2;
+    int :3, :4;
+    int m3;
+    int m4, m5, m6;
+    int *m7, *m8, *m9;
+    int (*m10)();
+    int *(*m11)(int);
+    T T;
+    T (T);
+
+// Cforall extensions
+
+    * int m12, m13;
+    * [ * int ] (int) m14;
+    int ;
+    int , , ;
+    int * , , ;
+    int *, *, *;
+    * int , , ;
+    int (*)();
+    int (**)( int );
+    T ;
+
+// errors
+
+//    void f(void);
+};
+
+struct S s;
+
+union U {
+    [5] int m1;
+    int m2[5];
+    * int m3;
+    int *m4;
+} u;
Index: translator/Tests/SynTree/Tuple.c
===================================================================
--- translator/Tests/SynTree/Tuple.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Tuple.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,62 @@
+int f( int, int );
+int g( int, int, int );
+static [ int, int, int, int ] h( int a, int b, * int c, [] char d );
+
+struct inner {
+    int f2, f3;
+};
+
+struct outer {
+    int f1;
+    struct inner i;
+    double f4;
+} s, *sp;
+
+const volatile [ int, int ] t1;
+static const [ int, const int ] t2;
+const static [ int, const int ] t3;
+
+[ int rc ] printf( * char fmt, ... );
+int printf( char *fmt, ... );
+
+[ short x, unsigned y ] f1( int w ) {
+    [ y, x ] = [ x, y ] = [ w, 23 ];
+}
+
+[ [ int, char, long, int ] r ] g1() {
+    short x, p;
+    unsigned int y;
+    [ int, int ] z;
+
+    [ x, y, z ] = [ p, f( 17 ), 3 ];
+    r = [ x, y, z ];
+}
+
+[ int rc ] main( int argc, ** char argv ) {
+    int a, b, c, d;
+    struct outer t = { .[ f1,f4 ] : [ 1,7.0 ] };
+    f( [ 3,5 ] );
+    g( [ 3,5 ], 3 );
+    f( t1 );
+    g( t1, 3 );
+    [ 3,5 ];
+    [ a,b ] = 3;
+    [ a,b ] = [ 4.6 ];
+    [ a,b ] = [ c,d ] = [ 3,5 ];
+    [ a,b,[ c ] ] = [ 2,[ a,b ] ];
+    [ a,b ] = 3 > 4 ? [ b,6 ] : [ 7,8 ];
+
+    t1 = [ a,b ];
+    t1 = t2 = [ a,b ];
+    [ a,b ] = [ c,d ] = d += c += 1;
+    [ a,b ] = [ c,d ] = t1;
+    [ a,b ] = t1 = [ c,d ];
+    [ a,b ] = t1 = t2 = [ c,d ];
+    t1 = [ 3,4 ] = [ 3,4 ] = t1 = [ 3,4 ];
+
+    s.[ f1, i.[ f2, f3 ], f4 ] = [ 11, 12, 13, 3.14159 ];
+    s.[ f1, i.[ f2, f3 ], f4 ] = h( 3, 3, 0, "abc" );
+    sp->[ f4,f1 ] = sp->[ f1,f4 ];
+    printf( "expecting 3, 17, 23, 4; got %d, %d, %d, %d\n", s.[ f4, i.[ f3,f2 ], f1 ] );
+    rc = 0;
+}
Index: translator/Tests/SynTree/TypeGenerator.c
===================================================================
--- translator/Tests/SynTree/TypeGenerator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/TypeGenerator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,19 @@
+context addable(type T) {
+   T ?+?(T,T);
+};
+
+type List(type T | addable(T) ) | addable(T) = struct { T data; List(T) *next; } *;
+typedef List(int) ListOfIntegers;
+ListOfIntegers li;
+int f( List(int) ((*g))(int) );
+[int] h( * List(int) p ); // new declaration syntax
+
+struct(type T | addable(T) ) node { T data; struct(T) node *next; };
+type List(type T) = struct(T) node *;
+List(int) my_list;
+
+type Complex | addable(Complex);
+
+int main() {
+    (struct(int) node)my_list;
+}
Index: translator/Tests/SynTree/Typedef.c
===================================================================
--- translator/Tests/SynTree/Typedef.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/Typedef.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,41 @@
+typedef int T;
+
+void f( void ) {
+    int T( T );
+    T( 3 );
+}
+
+struct {
+    T (T);
+} fred = { 3 };
+
+typedef int (*a)(int, char);
+a b;
+
+int g(void) {
+    double a;
+}
+a c;
+
+// typedef x = 3, y = 3;  /* GCC */
+
+// x p;
+// y q;
+
+int main() {
+//    typedef z = p = 3;
+}
+
+/* new-style function definitions */
+
+typedef [10] * int arrayOf10Pointers;
+arrayOf10Pointers x;
+typedef const * int constantPointer;
+typedef * [ int ]( [] int ) funcPtr;
+typedef [ int ] funcProto( []  int );
+typedef [ int, int ] tupleType;
+typedef * [ int, int ] tupleTypePtr;
+typedef * int a, b;
+typedef [ int ] f( * int ), g;
+typedef [ * [static 10] int ] t;
+typedef [ * [static 10] int x ] f();
Index: translator/Tests/SynTree/TypedefDeclarator.c
===================================================================
--- translator/Tests/SynTree/TypedefDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/TypedefDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,116 @@
+typedef int
+     f0,  f1,  f2,  f3,  f4,  f5,  f6,  f7,  f8,  f9,
+    f10, f11, f12, f13, f14, f15, f16, f17, f18, f19,
+    f20, f21, f22, f23, f24, f25, f26, f27, f28, f29,
+    f30, f31, f32, f33, f34, f35, f36, f37, f38, f39,
+    f40, f41, f42, f43, f44, f45, f46, f47, f48, f49,
+    f50, f51, f52, f53, f54, f55, f56, f57, f58, f59,
+    f60, f61, f62, f63, f64, f65, f66, f67, f68, f69,
+    f70, f71, f72, f73, f74, f75, f76, f77, f78, f79,
+    f80, f81, f82, f83, f84, f85, f86, f87, f88, f89;
+
+int main() {
+    //int f0[]();
+    //int (f0[])();
+    //int f0()[];
+    //int f0()();
+    //int (*f0)()();
+    //int ((*f0())())[];
+    
+    int f1;
+    int (f2);
+
+    int *f3;
+    int **f4;
+    int * const *f5;
+    int * const * const f6;
+
+    int *(f7);
+    int **(f8);
+    int * const *(f9);
+    int * const * const (f10);
+
+    int (*f11);
+    int (**f12);
+    int (* const *f13);
+    int (* const * const f14);
+
+    int f15[];
+    int f16[10];
+    int (f17[]);
+    int (f18[10]);
+
+    int *f19[];
+    int *f20[10];
+    int **f21[];
+    int **f22[10];
+    int * const *f23[];
+    int * const *f24[10];
+    int * const * const f25[];
+    int * const * const f26[10];
+
+    int *(f27[]);
+    int *(f28[10]);
+    int **(f29[]);
+    int **(f30[10]);
+    int * const *(f31[]);
+    int * const *(f32[10]);
+    int * const * const (f33[]);
+    int * const * const (f34[10]);
+
+    int (*f35[]);
+    int (*f36[10]);
+    int (**f37[]);
+    int (**f38[10]);
+    int (* const *f39[]);
+    int (* const *f40[10]);
+    int (* const * const f41[]);
+    int (* const * const f42[10]);
+
+    int f43[][3];
+    int f44[3][3];
+    int (f45[])[3];
+    int (f46[3])[3];
+    int ((f47[]))[3];
+    int ((f48[3]))[3];
+
+    int *f49[][3];
+    int *f50[3][3];
+    int **f51[][3];
+    int **f52[3][3];
+    int * const *f53[][3];
+    int * const *f54[3][3];
+    int * const * const f55[][3];
+    int * const * const f56[3][3];
+
+    int (*f57[][3]);
+    int (*f58[3][3]);
+    int (**f59[][3]);
+    int (**f60[3][3]);
+    int (* const *f61[][3]);
+    int (* const *f62[3][3]);
+    int (* const * const f63[][3]);
+    int (* const * const f64[3][3]);
+
+    int f65(int);
+    int (f66)(int);
+
+    int *f67(int);
+    int **f68(int);
+    int * const *f69(int);
+    int * const * const f70(int);
+
+    int *(f71)(int);
+    int **(f72)(int);
+    int * const *(f73)(int);
+    int * const * const (f74)(int);
+
+    int (*f75)(int);
+    int (**f76)(int);
+    int (* const *f77)(int);
+    int (* const * const f78)(int);
+
+    int (*(*f79)(int))();
+    int (*(* const f80)(int))();
+    int (* const(* const f81)(int))();
+}
Index: translator/Tests/SynTree/TypedefParamDeclarator.c
===================================================================
--- translator/Tests/SynTree/TypedefParamDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/TypedefParamDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,150 @@
+typedef int
+     f0,   f1,   f2,   f3,   f4,   f5,   f6,   f7,   f8,   f9,
+    f10,  f11,  f12,  f13,  f14,  f15,  f16,  f17,  f18,  f19,
+    f20,  f21,  f22,  f23,  f24,  f25,  f26,  f27,  f28,  f29,
+    f30,  f31,  f32,  f33,  f34,  f35,  f36,  f37,  f38,  f39,
+    f40,  f41,  f42,  f43,  f44,  f45,  f46,  f47,  f48,  f49,
+    f50,  f51,  f52,  f53,  f54,  f55,  f56,  f57,  f58,  f59,
+    f60,  f61,  f62,  f63,  f64,  f65,  f66,  f67,  f68,  f69,
+    f70,  f71,  f72,  f73,  f74,  f75,  f76,  f77,  f78,  f79,
+    f80,  f81,  f82,  f83,  f84,  f85,  f86,  f87,  f88,  f89,
+    f90,  f91,  f92,  f93,  f94,  f95,  f96,  f97,  f98,  f99,
+    f100, f101, f102, f103, f104, f105, f106, f107, f108, f109,
+    f110, f111, f112, f113, f114, f115, f116, f117, f118, f119;
+
+int fred(
+/*
+    //int f0[](),
+    //int (f0[])(),
+    //int f0()[],
+    //int f0()(),
+    //int (*f0)()(),
+    //int ((*f0())())[],
+*/
+    int f1,
+
+    int *f3,
+    int **f4,
+    int * const *f5,
+    int * const * const f6,
+
+    int (*f11),
+    int (**f12),
+    int (* const *f13),
+    int (* const * const f14),
+
+    int f15[],
+    int f16[10],
+
+    int *f19[],
+    int *f20[10],
+    int **f21[],
+    int **f22[10],
+    int * const *f23[],
+    int * const *f24[10],
+    int * const * const f25[],
+    int * const * const f26[10],
+
+    int (*f35[]),
+    int (*f36[10]),
+    int (**f37[]),
+    int (**f38[10]),
+    int (* const *f39[]),
+    int (* const *f40[10]),
+    int (* const * const f41[]),
+    int (* const * const f42[10]),
+
+    int f43[][3],
+    int f44[3][3],
+/*
+    int (f45[])[3],
+    int (f46[3])[3],
+    int ((f47[]))[3],
+    int ((f48[3]))[3],
+*/
+    int *f49[][3],
+    int *f50[3][3],
+    int **f51[][3],
+    int **f52[3][3],
+    int * const *f53[][3],
+    int * const *f54[3][3],
+    int * const * const f55[][3],
+    int * const * const f56[3][3],
+
+    int (*f57[][3]),
+    int (*f58[3][3]),
+    int (**f59[][3]),
+    int (**f60[3][3]),
+    int (* const *f61[][3]),
+    int (* const *f62[3][3]),
+    int (* const * const f63[][3]),
+    int (* const * const f64[3][3]),
+
+    int f65(int),
+/*
+    int (f66)(int),
+*/
+    int *f67(int),
+    int **f68(int),
+    int * const *f69(int),
+    int * const * const f70(int),
+/*
+    int *(f71)(int),
+    int **(f72)(int),
+    int * const *(f73)(int),
+    int * const * const (f74)(int),
+*/
+    int (*f75)(int),
+    int (**f76)(int),
+    int (* const *f77)(int),
+    int (* const * const f78)(int),
+
+    int (*(*f79)(int))(),
+    int (*(* const f80)(int))(),
+    int (* const(* const f81)(int))(),
+
+    int f82[const *],
+    int f83[const 3],
+    int f84[static 3],
+    int f85[static const 3],
+
+    int (f86[const *]),
+    int (f87[const 3]),
+    int (f88[static 3]),
+    int (f89[static const 3]),
+
+    int *f90[const *],
+    int *f91[const 3],
+    int **f92[static 3],
+    int * const *f93[static const 3],
+    int * const * const f94[static const 3],
+
+    int *(f95[const *]),
+    int *(f96[const 3]),
+    int **(f97[static 3]),
+    int * const *(f98[static const 3]),
+    int * const * const (f99[static const 3]),
+
+    int f100[const *][3],
+    int f101[const 3][3],
+    int f102[static 3][3],
+    int f103[static const 3][3],
+
+    int (f104[const *][3]),
+    int (f105[const 3][3]),
+    int (f106[static 3][3]),
+    int (f107[static const 3][3]),
+
+    int *f108[const *][3],
+    int *f109[const 3][3],
+    int **f110[static 3][3],
+    int * const *f111[static const 3][3],
+    int * const * const f112[static const 3][3],
+
+    int *(f113[const *][3]),
+    int *(f114[const 3][3]),
+    int **(f115[static 3][3]),
+    int * const *(f116[static const 3][3]),
+    int * const * const (f117[static const 3][3])
+    ) {
+}
Index: translator/Tests/SynTree/VariableDeclarator.c
===================================================================
--- translator/Tests/SynTree/VariableDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/VariableDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,115 @@
+int f1;
+int (f2);
+
+int *f3;
+int **f4;
+int * const *f5;
+int * const * const f6;
+
+int *(f7);
+int **(f8);
+int * const *(f9);
+int * const * const (f10);
+
+int (*f11);
+int (**f12);
+int (* const *f13);
+int (* const * const f14);
+
+int f15[];
+int f16[10];
+int (f17[]);
+int (f18[10]);
+
+int *f19[];
+int *f20[10];
+int **f21[];
+int **f22[10];
+int * const *f23[];
+int * const *f24[10];
+int * const * const f25[];
+int * const * const f26[10];
+
+int *(f27[]);
+int *(f28[10]);
+int **(f29[]);
+int **(f30[10]);
+int * const *(f31[]);
+int * const *(f32[10]);
+int * const * const (f33[]);
+int * const * const (f34[10]);
+
+int (*f35[]);
+int (*f36[10]);
+int (**f37[]);
+int (**f38[10]);
+int (* const *f39[]);
+int (* const *f40[10]);
+int (* const * const f41[]);
+int (* const * const f42[10]);
+
+int f43[][3];
+int f44[3][3];
+int (f45[])[3];
+int (f46[3])[3];
+int ((f47[]))[3];
+int ((f48[3]))[3];
+
+int *f49[][3];
+int *f50[3][3];
+int **f51[][3];
+int **f52[3][3];
+int * const *f53[][3];
+int * const *f54[3][3];
+int * const * const f55[][3];
+int * const * const f56[3][3];
+
+int (*f57[][3]);
+int (*f58[3][3]);
+int (**f59[][3]);
+int (**f60[3][3]);
+int (* const *f61[][3]);
+int (* const *f62[3][3]);
+int (* const * const f63[][3]);
+int (* const * const f64[3][3]);
+
+int f65(int);
+int (f66)(int);
+
+int *f67(int);
+int **f68(int);
+int * const *f69(int);
+int * const * const f70(int);
+
+int *(f71)(int);
+int **(f72)(int);
+int * const *(f73)(int);
+
+int * const * const (f74)(int);
+
+int (*f75)(int);
+int (**f76)(int);
+int (* const *f77)(int);
+int (* const * const f78)(int);
+
+int (*(*f79)(int))();
+int (*(* const f80)(int))();
+int (* const(* const f81)(int))();
+
+// errors
+
+//int fe0[]();				// array of functions
+//int (fe1[])();				// array of functions
+//int fe2()[];				// returning an array
+//int fe3()();				// returning a function
+//int (*fe4)()();				// returning a function
+//int ((*fe5())())[];			// returning an array
+
+// Cforall extensions
+
+* [20] double z;
+[20] * char w;
+
+// function pointer
+
+*[]*[]* [ *[]*[] int ]( *[]*[] int, *[]*[] int ) v3;
Index: translator/Tests/SynTree/make-rules
===================================================================
--- translator/Tests/SynTree/make-rules	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/make-rules	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,21 @@
+CFA = ../../cfa-cpp
+
+DIFF = diff#/software/gnu/bin/diff
+
+# Basic SynTree printing
+EXPECTED := ${wildcard $(EXPECTDIR)/*.tst}
+TESTS := $(EXPECTED:$(EXPECTDIR)/%=$(OUTPUTDIR)/%)
+TEST_IN := $(TESTS:.tst=.c)
+
+$(OUTPUTDIR)/%.tst:%.c $(CFA)
+	$(CFA) $(CFAOPT) < $< > $@ 2>&1
+
+$(OUTPUTDIR)/report: $(TESTS) $(EXPECTED)
+	rm -f $@
+	@for i in $(TESTS); do \
+	  echo "---"`basename $$i`"---" | tee -a $@; \
+	  $(DIFF) -B -w $(EXPECTDIR)/`basename $$i` $$i | tee -a $@; \
+	done
+
+clean:
+	rm -rf $(OUTPUTDIR)
Index: translator/Tests/SynTree/run-tests.sh
===================================================================
--- translator/Tests/SynTree/run-tests.sh	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/SynTree/run-tests.sh	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,10 @@
+#!/bin/sh -v
+
+dotest() {
+  mkdir -p Output$1
+  OUTPUTDIR=Output$1 EXPECTDIR=Expected$1 CFAOPT=$2 make -f make-rules $3
+}
+
+dotest "" -ns "$*"
+dotest -SymTab -nm "$*"
+#dotest -Validate -v "$*"
Index: translator/Tests/Syntax/Array.c
===================================================================
--- translator/Tests/Syntax/Array.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/Array.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,33 @@
+int a1[];
+int a2[*];
+int a4[3];
+
+int m1[][3];
+int m2[*][*];
+int m4[3][3];
+
+typedef int T;
+
+int fred() {
+    int a1[];
+    int a2[*];
+    int a4[3];
+    int T[3];
+}
+
+int mary( int T[3],
+	  int p1[const 3],
+	  int p2[static 3],
+	  int p3[static const 3]
+    ) {
+}
+
+int (*tom())[3] {
+}
+
+int (*(jane)())( int T[3],
+		 int p1[const 3],
+		 int p2[static 3],
+		 int p3[static const 3]
+    ) {
+}
Index: translator/Tests/Syntax/AsmName.c
===================================================================
--- translator/Tests/Syntax/AsmName.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/AsmName.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,14 @@
+extern int x asm( "xx" );
+
+int fred( int x ) {
+    static int y asm( "yy" );
+
+// Cforall extensions
+
+    static * int z asm( "zz" );
+}
+
+// errors
+
+//typedef int t asm( "tt" );
+//int mary( int p asm( "pp" ) ) {}
Index: translator/Tests/Syntax/Attributes.c
===================================================================
--- translator/Tests/Syntax/Attributes.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/Attributes.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,22 @@
+int @max = 3;
+
+int main() {
+    int x;
+    type @type(type t);		// compiler intrinsic
+    type @widest(type t);
+    @type(x) *y;		// gcc: typeof(x) *y;
+    const @widest(double) *w;	// gcc: const typeof(x) *w;
+    * @type(3 + 4) z;		// cfa declaration syntax
+    y = @max;		
+    z = @max(x) + @size(int);
+    y = @min(3 + 4);
+    if ( @const(x) ) { }
+    if ( @volatile(y) ) { }
+    if ( @extern(y) ) { }
+    if ( @static(y) ) { }
+    @max;
+}
+
+int @foo(int) {
+    return 7;
+}
Index: translator/Tests/Syntax/CharStringConstants.c
===================================================================
--- translator/Tests/Syntax/CharStringConstants.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/CharStringConstants.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,82 @@
+int main() {
+// character constants
+
+    ' ';
+    'a';
+    '"';
+    '_';
+
+    '\a';				// simple escape
+    '\b';
+    '\e';				// GCC
+    '\f';
+    '\n';
+    '\r';
+    '\t';
+    '\v';
+    '\'';
+    '\"'; //"
+    '\?';
+    '\\';
+
+    '\0';				// octal escape
+    '\377';
+
+    '\xf';				// hex escape
+    '\xff';
+
+// warnings/errors
+
+    '';					// empty character
+    'aa';				// multi-character
+    'a\na';				// multi-character, embedded escape
+    'a\0a';
+    '\xfff';				// hex escape out of range
+    '_\377_';				// multi-character
+    '_\xff_';
+    '\xffff';				// hex escape out of range
+    'a\xff34w';
+    '\xf_f';				// multi-character
+    '\xff_ff';
+
+// string constants
+
+    " ";
+    "a";
+    "'";
+    '_';
+
+    "\a";				// simple escape
+    "\b";
+    "\e";				// GCC
+    "\f";
+    "\n";
+    "\r";
+    "\t";
+    "\v";
+    "\'";
+    "\"";
+    "\?";
+    "\\";
+
+    "\0";				// octal escape
+    "\377";
+
+    "\xf";				// hex escape
+    "\xff";
+
+    "";
+    "aa";
+    "a\na";
+    "a\0a";
+    "_\377_";
+    "_\xff_";
+    "\xf_f";
+    "\xff_ff";
+
+// warnings/errors
+
+    "\xfff";				// hex escape out of range
+    "a\xff34w";
+    "\xffff";
+}
Index: translator/Tests/Syntax/CommentMisc.c
===================================================================
--- translator/Tests/Syntax/CommentMisc.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/CommentMisc.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,44 @@
+/* single line */
+// single line
+
+// single line containing */
+// single line containing /*
+// single line containing /* */
+
+/* 1st */ int i;
+int i; /* 2nd */
+/* 1st */ int i; /* 2nd */
+/* 1st */ /* 2nd */
+
+/* 1st
+   2nd */ int i;
+
+/*
+*/
+
+/*
+
+*/
+
+/*
+  1st
+*/
+
+/*
+  1st
+  2nd
+*/
+
+// ignore preprocessor directives
+
+#line 2
+ #
+ #include <fred>
+	#define mary abc
+
+// alternative ANSI99 brackets
+
+int main() <%
+    int x<:10:>;
+%>
+
Index: translator/Tests/Syntax/Constant0-1.c
===================================================================
--- translator/Tests/Syntax/Constant0-1.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/Constant0-1.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,73 @@
+// Cforall extension
+
+int fred() {
+
+// value
+    {
+	int 0;
+	const int 0;
+	int 1;
+	const int 1;
+    }
+    static const int 0;
+    static const int 1;
+    {
+	int 0, 1;
+	const int 0, 1;
+    }
+    {
+	int (0), (1);
+    }
+    {
+	int ((0)), ((1));
+    }
+    {
+	static const int 0, 1;
+    }
+    {
+	struct { int i; } 0;
+	const struct { int i; } 1;
+    }
+    static const struct { int i; } 1;
+
+// pointer
+
+    {
+	int *0, *1;
+    }
+    {
+	int *(0), *(1);
+    }
+    {
+	int (*0), (*1);
+    }
+    {
+	int ((*0)), ((*1));
+    }
+    {
+	int * const (0), * const 1;
+    }
+    {
+	int (* const 0), (* const 1);
+    }
+    {
+	int ((* const 0)), ((* const 1));
+    }
+    struct { int i; } *0;
+
+// Cforall style
+
+    {
+	* int x, 0;
+	const * int x, 0;
+    }
+    static const * int x, 0;
+    * struct { int i; } 0;
+    const * struct { int i; } 0;
+    static const * struct { int i; } 0;
+    {
+	static * int x, 0;
+	static const * int x, 0;
+    }
+    const * * int x, 0;
+}
Index: translator/Tests/Syntax/DeclarationSpecifier.c
===================================================================
--- translator/Tests/Syntax/DeclarationSpecifier.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/DeclarationSpecifier.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,97 @@
+typedef short int Int;
+
+
+const short int volatile x1;
+static const short int volatile x2;
+const static short int volatile x3;
+const short static int volatile x4;
+const static volatile short int x4;
+const short int static volatile x5;
+const short int volatile static x6;
+const short volatile int static x7;
+short int volatile static const x8;
+
+const volatile struct { int i; } x10;
+const struct { int i; } volatile x11;
+struct { int i; } const volatile x12;
+static const volatile struct { int i; } x13;
+const static struct { int i; } volatile x14;
+struct { int i; } static const volatile x15;
+struct { int i; } const static volatile x16;
+struct { int i; } const volatile static x17;
+
+const Int volatile x20;
+static const Int volatile x21;
+const static Int volatile x22;
+const static Int volatile x23;
+const Int static volatile x24;
+const Int volatile static x25;
+const volatile Int static x26;
+Int volatile static const x27;
+
+const volatile struct { Int i; } x29;
+const struct { Int i; } volatile x30;
+struct { Int i; } const volatile x31;
+static const volatile struct { Int i; } x32;
+const static struct { Int i; } volatile x33;
+struct { Int i; } static const volatile x34;
+struct { Int i; } const static volatile x35;
+struct { Int i; } const volatile static x36;
+
+
+const static inline const volatile int f01();		// duplicate const
+volatile inline const volatile static int f02();	// duplicate volatile
+const inline const volatile int static f03();		// duplicate const
+volatile inline static const volatile int f04();	// duplicate volatile
+const static const inline volatile int f05();		// duplicate const
+volatile static const volatile inline int f06();	// duplicate volatile
+const static const volatile int inline f07();		// duplicate const
+volatile static const int inline volatile f08();	// duplicate volatile
+
+static inline const volatile int f11();
+inline const volatile static int f12();
+inline const volatile int static f13();
+inline static const volatile int f14();
+static const inline volatile int f15();
+static const volatile inline int f16();
+static const volatile int inline f17();
+static const int inline volatile f18();
+
+short static inline const volatile int f21();
+inline short const volatile static int f22();
+inline const short volatile int static f23();
+inline static const short volatile int f24();
+static const inline volatile short int f25();
+static const volatile inline int short f26();
+static const volatile int inline short f27();
+static const int inline volatile short f28();
+
+static inline const volatile struct { int i; } f31();
+inline const volatile static struct { int i; } f32();
+inline const volatile struct { int i; } static f33();
+inline static const volatile struct { int i; } f34();
+static const inline volatile struct { int i; } f35();
+static const volatile inline struct { int i; } f36();
+static const volatile struct { int i; } inline f37();
+static const struct { int i; } inline volatile f38();
+
+static inline const volatile Int f41();
+inline const volatile static Int f42();
+inline const volatile Int static f43();
+inline static const volatile Int f44();
+static const inline volatile Int f45();
+static const volatile inline Int f46();
+static const volatile Int inline f47();
+static const Int inline volatile f48();
+
+long long ll;
+long long int lli;
+double _Complex dc;
+long double _Complex lfc;
+
+// errors
+
+//static short int volatile static const e1;		// duplicate static
+//struct { int i; } const static volatile static e2;	// duplicate static
+//struct { int i; } const static volatile static volatile e3; // duplicate static & volatile
+//static Int volatile static const e4;			// duplicate static
Index: translator/Tests/Syntax/Exception.c
===================================================================
--- translator/Tests/Syntax/Exception.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/Exception.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,24 @@
+int fred() {
+    int x;
+    throw 3;
+    throw x = 5;
+
+    try {
+    } catch( int i ) {}
+
+    try {
+	x/4;
+    } catch( int) {
+    } catch( int x ) {
+    } catch( struct { int i; } ) {
+    } catch( struct { int i; } x ) {
+    } catch( struct { int i; } *x ) {
+
+// Cforall extensions
+
+    } catch( * struct { int i; } ) {
+    } catch( * struct { int i; } x ) {
+    } catch( ... ) {
+//    } finally {
+    } // try
+}
Index: translator/Tests/Syntax/Expression.c
===================================================================
--- translator/Tests/Syntax/Expression.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/Expression.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,67 @@
+int fred() {
+    struct s { int i; } *p;
+    int i;
+
+    // order of evaluation (GCC is different)
+/*
+    i = sizeof( (int){3} );
+    i = sizeof (int){3};
+*/
+    // operators
+
+    !i;
+    ~i;
+    +i;
+    -i;
+    *p;
+    ++p;
+    --p;
+    p++;
+    p--;
+
+    i+i;
+    i-i;
+    i*i;
+
+    i/i;
+    i%i;
+    i^i;
+    i&i;
+    i|i;
+    i<i;
+    i>i;
+    i=i;
+
+    i==i;
+    i!=i;
+    i<<i;
+    i>>i;
+    i<=i;
+    i>=i;
+    i&&i;
+    i||i;
+    p->i;
+    i+=i;
+    i-=i;
+    i*=i;
+    i/=i;
+    i%=i;
+    i&=i;
+    i|=i;
+    i^=i;
+    i<<=i;
+    i>>=i;
+
+    i?i:i;
+
+    // cast
+/*
+    double d;
+    int *ip;
+    (int *) i;
+    (* int) i;
+    ([char, int *])[d, d];
+    [i,ip,ip] = ([int, * int, int *])[1,(void *)2,(void *)3];
+    [i,ip,ip] = ([int, * int, int *])([1,(void *)2,(void *)3]);
+*/
+}
Index: translator/Tests/Syntax/Forall.c
===================================================================
--- translator/Tests/Syntax/Forall.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/Forall.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,56 @@
+typedef forall ( type T ) int (*f)( int );
+
+forall( type T )
+    void swap( T left, T right ) {
+	T temp = left;
+	left = right;
+	right = temp;
+    }
+
+context sumable( type T ) {
+    const T 0;
+    T ?+?(T, T);
+    T ?++(T*);
+    [T] ?+=?(T*,T);
+};
+
+type T1 | { const T1 0; T1 ?+?(T1, T1); T1 ?++(T1); [T1] ?+=?(T1,T1); },
+     T2(type P1, type P2 ) | (type Q, type W){ const Q 0; W ?+?(W, W); Q ?++(W); [Q] ?+=?(W,W); }(T1,T2(T1,f)),
+     T3 | sumable(T3);
+
+type T2(type P1, type P2) | sumable(T2(P1,P2)) = struct { P1 i; P2 j; };
+
+T2(int, int) w1;
+typedef T2(int, int) w2;
+w2 g2;
+type w3 = T2(int, int);
+w3 g3;
+
+forall( type T | sumable( T ) )
+    T sum( int n, T a[] ) {
+	T total = 0;
+	int i;
+	for ( i = 0; i < n; i += 1 )
+	    total = total + a[i];
+	return total;
+    }
+
+forall( type T | { T ?+?(T, T); T ?++(T*); [T] ?+=?(T*,T); } )
+    T twice( T t ) {
+	return t + t;
+    }
+
+forall( type T | { const T 0; int ?!=?(T, T); int ?<?(T, T); } )
+    T min( T t1, T t2 ) {
+	return t1 < t2 ? t1 : t2;
+    }
+
+int main() {
+    int x = 1, y = 2, a[10];
+    float f;
+
+    swap( x, y );
+    twice( x );
+    f = min( 4.0, 3.0 );
+    sum( 10, a );
+}
Index: translator/Tests/Syntax/Functions.c
===================================================================
--- translator/Tests/Syntax/Functions.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/Functions.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,165 @@
+// ANSI function definitions
+
+void h(void) {}
+
+int f (
+    int p1(void),
+    int p2(int),
+    int (p3(void)),
+    int (p4(int)),
+    void g(void)
+  ) {
+    (*g)();
+    g();
+    g = h;
+}
+
+int f1() {}
+int (f2()) {}
+int (*f3())() {}
+int *((f4())) {}
+int ((*f5()))() {}
+int *f6() {}
+int *(f7)() {}
+int **f8() {}
+int * const *(f9)() {}
+int (*f10())[] {}
+int (*f11())[][3] {}
+int ((*f12())[])[3] {}
+
+// "implicit int" type specifier (not ANSI)
+
+fII1( int i ) {}
+const fII2( int i ) {}
+extern fII3( int i ) {}
+extern const fII4( int i ) {}
+
+*fII5() {}
+const *fII6() {}
+const long *fII7() {}
+static const long *fII8() {}
+const static long *fII9() {}
+
+// K&R function definitions
+
+fO1( i ) int i; {}
+int fO2( i ) int i; {}
+const fO3( i ) int i; {}
+extern fO4( i ) int i; {}
+extern const fO5( i ) int i; {}
+
+// Cforall extensions
+#if 1
+[] f( );
+[int] f( );
+[] f(int);
+[int] f(int);
+[] f( ) {}
+[int] f( ) {}
+[] f(int) {}
+[int] f(int) {}
+
+[int x] f( );
+[] f(int x);
+[int x] f(int x);
+[int x] f( ) {}
+[] f(int x) {}
+[int x] f(int x) {}
+
+[int, int x] f( );
+[] f(int, int x);
+[int, int x] f(int, int x);
+[int, int x] f( ) {}
+[] f(int, int x) {}
+[int, int x] f(int, int x) {}
+
+[int, int x, int] f( );
+[] f(int, int x, int);
+[int, int x, int] f(int, int x, int);
+[int, int x, int] f( ) {}
+[] f(int, int x, int) {}
+[int, int x, int] f(int, int x, int) {}
+
+[int, int x, * int y] f( );
+[] f(int, int x, * int y);
+[int, int x, * int y] f(int, int x, * int y);
+[int, int x, * int y] f( ) {}
+[] f(int, int x, * int y) {}
+[int, int x, * int y] f(int, int x, * int y) {}
+
+[ int ] f11( int ), f12;  // => int f11( int ), f12( int );
+
+[int] f(
+	int ( int, int p ),
+	[int](int)
+    ) {
+    int (*(*p)[][10])[][3];
+    * [][10] * [][3] int p;
+    * [] * [int](int) p;
+}
+
+static const int *g1() {}
+static [ const int ] g2() {}
+static inline [ const * int ] g3() {}
+static inline [ const [ * int, int ] ] g4() {}
+static [ const [ * int, const int ] ] g5() {}
+#endif
+
+// unnamed parameter
+
+int g(
+    int (),
+
+    int *(),
+    int **(),
+    int * const *(),
+    int * const * const (),
+
+    int ([]),
+    int ([10]),
+
+    int *([]),
+    int *([10]),
+    int **([]),
+    int **([10]),
+    int * const *([]),
+    int * const *([10]),
+    int * const * const ([]),
+    int * const * const ([10])
+    );
+
+int g(
+    int (),
+
+    int *(),
+    int **(),
+    int * const *(),
+    int * const * const (),
+
+    int ([]),
+    int ([10]),
+
+    int *([]),
+    int *([10]),
+    int **([]),
+    int **([10]),
+    int * const *([]),
+    int * const *([10]),
+    int * const * const ([]),
+    int * const * const ([10])
+    ) {
+}
+
+typedef int T;
+
+int g( T g(T), T T ) {
+    g(T);
+    T = 3;
+}
+
+// errors
+
+//int f()[] {}
+//int (f[])() {}
+//int f[]() {}
+//int ((*f15())())[] {}
Index: translator/Tests/Syntax/GccExtensions.c
===================================================================
--- translator/Tests/Syntax/GccExtensions.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/GccExtensions.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,48 @@
+int fred() {
+    asm( "nop" );
+    __asm( "nop" );
+    __asm__( "nop" );
+
+    __complex__ c1;
+    _Complex c2;
+
+    const int i1;
+    __const int i2;
+    __const__ int i3;
+
+    __extension__ const int ex;
+
+    __inline int f1();
+    __inline__ int f2();
+
+    __signed s1;
+    __signed s2;
+
+    __typeof(s1) t1;
+    __typeof__(s1) t2;
+
+    __volatile int v1;
+    __volatile__ int v2;
+
+    __attribute__(()) int a1;
+    const __attribute(()) int a2;
+    const static __attribute(()) int a3;
+    const static int __attribute(()) a4;
+    const static int a5 __attribute(());
+    const static int a6, __attribute(()) a7;
+
+    int * __attribute(()) p1;
+    int (* __attribute(()) p2);
+//    int (__attribute(()) (p3));
+//    int ( __attribute(()) (* __attribute(()) p4));
+
+    struct __attribute(()) s1;
+    struct __attribute(()) s2 { int i; };
+    struct __attribute(()) s3 { int i; } x1, __attribute(()) y1;
+    struct __attribute(()) s4 { int i; } x2, y2 __attribute(());
+
+    int m1 [10] __attribute(());
+    int m2 [10][10] __attribute(());
+    int __attribute(()) m3 [10][10];
+//    int ( __attribute(()) m4 [10] )[10];
+}
Index: translator/Tests/Syntax/IdentFuncDeclarator.c
===================================================================
--- translator/Tests/Syntax/IdentFuncDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/IdentFuncDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,105 @@
+int main() {
+    //int f0[]();
+    //int (f0[])();
+    //int f0()[];
+    //int f0()();
+    //int (*f0)()();
+    //int ((*f0())())[];
+    
+    int f1;
+    int (f2);
+
+    int *f3;
+    int **f4;
+    int * const *f5;
+    int * const * const f6;
+
+    int *(f7);
+    int **(f8);
+    int * const *(f9);
+    int * const * const (f10);
+
+    int (*f11);
+    int (**f12);
+    int (* const *f13);
+    int (* const * const f14);
+
+    int f15[];
+    int f16[10];
+    int (f17[]);
+    int (f18[10]);
+
+    int *f19[];
+    int *f20[10];
+    int **f21[];
+    int **f22[10];
+    int * const *f23[];
+    int * const *f24[10];
+    int * const * const f25[];
+    int * const * const f26[10];
+
+    int *(f27[]);
+    int *(f28[10]);
+    int **(f29[]);
+    int **(f30[10]);
+    int * const *(f31[]);
+    int * const *(f32[10]);
+    int * const * const (f33[]);
+    int * const * const (f34[10]);
+
+    int (*f35[]);
+    int (*f36[10]);
+    int (**f37[]);
+    int (**f38[10]);
+    int (* const *f39[]);
+    int (* const *f40[10]);
+    int (* const * const f41[]);
+    int (* const * const f42[10]);
+
+    int f43[][3];
+    int f44[3][3];
+    int (f45[])[3];
+    int (f46[3])[3];
+    int ((f47[]))[3];
+    int ((f48[3]))[3];
+
+    int *f49[][3];
+    int *f50[3][3];
+    int **f51[][3];
+    int **f52[3][3];
+    int * const *f53[][3];
+    int * const *f54[3][3];
+    int * const * const f55[][3];
+    int * const * const f56[3][3];
+
+    int (*f57[][3]);
+    int (*f58[3][3]);
+    int (**f59[][3]);
+    int (**f60[3][3]);
+    int (* const *f61[][3]);
+    int (* const *f62[3][3]);
+    int (* const * const f63[][3]);
+    int (* const * const f64[3][3]);
+
+    int f65(int);
+    int (f66)(int);
+
+    int *f67(int);
+    int **f68(int);
+    int * const *f69(int);
+    int * const * const f70(int);
+
+    int *(f71)(int);
+    int **(f72)(int);
+    int * const *(f73)(int);
+    int * const * const (f74)(int);
+
+    int (*f75)(int);
+    int (**f76)(int);
+    int (* const *f77)(int);
+    int (* const * const f78)(int);
+
+    int (*(*f79)(int))();
+    int (*(* const f80)(int))();
+    int (* const(* const f81)(int))();
+}
Index: translator/Tests/Syntax/IdentFuncParamDeclarator.c
===================================================================
--- translator/Tests/Syntax/IdentFuncParamDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/IdentFuncParamDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,150 @@
+int fred(
+    //int f0[](),
+    //int (f0[])(),
+    //int f0()[],
+    //int f0()(),
+    //int (*f0)()(),
+    //int ((*f0())())[],
+    
+    int f1,
+    int (f2),
+
+    int *f3,
+    int **f4,
+    int * const *f5,
+    int * const * const f6,
+
+    int *(f7),
+    int **(f8),
+    int * const *(f9),
+    int * const * const (f10),
+
+    int (*f11),
+    int (**f12),
+    int (* const *f13),
+    int (* const * const f14),
+
+    int f15[],
+    int f16[10],
+    int (f17[]),
+    int (f18[10]),
+
+    int *f19[],
+    int *f20[10],
+    int **f21[],
+    int **f22[10],
+    int * const *f23[],
+    int * const *f24[10],
+    int * const * const f25[],
+    int * const * const f26[10],
+
+    int *(f27[]),
+    int *(f28[10]),
+    int **(f29[]),
+    int **(f30[10]),
+    int * const *(f31[]),
+    int * const *(f32[10]),
+    int * const * const (f33[]),
+    int * const * const (f34[10]),
+
+    int (*f35[]),
+    int (*f36[10]),
+    int (**f37[]),
+    int (**f38[10]),
+    int (* const *f39[]),
+    int (* const *f40[10]),
+    int (* const * const f41[]),
+    int (* const * const f42[10]),
+
+    int f43[][3],
+    int f44[3][3],
+    int (f45[])[3],
+    int (f46[3])[3],
+    int ((f47[]))[3],
+    int ((f48[3]))[3],
+
+    int *f49[][3],
+    int *f50[3][3],
+    int **f51[][3],
+    int **f52[3][3],
+    int * const *f53[][3],
+    int * const *f54[3][3],
+    int * const * const f55[][3],
+    int * const * const f56[3][3],
+
+    int (*f57[][3]),
+    int (*f58[3][3]),
+    int (**f59[][3]),
+    int (**f60[3][3]),
+    int (* const *f61[][3]),
+    int (* const *f62[3][3]),
+    int (* const * const f63[][3]),
+    int (* const * const f64[3][3]),
+
+    int f65(int),
+    int (f66)(int),
+
+    int *f67(int),
+    int **f68(int),
+    int * const *f69(int),
+    int * const * const f70(int),
+
+    int *(f71)(int),
+    int **(f72)(int),
+    int * const *(f73)(int),
+    int * const * const (f74)(int),
+
+    int (*f75)(int),
+    int (**f76)(int),
+    int (* const *f77)(int),
+    int (* const * const f78)(int),
+
+    int (*(*f79)(int))(),
+    int (*(* const f80)(int))(),
+    int (* const(* const f81)(int))(),
+
+    int f82[const *],
+    int f83[const 3],
+    int f84[static 3],
+    int f85[static const 3],
+
+    int (f86[const *]),
+    int (f87[const 3]),
+    int (f88[static 3]),
+    int (f89[static const 3]),
+
+    int *f90[const *],
+    int *f91[const 3],
+    int **f92[static 3],
+    int * const *f93[static const 3],
+    int * const * const f94[static const 3],
+
+    int *(f95[const *]),
+    int *(f96[const 3]),
+    int **(f97[static 3]),
+    int * const *(f98[static const 3]),
+    int * const * const (f99[static const 3]),
+
+    int f100[const *][3],
+    int f101[const 3][3],
+    int f102[static 3][3],
+    int f103[static const 3][3],
+
+    int (f104[const *][3]),
+    int (f105[const 3][3]),
+    int (f106[static 3][3]),
+    int (f107[static const 3][3]),
+
+    int *f108[const *][3],
+    int *f109[const 3][3],
+    int **f110[static 3][3],
+    int * const *f111[static const 3][3],
+    int * const * const f112[static const 3][3],
+
+    int *(f113[const *][3]),
+    int *(f114[const 3][3]),
+    int **(f115[static 3][3]),
+    int * const *(f116[static const 3][3]),
+    int * const * const (f117[static const 3][3])
+    ) {
+}
Index: translator/Tests/Syntax/Initialization.c
===================================================================
--- translator/Tests/Syntax/Initialization.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/Initialization.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,45 @@
+// Cforall extensions
+
+int * v1 = 0, v2 = 0;
+int * v3 = 0, v4 = 0;
+
+void fred() {
+    int y1, y2[20]  = { 1, 2, 3 };
+
+    // designators
+
+    struct {
+	[int] w;
+    } a = { .w : [2] };
+
+    struct { int a[3], b; } w [] = { [0].a : {1}, [0].b : 1, [1].a[0] : 2 };
+
+    struct {
+	int f1, f2, f3;
+	struct { int g1, g2, g3; } f4[4];
+    } v7 = {
+	.f1 : 4,
+	.f2 : 3,
+	.f4[2] : {
+	    .g1 : 3,
+	    .g3 : 0,
+	},
+	.f4[3].g3 : 7,
+    };
+}
+
+struct point { int x; int z; struct {int y1, y2, y3;} y; int w;};
+struct quintet { int v, w, x, y, z;};
+
+int foo(){
+  return 4;
+}
+
+int main(){
+  foo();
+  int i;
+  struct point p1 = { x: 3 };
+  struct point p2 = { 3, 4 };
+  struct point p3 = { .[x,z]: 5, y : { .[y3,y1] : 6, 17 } };
+  struct point p4 = { w : 5, 4 };
+}
Index: translator/Tests/Syntax/LabelledExit.c
===================================================================
--- translator/Tests/Syntax/LabelledExit.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/LabelledExit.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,139 @@
+int main() {
+    int i;
+    int x, y;
+
+    x = 0; y = 0;
+
+// block, labelled exits
+
+  Block: {
+	if ( x == y ) {
+	    for ( ; i < y; ) {
+		y += 1;
+		if ( y < 10 ) break Block;
+	    }
+	}
+    }
+
+// loops, labelled exits
+
+  w1: while ( y == 10 );
+
+  w2: while ( x < 10 ) {
+      while (y < 5 ) {
+	  if ( y == 3 ) break w2;
+      }
+      x += 1;
+  }
+
+  A: for ( i = 0; i < 10; i += 1 ) {
+    B: for ( i = 0; i < 10; i += 1 ) {
+      C: for ( i = 0; i < 10; i += 1 ) {
+	  goto A;
+	  goto B;
+	  goto C;
+	  continue A;
+	  continue B;
+	  continue C;
+	  continue;
+	  break A;
+	  break B;
+	  break C;
+	  break;
+      }
+    }
+  }
+
+  D: for ( ;; ) {
+      break D;
+      continue D;
+  }
+
+    Z : i += 1;
+    goto Z;
+  X: Y: for ( ;; ) {
+      i += 1;
+      if ( i > 5 ) continue X;
+      if ( i < 5 ) break X;
+      if ( i < 5 ) break Y;
+      break;
+  }
+  XX: for ( ;; ) {
+    YY: for ( ;; ) {
+      ZZ: for ( ;; ) {
+	  i += 1;
+	  if ( i > 5 ) continue XX;
+	  if ( i < 5 ) continue YY;
+	  if ( i < 5 ) continue ZZ;
+	  if ( i > 5 ) break XX;
+	  if ( i < 5 ) break YY;
+	  if ( i < 5 ) break ZZ;
+	  break;
+      }
+    }
+  }
+
+    for ( ;; ) ;
+    for ( int i = 0 ;; ) ;
+    for (  ; i < 0; ) ;
+    for (  ; ; i += 1 ) ;
+  L0:  L1:  L2:  L3:  L4:  L5:  L6:  L7:  L8:  L9:
+  L10: L11: L12: L13: L14: L15: L16: L17: L18: L19:
+  L20: L21: L22: L23: L24: L25: L26: L27: L28: L29:
+  L31: L32: L33: L34:
+    for ( ;; ) {
+	break L0;
+    }
+
+// switch/choose, labelled exits
+
+  Switch: switch ( i ) {
+    default:
+      i += 1;
+    case 0:
+      i += 1;
+      break Switch;
+    case 1:
+      switch ( i ) {
+	case 0:
+	  break Switch;
+	default:
+	  break;
+      }
+  }
+
+  Choose: choose ( i ) {
+    default:
+      i += 1;
+    case 0:
+      i += 1;
+      break Choose;
+    case 1:
+      choose ( i ) {
+	case 0:
+	  break;
+	default:
+	  break Choose;
+      }
+      fallthru;
+    case 2:
+      i += 1;
+  }
+#if 0
+// computed goto
+
+    {
+	static void *array[] = { &&foo, &&bar, &&hack };
+
+      foo: bar: hack:
+	goto *array[i];
+    }
+#endif
+#if 0
+  Q: if ( i > 5 ) {
+      i += 1;
+      break Q;
+  } else
+      i += 1;
+#endif
+}
Index: translator/Tests/Syntax/Makefile
===================================================================
--- translator/Tests/Syntax/Makefile	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/Makefile	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,22 @@
+CFA = ../../cfa-cpp
+
+TESTS = ${shell ls *.c}
+TEST_OUT = $(TESTS:.c=.tst)
+
+%.tst:%.c $(CFA)
+	$(CFA) -nd < $< > $@ 2>&1
+
+tests: $(TEST_OUT)
+
+clean:
+	rm -rf $(TEST_OUT)
+
+force: clean tests
+
+all: $(TESTS)
+	@for i in $(TESTS); do     \
+	  echo -n $$i "... " ;     \
+	  $(CFA) -d < $$i > $$i.log;  \
+	done
+
+
Index: translator/Tests/Syntax/NamedParmArg.c
===================================================================
--- translator/Tests/Syntax/NamedParmArg.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/NamedParmArg.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,14 @@
+int f1( int i = 3, int *j = 0 ) {}  /* ANSI */
+[int, int ] f2( int i = 3, * int j = 0 ) {}  /* CFA */
+
+int main() {
+    f1();		/* identical calls */
+    f1( 3 );
+    f1( 3, );
+    f1( 3, 0 );
+    f1( 3, j : 0 );
+    f1( j : 0, 3 );
+    f1( i : 3, j : 0 );
+    f1( j : 0, i : 3 );
+    f1( [j, i] : f2() );
+}
Index: translator/Tests/Syntax/NumericConstants.c
===================================================================
--- translator/Tests/Syntax/NumericConstants.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/NumericConstants.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,50 @@
+int main() {
+    1;							/* decimal */
+    2_1;
+    2_147_483_647;
+    37LL;
+    45ull;
+    89llu;
+    99LLu;
+    56_lu;
+    88_LLu;
+
+//    0;							/* octal */
+    0u;
+    0_3_77;
+    0_377_ul;
+
+    0x1;						/* hexadecimal */
+    0x1u;
+    0xabL;
+    0x_80000000;
+    0x_fff;
+    0x_ef3d_aa5c;
+    0x_3LL;
+
+    3.;							/* integral real */
+    3_100.;
+    1_000_000.;
+
+    3.1;						/* integral/fractional real */
+    3.141_592_654L;
+    123_456.123_456;
+
+    3E1;						/* integral/exponent real */
+    3_e1f;
+    3_E1_1_F;
+    3_E_11;
+    3_e_+11;
+    3_E_-11;
+
+    3.0E1;						/* integral/fractional/exponent real */
+    3.0_E1L;
+    3.0_e1_1;
+    3.0_E_11_l;
+    3.0_e_+11l;
+    3.0_E_-11;
+    123_456.123_456E-16;
+
+    0x_ff.ffp0;						/* hex real */
+    0x_1.ffff_ffff_p_128_l;
+}
Index: translator/Tests/Syntax/Scope.c
===================================================================
--- translator/Tests/Syntax/Scope.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/Scope.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,68 @@
+int x;
+typedef double y;
+typedef float t;
+y z;
+type u = struct { int a; double b; };
+int f( int y );
+y q;
+
+y w(y y, u v) {
+    type x | { x t(u); };
+    u u = y;
+    x z = t(u);
+}
+
+y p;
+
+context has_u( type z )
+{
+  forall( type t ) z u(t);
+};
+
+forall( type t | has_u( t ) )
+y q( t the_t )
+{
+    t y = u( the_t );
+}
+
+t f( y p ) {
+    int y;
+    typedef char x;
+
+    {
+	x y;
+	typedef x z;
+
+	{
+	    z x;
+	    typedef z y;
+	    y z = x;
+	}
+
+	z x = y;
+    }
+
+    x q = y;
+}
+
+t g( void ) {
+    typedef char x;
+    try {
+	some_func();
+    } catch ( x x ) {
+	t y = x;
+    }
+    x z;
+}
+
+y q(i)							/* K&R style */
+    int i;
+{
+    switch (i) {
+	y q = i;
+      case 0:
+	return q;
+      default:
+	return i;
+    }
+}
Index: translator/Tests/Syntax/StructMember.c
===================================================================
--- translator/Tests/Syntax/StructMember.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/StructMember.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,40 @@
+typedef int T;
+
+struct S {
+    int m1:3, m2:4;
+    int :2;
+    int :3, :4;
+    int m3;
+    int m4, m5, m6;
+    int *m7, *m8, *m9;
+    int (*m10)();
+    int *(*m11)(int);
+    T T;
+    T (T);
+
+// Cforall extensions
+
+    * int m12, m13;
+    * [ * int ] (int) m14;
+    int ;
+    int , , ;
+    int * , , ;
+    int *, *, *;
+    * int , , ;
+    int (*)();
+    int (**)( int );
+    T ;
+
+// errors
+
+//    void f(void);
+};
+
+struct S s;
+
+union U {
+    [5] int m1;
+    int m2[5];
+    * int m3;
+    int *m4;
+} u;
Index: translator/Tests/Syntax/Subrange.c
===================================================================
--- translator/Tests/Syntax/Subrange.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/Subrange.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,63 @@
+// A small context defining the notion of an ordered type.  (The standard
+// library should probably contain a context for this purpose.)
+context ordered(type T) {
+    int ?<?(T, T), ?<=?(T, T);
+};
+
+// A subrange type resembling an Ada subtype with a base type and a range
+// constraint.
+type subrange(type base_t | ordered(base_t), base_t low = 0, base_t high = 8) = base_t;
+
+// Note that subrange() can be applied to floating-point and pointer types, not
+// just integral types.
+//   This requires a "type generator" extension to Cforall.  Type generators
+// must accept type and non-type parameters, which is beyond what we discussed
+// previously.  Type parameters must be usable in the declaration of
+// subsequent parameters: parameter T is used to declare parameters "low"
+// and "high".
+
+// Example usage:
+subrange(unsigned, 1, 31) day_of_month;
+subrange(char, 'a', 'z')  lcase;
+subrange(int, 0, (rand() & 0xF) ) foo;
+
+// What sorts of expressions can be used as arguments of type generators?  Is
+// "subrange(int, 0, rand() & 0xF)" legal?  Probably.  The nearest C equivalent
+// to the "low" and "high" arguments is the array size in a variable-length
+// array declaration, and C allows assignment expressions there.
+
+// Convenient access to subrange bounds, for instance for iteration:
+forall (type T, T low, T high)
+T lbound( subrange(T, low, high) v) {
+    return low;
+}
+
+forall (type T, T low, T high)
+T hbound( subrange(T, low, high) v) {
+    return high;
+}
+
+// Example usage:
+unsigned lday = lbound(day_of_month);
+
+// Assignment from the base type, with bounds checking.  I'll ignore the issue
+// of exception handling here.  Inlining allows the compiler to eliminate
+// bounds checks.
+forall (type T | ordered(T), T low, T high)
+inline subrange(T, low, high) ?=?(subrange(T, low, high)* target, T source) {
+    if (low <= source && source <= high) *((T*)target) = source;
+    else abort();
+    return target;
+}
+
+// Assignment between subranges with a common base type.  The bounds check
+// compares range bounds so that the compiler can optimize checks away when the
+// ranges are known to overlap.
+forall (type T | ordered(T), T t_low, T t_high, T s_low, T s_high)
+inline subrange(T, t_low, t_high) ?=?(subrange(T, t_low, t_high)* target,
+				      subrange(T, s_low, s_high) source) {
+    if ( (t_low <= s_low || t_low <= source)
+	 && (s_high <= t_high || source <= t_high) ) *((T*)target) = source;
+    else abort();
+    return target;
+}
Index: translator/Tests/Syntax/Switch.c
===================================================================
--- translator/Tests/Syntax/Switch.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/Switch.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,42 @@
+int fred() {
+    int i;
+    switch ( i ) case 3 : i = 1;
+    switch ( i ) default : i = 1;
+    switch ( 3 )
+      default:
+      case 2:
+      case 3:
+	3;
+
+    switch ( i ) {
+    }
+
+    switch ( i ) {
+	int i;
+      case 8~10:
+      default:
+	i = 3;
+      case 3:
+      case 'A' ... 'Z':
+      case 5 ... 6:
+      case 2, 4:
+	i = 3;
+	break;
+    }
+
+    choose ( i ) case 3 : i = 1;
+    choose ( i ) default : i = 1;
+    choose ( i ) {
+	int i;
+      case 3:
+      case 'A' ... 'Z':
+      case 5 ... 6:
+      case 2, 4, 7:
+	i = 3;
+	fallthru;
+      default:
+	i = 3;
+      case 8~10:
+	fallthru
+    }
+}
Index: translator/Tests/Syntax/Tuple.c
===================================================================
--- translator/Tests/Syntax/Tuple.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/Tuple.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,66 @@
+int f( int, int );
+int g( int, int, int );
+static [ int, int, int, int ] h( int a, int b, * int c, [] char d );
+
+struct inner {
+    int f2, f3;
+};
+
+struct outer {
+    int f1;
+    struct inner i;
+    double f4;
+} s, *sp;
+
+const volatile [ int, int ] t1;
+static const [ int, const int ] t2;
+const static [ int, const int ] t3;
+
+[ int rc ] printf( * char fmt, ... );
+int printf( char *fmt, ... );
+
+[ short x, unsigned y ] f1( int w ) {
+    [ y, x ] = [ x, y ] = [ w, 23 ];
+}
+
+[ [ int, char, long, int ] r ] g1() {
+    short x, p;
+    unsigned int y;
+    [ int, int ] z;
+
+    [ x, y, z ] = [ p, f( 17 ), 3 ];
+    r = [ x, y, z ];
+}
+
+[ int rc ] main( int argc, ** char argv ) {
+    int a, b, c, d;
+    struct outer t = { .[ f1,f4 ] : [ 1,7.0 ] };
+    f( [ 3,5 ] );
+    g( [ 3,5 ], 3 );
+    f( t1 );
+    g( t1, 3 );
+
+    [ ,,, ];						/* empty tuple */
+    [ 3,5 ];
+    [ a,b ] = 3;
+    [ a,b ] = [ 4.6 ];
+    [ a,b ] = [ c,d ] = [ 3,5 ];
+    [ a,b,[ c ] ] = [ 2,[ a,b ] ];
+    [ a,b ] = 3 > 4 ? [ b,6 ] : [ 7,8 ];
+
+    t1 = [ a,b ];
+    t1 = [ a, ];					/* semantic error */
+    t1 = t2 = [ a,b ];
+    [ a,b ] = [ c,d ] = d += c += 1;
+    [ a,b ] = [ c,d ] = t1;
+    [ a,b ] = t1 = [ c,d ];
+    [ a,b ] = t1 = t2 = [ c,d ];
+    t1 = [ 3,4 ] = [ 3,4 ] = t1 = [ 3,4 ];
+
+    s.[ f1, i.[ f2, f3 ], f4 ] = [ 11, 12, 13, 3.14159 ];
+    s.[ f1, i.[ f2, f3 ], f4 ] = h( 3, 3, 0, "abc" );
+    [ a, ,b, ] = h( 3, 3, 0, "abc" );			/* ignore some results */
+    sp->[ f4,f1 ] = sp->[ f1,f4 ];
+    printf( "expecting 3, 17, 23, 4; got %d, %d, %d, %d\n", s.[ f4, i.[ f3,f2 ], f1 ] );
+    rc = 0;
+}
Index: translator/Tests/Syntax/TypeGenerator.c
===================================================================
--- translator/Tests/Syntax/TypeGenerator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/TypeGenerator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,25 @@
+context addable(type T) {
+   T ?+?(T,T);
+};
+
+type List(type T | addable(T) ) | addable(T) = struct { T data; List(T) *next; } *;
+typedef List(int) ListOfIntegers;
+ListOfIntegers li;
+int f( List(int) ((*g))(int) );
+[int] h( * List(int) p ); // new declaration syntax
+
+struct(type T) S1;			// forward definition
+struct(type T) S1 { T i; };		// actual definition
+struct(int) S1 v1, *p;			// expansion and instantiation
+struct(type T)(int) S2 { T i; } v2;	// actual definition, expansion and instantiation
+struct(type T)(int) { T i; } v2;	// anonymous actual definition, expansion and instantiation
+
+struct(type T | addable(T) ) node { T data; struct(T) node *next; };
+type List(type T) = struct(T) node *;
+List(int) my_list;
+
+type Complex | addable(Complex);
+
+int main() {
+    (struct(int) node)my_list;
+}
Index: translator/Tests/Syntax/Typedef.c
===================================================================
--- translator/Tests/Syntax/Typedef.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/Typedef.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,43 @@
+typedef int T;
+
+void f( void ) {
+    int T( T );
+    T( 3 );
+}
+
+struct {
+    T (T);
+} fred = { 3 };
+
+typedef int (*a)(int, char);
+a b;
+
+int g(void) {
+    double a;
+}
+a c;
+
+typedef typeof(3) x, y;  /* GCC */
+
+x p;
+y q;
+
+int main() {
+    typedef typeof(3) z, p;
+    z w;
+    p x;
+}
+
+/* new-style function definitions */
+
+typedef [10] * int arrayOf10Pointers;
+arrayOf10Pointers array;
+typedef const * int constantPointer;
+typedef * [ int ]( [] int ) funcPtr;
+typedef [ int ] funcProto( []  int );
+typedef [ int, int ] tupleType;
+typedef * [ int, int ] tupleTypePtr;
+typedef * int a, b;
+typedef [ int ] f( * int ), g;
+typedef [ * [static 10] int ] t;
+typedef [ * [static 10] int x ] f();
Index: translator/Tests/Syntax/TypedefDeclarator.c
===================================================================
--- translator/Tests/Syntax/TypedefDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/TypedefDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,116 @@
+typedef int
+     f0,  f1,  f2,  f3,  f4,  f5,  f6,  f7,  f8,  f9,
+    f10, f11, f12, f13, f14, f15, f16, f17, f18, f19,
+    f20, f21, f22, f23, f24, f25, f26, f27, f28, f29,
+    f30, f31, f32, f33, f34, f35, f36, f37, f38, f39,
+    f40, f41, f42, f43, f44, f45, f46, f47, f48, f49,
+    f50, f51, f52, f53, f54, f55, f56, f57, f58, f59,
+    f60, f61, f62, f63, f64, f65, f66, f67, f68, f69,
+    f70, f71, f72, f73, f74, f75, f76, f77, f78, f79,
+    f80, f81, f82, f83, f84, f85, f86, f87, f88, f89;
+
+int main() {
+    //int f0[]();
+    //int (f0[])();
+    //int f0()[];
+    //int f0()();
+    //int (*f0)()();
+    //int ((*f0())())[];
+    
+    int f1;
+    int (f2);
+
+    int *f3;
+    int **f4;
+    int * const *f5;
+    int * const * const f6;
+
+    int *(f7);
+    int **(f8);
+    int * const *(f9);
+    int * const * const (f10);
+
+    int (*f11);
+    int (**f12);
+    int (* const *f13);
+    int (* const * const f14);
+
+    int f15[];
+    int f16[10];
+    int (f17[]);
+    int (f18[10]);
+
+    int *f19[];
+    int *f20[10];
+    int **f21[];
+    int **f22[10];
+    int * const *f23[];
+    int * const *f24[10];
+    int * const * const f25[];
+    int * const * const f26[10];
+
+    int *(f27[]);
+    int *(f28[10]);
+    int **(f29[]);
+    int **(f30[10]);
+    int * const *(f31[]);
+    int * const *(f32[10]);
+    int * const * const (f33[]);
+    int * const * const (f34[10]);
+
+    int (*f35[]);
+    int (*f36[10]);
+    int (**f37[]);
+    int (**f38[10]);
+    int (* const *f39[]);
+    int (* const *f40[10]);
+    int (* const * const f41[]);
+    int (* const * const f42[10]);
+
+    int f43[][3];
+    int f44[3][3];
+    int (f45[])[3];
+    int (f46[3])[3];
+    int ((f47[]))[3];
+    int ((f48[3]))[3];
+
+    int *f49[][3];
+    int *f50[3][3];
+    int **f51[][3];
+    int **f52[3][3];
+    int * const *f53[][3];
+    int * const *f54[3][3];
+    int * const * const f55[][3];
+    int * const * const f56[3][3];
+
+    int (*f57[][3]);
+    int (*f58[3][3]);
+    int (**f59[][3]);
+    int (**f60[3][3]);
+    int (* const *f61[][3]);
+    int (* const *f62[3][3]);
+    int (* const * const f63[][3]);
+    int (* const * const f64[3][3]);
+
+    int f65(int);
+    int (f66)(int);
+
+    int *f67(int);
+    int **f68(int);
+    int * const *f69(int);
+    int * const * const f70(int);
+
+    int *(f71)(int);
+    int **(f72)(int);
+    int * const *(f73)(int);
+    int * const * const (f74)(int);
+
+    int (*f75)(int);
+    int (**f76)(int);
+    int (* const *f77)(int);
+    int (* const * const f78)(int);
+
+    int (*(*f79)(int))();
+    int (*(* const f80)(int))();
+    int (* const(* const f81)(int))();
+}
Index: translator/Tests/Syntax/TypedefParamDeclarator.c
===================================================================
--- translator/Tests/Syntax/TypedefParamDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/TypedefParamDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,150 @@
+typedef int
+     f0,   f1,   f2,   f3,   f4,   f5,   f6,   f7,   f8,   f9,
+    f10,  f11,  f12,  f13,  f14,  f15,  f16,  f17,  f18,  f19,
+    f20,  f21,  f22,  f23,  f24,  f25,  f26,  f27,  f28,  f29,
+    f30,  f31,  f32,  f33,  f34,  f35,  f36,  f37,  f38,  f39,
+    f40,  f41,  f42,  f43,  f44,  f45,  f46,  f47,  f48,  f49,
+    f50,  f51,  f52,  f53,  f54,  f55,  f56,  f57,  f58,  f59,
+    f60,  f61,  f62,  f63,  f64,  f65,  f66,  f67,  f68,  f69,
+    f70,  f71,  f72,  f73,  f74,  f75,  f76,  f77,  f78,  f79,
+    f80,  f81,  f82,  f83,  f84,  f85,  f86,  f87,  f88,  f89,
+    f90,  f91,  f92,  f93,  f94,  f95,  f96,  f97,  f98,  f99,
+    f100, f101, f102, f103, f104, f105, f106, f107, f108, f109,
+    f110, f111, f112, f113, f114, f115, f116, f117, f118, f119;
+
+int fred(
+/*
+    //int f0[](),
+    //int (f0[])(),
+    //int f0()[],
+    //int f0()(),
+    //int (*f0)()(),
+    //int ((*f0())())[],
+*/
+    int f1,
+
+    int *f3,
+    int **f4,
+    int * const *f5,
+    int * const * const f6,
+
+    int (*f11),
+    int (**f12),
+    int (* const *f13),
+    int (* const * const f14),
+
+    int f15[],
+    int f16[10],
+
+    int *f19[],
+    int *f20[10],
+    int **f21[],
+    int **f22[10],
+    int * const *f23[],
+    int * const *f24[10],
+    int * const * const f25[],
+    int * const * const f26[10],
+
+    int (*f35[]),
+    int (*f36[10]),
+    int (**f37[]),
+    int (**f38[10]),
+    int (* const *f39[]),
+    int (* const *f40[10]),
+    int (* const * const f41[]),
+    int (* const * const f42[10]),
+
+    int f43[][3],
+    int f44[3][3],
+/*
+    int (f45[])[3],
+    int (f46[3])[3],
+    int ((f47[]))[3],
+    int ((f48[3]))[3],
+*/
+    int *f49[][3],
+    int *f50[3][3],
+    int **f51[][3],
+    int **f52[3][3],
+    int * const *f53[][3],
+    int * const *f54[3][3],
+    int * const * const f55[][3],
+    int * const * const f56[3][3],
+
+    int (*f57[][3]),
+    int (*f58[3][3]),
+    int (**f59[][3]),
+    int (**f60[3][3]),
+    int (* const *f61[][3]),
+    int (* const *f62[3][3]),
+    int (* const * const f63[][3]),
+    int (* const * const f64[3][3]),
+
+    int f65(int),
+/*
+    int (f66)(int),
+*/
+    int *f67(int),
+    int **f68(int),
+    int * const *f69(int),
+    int * const * const f70(int),
+/*
+    int *(f71)(int),
+    int **(f72)(int),
+    int * const *(f73)(int),
+    int * const * const (f74)(int),
+*/
+    int (*f75)(int),
+    int (**f76)(int),
+    int (* const *f77)(int),
+    int (* const * const f78)(int),
+
+    int (*(*f79)(int))(),
+    int (*(* const f80)(int))(),
+    int (* const(* const f81)(int))(),
+
+    int f82[const *],
+    int f83[const 3],
+    int f84[static 3],
+    int f85[static const 3],
+
+    int (f86[const *]),
+    int (f87[const 3]),
+    int (f88[static 3]),
+    int (f89[static const 3]),
+
+    int *f90[const *],
+    int *f91[const 3],
+    int **f92[static 3],
+    int * const *f93[static const 3],
+    int * const * const f94[static const 3],
+
+    int *(f95[const *]),
+    int *(f96[const 3]),
+    int **(f97[static 3]),
+    int * const *(f98[static const 3]),
+    int * const * const (f99[static const 3]),
+
+    int f100[const *][3],
+    int f101[const 3][3],
+    int f102[static 3][3],
+    int f103[static const 3][3],
+
+    int (f104[const *][3]),
+    int (f105[const 3][3]),
+    int (f106[static 3][3]),
+    int (f107[static const 3][3]),
+
+    int *f108[const *][3],
+    int *f109[const 3][3],
+    int **f110[static 3][3],
+    int * const *f111[static const 3][3],
+    int * const * const f112[static const 3][3],
+
+    int *(f113[const *][3]),
+    int *(f114[const 3][3]),
+    int **(f115[static 3][3]),
+    int * const *(f116[static const 3][3]),
+    int * const * const (f117[static const 3][3])
+    ) {
+}
Index: translator/Tests/Syntax/Typeof.c
===================================================================
--- translator/Tests/Syntax/Typeof.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/Typeof.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,10 @@
+int main() {
+    int *v1;
+    typeof(v1) v2;
+    typeof(*v1) v3[4];
+    char *v4[4];
+    typeof(typeof(char *)[4]) v5;
+    typeof (int *) v6;
+    typeof( int ( int, int p ) ) *v7;
+    typeof( [int] ( int, int p ) ) *v8;
+}
Index: translator/Tests/Syntax/VariableDeclarator.c
===================================================================
--- translator/Tests/Syntax/VariableDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/Syntax/VariableDeclarator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,162 @@
+int f1;
+int (f2);
+
+int *f3;
+int **f4;
+int * const *f5;
+int * const * const f6;
+
+int *(f7);
+int **(f8);
+int * const *(f9);
+int * const * const (f10);
+
+int (*f11);
+int (**f12);
+int (* const *f13);
+int (* const * const f14);
+
+int f15[];
+int f16[10];
+int (f17[]);
+int (f18[10]);
+
+int *f19[];
+int *f20[10];
+int **f21[];
+int **f22[10];
+int * const *f23[];
+int * const *f24[10];
+int * const * const f25[];
+int * const * const f26[10];
+
+int *(f27[]);
+int *(f28[10]);
+int **(f29[]);
+int **(f30[10]);
+int * const *(f31[]);
+int * const *(f32[10]);
+int * const * const (f33[]);
+int * const * const (f34[10]);
+
+int (*f35)[];
+int (*f36)[10];
+int (**f37)[];
+int (**f38)[10];
+int (* const *f39)[];
+int (* const *f40)[10];
+int (* const * const f41)[];
+int (* const * const f42)[10];
+
+int f43[][3];
+int f44[3][3];
+int (f45[])[3];
+int (f46[3])[3];
+int ((f47[]))[3];
+int ((f48[3]))[3];
+
+int *f49[][3];
+int *f50[3][3];
+int **f51[][3];
+int **f52[3][3];
+int * const *f53[][3];
+int * const *f54[3][3];
+int * const * const f55[][3];
+int * const * const f56[3][3];
+
+int (*f57[][3]);
+int (*f58[3][3]);
+int (**f59[][3]);
+int (**f60[3][3]);
+int (* const *f61[][3]);
+int (* const *f62[3][3]);
+int (* const * const f63[][3]);
+int (* const * const f64[3][3]);
+
+int f65(int);
+int (f66)(int);
+
+int *f67(int);
+int **f68(int);
+int * const *f69(int);
+int * const * const f70(int);
+
+int *(f71)(int);
+int **(f72)(int);
+int * const *(f73)(int);
+
+int * const * const (f74)(int);
+
+int (*f75)(int);
+int (**f76)(int);
+int (* const *f77)(int);
+int (* const * const f78)(int);
+
+int (*(*f79)(int))();
+int (*(* const f80)(int))();
+int (* const(* const f81)(int))();
+
+// errors
+
+//int fe0[]();				// array of functions
+//int (fe1[])();				// array of functions
+//int fe2()[];				// returning an array
+//int fe3()();				// returning a function
+//int (*fe4)()();				// returning a function
+//int ((*fe5())())[];			// returning an array
+
+// Cforall extensions
+
+* int cf3;
+* * int cf4;
+* const * int cf5;
+const * const * int cf6;
+
+[] int cf15;
+[10] int cf16;
+
+[] * int cf19;
+[10] * int cf20;
+int **cf21[];
+[10] * * int cf22;
+[] * const * int cf23;
+[10] * const * int cf24;
+[] const * const * int cf25;
+[10] const * const * int cf26;
+
+* [] int cf35;
+* [10] int cf36;
+* * [] int cf37;
+* * [10] int cf38;
+* const * [] int cf39;
+* const * [10] int cf40;
+const * const * [] int cf41;
+const * const * [10] int cf42;
+
+[][3] int cf43;
+[3][3] int cf44;
+
+[][3] * int cf49;
+[3][3] * int cf50;
+[][3] * * int cf51;
+[3][3] * * int cf52;
+[][3] const * int cf53;
+[3][3] * const * int cf54;
+[][3] const * const * int cf55;
+[3][3] const * const * int cf56;
+
+[int] cf65(int);
+[int] cf66(int);
+
+[* int] cf67(int);
+[* * int] cf68(int);
+[const * * int] cf69(int);
+[const * const * int] cf70(int);
+
+
+* [20] double z;
+[20] * char w;
+
+// function pointer
+
+*[]*[]* [ *[]*[] int ]( *[]*[] int, *[]*[] int ) v3;
Index: translator/Tests/TupleAssign/Initialization2.c
===================================================================
--- translator/Tests/TupleAssign/Initialization2.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/TupleAssign/Initialization2.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,15 @@
+int a = 3;
+struct { int x; int y; } z = { 3, 7 };      /* OK */
+struct { int x; int y; } z1 = { .[x,y]:3 }; /* OK */
+struct { int x; int y; } z2 = { y:3, x:4 }; /* OK */
+struct { int x; struct { int y1; int y2; } y; } z3 = { x:3, y:{y1:4, y2:5} };  /* OK */
+struct { int x; struct { int y1; int y2; } y; } z3 = { y:{y2:9, y1:8}, x:7 };  /* OK */
+struct { int x; struct { int y1; int y2; } y; } z3 = { x:7, {y2:9, y1:8} };  /* OK */
+struct { int x; struct { int y1; int y2; } y; } z3 = { 3, {4, 5} };   /* OK */
+//struct { int x; struct { int y1; int y2; } } z3 = {4, {5,6}};
+//struct { int x; struct { int y1; int y2; } y; } z4 = { y:{4,5}, a:3 };
+//struct { int x; struct { int y1; int y2; } y; } z5 = { a:3, {4,5}};
+//int x[20] = { [10]: 4 };
+struct t { int a, b; };
+struct t x = { b:4, a:3 };
+struct { int x; int y; } z6= {5,6,4};  /* (should be an) error */
Index: translator/Tests/gcc/900407-1.c
===================================================================
--- translator/Tests/gcc/900407-1.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/gcc/900407-1.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,9 @@
+foo (int a, int b, int *p)
+{
+  int c;
+  p[2] = a + 0x1000;
+  c = b + 0xffff0000;
+  if ((b + 0xffff0000) == 2)
+    c++;
+  p[2] = c;
+}
Index: translator/Tests/gcc/900516-1.c
===================================================================
--- translator/Tests/gcc/900516-1.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/gcc/900516-1.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,2 @@
+/* added 'int' to argument */
+f(int c){ return!(c?2.0:1.0); }
Index: translator/Tests/gcc/920301-1.c
===================================================================
--- translator/Tests/gcc/920301-1.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/gcc/920301-1.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,2 @@
+f(){static void*t[];/*={&&x};*/ x:y:;}
+g(){static unsigned p[5];}
Index: translator/Tests/gcc/920409-1.c
===================================================================
--- translator/Tests/gcc/920409-1.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/gcc/920409-1.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,1 @@
+x(){int y;y>0.0?y:y-1;}
Index: translator/Tests/gcc/920409-2.c
===================================================================
--- translator/Tests/gcc/920409-2.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/gcc/920409-2.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,2 @@
+double x(){int x1,x2;double v;
+if(((long)(x1-x2))<1)return -1.0;v=t(v);v=y(1,v>0.0?(int)v:((int)v-1));}
Index: translator/Tests/gcc/920410-2.c
===================================================================
--- translator/Tests/gcc/920410-2.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/gcc/920410-2.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,12 @@
+joe()
+  {
+    int j;
+
+    while( 1 )
+      {
+	for( j = 0; j < 4; j++ )
+	  ;
+	for( j = 0; j < 4; j++ )
+	  ;
+      }
+  }
Index: translator/Tests/gcc/920501-1.c
===================================================================
--- translator/Tests/gcc/920501-1.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/gcc/920501-1.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,1 @@
+a(){int**b[]={&&c};c:;}
Index: translator/Tests/gcc/920501-11.c
===================================================================
--- translator/Tests/gcc/920501-11.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/gcc/920501-11.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,1 @@
+typedef struct{int s;}S;foo(){int i=(int)&(S){(void*)((int)&(S){1})};}
Index: translator/Tests/gcc/920501-19.c
===================================================================
--- translator/Tests/gcc/920501-19.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tests/gcc/920501-19.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,1 @@
+long long x=0;y(){x=0;}
Index: translator/Tuples/AssignExpand.cc
===================================================================
--- translator/Tuples/AssignExpand.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/AssignExpand.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,131 @@
+#include <ctime>
+#include <cstdlib>
+
+#include <list>
+#include <cassert>
+#include <algorithm>
+
+#include "AssignExpand.h"
+
+#include "SynTree/Type.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Declaration.h"
+
+namespace Tuples {
+  AssignExpander::AssignExpander() : temporaryNamer("__tpl") {}
+
+  Statement *AssignExpander::mutate( ExprStmt *exprStmt ) {
+    replace.clear();
+    extra.clear();
+    extra2.clear();
+    exprStmt->set_expr( maybeMutate( exprStmt->get_expr(), *this ) );
+
+    CompoundStmt *newSt = 0;
+    if (! extra.empty() ) {
+      if ( !newSt )
+	newSt= new CompoundStmt(std::list<Label>());
+
+      newSt->get_kids().splice(newSt->get_kids().end(), extra);
+    }
+
+    if (! extra2.empty() ) {
+      if ( !newSt )
+	newSt= new CompoundStmt(std::list<Label>());
+
+      newSt->get_kids().splice(newSt->get_kids().end(), extra2);
+    }
+
+    if (! replace.empty() ) {
+      if ( !newSt )
+	newSt= new CompoundStmt(std::list<Label>());
+
+      for ( std::list<Expression *>::iterator r = replace.begin(); r != replace.end(); r++ )
+	newSt->get_kids().push_back( new ExprStmt( std::list<Label>(), *r ));
+    }
+
+    if( newSt ) return newSt; else return exprStmt;
+  }
+
+  Expression *AssignExpander::mutate( SolvedTupleExpr *tupleExpr ) {
+    /* 
+    std::list<Expression *> &exprs = tupleExpr->get_exprs();
+
+    if ( tupleExpr->get_type() == SolvedTupleExpr::MASS ) {
+      // extract lhs of assignments, assert that rhs is the same, create temporaries
+      assert (! exprs.empty());
+      ApplicationExpr *ap1 = dynamic_cast< ApplicationExpr * >( exprs.front() );
+      std::list<Expression *> &args = ap1->get_args();
+      assert(args.size() == 2);
+      std::list<Type *> &temp_types = args.back()->get_results();
+      assert(temp_types.size() == 1);
+      extra.push_back(new DeclStmt( std::list<Label>(), new ObjectDecl(temporaryNamer.newName(), Declaration::Auto, LinkageSpec::C, 0, temp_types.front(), 0 ) ));
+
+      for ( std::list<Expression *>::iterator e = exprs.begin(); e != exprs.end(); e++ ) {
+	ApplicationExpr *ap = dynamic_cast< ApplicationExpr * >( *e );
+	assert( ap != 0 );
+	replace.push_back(ap);
+      }
+
+      return tupleExpr;
+    } else if ( tupleExpr->get_type() == SolvedTupleExpr::MULTIPLE ||
+		   tupleExpr->get_type() == SolvedTupleExpr::MASS ) */ {
+      std::list<Expression *> &comps = tupleExpr->get_exprs();
+      for( std::list<Expression *>::iterator i = comps.begin(); i != comps.end(); ++i ) {
+	std::list<Statement *> decls;
+	std::list<Statement *> temps;
+	std::list<Statement *> assigns;
+	if( ApplicationExpr *app = dynamic_cast< ApplicationExpr * >(*i) ) {
+	  assert( app->get_args().size() == 2 );
+
+	  Expression *lhsT = app->get_args().front();
+	  Expression *rhsT = app->get_args().back();
+	  // after the round of type analysis this should be true
+	  assert( lhsT->get_results().size() == 1 );
+	  assert( rhsT->get_results().size() == 1 );
+	  // declare temporaries
+	  ObjectDecl *lhs = new ObjectDecl( temporaryNamer.newName("_lhs_"), Declaration::NoStorageClass, LinkageSpec::Intrinsic, 0,
+					    lhsT->get_results().front(), 0 );
+	  decls.push_back( new DeclStmt( std::list< Label >(), lhs ) );
+	  ObjectDecl *rhs = new ObjectDecl( temporaryNamer.newName("_rhs_"), Declaration::NoStorageClass, LinkageSpec::Intrinsic, 0,
+					    rhsT->get_results().front(), 0);
+	  decls.push_back( new DeclStmt( std::list< Label >(), rhs ));
+
+
+	  // create temporary for lhs, assign address
+	  UntypedExpr *assgnL = new UntypedExpr( new NameExpr( "?=?" ) );
+	  assgnL->get_args().push_back( new VariableExpr( lhs ) );
+	  assgnL->get_args().push_back( lhsT );
+	  temps.push_back( new ExprStmt(std::list<Label>(), assgnL) );
+
+	  // create temporary for rhs, assign value
+	  UntypedExpr *assgnR = new UntypedExpr( new NameExpr( "?=?" ) );
+	  assgnR->get_args().push_back( new VariableExpr( rhs ) );
+	  assgnR->get_args().push_back( rhsT );
+	  temps.push_back( new ExprStmt(std::list<Label>(), assgnR) );
+
+	  // assign rhs to lhs
+	  UntypedExpr *assgn = new UntypedExpr( new NameExpr( "?=?" ) );
+	  UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
+	  deref->get_args().push_back( new VariableExpr( lhs ) );
+	  assgn->get_args().push_back( deref );
+	  assgn->get_args().push_back( new VariableExpr( rhs ) );
+	  assigns.push_back( new ExprStmt(std::list<Label>(), assgn) );
+
+	} else
+	  throw CompilerError("Solved Tuple should contain only assignment statements");
+	  
+	extra.splice( extra.begin(), decls );
+	extra.splice( extra.end(), temps );
+	extra2.splice( extra2.end(), assigns );
+      }
+
+      return tupleExpr;
+    }
+
+    throw 0; // shouldn't be here
+  }
+
+
+} // namespace Tuples
+
Index: translator/Tuples/AssignExpand.h
===================================================================
--- translator/Tuples/AssignExpand.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/AssignExpand.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,37 @@
+#ifndef _ASSIGN_EXPAND_H_
+#define _ASSIGN_EXPAND_H_
+
+#include <cstdlib>
+
+#include "SynTree/Mutator.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Expression.h"
+
+#include "UniqueName.h"
+
+namespace Tuples {
+  class AssignExpander : public Mutator
+  {
+    typedef Mutator Parent;
+
+  public:
+    AssignExpander();
+    virtual Statement *mutate( ExprStmt *expr );
+    virtual Expression *mutate( SolvedTupleExpr *tupleExpr );
+
+  private:
+    std::list<Statement *> extra, extra2;
+    std::list<Expression *> replace;
+    UniqueName temporaryNamer;
+  };
+
+} // namespace Tuples
+
+
+#endif // #ifndef _ASSIGN_EXPAND_H_
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/Tuples/FlattenTuple.cc
===================================================================
--- translator/Tuples/FlattenTuple.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/FlattenTuple.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,51 @@
+#include <list>
+#include <vector>
+#include <cassert>
+#include <algorithm>
+
+#include "FlattenTuple.h"
+
+
+namespace Tuples {
+
+  FlattenTuple::FlattenTuple()
+  {
+  }
+
+  FlattenTuple::~FlattenTuple()
+  {
+  }
+
+  Expression *FlattenTuple::mutate( TupleExpr *tupleExpr )
+  {
+    CollectArgs c;
+
+    acceptAll( tupleExpr->get_exprs(), c );
+    tupleExpr->set_exprs( c.get_args() );
+
+    return tupleExpr;
+  }
+
+  void FlattenTuple::CollectArgs::visit( UntypedExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( NameExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( CastExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( AddressExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( UntypedMemberExpr *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( MemberExpr        *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( VariableExpr      *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( ConstantExpr      *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( SizeofExpr        *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( AttrExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( LogicalExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( ConditionalExpr   *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( CommaExpr         *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( TypeExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+  void FlattenTuple::CollectArgs::visit( UntypedValofExpr  *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+
+  void FlattenTuple::CollectArgs::visit( TupleExpr *tupleExpr)
+  {
+    acceptAll( tupleExpr->get_exprs(), *this );
+
+    //currentArgs.splice( currentArgs.end(), c.get_args() );
+  }
+} // namespace Tuples
Index: translator/Tuples/FlattenTuple.h
===================================================================
--- translator/Tuples/FlattenTuple.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/FlattenTuple.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,58 @@
+#ifndef _FLATTEN_TUPLE_H_
+#define _FLATTEN_TUPLE_H_
+
+#include "SynTree/Mutator.h"
+#include "SynTree/Visitor.h"
+
+#include "SynTree/Expression.h"
+
+namespace Tuples {
+  class FlattenTuple : public Mutator
+  {
+    typedef Mutator Parent;
+
+  public:
+    FlattenTuple();
+    ~FlattenTuple();
+
+    virtual Expression *mutate( TupleExpr *tupleExpr );
+
+  private:
+    class CollectArgs : public Visitor
+    {
+    public:
+      virtual void visit( UntypedExpr * );
+      virtual void visit( NameExpr * );
+      virtual void visit( CastExpr *);
+      virtual void visit( AddressExpr * );
+      virtual void visit( UntypedMemberExpr * );
+      virtual void visit( MemberExpr * );
+      virtual void visit( VariableExpr * );
+      virtual void visit( ConstantExpr * ); 
+      virtual void visit( SizeofExpr * );
+      virtual void visit( AttrExpr * );
+      virtual void visit( LogicalExpr * );
+      virtual void visit( ConditionalExpr * );
+      virtual void visit( CommaExpr * );
+      virtual void visit( TypeExpr * );
+      virtual void visit( UntypedValofExpr * );
+
+      virtual void visit( TupleExpr *tupleExpr );
+
+      std::list< Expression *> &get_args() { return currentArgs; }
+    private:
+      std::list< Expression * > currentArgs;
+    };
+
+  };
+
+} // namespace Tuples
+
+
+#endif // #ifndef _FLATTEN_TUPLE_H_
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/Tuples/FunctionChecker.cc
===================================================================
--- translator/Tuples/FunctionChecker.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/FunctionChecker.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,120 @@
+#include "FunctionChecker.h"
+#include "FunctionFixer.h"
+#include "SemanticError.h"
+
+#include <algorithm>
+#include <iostream>
+#include <cassert>
+
+namespace Tuples {
+  using namespace std;
+
+  void checkFunctions( std::list< Declaration * > translationUnit )
+  {
+    FunctionChecker fchk(true);
+    TupleDistrib td;
+    FunctionFixer ff;
+
+    mutateAll( translationUnit , fchk );
+    mutateAll( translationUnit , ff );
+    mutateAll( translationUnit , td );
+    return;
+  }
+
+  FunctionChecker::FunctionChecker( bool _topLevel, UniqueName *_nameGen ) : topLevel( _topLevel ), nameGen( _nameGen ) {
+    if( topLevel) {
+      assert( !nameGen );
+      nameGen = new UniqueName("_MVR_");
+    } else
+      assert( nameGen );
+  }
+
+  FunctionChecker::~FunctionChecker() {
+    if( topLevel) {
+      delete nameGen;
+      nameGen = 0;
+    }
+  }
+
+  Statement* FunctionChecker::mutate(ExprStmt *exprStmt) {
+    exprStmt->set_expr( maybeMutate( exprStmt->get_expr(), *this ) );
+    if ( !tempExpr.empty() ) {
+      assert ( !temporaries.empty() );
+      CompoundStmt *newBlock = new CompoundStmt( std::list< Label >() );
+      // declarations
+      for( std::list< ObjectDecl *>::iterator d = temporaries.begin(); d != temporaries.end(); ++d )
+	newBlock->get_kids().push_back( new DeclStmt( std::list<Label>(), *d ) );
+      // new expression statements
+      for( std::list< Expression *>::iterator e = tempExpr.begin(); e != tempExpr.end(); ++e )
+	newBlock->get_kids().push_back( new ExprStmt( std::list<Label>(), *e ) );
+
+      newBlock->get_kids().push_back( exprStmt );
+      return newBlock;
+    } else
+      return exprStmt;
+  }
+
+  Expression* FunctionChecker::mutate(ApplicationExpr *applicationExpr) {
+    if ( topLevel )
+      ; // In top level of Functionchecker
+
+    if ( applicationExpr->get_results().size() > 1 ) {
+      for ( std::list< Type *>::iterator res = applicationExpr->get_results().begin(); res != applicationExpr->get_results().end(); res++ )
+	temporaries.push_back( new ObjectDecl(nameGen->newName(),Declaration::Auto,LinkageSpec::AutoGen, 0, (*res)->clone(), 0 ) );
+
+      assert( ! temporaries.empty() );
+    }
+
+    applicationExpr->set_function(  maybeMutate( applicationExpr->get_function(), *this ) );
+
+    std::list< Expression * > newArgs;
+    for( std::list< Expression *>::iterator e = applicationExpr->get_args().begin(); e != applicationExpr->get_args().end(); ++e ) {
+      FunctionChecker rec( false, nameGen );
+      (*e)->acceptMutator( rec );
+
+      if ( !rec.temporaries.empty() ) {
+	TupleExpr *lhs = new TupleExpr;
+	std::list< Expression * > &tmem = lhs->get_exprs();
+	for( std::list<ObjectDecl *>::iterator d = rec.temporaries.begin();  d != rec.temporaries.end(); ++d ) {
+	  tmem.push_back( new VariableExpr( *d ) );
+	  newArgs.push_back( new VariableExpr( *d ) );
+	}
+
+	// construct tuple assignment
+	std::list<Expression *> args;
+	args.push_back( new AddressExpr(lhs) );
+	args.push_back( *e );
+	tempExpr.push_back( new UntypedExpr( new NameExpr("?=?"), args ) );
+
+	temporaries.splice( temporaries.end(), rec.temporaries );
+      } else
+	newArgs.push_back( *e );
+      // percolate to recursive calls
+    }
+
+    applicationExpr->get_args().clear();
+    std::copy( newArgs.begin(), newArgs.end(), back_inserter(applicationExpr->get_args()) );
+
+    return applicationExpr;
+  }
+
+  Expression* TupleDistrib::mutate(UntypedExpr *expr) {
+    if(  NameExpr *assgnop = dynamic_cast< NameExpr * >(expr->get_function()) ) {
+      if( assgnop->get_name() == std::string("?=?") ) {
+	std::list<Expression *> &args = expr->get_args();
+	assert(args.size() == 2);
+	//if args.front() points to a tuple and if args.back() is already resolved
+	if( AddressExpr *addr = dynamic_cast<AddressExpr *>(args.front()) )
+	  if( TupleExpr *lhs = dynamic_cast<TupleExpr *>(addr->get_arg()) )
+	    if( ApplicationExpr *rhs = dynamic_cast<ApplicationExpr *>( args.back() ) ) {
+	      for ( std::list<Expression *>::iterator tc = lhs->get_exprs().begin(); tc != lhs->get_exprs().end(); ++tc )
+		rhs->get_args().push_back( new AddressExpr( *tc ) );
+	      return rhs; // XXX
+	    }
+      } else
+	assert(false); // It's not an assignment, shouldn't be here
+    }
+    return expr;
+  }
+
+} // namespace Tuples
Index: translator/Tuples/FunctionChecker.h
===================================================================
--- translator/Tuples/FunctionChecker.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/FunctionChecker.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,55 @@
+#ifndef _TUPLE_FUNCHK_H_
+#define _TUPLE_FUNCHK_H_
+
+#include <string>
+#include <list>
+#include <iostream>
+
+#include "UniqueName.h"
+
+#include "SynTree/SynTree.h"
+#include "SynTree/Mutator.h"
+
+#include "SynTree/Type.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Statement.h"
+
+
+namespace Tuples {
+  class FunctionChecker : public Mutator
+  {
+    typedef Mutator Parent;
+
+  public:
+    FunctionChecker( bool _topLevel = false, UniqueName *_nameGen = 0 );
+    ~FunctionChecker();
+
+    virtual Expression* mutate(ApplicationExpr *applicationExpr);
+    virtual Statement* mutate(ExprStmt *exprStmt);
+
+  private:
+    bool topLevel;
+    UniqueName *nameGen;
+    std::list< ObjectDecl * > temporaries;
+    std::list< Expression * > tempExpr;
+  };
+
+  class TupleDistrib : public Mutator {
+  public:
+    virtual Expression* mutate(UntypedExpr *utExpr);
+
+  private:
+  };
+
+  void checkFunctions( std::list< Declaration * > translationUnit );
+
+} // namespace Tuples
+
+#endif // #ifndef _TUPLE_FUNCHK_H_
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/Tuples/FunctionFixer.cc
===================================================================
--- translator/Tuples/FunctionFixer.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/FunctionFixer.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,109 @@
+#include <list>
+#include <vector>
+#include <cassert>
+#include <algorithm>
+
+#include "FunctionFixer.h"
+
+namespace Tuples {
+  DeclarationWithType *FunctionFixer::mutate( FunctionDecl *functionDecl ) {
+    functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
+    mutateAll( functionDecl->get_oldDecls(), *this );
+    functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
+    index.visit( functionDecl );
+    rets.clear();
+    return functionDecl;
+  }
+
+  Type *FunctionFixer::mutate( FunctionType *functionType )
+  {
+    typedef std::list< DeclarationWithType * >  Decls;
+
+    if ( functionType->get_returnVals().size() <= 1 )  return functionType;
+    std::copy( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), back_inserter(rets) );
+
+    Type::Qualifiers qual;
+    for ( Decls::iterator i = rets.begin(); i != rets.end(); i++ ) {
+      (*i)->set_type( new PointerType( qual, (*i)->get_type() ) );
+      functionType->get_parameters().push_back( *i );
+    }
+
+    functionType->get_returnVals() = *(new std::list< DeclarationWithType * >());
+
+    functionType->set_isVarArgs( false );
+    return functionType;
+  }
+
+  Statement *FunctionFixer::mutate( ReturnStmt *retStmt )
+  {
+    bool tupleReturn = false;
+    Expression *rhs = 0;
+    // also check if returning multiple values
+    if( CastExpr *cst = dynamic_cast<CastExpr *>( retStmt->get_expr() ) ) {
+      if( ApplicationExpr *app = dynamic_cast<ApplicationExpr *>( cst->get_arg() ) ) {
+	if( app->get_results().size() > 1 ) { // doesn't need to be ApplicationExpr
+	  tupleReturn = true;
+	  rhs = app;
+	}
+      } else if( TupleExpr *t = dynamic_cast<TupleExpr *>( cst->get_arg() ) ) {
+	tupleReturn = true;
+	assert( rets.size() == t->get_exprs().size() ); // stupid check, resolve expression
+	rhs = t;
+      }
+
+      if( tupleReturn ) {
+	assert ( rhs != 0 );
+	std::list< Expression * > lhs;
+	for( std::list< DeclarationWithType * >::iterator d = rets.begin(); d != rets.end(); ++d ) {
+	  std::list<Expression *> largs;
+	  largs.push_back(new VariableExpr( *d ));
+	  Expression *exp = ResolvExpr::resolveInVoidContext( new CastExpr( new UntypedExpr(new NameExpr("*?"), largs), (*d)->get_type()),
+								       index );
+	  lhs.push_back(exp);
+	}
+	std::list< Expression * > args;
+	TupleExpr *tlhs = new TupleExpr; tlhs->set_exprs( lhs );
+	args.push_back( new AddressExpr(tlhs) );
+	args.push_back(rhs);
+
+	return new ExprStmt( std::list< Label>(), new UntypedExpr( new NameExpr("?=?"), args ) );
+      }
+    }
+    /*
+    else
+      std::cerr << "Empty return statement" << std::endl;
+    */
+
+    return retStmt;
+  }
+
+  Expression* FunctionFixer::mutate( VariableExpr *variableExpr ) {
+    if ( rets.empty() ) return variableExpr;
+    mutateAll( variableExpr->get_results(), *this );
+    if( std::find( rets.begin(), rets.end(), variableExpr->get_var() ) != rets.end() )
+//      if ( PointerType *ptr = dynamic_cast<PointerType *>(variableExpr->get_var()->get_type()) ) {
+      if ( dynamic_cast<PointerType *>(variableExpr->get_var()->get_type()) != 0 ) {
+	std::list<Expression *> largs;
+	largs.push_back( new AddressExpr(variableExpr) );
+	  Expression *expr = ResolvExpr::resolveInVoidContext( /*new CastExpr(*/new UntypedExpr( new NameExpr( "*?" ), largs )/*,
+																 ptr->get_base()),*/, index);
+	  if( ApplicationExpr *app = dynamic_cast< ApplicationExpr * >( expr ) ) {
+	    assert( app->get_args().size() == 1 );
+	    app->get_args().pop_front();
+	    app->get_args().push_back( variableExpr );
+	    return app;
+	  }
+      }
+    return variableExpr;
+  }
+
+  /*
+  Expression* FunctionFixer::mutate(ApplicationExpr *applicationExpr) {
+    std::cerr << "In Application Expression" << std::endl;
+    mutateAll( applicationExpr->get_results(), *this );
+    applicationExpr->set_function(  maybeMutate( applicationExpr->get_function(), *this ) );
+    mutateAll( applicationExpr->get_args(), *this );
+    return applicationExpr;
+  }
+  */
+} // namespace Tuples
Index: translator/Tuples/FunctionFixer.h
===================================================================
--- translator/Tuples/FunctionFixer.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/FunctionFixer.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,63 @@
+#ifndef _FUNFIX_H_
+#define _FUNFIX_H_
+
+#include "SynTree/Mutator.h"
+
+#include "SynTree/Declaration.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Type.h"
+
+#include "SymTab/Indexer.h"
+#include "ResolvExpr/Resolver.h"
+#include "ResolvExpr/AlternativeFinder.h"
+
+namespace Tuples {
+  class FunctionFixer : public Mutator
+  {
+    typedef Mutator Parent;
+
+  public:
+    FunctionFixer() {}
+    virtual ~FunctionFixer() {}
+    virtual Type       *mutate( FunctionType *functionType );
+    virtual Statement  *mutate( ReturnStmt   *retStmt  );
+    virtual DeclarationWithType *mutate( FunctionDecl *functionDecl );
+    virtual Expression *mutate( VariableExpr *variableExpr);
+
+    // indexer runs
+    virtual ObjectDecl     *mutate( ObjectDecl *objectDecl )
+    { index.visit( objectDecl ); return objectDecl; }
+    virtual TypeDecl       *mutate( TypeDecl *typeDecl )
+    { index.visit( typeDecl ); return typeDecl; }
+    virtual TypedefDecl    *mutate( TypedefDecl *typeDecl )
+    { index.visit( typeDecl ); return typeDecl; }
+    virtual StructDecl     *mutate( StructDecl *aggregateDecl )
+    { index.visit( aggregateDecl ); return aggregateDecl; }
+    virtual UnionDecl      *mutate( UnionDecl *aggregateDecl )
+    { index.visit( aggregateDecl ); return aggregateDecl; }
+    virtual EnumDecl       *mutate( EnumDecl *aggregateDecl )
+    { index.visit( aggregateDecl ); return aggregateDecl; }
+
+    virtual Type           *mutate( StructInstType *aggrInst )
+    { index.visit( aggrInst ); return aggrInst; }
+    virtual Type           *mutate( UnionInstType *aggrInst )
+    { index.visit( aggrInst ); return aggrInst; }
+
+
+
+  private:
+    std::list< DeclarationWithType * > rets;
+    SymTab::Indexer index;
+  };
+
+} // namespace Tuples
+
+
+#endif // #ifndef _FUNFIX_H_
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/Tuples/MultRet.cc
===================================================================
--- translator/Tuples/MultRet.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/MultRet.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,157 @@
+#include <list>
+#include <vector>
+#include <cassert>
+#include <algorithm>
+
+#include "MultRet.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+
+namespace Tuples {
+
+  MVRMutator::MVRMutator() : newVars( 0 ), newCode( 0 )
+  {
+  }
+
+  MVRMutator::~MVRMutator()
+  {
+  }
+
+  int MVRMutator::curVal = 0;
+
+  Statement *MVRMutator::mutate( ExprStmt *exprStmt ){
+    MVRMutator toplevel;
+    exprStmt->set_expr( maybeMutate( exprStmt->get_expr(), toplevel ) );
+
+    if ( toplevel.hasCode() ) {
+      assert ( toplevel.getVars() != 0 );
+
+      typedef std::list<Statement *> Statements;
+
+      CompoundStmt *code = new CompoundStmt( std::list< Label >() );
+
+      // copy variables
+      Statements &vars = toplevel.getVars()->get_kids();
+      for( Statements::iterator i = vars.begin(); i != vars.end(); i++ )
+	code->get_kids().push_back( *i );
+
+      // copy statements
+      Statements &block = toplevel.getCode()->get_kids();
+      for( Statements::iterator i = block.begin(); i != block.end(); i++ )
+	code->get_kids().push_back( *i );
+
+      return code;
+    } else
+      return exprStmt;
+  }
+
+
+  Expression *MVRMutator::mutate( ApplicationExpr *appExpr )
+  {
+    // appExpr->set_function(  maybeMutate( appExpr->get_function(), *this ) );
+    bool mulretp = false;
+    VariableExpr *funname;
+    if ( (funname = dynamic_cast<VariableExpr *>(appExpr->get_function())) == 0 ) goto DoArgs;
+
+    FunctionDecl *fundecl;
+    if ((fundecl = dynamic_cast<FunctionDecl *>(funname->get_var())) == 0) goto DoArgs;
+
+    {
+      typedef std::list<DeclarationWithType*> RetType;
+
+      RetType &rets = fundecl->get_functionType()->get_returnVals();
+      if ( rets.size() <= 1 ) goto DoArgs;
+      mulretp = true;
+
+      if( newVars == 0 )
+	newVars = new CompoundStmt( std::list<Label>(0) );
+
+      for (RetType::iterator i = rets.begin() ; i != rets.end(); i++) {
+	DeclStmt *arg = newVar( *i );
+	newVars->get_kids().push_back( arg );
+	add_pending( arg->get_decl() );
+      }
+    }
+
+  DoArgs:
+     // mutate the argument list
+    typedef std::list< Expression *> Exprs;
+    Exprs &args = appExpr->get_args();
+    std::list< Expression * > newArgs;
+    for( Exprs::iterator i = args.begin(); i != args.end(); i++ ) {
+      MVRMutator next;
+      Expression *mutated = (*i)->acceptMutator( next );
+
+      if ( next.hasCode() ) {
+	// merge new vars and bodies
+	typedef std::list< Statement * > Stmts;
+	Stmts &vars = next.getVars()->get_kids();
+	Stmts &block = next.getCode()->get_kids();
+
+	if (newVars == 0)
+	  newVars = new CompoundStmt( std::list< Label >() );
+	for( Stmts::iterator i = vars.begin(); i != vars.end(); i++ )  // std::splice? -- need to append lists
+	  newVars->get_kids().push_back( *i );
+
+	if (newCode == 0)
+	  newCode = new CompoundStmt( std::list< Label >() );
+	for( Stmts::iterator i = block.begin(); i != block.end(); i++ )
+	  newCode->get_kids().push_back( *i );
+
+      }
+
+      if ( next.hasResults() ) {
+	Exprs &res = next.get_results();
+	for( Exprs::iterator i = res.begin(); i != res.end(); i++ )
+	  newArgs.push_back( *i );
+      } else
+	newArgs.push_back( mutated );
+    }
+
+    appExpr->get_args() = newArgs;  // new argument list
+
+
+    if ( mulretp ) {
+      // add 'out' parameters
+      if ( ! argsToAdd.empty() )
+	for(std::list< Expression *>::iterator i = argsToAdd.begin(); i != argsToAdd.end(); i++)
+	  (appExpr->get_args()).push_back( *i );
+      // clear 'out' parameters ( so that the list can be reused -- substitute by auto_ptr later? )
+
+      if (newCode == 0)
+	newCode = new CompoundStmt( std::list<Label>(0) );
+    }
+
+    // add to block of code
+    if ( newCode != 0 )
+      newCode->get_kids().push_back( new ExprStmt( std::list<Label>(), appExpr ) );
+
+    return appExpr;
+  }
+
+  // Auxiliary function to generate new names for the `output' parameters
+  DeclStmt *MVRMutator::newVar( DeclarationWithType *reqDecl ) {
+    // std::ostrstream os;
+    // os << "__" << curVal++ << "__";// << std::ends;
+    // os.freeze( false );
+
+    ObjectDecl *decl;
+    if ((decl = dynamic_cast<ObjectDecl *>( reqDecl )) != 0)
+      // return new DeclStmt( new ObjectDecl( std::string (os.str(), os.pcount()), );
+      return new DeclStmt( std::list<Label>(), decl );
+    else
+      return 0;
+  }
+
+  void MVRMutator::add_pending( Declaration *decl ) {
+    ObjectDecl *obj;
+    if ( (obj = dynamic_cast< ObjectDecl * >( decl )) == 0 ) return;
+
+    VariableExpr *var = new VariableExpr(obj, 0 );
+    results.push_back( var ); // probably change this name to newResults or something
+    argsToAdd.push_back( new AddressExpr( var ) );
+    return;
+  }
+}
Index: translator/Tuples/MultRet.h
===================================================================
--- translator/Tuples/MultRet.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/MultRet.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,49 @@
+#ifndef _MULTRET_H_
+#define _MULTRET_H_
+
+#include "SynTree/Mutator.h"
+#include "SynTree/Visitor.h"
+
+#include "SynTree/Expression.h"
+#include "SynTree/Statement.h"
+
+namespace Tuples {
+  class MVRMutator : public Mutator
+  {
+    typedef Mutator Parent;
+
+  public:
+    MVRMutator();
+    ~MVRMutator();
+
+    virtual Statement  *mutate( ExprStmt        *exprStmt );
+    virtual Expression *mutate( ApplicationExpr *appExpr  );
+
+    bool hasCode() const { return ( newCode != 0 ); }
+    CompoundStmt *getCode() const { return newCode; }
+    CompoundStmt *getVars() const { return newVars; }
+
+    bool hasResults() const { return (! results.empty()); }
+    std::list<Expression *> &get_results() { return results; }
+
+  private:
+    CompoundStmt *newVars;
+    CompoundStmt *newCode;
+    std::list<Expression *> argsToAdd;
+    std::list<Expression *> results;
+
+    static int curVal;
+    DeclStmt *newVar( DeclarationWithType * );
+    void add_pending( Declaration * );
+  };
+
+} // namespace Tuples
+
+
+#endif // #ifndef _MULTRET_H_
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/Tuples/Mutate.cc
===================================================================
--- translator/Tuples/Mutate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/Mutate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,24 @@
+#include "SynTree/Mutator.h"
+
+#include "Mutate.h"
+//#include "TupleFixer.h"
+//#include "FlattenTuple.h"
+//#include "MultRet.h"
+#include "FunctionFixer.h"
+#include "AssignExpand.h"
+//#include "FixReturn.h"
+//#include "MassAssignment.h"
+
+namespace Tuples {
+
+  void mutate( std::list< Declaration * > translationUnit )
+  {
+    //FunctionFixer fst;
+    AssignExpander snd;
+
+    //mutateAll( translationUnit, fst );
+    mutateAll( translationUnit, snd );
+  }
+} // namespace Tuples
+
+
Index: translator/Tuples/Mutate.h
===================================================================
--- translator/Tuples/Mutate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/Mutate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,23 @@
+#ifndef TUPLES_MUTATE_H
+#define TUPLES_MUTATE_H
+
+#include <list>
+#include <iostream>
+
+#include "SynTree/Declaration.h"
+
+
+namespace Tuples {
+
+  void mutate( std::list< Declaration* > translationUnit );
+  void mulReturn( std::list< Declaration * > translationUnit );
+
+} // namespace Tuples
+
+#endif // #ifndef TUPLES_MUTATE_H
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/Tuples/NameMatcher.cc
===================================================================
--- translator/Tuples/NameMatcher.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/NameMatcher.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,47 @@
+#include "NameMatcher.h"
+#include "NameMatcher.h"
+
+namespace Tuples {
+  NameMatcher::NameMatcher( std::list< DeclarationWithType* > &formals )
+    : current( 0 ) {
+    int cnt = 0;
+    for( std::list< DeclarationWithType *>::const_iterator f = formals.begin(); f != formals.end(); ++f ) {
+      table.insert( std::pair< std::string, int >( (*f)->get_name(), cnt++ ) );
+      index.push_back(*f);
+    }
+    exprs.reserve( index.size() );
+  }
+
+  NameMatcher::~NameMatcher() {}
+
+  void NameMatcher::match( ResolvExpr::AltList &alternatives ) throw (NoMatch) {
+    if( alternatives.size() != index.size() )
+      throw NoMatch("Length of actuals and formals differ");
+
+    for( ResolvExpr::AltList::const_iterator a = alternatives.begin(); a != alternatives.end(); ++a ) {
+      if( a->expr->get_argName() != 0 )
+	if ( NameExpr *name = dynamic_cast<NameExpr *>( a->expr->get_argName() ) ) {
+	  if ( table.find( name->get_name() ) != table.end() ) {
+	    std::cerr << "Rearranging to " << table[ name->get_name() ] << "position in the list." << std::endl;
+	    exprs[ table[ name->get_name() ] ] = &(*a);
+	  } else
+	    throw NoMatch( name->get_name() + "no such  designation" );
+	} /*else if( TupleExpr *tup = dynamic_cast<TupleExpr *>( a->expr->get_argName() ) )
+	    std::cerr << "Designated expression" << std::endl; */
+      exprs.push_back( &(*a) );
+    }
+
+    /*std::cerr << "In matcher/match: ";
+    if ( exprs.size() != index.size() )
+      std::cerr << "exprs and index differ in length" << std::endl;
+    else
+      std::cerr << "is all good." << std::endl;
+    */
+  }
+
+  ResolvExpr::Alternative &NameMatcher::get_next() throw (NoMoreElements) {
+    if( current++ >= (int)(index.size()) )
+      throw NoMoreElements();
+    return *(new ResolvExpr::Alternative());
+  }
+} // namespace Tuples
Index: translator/Tuples/NameMatcher.h
===================================================================
--- translator/Tuples/NameMatcher.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/NameMatcher.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,49 @@
+#ifndef _TUPLE_NAMEMATCH_H_
+#define _TUPLE_NAMEMATCH_H_
+
+#include <map>
+#include <vector>
+#include <string>
+
+#include "SynTree/SynTree.h"
+#include "SynTree/Mutator.h"
+
+#include "SynTree/Type.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Statement.h"
+
+#include "ResolvExpr/Alternative.h"
+
+namespace Tuples {
+  struct NoMoreElements {};
+  struct NoMatch {
+    NoMatch( std::string msg ) : message( msg ) {}
+    std::string message;
+  };
+
+  class NameMatcher
+  {
+  public:
+    NameMatcher( std::list< DeclarationWithType* >& );
+    ~NameMatcher();
+
+    void match( ResolvExpr::AltList &alternatives ) throw (NoMatch) ;
+    ResolvExpr::Alternative &get_next() throw (NoMoreElements);
+
+  private:
+    int current;
+    std::vector< DeclarationWithType* > index;
+    std::vector< const ResolvExpr::Alternative * > exprs;
+    std::map< std::string, int> table;
+  };
+
+} // namespace Tuples
+
+#endif // #ifndef _TUPLE_NAMEMATCH_H_
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/Tuples/TupleAssignment.cc
===================================================================
--- translator/Tuples/TupleAssignment.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/TupleAssignment.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,400 @@
+#include "ResolvExpr/AlternativeFinder.h"
+#include "ResolvExpr/Alternative.h"
+#include "ResolvExpr/typeops.h"
+#include "SynTree/Expression.h"
+#include "TupleAssignment.h"
+#include "SemanticError.h"
+
+#include <functional>
+#include <algorithm>
+#include <iterator>
+#include <iostream>
+#include <cassert>
+#include <set>
+
+namespace Tuples {
+  TupleAssignSpotter::TupleAssignSpotter( ResolvExpr::AlternativeFinder *f = 0 )
+    : currentFinder(f), matcher(0), hasMatched( false ) {}
+
+  bool TupleAssignSpotter::pointsToTuple( Expression *expr ) {
+    // also check for function returning tuple of reference types
+    if(AddressExpr *addr = dynamic_cast<AddressExpr *>(expr) )
+      if( isTuple(addr->get_arg() ) )
+	return true;
+    return false;
+  }
+
+  bool TupleAssignSpotter::isTupleVar( DeclarationWithType *decl ) {
+    if( dynamic_cast<TupleType *>(decl->get_type()) )
+      return true;
+    return false;
+  }
+
+  bool TupleAssignSpotter::isTuple( Expression *expr, bool isRight ) {
+    // true if `expr' is an expression returning a tuple: tuple, tuple variable or MRV function
+    if ( !expr ) return false;
+
+    if( dynamic_cast<TupleExpr *>(expr) )
+      return true;
+    else if( VariableExpr *var = dynamic_cast<VariableExpr *>(expr) ) {
+      if( isTupleVar(var->get_var()) )
+	return true;
+    }
+
+    return false;
+  }
+
+  bool TupleAssignSpotter::match() {
+    assert ( matcher != 0 );
+
+    std::list< Expression * > new_assigns;
+    if (! matcher->match(new_assigns) )
+      return false;
+
+    if( new_assigns.empty() ) return false;
+    /*return */matcher->solve( new_assigns );
+    if( dynamic_cast<TupleAssignSpotter::MultipleAssignMatcher *>( matcher ) ) {
+      // now resolve new assignments
+      std::list< Expression * > solved_assigns;
+      ResolvExpr::AltList solved_alts;
+      assert( currentFinder != 0 );
+
+      ResolvExpr::AltList current;
+      for( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) {
+	//try {
+	ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() );
+	finder.findWithAdjustment(*i);
+	// prune expressions that don't coincide with
+	ResolvExpr::AltList alts = finder.get_alternatives();
+	assert( alts.size() == 1 );
+	assert(alts.front().expr != 0 );
+	current.push_back( finder.get_alternatives().front() );
+	solved_assigns.push_back( alts.front().expr->clone() );
+	//solved_assigns.back()->print(std::cerr);
+	/*} catch( ... ) {
+	  continue; // no reasonable alternative found
+	  }*/
+      }
+      options.add_option( current );
+
+      return true;
+    } else { // mass assignment
+      //if( new_assigns.empty() ) return false;
+      std::list< Expression * > solved_assigns;
+      ResolvExpr::AltList solved_alts;
+      assert( currentFinder != 0 );
+
+      ResolvExpr::AltList current;
+      if ( optMass.empty() ) {
+	for( std::list< Expression * >::size_type i = 0; i != new_assigns.size(); ++i )
+	  optMass.push_back( ResolvExpr::AltList() );
+      }
+      int cnt = 0;
+      for( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i, cnt++ ) {
+
+	ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() );
+	finder.findWithAdjustment(*i);
+	ResolvExpr::AltList alts = finder.get_alternatives();
+	assert( alts.size() == 1 );
+	assert(alts.front().expr != 0 );
+	current.push_back( finder.get_alternatives().front() );
+	optMass[cnt].push_back( finder.get_alternatives().front() );
+	solved_assigns.push_back( alts.front().expr->clone() );
+      }
+
+      return true;
+    }
+
+    return false;
+  }
+
+  bool TupleAssignSpotter::isMVR( Expression *expr ) {
+    if( expr->get_results().size() > 1 ) {
+      // MVR processing
+      return true;
+    }
+    return false;
+  }
+
+  bool TupleAssignSpotter::isTupleAssignment( UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities ) {
+    if(  NameExpr *assgnop = dynamic_cast< NameExpr * >(expr->get_function()) ) {
+
+      if( assgnop->get_name() == std::string("?=?") ) {
+
+	for( std::list<ResolvExpr::AltList>::iterator ali = possibilities.begin(); ali != possibilities.end(); ++ali ) {
+	  assert( ali->size() == 2 );
+	  ResolvExpr::AltList::iterator opit = ali->begin();
+	  ResolvExpr::Alternative op1 = *opit, op2 = *(++opit);
+
+	  if( pointsToTuple(op1.expr) ) { // also handles tuple vars
+	    if ( isTuple( op2.expr, true ) )
+	      matcher = new MultipleAssignMatcher(op1.expr, op2.expr);
+	    else if( isMVR( op2.expr ) ) {
+	      // handle MVR differently
+	    } else
+	      // mass assignment
+	      matcher = new MassAssignMatcher(op1.expr, op2.expr);
+
+	    std::list< ResolvExpr::AltList > options;
+	    if( match() )
+	      /*
+	      if( hasMatched ) {
+		// throw SemanticError("Ambiguous tuple assignment");
+	      } else {*/
+		// Matched for the first time
+		hasMatched = true;
+		/*} */
+	  } /* else if ( isTuple( op2 ) )
+	    throw SemanticError("Inapplicable tuple assignment.");
+	    */
+	}
+
+	if( hasMatched ) {
+	  if( dynamic_cast<TupleAssignSpotter::MultipleAssignMatcher *>( matcher ) ) {
+	    //options.print( std::cerr );
+	    std::list< ResolvExpr::AltList >best = options.get_best();
+	    if( best.size() == 1 ) {
+	      std::list<Expression *> solved_assigns;
+	      for( ResolvExpr::AltList::iterator i = best.front().begin(); i != best.front().end(); ++i ){
+		solved_assigns.push_back( i->expr );
+	      }
+	      /* assigning cost zero? */
+	      currentFinder->get_alternatives().push_front( ResolvExpr::Alternative(new SolvedTupleExpr(solved_assigns/*, SolvedTupleExpr::MULTIPLE*/), currentFinder->get_environ(), ResolvExpr::Cost() ) );
+	    }
+	  } else {
+	    assert(! optMass.empty() );
+	    ResolvExpr::AltList winners;
+	    for( std::vector< ResolvExpr::AltList >::iterator i = optMass.begin(); i != optMass.end(); ++i )
+	      findMinCostAlt( i->begin(), i->end(), back_inserter(winners) );
+
+	    std::list< Expression *> solved_assigns;
+	    for( ResolvExpr::AltList::iterator i = winners.begin(); i != winners.end(); ++i )
+	      solved_assigns.push_back( i->expr );
+	    currentFinder->get_alternatives().push_front( ResolvExpr::Alternative(new SolvedTupleExpr(solved_assigns/*, SolvedTupleExpr::MASS*/), currentFinder->get_environ(), ResolvExpr::Cost() ) );
+	  }
+	}
+      }
+    }
+    return hasMatched;
+  }
+
+  void TupleAssignSpotter::Matcher::init( Expression *_lhs, Expression *_rhs ) {
+    lhs.clear();
+    if(AddressExpr *addr = dynamic_cast<AddressExpr *>(_lhs) )
+      if( TupleExpr *tuple = dynamic_cast<TupleExpr *>(addr->get_arg()) )
+	std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(lhs) );
+
+    rhs.clear();
+  }
+
+  TupleAssignSpotter::Matcher::Matcher( /*TupleAssignSpotter &spot,*/ Expression *_lhs, Expression *_rhs ) /*: own_spotter(spot) */{
+    init(_lhs,_rhs);
+  }
+
+  TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( Expression *_lhs, Expression *_rhs )/* : own_spotter(spot) */{
+    init(_lhs,_rhs);
+
+    if( TupleExpr *tuple = dynamic_cast<TupleExpr *>(_rhs) )
+      std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(rhs) );
+  }
+
+  UntypedExpr *TupleAssignSpotter::Matcher::createAssgn( Expression *left, Expression *right ) {
+    if ( left && right ) {
+      std::list< Expression * > args;
+      args.push_back(new AddressExpr(left->clone()));  args.push_back(right->clone());
+      return new UntypedExpr(new NameExpr("?=?"), args);
+    } else
+      throw 0; // xxx - diagnose the problem
+  }
+
+  bool TupleAssignSpotter::MassAssignMatcher::match( std::list< Expression * > &out ) {
+    if ( lhs.empty() || (rhs.size() != 1) ) return false;
+
+    for( std::list< Expression * >::iterator l = lhs.begin(); l != lhs.end(); l++ ) {
+      std::list< Expression * > args;
+      args.push_back( new AddressExpr(*l) );
+      args.push_back( rhs.front() );
+      out.push_back( new UntypedExpr(new NameExpr("?=?"), args) );
+    }
+
+    return true;
+  }
+
+  bool TupleAssignSpotter::MassAssignMatcher::solve( std::list< Expression * > &assigns ) {
+    /*
+    std::list< Expression * > solved_assigns;
+    ResolvExpr::AltList solved_alts;
+    assert( currentFinder != 0 );
+
+    ResolvExpr::AltList current;
+    if ( optMass.empty() ) {
+      for( std::list< Expression * >::size_type i = 0; i != new_assigns.size(); ++i )
+	optMass.push_back( ResolvExpr::AltList() );
+    }
+    int cnt = 0;
+    for( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i, cnt++ ) {
+
+      ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() );
+      finder.findWithAdjustment(*i);
+      ResolvExpr::AltList alts = finder.get_alternatives();
+      assert( alts.size() == 1 );
+      assert(alts.front().expr != 0 );
+      current.push_back( finder.get_alternatives().front() );
+      optMass[cnt].push_back( finder.get_alternatives().front() );
+      solved_assigns.push_back( alts.front().expr->clone() );
+    }
+    */
+    return true;
+  }
+
+  bool TupleAssignSpotter::MultipleAssignMatcher::match( std::list< Expression * > &out ) {
+    // need more complicated matching
+    if( lhs.size() == rhs.size() ) {
+      zipWith( lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), back_inserter(out), TupleAssignSpotter::Matcher::createAssgn );
+      return true;
+    } //else
+    //std::cerr << "The length of (left, right) is: (" << lhs.size() << "," << rhs.size() << ")" << std::endl;*/
+    return false;
+  }
+
+  bool TupleAssignSpotter::MultipleAssignMatcher::solve( std::list< Expression * > &assigns ) {
+    /*
+    std::list< Expression * > solved_assigns;
+    ResolvExpr::AltList solved_alts;
+    assert( currentFinder != 0 );
+
+    ResolvExpr::AltList current;
+    for( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) {
+      //try {
+      ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() );
+      finder.findWithAdjustment(*i);
+      // prune expressions that don't coincide with
+      ResolvExpr::AltList alts = finder.get_alternatives();
+      assert( alts.size() == 1 );
+      assert(alts.front().expr != 0 );
+      current.push_back( finder.get_alternatives().front() );
+      solved_assigns.push_back( alts.front().expr->clone() );
+      //solved_assigns.back()->print(std::cerr);
+      //} catch( ... ) {
+      //continue; // no reasonable alternative found
+      //}
+    }
+    options.add_option( current );
+    */
+
+    return true;
+  }
+
+  void TupleAssignSpotter::Options::add_option( ResolvExpr::AltList &opt ) {
+    using namespace std;
+
+    options.push_back( opt );
+    /*
+      vector< Cost > costs;
+      costs.reserve( opt.size() );
+      transform( opt.begin(), opt.end(), back_inserter(costs), ptr_fun(extract_cost) );
+    */
+    // transpose matrix
+    if ( costMatrix.empty() )
+      for( unsigned int i = 0; i< opt.size(); ++i)
+	costMatrix.push_back( vector<ResolvExpr::Cost>() );
+
+    int cnt = 0;
+    for( ResolvExpr::AltList::iterator i = opt.begin(); i != opt.end(); ++i, cnt++ )
+      costMatrix[cnt].push_back( i->cost );
+
+    return;
+  }
+
+  std::list< ResolvExpr::AltList > TupleAssignSpotter::Options::get_best() {
+    using namespace std;
+    using namespace ResolvExpr;
+    list< ResolvExpr::AltList > ret;
+    list< multiset<int> > solns;
+    for( vector< vector<Cost> >::iterator i = costMatrix.begin(); i != costMatrix.end(); ++i ) {
+      list<int> current;
+      findMinCost( i->begin(), i->end(), back_inserter(current) );
+      solns.push_back( multiset<int>(current.begin(), current.end()) );
+    }
+    // need to combine
+    multiset<int> result;
+    lift_intersection( solns.begin(), solns.end(), inserter( result, result.begin() ) );
+    if( result.size() != 1 )
+      throw SemanticError("Ambiguous tuple expression");
+    ret.push_back(get_option( *(result.begin() )));
+    return ret;
+  }
+
+  void TupleAssignSpotter::Options::print( std::ostream &ostr ) {
+    using namespace std;
+
+    for( vector< vector < ResolvExpr::Cost > >::iterator i = costMatrix.begin(); i != costMatrix.end(); ++i ) {
+      for( vector < ResolvExpr::Cost >::iterator j = i->begin(); j != i->end(); ++j )
+	ostr << *j << " " ;
+      ostr << std::endl;
+    }
+    
+    return;
+  }
+
+  ResolvExpr::Cost extract_cost( ResolvExpr::Alternative &alt ) {
+    return alt.cost;
+  }
+
+  template< typename InputIterator, typename OutputIterator >
+  void
+  TupleAssignSpotter::Options::findMinCost( InputIterator begin, InputIterator end, OutputIterator out )
+  {
+    using namespace ResolvExpr;
+    std::list<int> alternatives;
+
+    // select the alternatives that have the minimum parameter cost
+    Cost minCost = Cost::infinity;
+    unsigned int index = 0;
+    for( InputIterator i = begin; i != end; ++i, index++ ) {
+      if( *i < minCost ) {
+        minCost = *i;
+        alternatives.clear();
+        alternatives.push_back( index );
+      } else if( *i == minCost ) {
+        alternatives.push_back( index );
+      }
+    }
+    std::copy( alternatives.begin(), alternatives.end(), out );
+  }
+
+  template< class InputIterator, class OutputIterator >
+  void TupleAssignSpotter::Options::lift_intersection( InputIterator begin, InputIterator end, OutputIterator out ){
+    if( begin == end ) return;
+    InputIterator test = begin;
+
+    if(++test == end)
+      { copy(begin->begin(), begin->end(), out); return; }
+
+
+    std::multiset<int> cur; // InputIterator::value_type::value_type
+    copy( begin->begin(), begin->end(), inserter( cur, cur.begin() ) );
+
+    while( test != end ) {
+      std::multiset<int> temp;
+      set_intersection( cur.begin(), cur.end(), test->begin(), test->end(), inserter(temp,temp.begin()) );
+      cur.clear();
+      copy( temp.begin(), temp.end(), inserter(cur,cur.begin()));
+      ++test;
+    }
+
+    copy( cur.begin(), cur.end(), out );
+    return;
+  }
+
+
+  ResolvExpr::AltList TupleAssignSpotter::Options::get_option( std::list< ResolvExpr::AltList >::size_type index ) {
+    if( index >= options.size() )
+      throw 0; // XXX
+    std::list< ResolvExpr::AltList >::iterator it = options.begin();
+    for( std::list< ResolvExpr::AltList >::size_type i = 0; i < index; ++i, ++it );
+    return *it;
+  }
+
+
+} // namespace Tuples
Index: translator/Tuples/TupleAssignment.h
===================================================================
--- translator/Tuples/TupleAssignment.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/TupleAssignment.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,127 @@
+#ifndef _TUPLE_ASSIGNMENT_H_
+#define _TUPLE_ASSIGNMENT_H_
+
+#include <string>
+#include <vector>
+#include "ResolvExpr/AlternativeFinder.h"
+
+#include "SynTree/Expression.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+
+namespace Tuples {
+  class TupleAssignSpotter {
+  public:
+    // dispatcher for Tuple (multiple and mass) assignment operations
+    TupleAssignSpotter( ResolvExpr::AlternativeFinder * );
+    ~TupleAssignSpotter() { delete matcher; matcher = 0; }
+
+    bool pointsToTuple( Expression * );
+    static bool isTupleVar( DeclarationWithType * );
+    bool isTuple( Expression *, bool isRight = false );
+    bool isMVR( Expression * );
+    bool isTupleAssignment( UntypedExpr *, std::list<ResolvExpr::AltList> & );
+    bool match();
+
+  private:
+    // records for assignment generation
+    class Options {
+    public:
+      void add_option( ResolvExpr::AltList &opt );
+      std::list< ResolvExpr::AltList > get_best();
+      void print( std::ostream & );
+      int size() const { return options.size(); }
+      ResolvExpr::AltList get_option( std::list< ResolvExpr::AltList >::size_type index );
+
+      // should really use the one in ResolvExpr/AlternativeFinder, but it's too coupled with the object
+      template< typename InputIterator, typename OutputIterator >
+      void findMinCost( InputIterator begin, InputIterator end, OutputIterator out );
+
+      template< typename InputIterator, typename OutputIterator >
+      void lift_intersection( InputIterator begin, InputIterator end, OutputIterator out );
+    private:
+      std::list< ResolvExpr::AltList > options;
+      std::vector< std::vector< ResolvExpr::Cost > > costMatrix;
+    };
+
+    class Matcher {
+    public:
+      Matcher( /*TupleAssignSpotter &spot, */Expression *_lhs, Expression *_rhs );
+      virtual ~Matcher() {}
+      virtual bool match( std::list< Expression * > &out ) = 0;
+      virtual bool solve( std::list< Expression * > &assigns ) = 0;
+      static UntypedExpr *createAssgn( Expression *left, Expression *right );
+    protected:
+      Matcher() /*: own_spotter( TupleAssignSpotter(0) ) */{}
+      void init(/* TupleAssignSpotter &, */Expression *_lhs, Expression *_rhs );
+      std::list< Expression * > lhs, rhs;
+      //TupleAssignSpotter &own_spotter;
+    };
+
+    class MassAssignMatcher : public Matcher {
+    public:
+      MassAssignMatcher( Expression *_lhs, Expression *_rhs ) : Matcher( _lhs, _rhs ) {
+	rhs.push_back( _rhs );
+      }
+      virtual bool match( std::list< Expression * > &out );
+      virtual bool solve( std::list< Expression * > &assigns );
+    private:
+      //std::vector< ResolvExpr::AltList > optMass;
+    };
+
+    class MultipleAssignMatcher : public Matcher {
+    public:
+      MultipleAssignMatcher( Expression *_lhs, Expression *_rhs );
+      virtual bool match( std::list< Expression * > &out );
+      virtual bool solve( std::list< Expression * > &assigns );
+    private:
+      //Options options;
+    };
+
+    friend class Matcher;
+
+    ResolvExpr::AlternativeFinder *currentFinder;
+    //std::list<Expression *> rhs, lhs;
+    Expression *rhs, *lhs;
+    Matcher *matcher;
+    bool hasMatched;
+    Options options;
+    std::vector< ResolvExpr::AltList > optMass;
+  };
+
+
+  ResolvExpr::Cost extract_cost( ResolvExpr::Alternative & );
+
+  template< typename InputIterator, typename OutputIterator >
+  void
+  findMinCostAlt( InputIterator begin, InputIterator end, OutputIterator out )
+  {
+    using namespace ResolvExpr;
+    AltList alternatives;
+
+    // select the alternatives that have the minimum parameter cost
+    Cost minCost = Cost::infinity;
+    for( AltList::iterator i = begin; i != end; ++i ) {
+      if( i->cost < minCost ) {
+        minCost = i->cost;
+        i->cost = i->cvtCost;
+        alternatives.clear();
+        alternatives.push_back( *i );
+      } else if( i->cost == minCost ) {
+        i->cost = i->cvtCost;
+        alternatives.push_back( *i );
+      }
+    }
+    std::copy( alternatives.begin(), alternatives.end(), out );
+  }
+
+} // namespace Tuples
+
+
+#endif // #ifndef _TUPLE_ASSIGNMENT_H_
+
+/*
+  Local Variables:
+  mode: c++
+  End:
+*/
Index: translator/Tuples/module.mk
===================================================================
--- translator/Tuples/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/Tuples/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,14 @@
+SRC += 	Tuples/Mutate.cc \
+	Tuples/AssignExpand.cc \
+	Tuples/FunctionFixer.cc \
+	Tuples/TupleAssignment.cc \
+	Tuples/FunctionChecker.cc \
+	Tuples/NameMatcher.cc \
+#	Tuples/MultipleAssign.cc \
+#	Tuples/FlattenTuple.cc \
+#	Tuples/MultRet.cc \
+#	Tuples/FixReturn.cc \
+#	Tuples/MassAssignment.cc \
+#	Tuples/TupleFixer.cc \
+	$(NULL)
+
Index: translator/attr-ex
===================================================================
--- translator/attr-ex	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/attr-ex	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,49 @@
+I Compile-time resolution
+=========================
+
+1. an isolated name, where the argument is implicitly determined by the result context
+
+@max
+
+2. a direct application to a manifest type
+
+@max( int )
+
+3. constraining a type variable; the application is implicitly performed at the call site as in (2)
+
+forall( type T | { T @max( T ); } ) T x( T t );
+
+
+II Run-time resolution
+======================
+
+1. an indirect reference, where the argument is implicitly determined by the result context
+
+attr_var = &@max;
+x = (*attr_var);
+
+2. an indirect application to a manifest type
+
+(*attr_var)( int )
+
+3. a direct application to a type variable
+
+@max( T )
+
+Under what circumstances can this be done at compile/link time?
+
+
+III Declaration forms
+=====================
+
+1. monomorphic with implicit argument
+
+int @max;
+
+2. monomorphic with explicit argument
+
+int @max( int );
+
+3. polymorphic
+
+forall( type T | constraint( T ) ) int @attr( T );
Index: translator/comments.txt
===================================================================
--- translator/comments.txt	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/comments.txt	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,7 @@
+BasicInit::mutate(SynTree::CompoundStmt *compoundStmt)
+	- collect all decl stmts from kids
+	- move to top of block
+	- replace initializers with assignment stmts
+
+	- throw( 0 ) s.b. throw SemanticError( "type doesn't match initializer in ", odecl );
+	- doesn't work when initialization depends on previous computation in same block
Index: translator/ctxts.c
===================================================================
--- translator/ctxts.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ctxts.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,11 @@
+context has_f( type T )
+{
+  T f( T );
+};
+
+context has_g( type U | has_f( U ) )
+{
+  U g( U );
+};
+
+forall( type V | has_g( V ) ) void h( V );
Index: translator/esskaykay.c
===================================================================
--- translator/esskaykay.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/esskaykay.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,11 @@
+// "./cfa-cpp -cn esskaykay.c"
+
+// forall (type A, type B, type C) C ess (C (*f) (A,B), B (*g) (A), A x) { return f(x,g(x)); }
+forall (type A, type B, type C) C ess (C (*(*f)(A))(B), B (*g)(A), A x) { return f(x)(g(x)); }
+
+// forall (type A, type B) A kay (A a, B b) { return a; }
+forall (type A, type B) A (*kay(A a))(B b);
+
+// Now is the following function well-typed, or not?
+
+forall (type A) A esskaykay (A x) { ess (kay, kay, x); }
Index: translator/examples/Makefile
===================================================================
--- translator/examples/Makefile	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/examples/Makefile	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,24 @@
+CC=cfa
+CFLAGS=-g
+
+%.i: %.c
+	-$(CC) $(CFLAGS) -CFA $< > $@
+
+%.o: %.i
+	$(CC) $(CFLAGS) -c -o $@ $<
+
+all: vector_test
+
+vector_test: vector_test.o vector_int.o fstream.o iostream.o array.o iterator.o
+fstream_test: fstream_test.o fstream.o iostream.o
+
+array.o: array.i array.h iterator.h
+iterator.o: iterator.i iterator.h iostream.h
+vector_test.o: vector_test.i vector_int.h iostream.h fstream.h
+vector_int.o: vector_int.i vector_int.h
+fstream_test.o: fstream_test.i iostream.h fstream.h
+fstream.o: fstream.i iostream.h fstream.h
+iostream.o: iostream.i iostream.h
+
+clean:
+	rm -f fstream_test vector_test *.i *.o
Index: translator/examples/array.c
===================================================================
--- translator/examples/array.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/examples/array.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,28 @@
+// "cfa -c -o array.o array.c"
+// "cfa -CFA array.c > array_out.c"
+// "gcc32 array_out.c ../LibCfa/libcfa.a"
+
+#include "array.h"
+
+/// forall( type array_type, elt_type | bounded_array( array_type, elt_type ) )
+/// [ array_iterator begin, array_iterator end ]
+/// get_iterators( array_type array )
+/// {
+///   begin = 0;
+///   end = array_last( array );
+/// }
+
+forall( type array_type, type elt_type | bounded_array( array_type, elt_type ) )
+elt_type *
+get_begin( array_type array )
+{
+  return &array[ 0 ];
+}
+
+forall( type array_type, type elt_type | bounded_array( array_type, elt_type ) )
+elt_type *
+get_end( array_type array )
+{
+  return &array[ array_last( array ) ] + 1;
+}
+
Index: translator/examples/array.h
===================================================================
--- translator/examples/array.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/examples/array.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,26 @@
+#ifndef ARRAY_H
+#define ARRAY_H
+
+#include "iterator.h"
+
+context array( type array_type, type elt_type )
+{
+  lvalue elt_type ?[?]( array_type, int );
+};
+
+context bounded_array( type array_type, type elt_type | array( array_type, elt_type ) )
+{
+  int array_last( array_type );
+};
+
+// implement iterator_for
+
+typedef int array_iterator;
+/// forall( type array_type, elt_type | bounded_array( array_type, elt_type ) )
+/// [ array_iterator begin, array_iterator end ] get_iterators( array_type );
+forall( type array_type, type elt_type | bounded_array( array_type, elt_type ) )
+elt_type *get_begin( array_type );
+forall( type array_type, type elt_type | bounded_array( array_type, elt_type ) )
+elt_type *get_end( array_type );
+
+#endif /* #ifndef ARRAY_H */
Index: translator/examples/fstream.c
===================================================================
--- translator/examples/fstream.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/examples/fstream.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,137 @@
+// "cfa -E fstream.c > fstream_out.c"
+// "cfa -c -o fstream.o fstream.c"
+#include "fstream.h"
+
+#undef __cplusplus
+extern "C" {
+#include <stdio.h>
+#include <stdlib.h>
+}
+
+struct ofstream
+{
+  FILE *file;
+  int fail;
+};
+
+ofstream *
+write( ofstream *os, const char *data, streamsize_type size )
+{
+  if( !os->fail ) {
+    fwrite( data, size, 1, os->file );
+    os->fail = ferror( os->file );
+  }
+  return os;
+}
+
+int
+fail( ofstream *os )
+{
+  return os->fail;
+}
+
+static ofstream*
+make_ofstream()
+{
+  ofstream *new_stream = malloc( sizeof( ofstream ) );
+  new_stream->fail = 0;
+  return new_stream;
+}
+
+ofstream *
+ofstream_stdout()
+{
+  ofstream *stdout_stream = make_ofstream();
+  stdout_stream->file = stdout;
+  return stdout_stream;
+}
+
+ofstream *
+ofstream_stderr()
+{
+  ofstream *stderr_stream = make_ofstream();
+  stderr_stream->file = stderr;
+  return stderr_stream;
+}
+
+ofstream *
+ofstream_fromfile( const char *name )
+{
+  ofstream *file_stream = make_ofstream();
+  file_stream->file = fopen( name, "w" );
+  file_stream->fail = file_stream->file == 0;
+  return file_stream;
+}
+
+void
+ofstream_close( ofstream *os )
+{
+  if( os->file != stdout && os->file != stderr ) {
+    os->fail = fclose( os->file );
+  }
+  free( os );
+}
+
+struct ifstream
+{
+  FILE *file;
+  int fail;
+  int eof;
+};
+
+ifstream *
+read( ifstream *is, char *data, streamsize_type size )
+{
+  if( !is->fail && !is->eof ) {
+    fread( data, size, 1, is->file );
+    is->fail = ferror( is->file );
+    is->eof = feof( is->file );
+  }
+  return is;
+}
+  
+ifstream *unread( ifstream *is, char c )
+{
+  if( !is->fail ) {
+    if( EOF == ungetc( c, is->file ) ) {
+      is->fail = 1;
+    }
+  }
+  return is;
+}
+
+int fail( ifstream *is )
+{
+  return is->fail;
+}
+
+int eof( ifstream *is )
+{
+  return is->eof;
+}
+
+static ifstream*
+make_ifstream()
+{
+  ifstream *new_stream = malloc( sizeof( ifstream ) );
+  new_stream->fail = 0;
+  new_stream->eof = 0;
+  return new_stream;
+}
+
+ifstream *ifstream_stdin()
+{
+  ifstream *stdin_stream = make_ifstream();
+  stdin_stream->file = stdin;
+  return stdin_stream;
+}
+
+ifstream *
+ifstream_fromfile( const char *name )
+{
+  ifstream *file_stream = make_ifstream();
+  file_stream->file = fopen( name, "r" );
+  file_stream->fail = file_stream->file == 0;
+  return file_stream;
+}
+
Index: translator/examples/fstream.h
===================================================================
--- translator/examples/fstream.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/examples/fstream.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,28 @@
+#ifndef FSTREAM_H
+#define FSTREAM_H
+
+#include "iostream.h"
+
+typedef struct ofstream ofstream;
+
+/* implement context ostream */
+ofstream *write( ofstream *, const char *, streamsize_type );
+int fail( ofstream * );
+
+ofstream *ofstream_stdout();
+ofstream *ofstream_stderr();
+ofstream *ofstream_fromfile( const char *name );
+void ofstream_close( ofstream *os );
+
+typedef struct ifstream ifstream;
+
+/* implement context istream */
+ifstream *read( ifstream *, char *, streamsize_type );
+ifstream *unread( ifstream *, char );
+int fail( ifstream * );
+int eof( ifstream * );
+
+ifstream *ifstream_stdin();
+ifstream *ifstream_fromfile( const char *name );
+
+#endif /* #ifndef FSTREAM_H */
Index: translator/examples/fstream_test.c
===================================================================
--- translator/examples/fstream_test.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/examples/fstream_test.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,17 @@
+// "cfa -c -o fstream_test.o fstream_test.c"
+// "cfa -CFA fstream_test.c > fstream_test_out.c"
+// "gcc31 -c fstream_test_out.c"
+
+#include "fstream.h"
+
+int
+main()
+{
+  ofstream *sout = ofstream_stdout();
+  ifstream *sin = ifstream_stdin();
+  int nombre;
+  sout << "Appuyez un nombre, s'il vous plâit:\n";
+  sin >> &nombre;
+  sout << "Vous avez appuyé: " << nombre << "\n";
+  return 0;
+}
Index: translator/examples/fwrite.c
===================================================================
--- translator/examples/fwrite.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/examples/fwrite.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,11 @@
+// "cfa -CFA fwrite.c > fwrite.i"
+// "cfa fwrite.i"
+
+#include <stdio.h>
+
+int
+main()
+{
+  fwrite( "test\n", 5, 1, stdout );
+  return 0;
+}
Index: translator/examples/hello.c
===================================================================
--- translator/examples/hello.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/examples/hello.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,16 @@
+// "cfa hello.c fstream.c iostream.o"
+// "cfa -CFA hello.c > hello.i"
+// "cfa hello.i fstream.i iostream.o"
+
+extern "C" {
+int printf( const char*, ... );
+}
+
+#include "fstream.h"
+
+int main() {
+  ofstream *sout = ofstream_stdout();
+  write( sout, "test\n", 5 );
+  sout << "Bonjour au monde!\n";
+  return 0;
+}
Index: translator/examples/index.h
===================================================================
--- translator/examples/index.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/examples/index.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,6 @@
+context index( type T )
+{
+  T ?+?( T, T );
+  T ?-?( T, T );
+  const T 0, 1;
+};
Index: translator/examples/iostream.c
===================================================================
--- translator/examples/iostream.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/examples/iostream.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,67 @@
+// "cfa -c -o iostream.o iostream.c"
+// "cfa -v -E iostream.c > iostream_out.c"
+// "cfa -CFA iostream.c > iostream_out.c"
+// "cfa iostream_out.c"
+// "gcc32 iostream_out.c LibCfa/libcfa.a"
+
+#include "iostream.h"
+#undef __cplusplus
+extern "C" {
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+}
+
+forall( dtype ostype | ostream( ostype ) )
+ostype *
+?<<?( ostype *os, char c )
+{
+  return write( os, &c, 1 );
+}
+
+forall( dtype ostype | ostream( ostype ) )
+ostype *
+?<<?( ostype *os, int i )
+{
+  char buffer[20];      // larger than the largest integer
+  sprintf( buffer, "%d", i );
+  return write( os, buffer, strlen( buffer ) );
+}
+
+forall( dtype ostype | ostream( ostype ) )
+ostype *
+?<<?( ostype *os, const char *cp )
+{
+  return write( os, cp, strlen( cp ) );
+}
+
+forall( dtype istype | istream( istype ) )
+istype *
+?>>?( istype *is, char *cp )
+{
+  return read( is, cp, 1 );
+}
+
+forall( dtype istype | istream( istype ) )
+istype *
+?>>?( istype *is, int *ip )
+{
+  char cur;
+  
+  // skip some whitespace
+  do {
+    is >> &cur;
+    if( fail( is ) || eof( is ) ) return is;
+  } while( !( cur >= '0' && cur <= '9' ) );
+  
+  // accumulate digits
+  *ip = 0;
+  while( cur >= '0' && cur <= '9' ) {
+    *ip = *ip * 10 + ( cur - '0' );
+    is >> &cur;
+    if( fail( is ) || eof( is ) ) return is;
+  }
+  
+  unread( is, cur );
+  return is;
+}
Index: translator/examples/iostream.h
===================================================================
--- translator/examples/iostream.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/examples/iostream.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,45 @@
+#ifndef IOSTREAM_H
+#define IOSTREAM_H
+
+typedef unsigned long streamsize_type;
+
+context ostream( dtype ostype )
+{
+  ostype *write( ostype *, const char *, streamsize_type );
+  int fail( ostype * );
+};
+
+context writeable( type T )
+{
+  forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, T );
+};
+
+// implement writable for some intrinsic types
+
+forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, char );
+
+forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, int );
+
+forall( dtype ostype | ostream( ostype ) ) ostype * ?<<?( ostype *, const char * );
+
+
+context istream( dtype istype )
+{
+  istype *read( istype *, char *, streamsize_type );
+  istype *unread( istype *, char );
+  int fail( istype * );
+  int eof( istype * );
+};
+
+context readable( type T )
+{
+  forall( dtype istype | istream( istype ) ) istype * ?<<?( istype *, T );
+};
+
+forall( dtype istype | istream( istype ) )
+istype * ?>>?( istype *, char* );
+
+forall( dtype istype | istream( istype ) )
+istype * ?>>?( istype *, int* );
+
+#endif /* #ifndef IOSTREAM_H */
Index: translator/examples/iterator.c
===================================================================
--- translator/examples/iterator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/examples/iterator.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,28 @@
+// "cfa iterator.c"
+// "cfa -CFA iterator.c > iterator_out.c"
+// "gcc31 iterator_out.c ../LibCfa/libcfa.a"
+
+#include "iterator.h"
+
+/// forall( type iterator_type, type elt_type | iterator( iterator_type, elt_type ) )
+/// void
+/// for_each( iterator_type begin, iterator_type end, void (*func)( elt_type ) )
+/// {
+///   iterator_type i;
+///   for( i = begin; i != end; ++i ) {
+///     func( *i );
+///   }
+/// }
+
+forall( type elt_type | writeable( elt_type ),
+        type iterator_type | iterator( iterator_type, elt_type ),
+        dtype os_type | ostream( os_type ) )
+void
+write_all( iterator_type begin, iterator_type end, os_type *os )
+{
+  iterator_type i;
+  for( i = begin; i != end; ++i ) {
+    os << *i << ' ';
+  }
+}
+
Index: translator/examples/iterator.h
===================================================================
--- translator/examples/iterator.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/examples/iterator.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,30 @@
+#ifndef ITERATOR_H
+#define ITERATOR_H
+
+#include "iostream.h"
+
+context iterator( type iterator_type, type elt_type )
+{
+  iterator_type ?++( iterator_type* );
+  iterator_type ++?( iterator_type* );
+  int ?==?( iterator_type, iterator_type );
+  int ?!=?( iterator_type, iterator_type );
+  lvalue elt_type *?( iterator_type );
+};
+
+context iterator_for( type iterator_type, type collection_type, type elt_type | iterator( iterator_type, elt_type ) )
+{
+///   [ iterator_type begin, iterator_type end ] get_iterators( collection_type );
+  iterator_type get_begin( collection_type );
+  iterator_type get_end( collection_type );
+};
+
+forall( type iterator_type, type elt_type | iterator( iterator_type, elt_type ) )
+void for_each( iterator_type begin, iterator_type end, void (*func)( elt_type ) );
+
+forall( type elt_type | writeable( elt_type ),
+        type iterator_type | iterator( iterator_type, elt_type ),
+        dtype os_type | ostream( os_type ) )
+void write_all( iterator_type begin, iterator_type end, os_type *os );
+
+#endif /* #ifndef ITERATOR_H */
Index: translator/examples/test.c
===================================================================
--- translator/examples/test.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/examples/test.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,20 @@
+// "cfa -c -o test.o test.c"
+// "cfa -CFA test.c > test_out.c"
+// "gcc31 -c test_out.c -o test.o"
+
+#include "fstream.h"
+#include "vector_int.h"
+
+int
+main()
+{
+  ofstream *sout = ofstream_stdout();
+  vector_int vec = vector_int_allocate();
+  int index;
+  switch(1) {
+  case 1:
+    sout << vec[ index ];
+  }
+  sout << "\n";
+  return 0;
+}
Index: translator/examples/vector_int.c
===================================================================
--- translator/examples/vector_int.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/examples/vector_int.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,67 @@
+// "cfa vector_int.c"
+
+#include "vector_int.h"
+
+#undef __cplusplus
+extern "C" {
+#include <stdlib.h>
+#include <assert.h>
+}
+
+#define DEFAULT_CAPACITY 20
+
+vector_int
+vector_int_allocate()
+{
+  return vector_int_allocate( DEFAULT_CAPACITY );
+}
+
+vector_int
+vector_int_allocate( int reserve )
+{
+  vector_int new_vector;
+  new_vector.last = -1;
+  new_vector.capacity = reserve;
+  new_vector.data = malloc( sizeof( int ) * reserve );
+  return new_vector;
+}
+
+void
+vector_int_deallocate( vector_int vec )
+{
+  free( vec.data );
+}
+
+void
+reserve( vector_int *vec, int reserve )
+{
+  if( reserve > vec->capacity ) {
+    vec->data = realloc( vec->data, sizeof( int ) * reserve );
+    vec->capacity = reserve;
+  }
+}
+
+void append( vector_int *vec, int element )
+{
+  vec->last++;
+  if( vec->last == vec->capacity ) {
+    vec->capacity *= 2;
+    vec->data = realloc( vec->data, sizeof( int ) * vec->capacity );
+  }
+  vec->data[ vec->last ] = element;
+}
+
+// implement bounded_array
+
+lvalue int
+?[?]( vector_int vec, int index )
+{
+  return vec.data[ index ];
+}
+
+int
+array_last( vector_int vec )
+{
+  return vec.last;
+}
+
Index: translator/examples/vector_int.h
===================================================================
--- translator/examples/vector_int.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/examples/vector_int.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,24 @@
+#ifndef VECTOR_INT_H
+#define VECTOR_INT_H
+
+typedef struct vector_int
+{
+  int last;
+  int capacity;
+  int *data;
+} vector_int;
+
+
+vector_int vector_int_allocate();
+vector_int vector_int_allocate( int reserve );
+void vector_int_deallocate( vector_int );
+
+void reserve( vector_int *vec, int reserve );
+void append( vector_int *vec, int element );
+
+// implement bounded_array
+
+lvalue int ?[?]( vector_int vec, int index );
+int array_last( vector_int vec );
+
+#endif /* #ifndef VECTOR_INT_H */
Index: translator/examples/vector_test.c
===================================================================
--- translator/examples/vector_test.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/examples/vector_test.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,34 @@
+// "cfa -c -o vector_test.o vector_test.c"
+// "cfa -CFA vector_test.c > vector_test_out.c"
+// "cfa -E vector_test.c > vector_test_out.c"
+// "gcc31 -c vector_test_out.c -o vector_test.o"
+
+#include "fstream.h"
+#include "vector_int.h"
+#include "array.h"
+
+extern "C" {
+int printf( const char *, ... );
+}
+
+int
+main()
+{
+  ofstream *sout = ofstream_stdout();
+  ifstream *sin = ifstream_stdin();
+  vector_int vec = vector_int_allocate();
+  int nombre;
+  for(;;) {
+    sin >> &nombre;
+    if( fail( sin ) || eof( sin ) ) break;
+    append( &vec, nombre );
+  }
+  sout << "Array elements: ";
+  write_all( get_begin( vec ), get_end( vec ), sout );
+///   int index;
+///   for( index = 0; index <= array_last( vec ); ++index ) {
+///     sout << vec[ index ] << " ";
+///   }
+  sout << "\n";
+  return 0;
+}
Index: translator/factorial.c
===================================================================
--- translator/factorial.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/factorial.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,18 @@
+//#include <stdio.h>
+
+int
+factorial( int n )
+{
+  if( n ) {
+    return factorial( n - 1 );
+  } else {
+    return 1;
+  }
+}
+
+int
+main()
+{
+  printf( "result is %d\n", factorial( 6 ) );
+  return 0;
+}
Index: translator/forall.c
===================================================================
--- translator/forall.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/forall.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,46 @@
+// "./cfa forall.c"
+
+typedef forall ( type T ) int (*f)( int );
+
+forall( type T )
+    void swap( T left, T right ) {
+	T temp = left;
+	left = right;
+	right = temp;
+    }
+
+context sumable( type T ) {
+    const T 0;
+    T ?+?(T, T);
+    T ?++(T*);
+    [T] ?+=?(T*,T);
+};
+
+forall( type T | sumable( T ) )
+    T sum( int n, T a[] ) {
+	T total = 0;
+	int i;
+	for ( i = 0; i < n; i += 1 )
+	    total = total + a[i];
+	return total;
+    }
+
+forall( type T | { T ?+?(T, T); T ?++(T*); [T] ?+=?(T*,T); } )
+    T twice( T t ) {
+	return t + t;
+    }
+
+forall( type T | { const T 0; int ?!=?(T, T); int ?<?(T, T); } )
+    T min( T t1, T t2 ) {
+	return t1 < t2 ? t1 : t2;
+    }
+
+int main() {
+    int x = 1, y = 2, a[10];
+    float f;
+
+    swap( x, y );
+    twice( x );
+    f = min( 4.0, 3.0 );
+    sum( 10, a );
+}
Index: translator/forward.c
===================================================================
--- translator/forward.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/forward.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,12 @@
+// "./cfa-cpp -nc forward.c"
+
+forall(type T) lvalue T *?( T* );
+int ?=?( int*, int );
+
+struct q { int y; };
+struct q *x;
+
+void f()
+{
+	*x;
+}
Index: translator/huge.c
===================================================================
--- translator/huge.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/huge.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,8 @@
+int huge (int n, forall (type T) T (*f) (T))
+{
+        if (n <= 0)
+                return f(0);
+        else
+                return huge (n-1, f(f));
+}
+
Index: translator/identity.c
===================================================================
--- translator/identity.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/identity.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,19 @@
+// './cfa identity.c'
+
+extern "C" {
+int printf( const char *fmt, ... );
+}
+
+forall( type T )
+T
+identity( T t )
+{
+  return t;
+}
+
+int
+main()
+{
+  printf( "result of identity of 5 is %d\n", identity( 5 ) );
+  return 0;
+}
Index: translator/initialization.txt
===================================================================
--- translator/initialization.txt	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/initialization.txt	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,35 @@
+From the refrat (5.5) we have our specification:
+
+    \section{Initialization} An expression that is used as an
+    \nonterm{initializer} is treated as being cast to the type of the
+    object being initialized.  An expression used in an
+    \nonterm{initializer-list} is treated as being cast to the type of
+    the aggregate member that it initializes.  In either case the cast
+    must have a single unambiguous
+    interpretation\index{interpretations}.
+
+Steps:
+
+- add a member function "void Resolver::visit( SynTree::DeclStmt
+*declStmt )"; for each DeclStmt:
+
+- do what you need to do to establish correspondences between
+expressions in the initializer and pieces of the object to be
+initialized
+
+- for each initializer expression, construct a cast expression that
+casts the value of the expression to the type of the corresponding
+sub-object
+
+- invoke the resolver recursively on each cast expression; it's an invariant
+of the resolver that attempting to resolve a cast expression results either
+in a single resolved expression (corresponding to the unambiguous interpretation
+referred to above) or a thrown SemanticError.
+
+- construct a new initializer from the resolved expressions
+
+You'll undoubtedly have to play with the CodeGen stuff a bit; I
+hacked it to spit out unresolved initializers for file-scope
+declarations so that real programs would compile.  You'll want to make
+sure that resolved initializers for all declarations are being
+generated.
Index: translator/it_out.c
===================================================================
--- translator/it_out.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/it_out.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,102 @@
+# 1 "iterator.c"
+# 1 "<built-in>"
+# 1 "<command line>"
+# 1 "iterator.c"
+# 1 "iterator.h" 1
+
+
+
+# 1 "iostream.h" 1
+
+
+
+typedef unsigned long streamsize_type;
+
+
+
+context ostream( dtype os_type )
+{
+
+  os_type *write( os_type *, const char *, streamsize_type );
+
+
+  int fail( os_type * );
+};
+
+
+
+
+context writeable( type T )
+{
+  forall( dtype os_type | ostream( os_type ) ) os_type * ?<<?( os_type *, T );
+};
+
+
+
+forall( dtype os_type | ostream( os_type ) ) os_type * ?<<?( os_type *, char );
+forall( dtype os_type | ostream( os_type ) ) os_type * ?<<?( os_type *, int );
+forall( dtype os_type | ostream( os_type ) ) os_type * ?<<?( os_type *, const char * );
+
+
+
+
+context istream( dtype is_type )
+{
+
+  is_type *read( is_type *, char *, streamsize_type );
+
+
+  is_type *unread( is_type *, char );
+
+
+  int fail( is_type * );
+
+
+  int eof( is_type * );
+};
+
+
+
+
+context readable( type T )
+{
+  forall( dtype is_type | istream( is_type ) ) is_type * ?<<?( is_type *, T );
+};
+
+
+
+forall( dtype is_type | istream( is_type ) ) is_type * ?>>?( is_type *, char* );
+forall( dtype is_type | istream( is_type ) ) is_type * ?>>?( is_type *, int* );
+# 5 "iterator.h" 2
+
+
+context iterator( type iterator_type, type elt_type )
+{
+
+  iterator_type ?++( iterator_type* );
+  iterator_type ++?( iterator_type* );
+
+
+  int ?==?( iterator_type, iterator_type );
+  int ?!=?( iterator_type, iterator_type );
+
+
+  lvalue elt_type *?( iterator_type );
+};
+
+
+
+forall( type elt_type | writeable( elt_type ),
+        type iterator_type | iterator( iterator_type, elt_type ),
+        dtype os_type | ostream( os_type ) )
+void write_all( iterator_type begin, iterator_type end, os_type *os );
+# 2 "iterator.c" 2
+
+forall( type elt_type | writeable( elt_type ),
+        type iterator_type | iterator( iterator_type, elt_type ),
+        dtype os_type | ostream( os_type ) )
+void
+write_all( elt_type begin, iterator_type end, os_type *os )
+{
+    os << begin;
+}
Index: translator/main.cc
===================================================================
--- translator/main.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/main.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,314 @@
+#include <iostream>
+#include <fstream>
+#include <iterator>
+#include <algorithm>
+#include <cstdio>
+#include "Parser/Parser.h"
+#include "Parser/ParseNode.h"
+#include "Parser/LinkageSpec.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Visitor.h"
+#include "GenPoly/Lvalue.h"
+#include "GenPoly/Specialize.h"
+#include "GenPoly/Box.h"
+#include "GenPoly/CopyParams.h"
+#include "CodeGen/Generate.h"
+#include "CodeGen/FixNames.h"
+#include "ControlStruct/Mutate.h"
+#include "Tuples/Mutate.h"
+#include "Tuples/FunctionChecker.h"
+#include "SymTab/Mangler.h"
+#include "SymTab/Indexer.h"
+#include "SymTab/Validate.h"
+#include "ResolvExpr/AlternativePrinter.h"
+#include "ResolvExpr/Resolver.h"
+#include "MakeLibCfa.h"
+#include "InitTweak/Mutate.h"
+//#include "Explain/GenProlog.h"
+//#include "Try/Visit.h"
+
+#include "SemanticError.h"
+#include "UnimplementedError.h"
+#include "utility.h"
+
+#include "../config.h"
+
+using namespace std;
+
+extern "C"{
+#include <unistd.h>
+  extern int  getopt(int, char *const *, const char *);
+  extern char *optarg;
+  extern int opterr, optind, optopt;
+}
+
+FILE *open_prelude();
+FILE *open_builtins();
+bool beVerbose = false;
+
+int main(int argc, char *argv[]){
+  bool debugp = false, treep = false, astp = false, manglep = false, symtabp = false, validp = false;
+  bool preludep = true, protop = false, libp = false;
+  bool exprp = false;
+  int c;
+  FILE *input, *prelude, *builtins;
+  std::ostream *output = &std::cout;
+
+  opterr = 0;
+
+  while((c = getopt(argc, argv, "dtsgmvxcenplD:")) != -1) {
+    switch(c){
+    case 'd':
+      /* bison debugging info */
+      debugp = true;
+      break;
+    case 't':
+      /* dump parse tree */
+      treep = true;
+      break;
+    case 's':
+      /* dump AST */
+      astp = true;
+      break;
+     case 'g':
+       /* print alternatives for expressions */
+       manglep = true;
+       break;
+     case 'm':
+       /* print symbol table events */
+       symtabp = true;
+       break;
+    case 'x':
+      /* dump AST after decl validation pass */
+      validp = true;
+      break;
+    case 'e':
+      /* dump AST after expression analysis */
+      exprp = true;
+      break;
+    case 'n':
+      /* don't read preamble */
+      preludep = false;
+      break;
+    case 'p':
+      /* generate prototypes for preamble functions */
+      protop = true;
+      break;
+    case 'l':
+      /* generate libcfa.c */
+      libp = true;
+      break;
+    case 'v':
+      /* verbose */
+      beVerbose = true;
+      break;
+    case 'D':
+      /* ignore -Dxxx */
+      break;
+    case '?':
+      cout << "Unknown option: '" << (char)optopt << "'" << endl;
+      exit(1);
+    default:
+      abort();
+    }
+  }
+
+  try {
+    if( optind < argc ) {
+      input = fopen( argv[ optind ], "r" );
+      if( !input ) {
+        std::cout << "Error: can't open " << argv[optind] << std::endl;
+        exit( 1 );
+      }
+      optind++;
+    } else {
+      input = stdin;
+    }
+
+    if( optind < argc ) {
+      output = new ofstream( argv[ optind ] );
+    }
+    
+    Parser::get_parser().set_debug( debugp );
+    
+    if( preludep ) {
+      // include gcc builtins
+      builtins = open_builtins();
+      if( !builtins ) {
+        std::cout << "Error: can't open builtins" << std::endl;
+        exit( 1 );
+      }
+      
+      Parser::get_parser().set_linkage( LinkageSpec::Compiler );
+      Parser::get_parser().parse( builtins );
+    
+      if( Parser::get_parser().get_parseStatus() != 0 ) {
+        return Parser::get_parser().get_parseStatus();
+      }
+      fclose( builtins );
+
+      // include cfa prelude
+      if( libp ) {
+        prelude = input;
+      } else {
+        prelude = open_prelude();
+      }
+      if( !prelude ) {
+        std::cout << "Error: can't open prelude" << std::endl;
+        exit( 1 );
+      }
+      
+      Parser::get_parser().set_linkage( LinkageSpec::Intrinsic );
+      Parser::get_parser().parse( prelude );
+    
+      if( Parser::get_parser().get_parseStatus() != 0 ) {
+        return Parser::get_parser().get_parseStatus();
+      }
+      fclose( prelude );
+    }
+    
+    if( libp ) {
+      std::list< Declaration* > translationUnit;
+      buildList( Parser::get_parser().get_parseTree(), translationUnit );
+      Parser::get_parser().freeTree();
+      SymTab::validate( translationUnit, false );
+      CodeGen::fixNames( translationUnit );
+      LibCfa::makeLibCfa( translationUnit );
+      ResolvExpr::resolve( translationUnit );
+      GenPoly::convertLvalue( translationUnit );
+      GenPoly::box( translationUnit );
+      CodeGen::generate( translationUnit, *output, true );
+      if( output != &std::cout ) {
+	delete output;
+      }
+      return 0;
+    }
+    
+    Parser::get_parser().set_linkage( LinkageSpec::Cforall );
+  
+    Parser::get_parser().parse( input );
+    if( debugp || Parser::get_parser().get_parseStatus() != 0 ) {
+      return Parser::get_parser().get_parseStatus();
+    }
+    fclose( input );
+  
+    if( treep ) {
+      Parser::get_parser().get_parseTree()->printList( std::cout );
+      Parser::get_parser().freeTree();
+      return 0;
+    }
+
+    std::list< Declaration* > translationUnit;
+    buildList( Parser::get_parser().get_parseTree(), translationUnit );
+
+    Parser::get_parser().freeTree();
+    if( astp ) {
+      printAll( translationUnit, std::cout );
+      return 0;
+    }
+
+    if( manglep ) {
+      SymTab::validate( translationUnit, false );
+      ResolvExpr::AlternativePrinter printer( std::cout );
+      acceptAll( translationUnit, printer );
+      return 0;
+    }
+
+    if( symtabp ) {
+      SymTab::validate( translationUnit, true );
+      return 0;
+    }
+
+    if( validp ) {
+      SymTab::validate( translationUnit, false );
+      printAll( translationUnit, std::cout );
+      return 0;
+    }
+    if( exprp ) {
+      SymTab::validate( translationUnit, false );
+      ResolvExpr::resolve( translationUnit );
+      printAll( translationUnit, std::cout );
+      return 0;
+    }
+
+    SymTab::validate( translationUnit, false );
+    //Try::visit( translationUnit );
+    //Tuples::mutate( translationUnit );
+    //InitTweak::mutate( translationUnit );
+    ControlStruct::mutate( translationUnit );
+    CodeGen::fixNames( translationUnit );
+    ResolvExpr::resolve( translationUnit );
+    //Tuples::checkFunctions( translationUnit );
+    //      std::cerr << "Finished tuple checkfunctions" << std::endl;
+    //printAll( translationUnit, std::cerr );
+    GenPoly::copyParams( translationUnit );
+    GenPoly::convertSpecializations( translationUnit );
+    GenPoly::convertLvalue( translationUnit );
+    GenPoly::box( translationUnit );
+    //Tuples::mutate( translationUnit );
+
+    CodeGen::generate( translationUnit, *output, protop );
+
+    if( output != &std::cout ) {
+	delete output;
+    }
+
+  } catch ( SemanticError &e ) {
+    e.print( cout );
+    if( output != &std::cout ) {
+      delete output;
+    }
+    return 1;
+  } catch ( UnimplementedError &e ) {
+    std::cout << "Sorry, " << e.get_what() << " is not currently implemented" << std::endl;
+    if( output != &std::cout ) {
+      delete output;
+    }
+    return 1;
+  } catch ( CompilerError &e ) {
+    std::cerr << "Compiler Error: " << e.get_what() << std::endl;
+    std::cerr << "(please report bugs to " << std::endl;
+    if( output != &std::cout ) {
+      delete output;
+    }
+    return 1;
+  }
+
+  return 0;
+}
+
+FILE *open_prelude(){
+  FILE *ret;
+
+  const string name("prelude.cf"),
+               full_name = string(CFA_LIBDIR) + "/" + name;
+
+  if( beVerbose ) {
+    cout << "Reading from " << full_name << endl;
+  }
+
+  if (! (ret = fopen(full_name.c_str(), "r" ) ) )
+    return fopen(name.c_str(), "r" );             // trying current directory
+  else
+    return ret;
+}
+
+FILE *open_builtins(){
+  FILE *ret;
+
+  const char *name = "builtins.cf";
+  const char *full_name = CFA_LIBDIR "/builtins.cf";
+
+  if( beVerbose ) {
+    cout << "Reading from " << full_name << endl;
+  }
+
+  if (! (ret = fopen(full_name, "r" ) ) )
+    return fopen(name, "r" );             // trying current directory
+  else
+    return ret;
+}
+
+// Local Variables: //
+// compile-command: "make" //
+// End:  //
Index: translator/min.c
===================================================================
--- translator/min.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/min.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,18 @@
+// "./cfa min.c"
+// "./cfa -CFA min.c > min_out.c"
+// "gcc32 -g min_out.c LibCfa/libcfa.a"
+
+extern "C" {
+  int printf( const char *, ... );
+}
+
+forall( type T | { const T 0; int ?!=?(T, T); int ?<?(T, T); } )
+    T min( T t1, T t2 ) {
+	return t1 < t2 ? t1 : t2;
+    }
+
+int main() {
+    float f;
+    f = min( 4.0, 3.0 );
+    printf( "result is %f\n", f );
+}
Index: translator/new.c
===================================================================
--- translator/new.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/new.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,16 @@
+// "./cfa-cpp -c new.c"
+
+forall( type T )
+void f( T *t )
+{
+  t--;
+///   *t;
+///   ++t;
+///   t+=2;
+///   t+2;
+///   --t;
+///   t-=2;
+///   t-4;
+///   t[7];
+///   7[t];
+}
Index: translator/preludesrc.c
===================================================================
--- translator/preludesrc.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/preludesrc.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,3117 @@
+typedef long int _ptrdiff_t;
+const int 0;
+const int 1;
+const DT *const 0;
+FT *const 0;
+int ?++(int *);
+int ?--(int *);
+unsigned int ?++(unsigned int *);
+unsigned int ?--(unsigned int *);
+long int ?++(long int *);
+long int ?--(long int *);
+long unsigned int ?++(long unsigned int *);
+long unsigned int ?--(long unsigned int *);
+float ?++(float *);
+float ?--(float *);
+double ?++(double *);
+double ?--(double *);
+long double ?++(long double *);
+long double ?--(long double *);
+T * ?++(T **);
+T * ?--(T **);
+const T * ?++(const T **);
+const T * ?--(const T **);
+volatile T * ?++(volatile T **);
+volatile T * ?--(volatile T **);
+volatile const T * ?++(volatile const T **);
+volatile const T * ?--(volatile const T **);
+T ?[?](T *, _ptrdiff_t );
+const T ?[?](const T *, _ptrdiff_t );
+volatile T ?[?](volatile T *, _ptrdiff_t );
+volatile const T ?[?](volatile const T *, _ptrdiff_t );
+T ?[?](_ptrdiff_t , T *);
+const T ?[?](_ptrdiff_t , const T *);
+volatile T ?[?](_ptrdiff_t , volatile T *);
+volatile const T ?[?](_ptrdiff_t , volatile const T *);
+int ++?(int *);
+int --?(int *);
+unsigned int ++?(unsigned int *);
+unsigned int --?(unsigned int *);
+long int ++?(long int *);
+long int --?(long int *);
+long unsigned int ++?(long unsigned int *);
+long unsigned int --?(long unsigned int *);
+float ++?(float *);
+float --?(float *);
+double ++?(double *);
+double --?(double *);
+long double ++?(long double *);
+long double --?(long double *);
+T *++?(T **);
+T *--?(T **);
+const T *++?(const T **);
+const T *--?(const T **);
+volatile T *++?(volatile T **);
+volatile T *--?(volatile T **);
+volatile const T *++?(volatile const T **);
+volatile const T *--?(volatile const T **);
+T (*?)(T *);
+const T (*?)(const T *);
+volatile T (*?)(volatile T *);
+volatile const T (*?)(volatile const T *);
+FT (*?)(FT *);
+int +?(int );
+int -?(int );
+int ~?(int );
+unsigned int +?(unsigned int );
+unsigned int -?(unsigned int );
+unsigned int ~?(unsigned int );
+long unsigned int +?(long unsigned int );
+long unsigned int -?(long unsigned int );
+long unsigned int ~?(long unsigned int );
+long int +?(long int );
+long int -?(long int );
+long int ~?(long int );
+float +?(float );
+float -?(float );
+double +?(double );
+double -?(double );
+long double +?(long double );
+long double -?(long double );
+int !?(int );
+int !?(unsigned int );
+int !?(long int );
+int !?(long unsigned int );
+int !?(float );
+int !?(double );
+int !?(volatile const DT *);
+int !?(FT *);
+int ?*?(int , int );
+int ?/?(int , int );
+int ?%?(int , int );
+unsigned int ?*?(unsigned int , unsigned int );
+unsigned int ?/?(unsigned int , unsigned int );
+unsigned int ?%?(unsigned int , unsigned int );
+long unsigned int ?*?(long unsigned int , long unsigned int );
+long unsigned int ?/?(long unsigned int , long unsigned int );
+long unsigned int ?%?(long unsigned int , long unsigned int );
+long int ?*?(long int , long int );
+long int ?/?(long int , long int );
+long int ?%?(long int , long int );
+float ?*?(float , float );
+float ?/?(float , float );
+double ?*?(double , double );
+double ?/?(double , double );
+long double ?*?(long double , long double );
+long double ?/?(long double , long double );
+int ?+?(int , int );
+int ?-?(int , int );
+long int ?+?(long int , long int );
+long int ?-?(long int , long int );
+unsigned int ?+?(unsigned int , unsigned int );
+unsigned int ?-?(unsigned int , unsigned int );
+long unsigned int ?+?(long unsigned int , long unsigned int );
+long unsigned int ?-?(long unsigned int , long unsigned int );
+float ?+?(float , float );
+float ?-?(float , float );
+double ?+?(double , double );
+double ?-?(double , double );
+long double ?+?(long double , long double );
+long double ?-?(long double , long double );
+T * ?+?(T *, _ptrdiff_t );
+T * ?+?(_ptrdiff_t , T *);
+T * ?-?(T *, _ptrdiff_t );
+const T * ?+?(const T *, _ptrdiff_t );
+const T * ?+?(_ptrdiff_t , const T *);
+const T * ?-?(const T *, _ptrdiff_t );
+volatile T * ?+?(volatile T *, _ptrdiff_t );
+volatile T * ?+?(_ptrdiff_t , volatile T *);
+volatile T * ?-?(volatile T *, _ptrdiff_t );
+volatile const T * ?+?(volatile const T *, _ptrdiff_t );
+volatile const T * ?+?(_ptrdiff_t , volatile const T *);
+volatile const T * ?-?(volatile const T *, _ptrdiff_t );
+_ptrdiff_t ?-?(volatile const T *, volatile const T *);
+int ?<<?(int , int );
+int ?>>?(int , int );
+long int ?<<?(long int , long int );
+long int ?>>?(long int , long int );
+unsigned int ?<<?(unsigned int , unsigned int );
+unsigned int ?>>?(unsigned int , unsigned int );
+long unsigned int ?<<?(long unsigned int , long unsigned int );
+long unsigned int ?>>?(long unsigned int , long unsigned int );
+int ?<?(int , int );
+int ?<=?(int , int );
+int ?>?(int , int );
+int ?>=?(int , int );
+int ?<?(long int , long int );
+int ?<=?(long int , long int );
+int ?>?(long int , long int );
+int ?>=?(long int , long int );
+int ?<?(unsigned int , unsigned int );
+int ?<=?(unsigned int , unsigned int );
+int ?>?(unsigned int , unsigned int );
+int ?>=?(unsigned int , unsigned int );
+int ?<?(long unsigned int , long unsigned int );
+int ?<=?(long unsigned int , long unsigned int );
+int ?>?(long unsigned int , long unsigned int );
+int ?>=?(long unsigned int , long unsigned int );
+int ?<?(float , float );
+int ?<=?(float , float );
+int ?>?(float , float );
+int ?>=?(float , float );
+int ?<?(double , double );
+int ?<=?(double , double );
+int ?>?(double , double );
+int ?>=?(double , double );
+int ?<?(long double , long double );
+int ?<=?(long double , long double );
+int ?>?(long double , long double );
+int ?>=?(long double , long double );
+int ?<?(volatile const DT *, volatile const DT *);
+int ?>?(volatile const DT *, volatile const DT *);
+int ?<=?(volatile const DT *, volatile const DT *);
+int ?>=?(volatile const DT *, volatile const DT *);
+int ?==?(int , int );
+int ?!=?(int , int );
+int ?==?(long int , long int );
+int ?!=?(long int , long int );
+int ?==?(unsigned int , unsigned int );
+int ?!=?(unsigned int , unsigned int );
+int ?==?(long unsigned int , long unsigned int );
+int ?!=?(long unsigned int , long unsigned int );
+int ?==?(float , float );
+int ?!=?(float , float );
+int ?==?(double , double );
+int ?!=?(double , double );
+int ?==?(long double , long double );
+int ?!=?(long double , long double );
+int ?==?(volatile const DT *, volatile const DT *);
+int ?!=?(volatile const DT *, volatile const DT *);
+int ?==?(FT *, FT *);
+int ?!=?(FT *, FT *);
+int ?==?(volatile const DT *, volatile const void *);
+int ?!=?(volatile const DT *, volatile const void *);
+int ?==?(volatile const void *, volatile const DT *);
+int ?!=?(volatile const void *, volatile const DT *);
+int ?==?(volatile const DT *, const DT2 *);
+int ?!=?(volatile const DT *, const DT2 *);
+int ?==?(const DT2 *, volatile const DT *);
+int ?!=?(const DT2 *, volatile const DT *);
+int ?==?(FT *, FT2 *);
+int ?!=?(FT *, FT2 *);
+int ?==?(FT2 *, FT *);
+int ?!=?(FT2 *, FT *);
+int ?&?(int , int );
+long int ?&?(long int , long int );
+unsigned int ?&?(unsigned int , unsigned int );
+long unsigned int ?&?(long unsigned int , long unsigned int );
+int ?^?(int , int );
+long int ?^?(long int , long int );
+unsigned int ?^?(unsigned int , unsigned int );
+long unsigned int ?^?(long unsigned int , long unsigned int );
+int ?|?(int , int );
+long int ?|?(long int , long int );
+unsigned int ?|?(unsigned int , unsigned int );
+long unsigned int ?|?(long unsigned int , long unsigned int );
+FT * ?=?(FT **, FT *);
+FT * ?=?(FT *volatile *, FT *);
+DT * ?=?(DT **, DT *);
+DT * ?=?(DT *volatile *, DT *);
+const DT * ?=?(const DT **, DT *);
+const DT * ?=?(const DT *volatile *, DT *);
+volatile DT * ?=?(volatile DT **, DT *);
+volatile DT * ?=?(volatile DT *volatile *, DT *);
+volatile const DT * ?=?(volatile const DT **, DT *);
+volatile const DT * ?=?(volatile const DT *volatile *, DT *);
+volatile const DT * ?=?(volatile const DT **, volatile DT *);
+volatile const DT * ?=?(volatile const DT *volatile *, volatile DT *);
+volatile const DT * ?=?(volatile const DT **, const DT *);
+volatile const DT * ?=?(volatile const DT *volatile *, const DT *);
+DT * ?=?(DT **, void *);
+DT * ?=?(DT *volatile *, void *);
+const DT * ?=?(const DT **, void *);
+const DT * ?=?(const DT *volatile *, void *);
+const DT * ?=?(const DT **, const void *);
+const DT * ?=?(const DT *volatile *, const void *);
+volatile DT * ?=?(volatile DT **, void *);
+volatile DT * ?=?(volatile DT *volatile *, void *);
+volatile DT * ?=?(volatile DT **, volatile void *);
+volatile DT * ?=?(volatile DT *volatile *, volatile void *);
+volatile const DT * ?=?(volatile const DT **, void *);
+volatile const DT * ?=?(volatile const DT *volatile *, void *);
+volatile const DT * ?=?(volatile const DT **, const void *);
+volatile const DT * ?=?(volatile const DT *volatile *, const void *);
+volatile const DT * ?=?(volatile const DT **, volatile void *);
+volatile const DT * ?=?(volatile const DT *volatile *, volatile void *);
+volatile const DT * ?=?(volatile const DT **, volatile const void *);
+volatile const DT * ?=?(volatile const DT *volatile *, volatile const void *);
+void * ?=?(void **, DT *);
+void * ?=?(void *volatile *, DT *);
+const void * ?=?(const void **, DT *);
+const void * ?=?(const void *volatile *, DT *);
+const void * ?=?(const void **, const DT *);
+const void * ?=?(const void *volatile *, const DT *);
+volatile void * ?=?(volatile const void **, DT *);
+volatile void * ?=?(volatile const void *volatile *, DT *);
+volatile void * ?=?(volatile const void **, const DT *);
+volatile void * ?=?(volatile const void *volatile *, const DT *);
+volatile void * ?=?(volatile const void **, volatile DT *);
+volatile void * ?=?(volatile const void *volatile *, volatile DT *);
+volatile void * ?=?(volatile const void **, volatile const DT *);
+volatile void * ?=?(volatile const void *volatile *, volatile const DT *);
+DT * ?=?(DT **, const DT2 *);
+DT * ?=?(DT *volatile *, const DT2 *);
+const DT * ?=?(const DT **, const DT2 *);
+const DT * ?=?(const DT *volatile *, const DT2 *);
+volatile DT * ?=?(volatile DT **, const DT2 *);
+volatile DT * ?=?(volatile DT *volatile *, const DT2 *);
+volatile const DT * ?=?(volatile const DT **, const DT2 *);
+volatile const DT * ?=?(volatile const DT *volatile *, const DT2 *);
+FT * ?=?(FT **, FT2 *);
+FT * ?=?(FT *volatile *, FT2 *);
+T * ?+=?(T **, _ptrdiff_t );
+T * ?+=?(T *volatile *, _ptrdiff_t );
+T * ?-=?(T **, _ptrdiff_t );
+T * ?-=?(T *volatile *, _ptrdiff_t );
+const T * ?+=?(const T **, _ptrdiff_t );
+const T * ?+=?(const T *volatile *, _ptrdiff_t );
+const T * ?-=?(const T **, _ptrdiff_t );
+const T * ?-=?(const T *volatile *, _ptrdiff_t );
+volatile T * ?+=?(volatile T **, _ptrdiff_t );
+volatile T * ?+=?(volatile T *volatile *, _ptrdiff_t );
+volatile T * ?-=?(volatile T **, _ptrdiff_t );
+volatile T * ?-=?(volatile T *volatile *, _ptrdiff_t );
+volatile const T * ?+=?(volatile const T **, _ptrdiff_t );
+volatile const T * ?+=?(volatile const T *volatile *, _ptrdiff_t );
+volatile const T * ?-=?(volatile const T **, _ptrdiff_t );
+volatile const T * ?-=?(volatile const T *volatile *, _ptrdiff_t );
+char ?=?(char *, char );
+char ?=?(volatile char *, char );
+unsigned char ?=?(unsigned char *, unsigned char );
+unsigned char ?=?(volatile unsigned char *, unsigned char );
+int ?=?(int *, int );
+int ?=?(volatile int *, int );
+unsigned int ?=?(unsigned int *, unsigned int );
+unsigned int ?=?(volatile unsigned int *, unsigned int );
+long int ?=?(long int *, long int );
+long int ?=?(volatile long int *, long int );
+long unsigned int ?=?(long unsigned int *, long unsigned int );
+long unsigned int ?=?(volatile long unsigned int *, long unsigned int );
+char ?*=?(char *, char );
+char ?*=?(volatile char *, char );
+unsigned char ?*=?(unsigned char *, unsigned char );
+unsigned char ?*=?(volatile unsigned char *, unsigned char );
+int ?*=?(int *, int );
+int ?*=?(volatile int *, int );
+unsigned int ?*=?(unsigned int *, unsigned int );
+unsigned int ?*=?(volatile unsigned int *, unsigned int );
+long int ?*=?(long int *, long int );
+long int ?*=?(volatile long int *, long int );
+long unsigned int ?*=?(long unsigned int *, long unsigned int );
+long unsigned int ?*=?(volatile long unsigned int *, long unsigned int );
+char ?/=?(char *, char );
+char ?/=?(volatile char *, char );
+unsigned char ?/=?(unsigned char *, unsigned char );
+unsigned char ?/=?(volatile unsigned char *, unsigned char );
+int ?/=?(int *, int );
+int ?/=?(volatile int *, int );
+unsigned int ?/=?(unsigned int *, unsigned int );
+unsigned int ?/=?(volatile unsigned int *, unsigned int );
+long int ?/=?(long int *, long int );
+long int ?/=?(volatile long int *, long int );
+long unsigned int ?/=?(long unsigned int *, long unsigned int );
+long unsigned int ?/=?(volatile long unsigned int *, long unsigned int );
+char ?%=?(char *, char );
+char ?%=?(volatile char *, char );
+unsigned char ?%=?(unsigned char *, unsigned char );
+unsigned char ?%=?(volatile unsigned char *, unsigned char );
+int ?%=?(int *, int );
+int ?%=?(volatile int *, int );
+unsigned int ?%=?(unsigned int *, unsigned int );
+unsigned int ?%=?(volatile unsigned int *, unsigned int );
+long int ?%=?(long int *, long int );
+long int ?%=?(volatile long int *, long int );
+long unsigned int ?%=?(long unsigned int *, long unsigned int );
+long unsigned int ?%=?(volatile long unsigned int *, long unsigned int );
+char ?+=?(char *, char );
+char ?+=?(volatile char *, char );
+unsigned char ?+=?(unsigned char *, unsigned char );
+unsigned char ?+=?(volatile unsigned char *, unsigned char );
+int ?+=?(int *, int );
+int ?+=?(volatile int *, int );
+unsigned int ?+=?(unsigned int *, unsigned int );
+unsigned int ?+=?(volatile unsigned int *, unsigned int );
+long int ?+=?(long int *, long int );
+long int ?+=?(volatile long int *, long int );
+long unsigned int ?+=?(long unsigned int *, long unsigned int );
+long unsigned int ?+=?(volatile long unsigned int *, long unsigned int );
+char ?-=?(char *, char );
+char ?-=?(volatile char *, char );
+unsigned char ?-=?(unsigned char *, unsigned char );
+unsigned char ?-=?(volatile unsigned char *, unsigned char );
+int ?-=?(int *, int );
+int ?-=?(volatile int *, int );
+unsigned int ?-=?(unsigned int *, unsigned int );
+unsigned int ?-=?(volatile unsigned int *, unsigned int );
+long int ?-=?(long int *, long int );
+long int ?-=?(volatile long int *, long int );
+long unsigned int ?-=?(long unsigned int *, long unsigned int );
+long unsigned int ?-=?(volatile long unsigned int *, long unsigned int );
+char ?<<=?(char *, char );
+char ?<<=?(volatile char *, char );
+unsigned char ?<<=?(unsigned char *, unsigned char );
+unsigned char ?<<=?(volatile unsigned char *, unsigned char );
+int ?<<=?(int *, int );
+int ?<<=?(volatile int *, int );
+unsigned int ?<<=?(unsigned int *, unsigned int );
+unsigned int ?<<=?(volatile unsigned int *, unsigned int );
+long int ?<<=?(long int *, long int );
+long int ?<<=?(volatile long int *, long int );
+long unsigned int ?<<=?(long unsigned int *, long unsigned int );
+long unsigned int ?<<=?(volatile long unsigned int *, long unsigned int );
+char ?>>=?(char *, char );
+char ?>>=?(volatile char *, char );
+unsigned char ?>>=?(unsigned char *, unsigned char );
+unsigned char ?>>=?(volatile unsigned char *, unsigned char );
+int ?>>=?(int *, int );
+int ?>>=?(volatile int *, int );
+unsigned int ?>>=?(unsigned int *, unsigned int );
+unsigned int ?>>=?(volatile unsigned int *, unsigned int );
+long int ?>>=?(long int *, long int );
+long int ?>>=?(volatile long int *, long int );
+long unsigned int ?>>=?(long unsigned int *, long unsigned int );
+long unsigned int ?>>=?(volatile long unsigned int *, long unsigned int );
+char ?&=?(char *, char );
+char ?&=?(volatile char *, char );
+unsigned char ?&=?(unsigned char *, unsigned char );
+unsigned char ?&=?(volatile unsigned char *, unsigned char );
+int ?&=?(int *, int );
+int ?&=?(volatile int *, int );
+unsigned int ?&=?(unsigned int *, unsigned int );
+unsigned int ?&=?(volatile unsigned int *, unsigned int );
+long int ?&=?(long int *, long int );
+long int ?&=?(volatile long int *, long int );
+long unsigned int ?&=?(long unsigned int *, long unsigned int );
+long unsigned int ?&=?(volatile long unsigned int *, long unsigned int );
+char ?|=?(char *, char );
+char ?|=?(volatile char *, char );
+unsigned char ?|=?(unsigned char *, unsigned char );
+unsigned char ?|=?(volatile unsigned char *, unsigned char );
+int ?|=?(int *, int );
+int ?|=?(volatile int *, int );
+unsigned int ?|=?(unsigned int *, unsigned int );
+unsigned int ?|=?(volatile unsigned int *, unsigned int );
+long int ?|=?(long int *, long int );
+long int ?|=?(volatile long int *, long int );
+long unsigned int ?|=?(long unsigned int *, long unsigned int );
+long unsigned int ?|=?(volatile long unsigned int *, long unsigned int );
+char ?^=?(char *, char );
+char ?^=?(volatile char *, char );
+unsigned char ?^=?(unsigned char *, unsigned char );
+unsigned char ?^=?(volatile unsigned char *, unsigned char );
+int ?^=?(int *, int );
+int ?^=?(volatile int *, int );
+unsigned int ?^=?(unsigned int *, unsigned int );
+unsigned int ?^=?(volatile unsigned int *, unsigned int );
+long int ?^=?(long int *, long int );
+long int ?^=?(volatile long int *, long int );
+long unsigned int ?^=?(long unsigned int *, long unsigned int );
+long unsigned int ?^=?(volatile long unsigned int *, long unsigned int );
+float ?=?(float *, float );
+float ?=?(volatile float *, float );
+float ?*=?(float *, float );
+float ?*=?(volatile float *, float );
+float ?/=?(float *, float );
+float ?/=?(volatile float *, float );
+float ?+=?(float *, float );
+float ?+=?(volatile float *, float );
+float ?-=?(float *, float );
+float ?-=?(volatile float *, float );
+double ?=?(double *, double );
+double ?=?(volatile double *, double );
+double ?*=?(double *, double );
+double ?*=?(volatile double *, double );
+double ?/=?(double *, double );
+double ?/=?(volatile double *, double );
+double ?+=?(double *, double );
+double ?+=?(volatile double *, double );
+double ?-=?(double *, double );
+double ?-=?(volatile double *, double );
+long double ?=?(long double *, long double );
+long double ?=?(volatile long double *, long double );
+long double ?*=?(long double *, long double );
+long double ?*=?(volatile long double *, long double );
+long double ?/=?(long double *, long double );
+long double ?/=?(volatile long double *, long double );
+long double ?+=?(long double *, long double );
+long double ?+=?(volatile long double *, long double );
+long double ?-=?(long double *, long double );
+long double ?-=?(volatile long double *, long double );
+const int 0;
+const int 1;
+const DT *const 0;
+FT *const 0;
+int ?++(int *_p0)
+{
+        return (*_p0)++;
+
+}
+
+int ?--(int *_p0)
+{
+        return (*_p0)--;
+
+}
+
+unsigned int ?++(unsigned int *_p0)
+{
+        return (*_p0)++;
+
+}
+
+unsigned int ?--(unsigned int *_p0)
+{
+        return (*_p0)--;
+
+}
+
+long int ?++(long int *_p0)
+{
+        return (*_p0)++;
+
+}
+
+long int ?--(long int *_p0)
+{
+        return (*_p0)--;
+
+}
+
+long unsigned int ?++(long unsigned int *_p0)
+{
+        return (*_p0)++;
+
+}
+
+long unsigned int ?--(long unsigned int *_p0)
+{
+        return (*_p0)--;
+
+}
+
+float ?++(float *_p0)
+{
+        return (*_p0)++;
+
+}
+
+float ?--(float *_p0)
+{
+        return (*_p0)--;
+
+}
+
+double ?++(double *_p0)
+{
+        return (*_p0)++;
+
+}
+
+double ?--(double *_p0)
+{
+        return (*_p0)--;
+
+}
+
+long double ?++(long double *_p0)
+{
+        return (*_p0)++;
+
+}
+
+long double ?--(long double *_p0)
+{
+        return (*_p0)--;
+
+}
+
+T * ?++(T **_p0)
+{
+        return (*_p0)++;
+
+}
+
+T * ?--(T **_p0)
+{
+        return (*_p0)--;
+
+}
+
+const T * ?++(const T **_p0)
+{
+        return (*_p0)++;
+
+}
+
+const T * ?--(const T **_p0)
+{
+        return (*_p0)--;
+
+}
+
+volatile T * ?++(volatile T **_p0)
+{
+        return (*_p0)++;
+
+}
+
+volatile T * ?--(volatile T **_p0)
+{
+        return (*_p0)--;
+
+}
+
+volatile const T * ?++(volatile const T **_p0)
+{
+        return (*_p0)++;
+
+}
+
+volatile const T * ?--(volatile const T **_p0)
+{
+        return (*_p0)--;
+
+}
+
+T ?[?](T *_p0, _ptrdiff_t _p1)
+{
+        return _p0[_p1];
+
+}
+
+const T ?[?](const T *_p0, _ptrdiff_t _p1)
+{
+        return _p0[_p1];
+
+}
+
+volatile T ?[?](volatile T *_p0, _ptrdiff_t _p1)
+{
+        return _p0[_p1];
+
+}
+
+volatile const T ?[?](volatile const T *_p0, _ptrdiff_t _p1)
+{
+        return _p0[_p1];
+
+}
+
+T ?[?](_ptrdiff_t _p0, T *_p1)
+{
+        return _p0[_p1];
+
+}
+
+const T ?[?](_ptrdiff_t _p0, const T *_p1)
+{
+        return _p0[_p1];
+
+}
+
+volatile T ?[?](_ptrdiff_t _p0, volatile T *_p1)
+{
+        return _p0[_p1];
+
+}
+
+volatile const T ?[?](_ptrdiff_t _p0, volatile const T *_p1)
+{
+        return _p0[_p1];
+
+}
+
+int ++?(int *_p0)
+{
+        return (++(*_p0));
+
+}
+
+int --?(int *_p0)
+{
+        return (--(*_p0));
+
+}
+
+unsigned int ++?(unsigned int *_p0)
+{
+        return (++(*_p0));
+
+}
+
+unsigned int --?(unsigned int *_p0)
+{
+        return (--(*_p0));
+
+}
+
+long int ++?(long int *_p0)
+{
+        return (++(*_p0));
+
+}
+
+long int --?(long int *_p0)
+{
+        return (--(*_p0));
+
+}
+
+long unsigned int ++?(long unsigned int *_p0)
+{
+        return (++(*_p0));
+
+}
+
+long unsigned int --?(long unsigned int *_p0)
+{
+        return (--(*_p0));
+
+}
+
+float ++?(float *_p0)
+{
+        return (++(*_p0));
+
+}
+
+float --?(float *_p0)
+{
+        return (--(*_p0));
+
+}
+
+double ++?(double *_p0)
+{
+        return (++(*_p0));
+
+}
+
+double --?(double *_p0)
+{
+        return (--(*_p0));
+
+}
+
+long double ++?(long double *_p0)
+{
+        return (++(*_p0));
+
+}
+
+long double --?(long double *_p0)
+{
+        return (--(*_p0));
+
+}
+
+T *++?(T **_p0)
+{
+        return (++(*_p0));
+
+}
+
+T *--?(T **_p0)
+{
+        return (--(*_p0));
+
+}
+
+const T *++?(const T **_p0)
+{
+        return (++(*_p0));
+
+}
+
+const T *--?(const T **_p0)
+{
+        return (--(*_p0));
+
+}
+
+volatile T *++?(volatile T **_p0)
+{
+        return (++(*_p0));
+
+}
+
+volatile T *--?(volatile T **_p0)
+{
+        return (--(*_p0));
+
+}
+
+volatile const T *++?(volatile const T **_p0)
+{
+        return (++(*_p0));
+
+}
+
+volatile const T *--?(volatile const T **_p0)
+{
+        return (--(*_p0));
+
+}
+
+T (*?)(T *_p0)
+{
+        return (*_p0);
+
+}
+
+const T (*?)(const T *_p0)
+{
+        return (*_p0);
+
+}
+
+volatile T (*?)(volatile T *_p0)
+{
+        return (*_p0);
+
+}
+
+volatile const T (*?)(volatile const T *_p0)
+{
+        return (*_p0);
+
+}
+
+FT (*?)(FT *_p0)
+{
+        return (*_p0);
+
+}
+
+int +?(int _p0)
+{
+        return (+_p0);
+
+}
+
+int -?(int _p0)
+{
+        return (-_p0);
+
+}
+
+int ~?(int _p0)
+{
+        return (~_p0);
+
+}
+
+unsigned int +?(unsigned int _p0)
+{
+        return (+_p0);
+
+}
+
+unsigned int -?(unsigned int _p0)
+{
+        return (-_p0);
+
+}
+
+unsigned int ~?(unsigned int _p0)
+{
+        return (~_p0);
+
+}
+
+long unsigned int +?(long unsigned int _p0)
+{
+        return (+_p0);
+
+}
+
+long unsigned int -?(long unsigned int _p0)
+{
+        return (-_p0);
+
+}
+
+long unsigned int ~?(long unsigned int _p0)
+{
+        return (~_p0);
+
+}
+
+long int +?(long int _p0)
+{
+        return (+_p0);
+
+}
+
+long int -?(long int _p0)
+{
+        return (-_p0);
+
+}
+
+long int ~?(long int _p0)
+{
+        return (~_p0);
+
+}
+
+float +?(float _p0)
+{
+        return (+_p0);
+
+}
+
+float -?(float _p0)
+{
+        return (-_p0);
+
+}
+
+double +?(double _p0)
+{
+        return (+_p0);
+
+}
+
+double -?(double _p0)
+{
+        return (-_p0);
+
+}
+
+long double +?(long double _p0)
+{
+        return (+_p0);
+
+}
+
+long double -?(long double _p0)
+{
+        return (-_p0);
+
+}
+
+int !?(int _p0)
+{
+        return (!_p0);
+
+}
+
+int !?(unsigned int _p0)
+{
+        return (!_p0);
+
+}
+
+int !?(long int _p0)
+{
+        return (!_p0);
+
+}
+
+int !?(long unsigned int _p0)
+{
+        return (!_p0);
+
+}
+
+int !?(float _p0)
+{
+        return (!_p0);
+
+}
+
+int !?(double _p0)
+{
+        return (!_p0);
+
+}
+
+int !?(volatile const DT *_p0)
+{
+        return (!_p0);
+
+}
+
+int !?(FT *_p0)
+{
+        return (!_p0);
+
+}
+
+int ?*?(int _p0, int _p1)
+{
+        return (_p0*_p1);
+
+}
+
+int ?/?(int _p0, int _p1)
+{
+        return (_p0/_p1);
+
+}
+
+int ?%?(int _p0, int _p1)
+{
+        return (_p0%_p1);
+
+}
+
+unsigned int ?*?(unsigned int _p0, unsigned int _p1)
+{
+        return (_p0*_p1);
+
+}
+
+unsigned int ?/?(unsigned int _p0, unsigned int _p1)
+{
+        return (_p0/_p1);
+
+}
+
+unsigned int ?%?(unsigned int _p0, unsigned int _p1)
+{
+        return (_p0%_p1);
+
+}
+
+long unsigned int ?*?(long unsigned int _p0, long unsigned int _p1)
+{
+        return (_p0*_p1);
+
+}
+
+long unsigned int ?/?(long unsigned int _p0, long unsigned int _p1)
+{
+        return (_p0/_p1);
+
+}
+
+long unsigned int ?%?(long unsigned int _p0, long unsigned int _p1)
+{
+        return (_p0%_p1);
+
+}
+
+long int ?*?(long int _p0, long int _p1)
+{
+        return (_p0*_p1);
+
+}
+
+long int ?/?(long int _p0, long int _p1)
+{
+        return (_p0/_p1);
+
+}
+
+long int ?%?(long int _p0, long int _p1)
+{
+        return (_p0%_p1);
+
+}
+
+float ?*?(float _p0, float _p1)
+{
+        return (_p0*_p1);
+
+}
+
+float ?/?(float _p0, float _p1)
+{
+        return (_p0/_p1);
+
+}
+
+double ?*?(double _p0, double _p1)
+{
+        return (_p0*_p1);
+
+}
+
+double ?/?(double _p0, double _p1)
+{
+        return (_p0/_p1);
+
+}
+
+long double ?*?(long double _p0, long double _p1)
+{
+        return (_p0*_p1);
+
+}
+
+long double ?/?(long double _p0, long double _p1)
+{
+        return (_p0/_p1);
+
+}
+
+int ?+?(int _p0, int _p1)
+{
+        return (_p0+_p1);
+
+}
+
+int ?-?(int _p0, int _p1)
+{
+        return (_p0-_p1);
+
+}
+
+long int ?+?(long int _p0, long int _p1)
+{
+        return (_p0+_p1);
+
+}
+
+long int ?-?(long int _p0, long int _p1)
+{
+        return (_p0-_p1);
+
+}
+
+unsigned int ?+?(unsigned int _p0, unsigned int _p1)
+{
+        return (_p0+_p1);
+
+}
+
+unsigned int ?-?(unsigned int _p0, unsigned int _p1)
+{
+        return (_p0-_p1);
+
+}
+
+long unsigned int ?+?(long unsigned int _p0, long unsigned int _p1)
+{
+        return (_p0+_p1);
+
+}
+
+long unsigned int ?-?(long unsigned int _p0, long unsigned int _p1)
+{
+        return (_p0-_p1);
+
+}
+
+float ?+?(float _p0, float _p1)
+{
+        return (_p0+_p1);
+
+}
+
+float ?-?(float _p0, float _p1)
+{
+        return (_p0-_p1);
+
+}
+
+double ?+?(double _p0, double _p1)
+{
+        return (_p0+_p1);
+
+}
+
+double ?-?(double _p0, double _p1)
+{
+        return (_p0-_p1);
+
+}
+
+long double ?+?(long double _p0, long double _p1)
+{
+        return (_p0+_p1);
+
+}
+
+long double ?-?(long double _p0, long double _p1)
+{
+        return (_p0-_p1);
+
+}
+
+T * ?+?(T *_p0, _ptrdiff_t _p1)
+{
+        return (_p0+_p1);
+
+}
+
+T * ?+?(_ptrdiff_t _p0, T *_p1)
+{
+        return (_p0+_p1);
+
+}
+
+T * ?-?(T *_p0, _ptrdiff_t _p1)
+{
+        return (_p0-_p1);
+
+}
+
+const T * ?+?(const T *_p0, _ptrdiff_t _p1)
+{
+        return (_p0+_p1);
+
+}
+
+const T * ?+?(_ptrdiff_t _p0, const T *_p1)
+{
+        return (_p0+_p1);
+
+}
+
+const T * ?-?(const T *_p0, _ptrdiff_t _p1)
+{
+        return (_p0-_p1);
+
+}
+
+volatile T * ?+?(volatile T *_p0, _ptrdiff_t _p1)
+{
+        return (_p0+_p1);
+
+}
+
+volatile T * ?+?(_ptrdiff_t _p0, volatile T *_p1)
+{
+        return (_p0+_p1);
+
+}
+
+volatile T * ?-?(volatile T *_p0, _ptrdiff_t _p1)
+{
+        return (_p0-_p1);
+
+}
+
+volatile const T * ?+?(volatile const T *_p0, _ptrdiff_t _p1)
+{
+        return (_p0+_p1);
+
+}
+
+volatile const T * ?+?(_ptrdiff_t _p0, volatile const T *_p1)
+{
+        return (_p0+_p1);
+
+}
+
+volatile const T * ?-?(volatile const T *_p0, _ptrdiff_t _p1)
+{
+        return (_p0-_p1);
+
+}
+
+_ptrdiff_t ?-?(volatile const T *_p0, volatile const T *_p1)
+{
+        return (_p0-_p1);
+
+}
+
+int ?<<?(int _p0, int _p1)
+{
+        return (_p0<<_p1);
+
+}
+
+int ?>>?(int _p0, int _p1)
+{
+        return (_p0>>_p1);
+
+}
+
+long int ?<<?(long int _p0, long int _p1)
+{
+        return (_p0<<_p1);
+
+}
+
+long int ?>>?(long int _p0, long int _p1)
+{
+        return (_p0>>_p1);
+
+}
+
+unsigned int ?<<?(unsigned int _p0, unsigned int _p1)
+{
+        return (_p0<<_p1);
+
+}
+
+unsigned int ?>>?(unsigned int _p0, unsigned int _p1)
+{
+        return (_p0>>_p1);
+
+}
+
+long unsigned int ?<<?(long unsigned int _p0, long unsigned int _p1)
+{
+        return (_p0<<_p1);
+
+}
+
+long unsigned int ?>>?(long unsigned int _p0, long unsigned int _p1)
+{
+        return (_p0>>_p1);
+
+}
+
+int ?<?(int _p0, int _p1)
+{
+        return (_p0<_p1);
+
+}
+
+int ?<=?(int _p0, int _p1)
+{
+        return (_p0<=_p1);
+
+}
+
+int ?>?(int _p0, int _p1)
+{
+        return (_p0>_p1);
+
+}
+
+int ?>=?(int _p0, int _p1)
+{
+        return (_p0>=_p1);
+
+}
+
+int ?<?(long int _p0, long int _p1)
+{
+        return (_p0<_p1);
+
+}
+
+int ?<=?(long int _p0, long int _p1)
+{
+        return (_p0<=_p1);
+
+}
+
+int ?>?(long int _p0, long int _p1)
+{
+        return (_p0>_p1);
+
+}
+
+int ?>=?(long int _p0, long int _p1)
+{
+        return (_p0>=_p1);
+
+}
+
+int ?<?(unsigned int _p0, unsigned int _p1)
+{
+        return (_p0<_p1);
+
+}
+
+int ?<=?(unsigned int _p0, unsigned int _p1)
+{
+        return (_p0<=_p1);
+
+}
+
+int ?>?(unsigned int _p0, unsigned int _p1)
+{
+        return (_p0>_p1);
+
+}
+
+int ?>=?(unsigned int _p0, unsigned int _p1)
+{
+        return (_p0>=_p1);
+
+}
+
+int ?<?(long unsigned int _p0, long unsigned int _p1)
+{
+        return (_p0<_p1);
+
+}
+
+int ?<=?(long unsigned int _p0, long unsigned int _p1)
+{
+        return (_p0<=_p1);
+
+}
+
+int ?>?(long unsigned int _p0, long unsigned int _p1)
+{
+        return (_p0>_p1);
+
+}
+
+int ?>=?(long unsigned int _p0, long unsigned int _p1)
+{
+        return (_p0>=_p1);
+
+}
+
+int ?<?(float _p0, float _p1)
+{
+        return (_p0<_p1);
+
+}
+
+int ?<=?(float _p0, float _p1)
+{
+        return (_p0<=_p1);
+
+}
+
+int ?>?(float _p0, float _p1)
+{
+        return (_p0>_p1);
+
+}
+
+int ?>=?(float _p0, float _p1)
+{
+        return (_p0>=_p1);
+
+}
+
+int ?<?(double _p0, double _p1)
+{
+        return (_p0<_p1);
+
+}
+
+int ?<=?(double _p0, double _p1)
+{
+        return (_p0<=_p1);
+
+}
+
+int ?>?(double _p0, double _p1)
+{
+        return (_p0>_p1);
+
+}
+
+int ?>=?(double _p0, double _p1)
+{
+        return (_p0>=_p1);
+
+}
+
+int ?<?(long double _p0, long double _p1)
+{
+        return (_p0<_p1);
+
+}
+
+int ?<=?(long double _p0, long double _p1)
+{
+        return (_p0<=_p1);
+
+}
+
+int ?>?(long double _p0, long double _p1)
+{
+        return (_p0>_p1);
+
+}
+
+int ?>=?(long double _p0, long double _p1)
+{
+        return (_p0>=_p1);
+
+}
+
+int ?<?(volatile const DT *_p0, volatile const DT *_p1)
+{
+        return (_p0<_p1);
+
+}
+
+int ?>?(volatile const DT *_p0, volatile const DT *_p1)
+{
+        return (_p0>_p1);
+
+}
+
+int ?<=?(volatile const DT *_p0, volatile const DT *_p1)
+{
+        return (_p0<=_p1);
+
+}
+
+int ?>=?(volatile const DT *_p0, volatile const DT *_p1)
+{
+        return (_p0>=_p1);
+
+}
+
+int ?==?(int _p0, int _p1)
+{
+        return (_p0==_p1);
+
+}
+
+int ?!=?(int _p0, int _p1)
+{
+        return (_p0!=_p1);
+
+}
+
+int ?==?(long int _p0, long int _p1)
+{
+        return (_p0==_p1);
+
+}
+
+int ?!=?(long int _p0, long int _p1)
+{
+        return (_p0!=_p1);
+
+}
+
+int ?==?(unsigned int _p0, unsigned int _p1)
+{
+        return (_p0==_p1);
+
+}
+
+int ?!=?(unsigned int _p0, unsigned int _p1)
+{
+        return (_p0!=_p1);
+
+}
+
+int ?==?(long unsigned int _p0, long unsigned int _p1)
+{
+        return (_p0==_p1);
+
+}
+
+int ?!=?(long unsigned int _p0, long unsigned int _p1)
+{
+        return (_p0!=_p1);
+
+}
+
+int ?==?(float _p0, float _p1)
+{
+        return (_p0==_p1);
+
+}
+
+int ?!=?(float _p0, float _p1)
+{
+        return (_p0!=_p1);
+
+}
+
+int ?==?(double _p0, double _p1)
+{
+        return (_p0==_p1);
+
+}
+
+int ?!=?(double _p0, double _p1)
+{
+        return (_p0!=_p1);
+
+}
+
+int ?==?(long double _p0, long double _p1)
+{
+        return (_p0==_p1);
+
+}
+
+int ?!=?(long double _p0, long double _p1)
+{
+        return (_p0!=_p1);
+
+}
+
+int ?==?(volatile const DT *_p0, volatile const DT *_p1)
+{
+        return (_p0==_p1);
+
+}
+
+int ?!=?(volatile const DT *_p0, volatile const DT *_p1)
+{
+        return (_p0!=_p1);
+
+}
+
+int ?==?(FT *_p0, FT *_p1)
+{
+        return (_p0==_p1);
+
+}
+
+int ?!=?(FT *_p0, FT *_p1)
+{
+        return (_p0!=_p1);
+
+}
+
+int ?==?(volatile const DT *_p0, volatile const void *_p1)
+{
+        return (_p0==_p1);
+
+}
+
+int ?!=?(volatile const DT *_p0, volatile const void *_p1)
+{
+        return (_p0!=_p1);
+
+}
+
+int ?==?(volatile const void *_p0, volatile const DT *_p1)
+{
+        return (_p0==_p1);
+
+}
+
+int ?!=?(volatile const void *_p0, volatile const DT *_p1)
+{
+        return (_p0!=_p1);
+
+}
+
+int ?==?(volatile const DT *_p0, const DT2 *_p1)
+{
+        return (_p0==_p1);
+
+}
+
+int ?!=?(volatile const DT *_p0, const DT2 *_p1)
+{
+        return (_p0!=_p1);
+
+}
+
+int ?==?(const DT2 *_p0, volatile const DT *_p1)
+{
+        return (_p0==_p1);
+
+}
+
+int ?!=?(const DT2 *_p0, volatile const DT *_p1)
+{
+        return (_p0!=_p1);
+
+}
+
+int ?==?(FT *_p0, FT2 *_p1)
+{
+        return (_p0==_p1);
+
+}
+
+int ?!=?(FT *_p0, FT2 *_p1)
+{
+        return (_p0!=_p1);
+
+}
+
+int ?==?(FT2 *_p0, FT *_p1)
+{
+        return (_p0==_p1);
+
+}
+
+int ?!=?(FT2 *_p0, FT *_p1)
+{
+        return (_p0!=_p1);
+
+}
+
+int ?&?(int _p0, int _p1)
+{
+        return (_p0&_p1);
+
+}
+
+long int ?&?(long int _p0, long int _p1)
+{
+        return (_p0&_p1);
+
+}
+
+unsigned int ?&?(unsigned int _p0, unsigned int _p1)
+{
+        return (_p0&_p1);
+
+}
+
+long unsigned int ?&?(long unsigned int _p0, long unsigned int _p1)
+{
+        return (_p0&_p1);
+
+}
+
+int ?^?(int _p0, int _p1)
+{
+        return (_p0^_p1);
+
+}
+
+long int ?^?(long int _p0, long int _p1)
+{
+        return (_p0^_p1);
+
+}
+
+unsigned int ?^?(unsigned int _p0, unsigned int _p1)
+{
+        return (_p0^_p1);
+
+}
+
+long unsigned int ?^?(long unsigned int _p0, long unsigned int _p1)
+{
+        return (_p0^_p1);
+
+}
+
+int ?|?(int _p0, int _p1)
+{
+        return (_p0|_p1);
+
+}
+
+long int ?|?(long int _p0, long int _p1)
+{
+        return (_p0|_p1);
+
+}
+
+unsigned int ?|?(unsigned int _p0, unsigned int _p1)
+{
+        return (_p0|_p1);
+
+}
+
+long unsigned int ?|?(long unsigned int _p0, long unsigned int _p1)
+{
+        return (_p0|_p1);
+
+}
+
+FT * ?=?(FT **_p0, FT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+FT * ?=?(FT *volatile *_p0, FT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+DT * ?=?(DT **_p0, DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+DT * ?=?(DT *volatile *_p0, DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+const DT * ?=?(const DT **_p0, DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+const DT * ?=?(const DT *volatile *_p0, DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile DT * ?=?(volatile DT **_p0, DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile DT * ?=?(volatile DT *volatile *_p0, DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile const DT * ?=?(volatile const DT **_p0, DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile const DT * ?=?(volatile const DT *volatile *_p0, DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile const DT * ?=?(volatile const DT **_p0, volatile DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile const DT * ?=?(volatile const DT *volatile *_p0, volatile DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile const DT * ?=?(volatile const DT **_p0, const DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile const DT * ?=?(volatile const DT *volatile *_p0, const DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+DT * ?=?(DT **_p0, void *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+DT * ?=?(DT *volatile *_p0, void *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+const DT * ?=?(const DT **_p0, void *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+const DT * ?=?(const DT *volatile *_p0, void *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+const DT * ?=?(const DT **_p0, const void *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+const DT * ?=?(const DT *volatile *_p0, const void *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile DT * ?=?(volatile DT **_p0, void *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile DT * ?=?(volatile DT *volatile *_p0, void *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile DT * ?=?(volatile DT **_p0, volatile void *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile DT * ?=?(volatile DT *volatile *_p0, volatile void *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile const DT * ?=?(volatile const DT **_p0, void *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile const DT * ?=?(volatile const DT *volatile *_p0, void *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile const DT * ?=?(volatile const DT **_p0, const void *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile const DT * ?=?(volatile const DT *volatile *_p0, const void *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile const DT * ?=?(volatile const DT **_p0, volatile void *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile const DT * ?=?(volatile const DT *volatile *_p0, volatile void *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile const DT * ?=?(volatile const DT **_p0, volatile const void *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile const DT * ?=?(volatile const DT *volatile *_p0, volatile const void *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+void * ?=?(void **_p0, DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+void * ?=?(void *volatile *_p0, DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+const void * ?=?(const void **_p0, DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+const void * ?=?(const void *volatile *_p0, DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+const void * ?=?(const void **_p0, const DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+const void * ?=?(const void *volatile *_p0, const DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile void * ?=?(volatile const void **_p0, DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile void * ?=?(volatile const void *volatile *_p0, DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile void * ?=?(volatile const void **_p0, const DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile void * ?=?(volatile const void *volatile *_p0, const DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile void * ?=?(volatile const void **_p0, volatile DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile void * ?=?(volatile const void *volatile *_p0, volatile DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile void * ?=?(volatile const void **_p0, volatile const DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile void * ?=?(volatile const void *volatile *_p0, volatile const DT *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+DT * ?=?(DT **_p0, const DT2 *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+DT * ?=?(DT *volatile *_p0, const DT2 *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+const DT * ?=?(const DT **_p0, const DT2 *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+const DT * ?=?(const DT *volatile *_p0, const DT2 *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile DT * ?=?(volatile DT **_p0, const DT2 *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile DT * ?=?(volatile DT *volatile *_p0, const DT2 *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile const DT * ?=?(volatile const DT **_p0, const DT2 *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+volatile const DT * ?=?(volatile const DT *volatile *_p0, const DT2 *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+FT * ?=?(FT **_p0, FT2 *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+FT * ?=?(FT *volatile *_p0, FT2 *_p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+T * ?+=?(T **_p0, _ptrdiff_t _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+T * ?+=?(T *volatile *_p0, _ptrdiff_t _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+T * ?-=?(T **_p0, _ptrdiff_t _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+T * ?-=?(T *volatile *_p0, _ptrdiff_t _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+const T * ?+=?(const T **_p0, _ptrdiff_t _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+const T * ?+=?(const T *volatile *_p0, _ptrdiff_t _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+const T * ?-=?(const T **_p0, _ptrdiff_t _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+const T * ?-=?(const T *volatile *_p0, _ptrdiff_t _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+volatile T * ?+=?(volatile T **_p0, _ptrdiff_t _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+volatile T * ?+=?(volatile T *volatile *_p0, _ptrdiff_t _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+volatile T * ?-=?(volatile T **_p0, _ptrdiff_t _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+volatile T * ?-=?(volatile T *volatile *_p0, _ptrdiff_t _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+volatile const T * ?+=?(volatile const T **_p0, _ptrdiff_t _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+volatile const T * ?+=?(volatile const T *volatile *_p0, _ptrdiff_t _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+volatile const T * ?-=?(volatile const T **_p0, _ptrdiff_t _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+volatile const T * ?-=?(volatile const T *volatile *_p0, _ptrdiff_t _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+char ?=?(char *_p0, char _p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+char ?=?(volatile char *_p0, char _p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+unsigned char ?=?(unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+unsigned char ?=?(volatile unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+int ?=?(int *_p0, int _p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+int ?=?(volatile int *_p0, int _p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+unsigned int ?=?(unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+unsigned int ?=?(volatile unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+long int ?=?(long int *_p0, long int _p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+long int ?=?(volatile long int *_p0, long int _p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+long unsigned int ?=?(long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+long unsigned int ?=?(volatile long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+char ?*=?(char *_p0, char _p1)
+{
+        return ((*_p0)*=_p1);
+
+}
+
+char ?*=?(volatile char *_p0, char _p1)
+{
+        return ((*_p0)*=_p1);
+
+}
+
+unsigned char ?*=?(unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)*=_p1);
+
+}
+
+unsigned char ?*=?(volatile unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)*=_p1);
+
+}
+
+int ?*=?(int *_p0, int _p1)
+{
+        return ((*_p0)*=_p1);
+
+}
+
+int ?*=?(volatile int *_p0, int _p1)
+{
+        return ((*_p0)*=_p1);
+
+}
+
+unsigned int ?*=?(unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)*=_p1);
+
+}
+
+unsigned int ?*=?(volatile unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)*=_p1);
+
+}
+
+long int ?*=?(long int *_p0, long int _p1)
+{
+        return ((*_p0)*=_p1);
+
+}
+
+long int ?*=?(volatile long int *_p0, long int _p1)
+{
+        return ((*_p0)*=_p1);
+
+}
+
+long unsigned int ?*=?(long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)*=_p1);
+
+}
+
+long unsigned int ?*=?(volatile long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)*=_p1);
+
+}
+
+char ?/=?(char *_p0, char _p1)
+{
+        return ((*_p0)/=_p1);
+
+}
+
+char ?/=?(volatile char *_p0, char _p1)
+{
+        return ((*_p0)/=_p1);
+
+}
+
+unsigned char ?/=?(unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)/=_p1);
+
+}
+
+unsigned char ?/=?(volatile unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)/=_p1);
+
+}
+
+int ?/=?(int *_p0, int _p1)
+{
+        return ((*_p0)/=_p1);
+
+}
+
+int ?/=?(volatile int *_p0, int _p1)
+{
+        return ((*_p0)/=_p1);
+
+}
+
+unsigned int ?/=?(unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)/=_p1);
+
+}
+
+unsigned int ?/=?(volatile unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)/=_p1);
+
+}
+
+long int ?/=?(long int *_p0, long int _p1)
+{
+        return ((*_p0)/=_p1);
+
+}
+
+long int ?/=?(volatile long int *_p0, long int _p1)
+{
+        return ((*_p0)/=_p1);
+
+}
+
+long unsigned int ?/=?(long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)/=_p1);
+
+}
+
+long unsigned int ?/=?(volatile long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)/=_p1);
+
+}
+
+char ?%=?(char *_p0, char _p1)
+{
+        return ((*_p0)%=_p1);
+
+}
+
+char ?%=?(volatile char *_p0, char _p1)
+{
+        return ((*_p0)%=_p1);
+
+}
+
+unsigned char ?%=?(unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)%=_p1);
+
+}
+
+unsigned char ?%=?(volatile unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)%=_p1);
+
+}
+
+int ?%=?(int *_p0, int _p1)
+{
+        return ((*_p0)%=_p1);
+
+}
+
+int ?%=?(volatile int *_p0, int _p1)
+{
+        return ((*_p0)%=_p1);
+
+}
+
+unsigned int ?%=?(unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)%=_p1);
+
+}
+
+unsigned int ?%=?(volatile unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)%=_p1);
+
+}
+
+long int ?%=?(long int *_p0, long int _p1)
+{
+        return ((*_p0)%=_p1);
+
+}
+
+long int ?%=?(volatile long int *_p0, long int _p1)
+{
+        return ((*_p0)%=_p1);
+
+}
+
+long unsigned int ?%=?(long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)%=_p1);
+
+}
+
+long unsigned int ?%=?(volatile long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)%=_p1);
+
+}
+
+char ?+=?(char *_p0, char _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+char ?+=?(volatile char *_p0, char _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+unsigned char ?+=?(unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+unsigned char ?+=?(volatile unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+int ?+=?(int *_p0, int _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+int ?+=?(volatile int *_p0, int _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+unsigned int ?+=?(unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+unsigned int ?+=?(volatile unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+long int ?+=?(long int *_p0, long int _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+long int ?+=?(volatile long int *_p0, long int _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+long unsigned int ?+=?(long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+long unsigned int ?+=?(volatile long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+char ?-=?(char *_p0, char _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+char ?-=?(volatile char *_p0, char _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+unsigned char ?-=?(unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+unsigned char ?-=?(volatile unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+int ?-=?(int *_p0, int _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+int ?-=?(volatile int *_p0, int _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+unsigned int ?-=?(unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+unsigned int ?-=?(volatile unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+long int ?-=?(long int *_p0, long int _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+long int ?-=?(volatile long int *_p0, long int _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+long unsigned int ?-=?(long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+long unsigned int ?-=?(volatile long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+char ?<<=?(char *_p0, char _p1)
+{
+        return ((*_p0)<<=_p1);
+
+}
+
+char ?<<=?(volatile char *_p0, char _p1)
+{
+        return ((*_p0)<<=_p1);
+
+}
+
+unsigned char ?<<=?(unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)<<=_p1);
+
+}
+
+unsigned char ?<<=?(volatile unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)<<=_p1);
+
+}
+
+int ?<<=?(int *_p0, int _p1)
+{
+        return ((*_p0)<<=_p1);
+
+}
+
+int ?<<=?(volatile int *_p0, int _p1)
+{
+        return ((*_p0)<<=_p1);
+
+}
+
+unsigned int ?<<=?(unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)<<=_p1);
+
+}
+
+unsigned int ?<<=?(volatile unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)<<=_p1);
+
+}
+
+long int ?<<=?(long int *_p0, long int _p1)
+{
+        return ((*_p0)<<=_p1);
+
+}
+
+long int ?<<=?(volatile long int *_p0, long int _p1)
+{
+        return ((*_p0)<<=_p1);
+
+}
+
+long unsigned int ?<<=?(long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)<<=_p1);
+
+}
+
+long unsigned int ?<<=?(volatile long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)<<=_p1);
+
+}
+
+char ?>>=?(char *_p0, char _p1)
+{
+        return ((*_p0)>>=_p1);
+
+}
+
+char ?>>=?(volatile char *_p0, char _p1)
+{
+        return ((*_p0)>>=_p1);
+
+}
+
+unsigned char ?>>=?(unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)>>=_p1);
+
+}
+
+unsigned char ?>>=?(volatile unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)>>=_p1);
+
+}
+
+int ?>>=?(int *_p0, int _p1)
+{
+        return ((*_p0)>>=_p1);
+
+}
+
+int ?>>=?(volatile int *_p0, int _p1)
+{
+        return ((*_p0)>>=_p1);
+
+}
+
+unsigned int ?>>=?(unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)>>=_p1);
+
+}
+
+unsigned int ?>>=?(volatile unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)>>=_p1);
+
+}
+
+long int ?>>=?(long int *_p0, long int _p1)
+{
+        return ((*_p0)>>=_p1);
+
+}
+
+long int ?>>=?(volatile long int *_p0, long int _p1)
+{
+        return ((*_p0)>>=_p1);
+
+}
+
+long unsigned int ?>>=?(long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)>>=_p1);
+
+}
+
+long unsigned int ?>>=?(volatile long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)>>=_p1);
+
+}
+
+char ?&=?(char *_p0, char _p1)
+{
+        return ((*_p0)&=_p1);
+
+}
+
+char ?&=?(volatile char *_p0, char _p1)
+{
+        return ((*_p0)&=_p1);
+
+}
+
+unsigned char ?&=?(unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)&=_p1);
+
+}
+
+unsigned char ?&=?(volatile unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)&=_p1);
+
+}
+
+int ?&=?(int *_p0, int _p1)
+{
+        return ((*_p0)&=_p1);
+
+}
+
+int ?&=?(volatile int *_p0, int _p1)
+{
+        return ((*_p0)&=_p1);
+
+}
+
+unsigned int ?&=?(unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)&=_p1);
+
+}
+
+unsigned int ?&=?(volatile unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)&=_p1);
+
+}
+
+long int ?&=?(long int *_p0, long int _p1)
+{
+        return ((*_p0)&=_p1);
+
+}
+
+long int ?&=?(volatile long int *_p0, long int _p1)
+{
+        return ((*_p0)&=_p1);
+
+}
+
+long unsigned int ?&=?(long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)&=_p1);
+
+}
+
+long unsigned int ?&=?(volatile long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)&=_p1);
+
+}
+
+char ?|=?(char *_p0, char _p1)
+{
+        return ((*_p0)|=_p1);
+
+}
+
+char ?|=?(volatile char *_p0, char _p1)
+{
+        return ((*_p0)|=_p1);
+
+}
+
+unsigned char ?|=?(unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)|=_p1);
+
+}
+
+unsigned char ?|=?(volatile unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)|=_p1);
+
+}
+
+int ?|=?(int *_p0, int _p1)
+{
+        return ((*_p0)|=_p1);
+
+}
+
+int ?|=?(volatile int *_p0, int _p1)
+{
+        return ((*_p0)|=_p1);
+
+}
+
+unsigned int ?|=?(unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)|=_p1);
+
+}
+
+unsigned int ?|=?(volatile unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)|=_p1);
+
+}
+
+long int ?|=?(long int *_p0, long int _p1)
+{
+        return ((*_p0)|=_p1);
+
+}
+
+long int ?|=?(volatile long int *_p0, long int _p1)
+{
+        return ((*_p0)|=_p1);
+
+}
+
+long unsigned int ?|=?(long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)|=_p1);
+
+}
+
+long unsigned int ?|=?(volatile long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)|=_p1);
+
+}
+
+char ?^=?(char *_p0, char _p1)
+{
+        return ((*_p0)^=_p1);
+
+}
+
+char ?^=?(volatile char *_p0, char _p1)
+{
+        return ((*_p0)^=_p1);
+
+}
+
+unsigned char ?^=?(unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)^=_p1);
+
+}
+
+unsigned char ?^=?(volatile unsigned char *_p0, unsigned char _p1)
+{
+        return ((*_p0)^=_p1);
+
+}
+
+int ?^=?(int *_p0, int _p1)
+{
+        return ((*_p0)^=_p1);
+
+}
+
+int ?^=?(volatile int *_p0, int _p1)
+{
+        return ((*_p0)^=_p1);
+
+}
+
+unsigned int ?^=?(unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)^=_p1);
+
+}
+
+unsigned int ?^=?(volatile unsigned int *_p0, unsigned int _p1)
+{
+        return ((*_p0)^=_p1);
+
+}
+
+long int ?^=?(long int *_p0, long int _p1)
+{
+        return ((*_p0)^=_p1);
+
+}
+
+long int ?^=?(volatile long int *_p0, long int _p1)
+{
+        return ((*_p0)^=_p1);
+
+}
+
+long unsigned int ?^=?(long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)^=_p1);
+
+}
+
+long unsigned int ?^=?(volatile long unsigned int *_p0, long unsigned int _p1)
+{
+        return ((*_p0)^=_p1);
+
+}
+
+float ?=?(float *_p0, float _p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+float ?=?(volatile float *_p0, float _p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+float ?*=?(float *_p0, float _p1)
+{
+        return ((*_p0)*=_p1);
+
+}
+
+float ?*=?(volatile float *_p0, float _p1)
+{
+        return ((*_p0)*=_p1);
+
+}
+
+float ?/=?(float *_p0, float _p1)
+{
+        return ((*_p0)/=_p1);
+
+}
+
+float ?/=?(volatile float *_p0, float _p1)
+{
+        return ((*_p0)/=_p1);
+
+}
+
+float ?+=?(float *_p0, float _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+float ?+=?(volatile float *_p0, float _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+float ?-=?(float *_p0, float _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+float ?-=?(volatile float *_p0, float _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+double ?=?(double *_p0, double _p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+double ?=?(volatile double *_p0, double _p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+double ?*=?(double *_p0, double _p1)
+{
+        return ((*_p0)*=_p1);
+
+}
+
+double ?*=?(volatile double *_p0, double _p1)
+{
+        return ((*_p0)*=_p1);
+
+}
+
+double ?/=?(double *_p0, double _p1)
+{
+        return ((*_p0)/=_p1);
+
+}
+
+double ?/=?(volatile double *_p0, double _p1)
+{
+        return ((*_p0)/=_p1);
+
+}
+
+double ?+=?(double *_p0, double _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+double ?+=?(volatile double *_p0, double _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+double ?-=?(double *_p0, double _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+double ?-=?(volatile double *_p0, double _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+long double ?=?(long double *_p0, long double _p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+long double ?=?(volatile long double *_p0, long double _p1)
+{
+        return ((*_p0)=_p1);
+
+}
+
+long double ?*=?(long double *_p0, long double _p1)
+{
+        return ((*_p0)*=_p1);
+
+}
+
+long double ?*=?(volatile long double *_p0, long double _p1)
+{
+        return ((*_p0)*=_p1);
+
+}
+
+long double ?/=?(long double *_p0, long double _p1)
+{
+        return ((*_p0)/=_p1);
+
+}
+
+long double ?/=?(volatile long double *_p0, long double _p1)
+{
+        return ((*_p0)/=_p1);
+
+}
+
+long double ?+=?(long double *_p0, long double _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+long double ?+=?(volatile long double *_p0, long double _p1)
+{
+        return ((*_p0)+=_p1);
+
+}
+
+long double ?-=?(long double *_p0, long double _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
+long double ?-=?(volatile long double *_p0, long double _p1)
+{
+        return ((*_p0)-=_p1);
+
+}
+
Index: translator/prolog.c
===================================================================
--- translator/prolog.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/prolog.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,35 @@
+// "./cfa prolog.c"
+
+extern "C" { extern int printf( const char *fmt, ... ); }
+
+void printResult( int x ) { printf( "int\n" ); }
+void printResult( double x ) { printf( "double\n" ); }
+void printResult( char * x ) { printf( "char*\n" ); }
+
+void is_arithmetic( int x ) {}
+void is_arithmetic( double x ) {}
+
+void is_integer( int x ) {}
+
+context ArithmeticType( type T )
+{
+  void is_arithmetic( T );
+};
+
+context IntegralType( type T | ArithmeticType( T ) )
+{
+  void is_integer( T );
+};
+
+forall( type T | IntegralType( T ) | { void printResult( T ); } ) void hornclause( T param )
+{
+  printResult( param );
+}
+
+int main()
+{
+  int x;
+  double x;
+  char * x;
+  hornclause( x );
+}
Index: translator/quad.c
===================================================================
--- translator/quad.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/quad.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,24 @@
+// "./cfa quad.c"
+// "./cfa -CFA quad.c > quad_out.c"
+// "gcc31 -g quad_out.c LibCfa/libcfa.a"
+
+#include <stdio.h>
+
+forall( type T | { T ?*?( T, T ); } )
+T square( T t )
+{
+  return t * t;
+}
+
+forall( type U | { U square( U ); } )
+U quad( U u )
+{
+  return square( square( u ) );
+}
+
+int
+main()
+{
+  printf( "result of quad of 5 is %d\n", quad( 5 ) );
+  return 0;
+}
Index: translator/resume-1.cc
===================================================================
--- translator/resume-1.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/resume-1.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,39 @@
+#include <uC++.h>
+#include <uIOStream.h>
+
+typedef void (*fixup)( int &i, fixup r1, fixup r2 );
+
+void f( int &i, fixup r1, fixup r2 );
+void g( int &i, fixup r1, fixup r2 );
+
+void h1( int &i, fixup r1, fixup r2 ) {
+	i -= 1;
+	uCout << "h1, i:" << i << endl;
+	f( i, r1, r2 );
+}
+void h2( int &i, fixup r1, fixup r2 ) {
+	i -= 2;
+	uCout << "h2, i:" << i << endl;
+	g( i, r1, r2 );
+}
+
+void f( int &i, fixup r1, fixup r2 ) {
+	i -= 1;
+	uCout << "f, i:" << i << endl;
+	if ( i > 0 ) {
+		if ( i % 2 != 0 ) r2(i, r1, r2);
+		g( i, r1, r2 );
+	}
+}
+void g( int &i, fixup r1, fixup r2 ) {
+	i -= 1;
+	uCout << "g, i:" << i << endl;
+	if ( i > 0 ) {
+		f( i );
+		r1(i, r1, r2);
+	}
+}
+void uMain::main() {
+	int i = 20;
+	f( i, h1, h2 );
+}
Index: translator/resume-2.cc
===================================================================
--- translator/resume-2.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/resume-2.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,47 @@
+#include <uC++.h>
+#include <uIOStream.h>
+
+struct h1;
+struct h2;
+
+void f( int &i, h1 &r1, h2 &r2 );
+void g( int &i, h1 &r1, h2 &r2 );
+
+struct h1 {
+	void operator()( int &i, h1 &r1, h2 &r2 ) {
+		i -= 1;
+		uCout << "h1, i:" << i << endl;
+		f( i, r1, r2 );
+	}
+};
+		
+struct h2 {
+	void operator()( int &i, h1 &r1, h2 &r2 ) {
+		i -= 2;
+		uCout << "h2, i:" << i << endl;
+		g( i, r1, r2 );
+	}
+};
+		
+void f( int &i, h1 &r1, h2 &r2 ) {
+	i -= 1;
+	uCout << "f, i:" << i << endl;
+	if ( i > 0 ) {
+		if ( i % 2 != 0 ) r2(i, r1, r2);
+		g( i, r1, r2 );
+	}
+}
+void g( int &i, h1 &r1, h2 &r2 ) {
+	i -= 1;
+	uCout << "g, i:" << i << endl;
+	if ( i > 0 ) {
+		f( i, r1, r2 );
+		r1(i, r1, r2);
+	}
+}
+void uMain::main() {
+	int i = 20;
+	h1 r1;
+	h2 r2;
+	f( i, r1, r2 );
+}
Index: translator/resume-3.cc
===================================================================
--- translator/resume-3.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/resume-3.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,43 @@
+#include <uC++.h>
+#include <uIOStream.h>
+
+template< class fixup >
+void f( int &i, fixup r1, fixup r2 );
+template< class fixup >
+void g( int &i, fixup r1, fixup r2 );
+
+template< class fixup >
+void h1( int &i, fixup r1, fixup r2 ) {
+	i -= 1;
+	uCout << "h1, i:" << i << endl;
+	f( i, r1, r2 );
+}
+template< class fixup >
+void h2( int &i, fixup r1, fixup r2 ) {
+	i -= 2;
+	uCout << "h2, i:" << i << endl;
+	g( i, r1, r2 );
+}
+
+template< class fixup >
+void f( int &i, fixup r1, fixup r2 ) {
+	i -= 1;
+	uCout << "f, i:" << i << endl;
+	if ( i > 0 ) {
+		if ( i % 2 != 0 ) r2(i, r1, r2);
+		g( i, r1, r2 );
+	}
+}
+template< class fixup >
+void g( int &i, fixup r1, fixup r2 ) {
+	i -= 1;
+	uCout << "g, i:" << i << endl;
+	if ( i > 0 ) {
+		f( i );
+		r1(i, r1, r2);
+	}
+}
+void uMain::main() {
+	int i = 20;
+	f( i, h1, h2 );
+}
Index: translator/resume-orig
===================================================================
--- translator/resume-orig	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/resume-orig	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,60 @@
+#include <uC++.h>
+#include <uIOStream.h>
+
+uRaiseEvent R1 {
+  public:
+	int &i;
+	R1( int &i ) : i(i) {}
+};
+uInitEvent( R1 );
+
+uRaiseEvent R2 {
+  public:
+	int &i;
+	R2( int &i ) : i(i) {}
+};
+uInitEvent( R2 );
+
+void f( int &i );
+void g( int &i );
+
+void h1( R1 &r ) {
+	r.i -= 1;
+	uCout << "h1, i:" << r.i << endl;
+	f( r.i );
+}
+void h2( R2 &r ) {
+	r.i -= 2;
+	uCout << "h2, i:" << r.i << endl;
+	g( r.i );
+}
+
+void f( int &i ) {
+	i -= 1;
+	uCout << "f, i:" << i << endl;
+	if ( i > 0 ) {
+		try <R1,h1><R2,h2> {
+			if ( i % 2 != 0 ) uRaise R2(i);
+			g( i );
+		}
+	}
+}
+void g( int &i ) {
+	i -= 1;
+	uCout << "g, i:" << i << endl;
+	if ( i > 0 ) {
+		try <R1,h1><R2,h2> {
+			f( i );
+			uRaise R1(i);
+		}
+	}
+}
+void uMain::main() {
+	int i = 20;
+	f( i );
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// End: //
+
Index: translator/resume-orig.cc
===================================================================
--- translator/resume-orig.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/resume-orig.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,60 @@
+#include <uC++.h>
+#include <uIOStream.h>
+
+uRaiseEvent R1 {
+  public:
+	int &i;
+	R1( int &i ) : i(i) {}
+};
+uInitEvent( R1 );
+
+uRaiseEvent R2 {
+  public:
+	int &i;
+	R2( int &i ) : i(i) {}
+};
+uInitEvent( R2 );
+
+void f( int &i );
+void g( int &i );
+
+void h1( R1 &r ) {
+	r.i -= 1;
+	uCout << "h1, i:" << r.i << endl;
+	f( r.i );
+}
+void h2( R2 &r ) {
+	r.i -= 2;
+	uCout << "h2, i:" << r.i << endl;
+	g( r.i );
+}
+
+void f( int &i ) {
+	i -= 1;
+	uCout << "f, i:" << i << endl;
+	if ( i > 0 ) {
+		try <R1,h1><R2,h2> {
+			if ( i % 2 != 0 ) uRaise R2(i);
+			g( i );
+		}
+	}
+}
+void g( int &i ) {
+	i -= 1;
+	uCout << "g, i:" << i << endl;
+	if ( i > 0 ) {
+		try <R1,h1><R2,h2> {
+			f( i );
+			uRaise R1(i);
+		}
+	}
+}
+void uMain::main() {
+	int i = 20;
+	f( i );
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// End: //
+
Index: translator/rodolfo1.c
===================================================================
--- translator/rodolfo1.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/rodolfo1.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,9 @@
+// "./cfa-cpp -c rodolfo1.c"
+
+void
+f()
+{
+	int a, b = 4, c = 5;
+	a = b + c;
+	int d = a + 7;
+}
Index: translator/rodolfo2.c
===================================================================
--- translator/rodolfo2.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/rodolfo2.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,10 @@
+// "./cfa-cpp -c rodolfo2.c"
+
+int a = 7;
+
+void f() {
+        int b;
+        b = a;
+        int a = 8;
+        assert( b == 7 );
+}
Index: translator/s.c
===================================================================
--- translator/s.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/s.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,7 @@
+int ?!=?( int, int );
+int 0;
+
+void f()
+{
+  0 ? 4 : 5;
+}
Index: translator/simple.c
===================================================================
--- translator/simple.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/simple.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,23 @@
+// './cfa square.c'
+
+context has_star( type T )
+{
+  T ?*?( T, T );
+};
+
+int ?*?( int, int );
+extern "C" { void printf( const char *, ... ); }
+int ?=?( int*, int );
+
+forall( type T | has_star( T ) )
+T
+square( T t )
+{
+  return t * t;
+}
+
+int
+main()
+{
+  printf( "result of square of 5 is %d\n", square( 5 ) );
+}
Index: translator/simple.out.c
===================================================================
--- translator/simple.out.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/simple.out.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,38 @@
+struct _ctx_has_star
+{
+    void (*___operator_multiply__PF2tT_2tT2tT_)();
+    void (*_adapterF2tT_2tT2tT_)(void (*)(), void *, void *, void *);
+};
+int ___operator_multiply__Fi_ii_(int , int );
+struct _ctx_has_star _ctx_has_star0 = { ((void (*)())(&___operator_multiply__Fi_ii_)), _adapterF2tT_2tT2tT_ };
+void printf(const char *, ...);
+int ___operator_assign__Fi_Pii_(int *, int );
+void __square__A1_0_0____operator_assign__PF2t0_P2t02t0______ctx_has_star_2t0_F2t0_2t0_(void (*_adapterF2tT_P2tT2tT_)(void (*)(), void *, void *, void *), void (*_adapterF2tT_2tT2tT_)(void (*)(), void *, void *, void *), long unsigned int T, void (*___operator_assign__PF2tT_P2tT2tT_)(), struct _ctx_has_star _ctx_has_star_2tT, void *_retparm, void *__t__2tT)
+{
+    void _adapterF2tT_2tT2tT_(void (*_adaptee)(), void *_ret, void *_p0, void *_p1)
+    {
+        ((*((void *)_ret))=((void *(*)(void *, void *))_adaptee)((*((void *)_p0)), (*((void *)_p1))));
+    }
+
+    _ctx_has_star_2tT._adapterF2tT_2tT2tT_(_ctx_has_star_2tT.___operator_multiply__PF2tT_2tT2tT_, _retparm, __t__2tT, __t__2tT);
+    return ;
+}
+
+int main()
+{
+    int _temp0;
+    int _temp1;
+    (_temp1=5);
+    void _adapterFi_Pii_(void (*_adaptee)(), void *_ret, void *_p0, void *_p1)
+    {
+        ((*((int *)_ret))=((int (*)(int *, int ))_adaptee)(_p0, (*((int *)_p1))));
+    }
+
+    void _adapterFi_ii_(void (*_adaptee)(), void *_ret, void *_p0, void *_p1)
+    {
+        ((*((int *)_ret))=((int (*)(int , int ))_adaptee)((*((int *)_p0)), (*((int *)_p1))));
+    }
+
+    printf(((const char *)"result of square of 5 is %d\n"), (__square__A1_0_0____operator_assign__PF2t0_P2t02t0______ctx_has_star_2t0_F2t0_2t0_(_adapterFi_Pii_, _adapterFi_ii_, sizeof(int ), ((void (*)())___operator_assign__Fi_Pii_), _ctx_has_star0, (&_temp0), (&_temp1)) , _temp0));
+}
+
Index: translator/simplePoly.c
===================================================================
--- translator/simplePoly.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/simplePoly.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,17 @@
+// './cfa-cpp -nc < simplePoly.c'
+
+forall( type T, type U | { T f( T, U ); } ) T q( T t, U u )
+{
+  return f( t, u );
+//  return t;
+}
+
+int f( int, double* );
+
+void g( void )
+{
+  int y;
+  double x;
+//  if( y )
+    q( 3, &x );
+}
Index: translator/simpler.c
===================================================================
--- translator/simpler.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/simpler.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,9 @@
+// "./cfa-cpp -c simpler.c"
+
+forall( type T ) T id( T, T );
+
+int
+main()
+{
+  id( 0, 7 );
+}
Index: translator/specialize.c
===================================================================
--- translator/specialize.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/specialize.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,43 @@
+// "./cfa specialize.c"
+// "./cfa -g simple.c"
+// "./cfa -CFA simple.c > simple_out.c"
+
+/// void f( const int * );
+/// 
+/// void m()
+/// {
+///   f( 0 );
+/// }
+
+/// forall( dtype T ) T* f( T* );
+/// void g( int* (*)(int*) );
+/// 
+/// int m() {
+///   g( f );
+/// }
+
+/// void f1( void (*q)( forall( dtype U ) U* (*p)( U* ) ) );
+/// void g1( int* (*)(int*) );
+/// 
+/// int m1() {
+///   f1( g1 );
+/// }
+
+extern "C" {
+  int printf( const char*, ... );
+}
+
+forall( type T ) T f( T t )
+{
+  printf( "in f; sizeof T is %d\n", sizeof( T ) );
+  return t;
+}
+
+void g( int (*p)(int) )
+{
+  printf( "g: f(7) returned %d\n", f(7) );
+}
+
+int main() {
+  g( f );
+}
Index: translator/spectest
===================================================================
--- translator/spectest	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/spectest	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,4 @@
+.cf:
+cpp %p %i -o %g.if
+/u/rcbilson/opt/lib/cfa-cpp -cp %{v} %g.if %g.i
+gcc %1 -o %b.o -c %g.i dummy
Index: translator/square.c
===================================================================
--- translator/square.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/square.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,20 @@
+// './cfa square.c'
+
+#undef __cplusplus
+extern "C" {
+#include <stdio.h>
+}
+
+forall( type T | { T ?*?( T, T ); })
+T
+square( T t )
+{
+  return t * t;
+}
+
+int
+main()
+{
+  printf( "result of square of 5 is %d\n", square( 5 ) );
+  return 0;
+}
Index: translator/square.cf
===================================================================
--- translator/square.cf	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/square.cf	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,20 @@
+// './cfa square.c'
+
+#undef __cplusplus
+extern "C" {
+#include <stdio.h>
+}
+
+forall( type T | { T ?*?( T, T ); })
+T
+square( T t )
+{
+  return t * t;
+}
+
+int
+main()
+{
+  printf( "result of square of 5 is %d\n", square( 5 ) );
+  return 0;
+}
Index: translator/sum.c
===================================================================
--- translator/sum.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/sum.c	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,35 @@
+// "./cfa -g sum.c"
+// "./cfa -CFA sum.c > sum_out.c"
+// "gcc32 -g sum_out.c LibCfa/libcfa.a"
+
+extern "C" {
+  int printf( const char *, ... );
+}
+
+context sumable( type T ) {
+    const T 0;
+    T ?+?(T, T);
+    T ?++(T*);
+    [T] ?+=?(T*,T);
+};
+
+forall( type T | sumable( T ) )
+    T sum( int n, T a[] ) {
+	T total = 0;
+	int i;
+	for ( i = 0; i < n; i += 1 )
+	    total = total + a[i];
+	return total;
+    }
+
+int
+main()
+{
+  int a[ 10 ];
+  int i;
+  for( i = 0; i < 10; ++i ) {
+    a[ i ] = i;
+  }
+  printf( "the sum is %d\n", sum( 10, a ) );
+  return 0;
+}
