Index: translator/ResolvExpr/AdjustExprType.cc
===================================================================
--- translator/ResolvExpr/AdjustExprType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/AdjustExprType.cc	(revision d9a0e763800888addddd70d8848a8f432b825e4b)
@@ -1,9 +1,2 @@
-/*
- * 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"
@@ -12,125 +5,94 @@
 
 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;
+    };
 
-class AdjustExprType : public Mutator
-{
-  typedef Mutator Parent;
+    void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
+	AdjustExprType adjuster( env, indexer );
+	Type *newType = type->acceptMutator( adjuster );
+	type = newType;
+    }
 
-public:
-  AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer );
+    AdjustExprType::AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer )
+	: env( env ), 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;
-};
+    Type *AdjustExprType::mutate(VoidType *voidType) {
+	return voidType;
+    }
 
-void
-adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer )
-{
-  AdjustExprType adjuster( env, indexer );
-  Type *newType = type->acceptMutator( adjuster );
-  type = newType;
-}
+    Type *AdjustExprType::mutate(BasicType *basicType) {
+	return basicType;
+    }
 
-AdjustExprType::AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer )
-  : env( env ), indexer( indexer )
-{
-}
+    Type *AdjustExprType::mutate(PointerType *pointerType) {
+	return pointerType;
+    }
 
-Type* 
-AdjustExprType::mutate(VoidType *voidType)
-{
-  return voidType;
-}
+    Type *AdjustExprType::mutate(ArrayType *arrayType) {
+	PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->get_base()->clone() );
+	delete arrayType;
+	return pointerType;
+    }
 
-Type* 
-AdjustExprType::mutate(BasicType *basicType)
-{
-  return basicType;
-}
+    Type *AdjustExprType::mutate(FunctionType *functionType) {
+	PointerType *pointerType = new PointerType( Type::Qualifiers(), functionType );
+	return pointerType;
+    }
 
-Type* 
-AdjustExprType::mutate(PointerType *pointerType)
-{
-  return pointerType;
-}
+    Type *AdjustExprType::mutate(StructInstType *aggregateUseType) {
+	return aggregateUseType;
+    }
 
-Type* 
-AdjustExprType::mutate(ArrayType *arrayType)
-{
-  PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->get_base()->clone() );
-  delete arrayType;
-  return pointerType;
-}
+    Type *AdjustExprType::mutate(UnionInstType *aggregateUseType) {
+	return aggregateUseType;
+    }
 
-Type* 
-AdjustExprType::mutate(FunctionType *functionType)
-{
-  PointerType *pointerType = new PointerType( Type::Qualifiers(), functionType );
-  return pointerType;
-}
+    Type *AdjustExprType::mutate(EnumInstType *aggregateUseType) {
+	return aggregateUseType;
+    }
 
-Type* 
-AdjustExprType::mutate(StructInstType *aggregateUseType)
-{
-  return aggregateUseType;
-}
+    Type *AdjustExprType::mutate(ContextInstType *aggregateUseType) {
+	return aggregateUseType;
+    }
 
-Type* 
-AdjustExprType::mutate(UnionInstType *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(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;
+    Type *AdjustExprType::mutate(TupleType *tupleType) {
+	return tupleType;
     }
-  } 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 d9a0e763800888addddd70d8848a8f432b825e4b)
@@ -1,9 +1,2 @@
-/*
- * 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"
@@ -12,64 +5,46 @@
 
 namespace ResolvExpr {
+    Alternative::Alternative() : expr( 0 ) {}
 
-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 )
-  : 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( 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( const Alternative &other )
-{
-  initialize( other, *this );
-}
+    Alternative &Alternative::operator=( const Alternative &other ) {
+	if ( &other == this ) return *this;
+	initialize( other, *this );
+	return *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;
+    }
 
-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;
+    }
 
-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;
-}
-
-
+    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 d9a0e763800888addddd70d8848a8f432b825e4b)
@@ -1,9 +1,2 @@
-/*
- * 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
@@ -15,29 +8,25 @@
 
 namespace ResolvExpr {
+    struct Alternative;
+    typedef std::list< Alternative > AltList;
 
-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();
+    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 initialize( const Alternative &src, Alternative &dest );
   
-  void print( std::ostream &os, int indent = 0 ) const;
+	void print( std::ostream &os, int indent = 0 ) const;
   
-  Cost cost;
-  Cost cvtCost;
-  Expression *expr;
-  TypeEnvironment env;
-};
-
-
+	Cost cost;
+	Cost cvtCost;
+	Expression *expr;
+	TypeEnvironment env;
+    };
 } // namespace ResolvExpr
 
-#endif /* #ifndef RESOLVEXPR_ALTERNATIVE_H */
+#endif // RESOLVEXPR_ALTERNATIVE_H
Index: translator/ResolvExpr/AlternativeFinder.cc
===================================================================
--- translator/ResolvExpr/AlternativeFinder.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/AlternativeFinder.cc	(revision d9a0e763800888addddd70d8848a8f432b825e4b)
@@ -1,9 +1,2 @@
-/*
- * 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>
@@ -32,897 +25,874 @@
 #include "utility.h"
 
-
+extern bool resolveVerbose;
+#define PRINT( text ) if ( resolveVerbose ) { text } 
 //#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;
-    }
+    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 ) {
+			PRINT(
+			    std::cout << "cost " << candidate->cost << " beats " << mapPlace->second.candidate->cost << std::endl;
+			    )
+			selected[ mangleName ] = current;
+		    } else if ( candidate->cost == mapPlace->second.candidate->cost ) {
+			PRINT(
+			    std::cout << "marking ambiguous" << std::endl;
+			    )
+			mapPlace->second.isAmbiguous = true;
+		    }
+		} else {
+		    selected[ mangleName ] = current;
+		}
+	    }
+
+	    PRINT(
+		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++;
+	    PRINT(
+		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 );
+	    }
+	}
+	PRINT(
+	    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() );
+	PRINT(
+	    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 ) {
+	    PRINT(
+		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;
+		    }
+		}
+		PRINT(
+		    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 );
+		PRINT(
+		    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 ) {
+	    PRINT(
+		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 );
+	    PRINT(
+		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 ) ) );
-  }
-}
-
+	}
+    }
+
+    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;
+		}
+		PRINT(
+		    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;
+		PRINT(
+		    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;
+	PRINT(
+	    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 ) {
+	    PRINT(
+		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 );
+	    PRINT(
+		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 ) ) {
+		PRINT(
+		    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() );
+		PRINT(
+		    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 ) {
+//	PRINT(
+//	    std::cout << "inferParameters: assertions needed are" << std::endl;
+//	    printAll( need, std::cout, 8 );
+//	    )
+	SymTab::Indexer decls( indexer );
+	PRINT(
+	    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 );
+//	PRINT(
+//	    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() );
+	    PRINT(
+		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 ) {
+	    PRINT(
+		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
+		    }
+		    PRINT(
+			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 );
+
+	    PRINT(
+		ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( withFunc->expr );
+		assert( appExpr );
+		PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
+		assert( pointer );
+		FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
+		assert( function );
+		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;
+		)
+	    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 );
+	PRINT(
+	    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() ) );
+	    PRINT(
+		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 );
+	PRINT(
+	    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 d9a0e763800888addddd70d8848a8f432b825e4b)
@@ -1,11 +1,4 @@
-/*
- * 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
+#ifndef ALTERNATIVEFINDER_H
+#define ALTERNATIVEFINDER_H
 
 #include <set>
@@ -18,62 +11,58 @@
 
 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 );
 
-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 );
 
- 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;
+    }; // AlternativeFinder
 
-  const SymTab::Indexer &indexer;
-  AltList alternatives;
-  const TypeEnvironment &env;
-};
-
-Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env )
-;
-
+    Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env );
 } // namespace ResolvExpr
 
-#endif /* #ifndef RESOLVEXPR_ALTERNATIVEFINDER_H */
+#endif // ALTERNATIVEFINDER_H
Index: translator/ResolvExpr/AlternativePrinter.cc
===================================================================
--- translator/ResolvExpr/AlternativePrinter.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/AlternativePrinter.cc	(revision d9a0e763800888addddd70d8848a8f432b825e4b)
@@ -1,9 +1,2 @@
-/*
- * 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"
@@ -15,25 +8,18 @@
 
 namespace ResolvExpr {
+    AlternativePrinter::AlternativePrinter( std::ostream &os ) : SymTab::Indexer( false ), os( os ) {}
 
-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;
-  }
-}
-
+    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;
+	} // for
+    } // AlternativePrinter::visit
 } // namespace ResolvExpr
Index: translator/ResolvExpr/AlternativePrinter.h
===================================================================
--- translator/ResolvExpr/AlternativePrinter.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/AlternativePrinter.h	(revision d9a0e763800888addddd70d8848a8f432b825e4b)
@@ -1,11 +1,4 @@
-/*
- * 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
+#ifndef ALTERNATIVEPRINTER_H
+#define ALTERNATIVEPRINTER_H
 
 #include <iostream>
@@ -15,16 +8,12 @@
 
 namespace ResolvExpr {
-
-class AlternativePrinter : public SymTab::Indexer
-{
-public:
-  AlternativePrinter( std::ostream &os );
-  virtual void visit(ExprStmt *exprStmt);
-
-private:
-  std::ostream &os;
-};
-
+    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 */
+#endif // ALTERNATIVEPRINTER_H
Index: translator/ResolvExpr/Cost.h
===================================================================
--- translator/ResolvExpr/Cost.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/Cost.h	(revision d9a0e763800888addddd70d8848a8f432b825e4b)
@@ -1,9 +1,2 @@
-/*
- * 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
@@ -12,129 +5,100 @@
 
 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;
 
-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;
+    };
 
-  int unsafe;
-  int poly;
-  int safe;
-};
+    inline Cost::Cost() : unsafe( 0 ), poly( 0 ), safe( 0 ) {}
 
-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
-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::incUnsafe( int inc )
-{
-  unsafe += inc;
-}
+    inline void 
+	Cost::incPoly( int inc ) {
+	unsafe += inc;
+    }
 
-inline void 
-Cost::incPoly( int inc )
-{
-  unsafe += inc;
-}
+    inline void 
+	Cost::incSafe( 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 ) 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 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
-{
-  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 unsafe == other.unsafe
-         && poly == other.poly
-         && safe == other.safe;
-}
+    inline bool Cost::operator!=( const Cost &other ) const {
+	return !( *this == other );
+    }
 
-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;
-}
-
+    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 */
+#endif // RESOLVEXPR_COST_H
Index: translator/ResolvExpr/ResolveTypeof.cc
===================================================================
--- translator/ResolvExpr/ResolveTypeof.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/ResolveTypeof.cc	(revision d9a0e763800888addddd70d8848a8f432b825e4b)
@@ -1,9 +1,2 @@
-/*
- * 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"
@@ -15,57 +8,53 @@
 
 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
+    }
 
-namespace {
+    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 ) {
 #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;
+	std::cout << "resolving typeof: ";
+	typeofType->print( std::cout );
+	std::cout << std::endl;
+#endif
+	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;
     }
-  }
-#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 d9a0e763800888addddd70d8848a8f432b825e4b)
@@ -1,11 +1,4 @@
-/*
- * 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
+#ifndef RESOLVETYPEOF_H
+#define RESOLVETYPEOF_H
 
 #include "SynTree/SynTree.h"
@@ -13,8 +6,6 @@
 
 namespace ResolvExpr {
-
-Type *resolveTypeof( Type*, const SymTab::Indexer &indexer );
-
+    Type *resolveTypeof( Type*, const SymTab::Indexer &indexer );
 } // namespace ResolvExpr
 
-#endif /* #ifndef RESOLVEXPR_RESOLVETYPEOF_H */
+#endif // RESOLVETYPEOF_H
Index: translator/ResolvExpr/Resolver.cc
===================================================================
--- translator/ResolvExpr/Resolver.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/Resolver.cc	(revision d9a0e763800888addddd70d8848a8f432b825e4b)
@@ -1,9 +1,2 @@
-/*
- * 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"
@@ -18,273 +11,244 @@
 #include "utility.h"
 
+#include <iostream>
+using namespace std;
+
 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 );
-}
-
+    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 );
+	virtual void visit( ListInit *listInit );
+      private:
+	std::list< Type * > functionReturn;
+	Type *initContext;
+	Type *switchType;
+    };
+
+    void resolve( std::list< Declaration * > translationUnit ) {
+	Resolver resolver;
+	acceptAll( translationUnit, resolver );
+#if 0
+	for ( std::list< Declaration * >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
+	    (*i)->print( std::cerr );
+	    (*i)->accept( resolver );
+	}
+#endif
+    }
+
+    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 0
+	    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 );
+		}
+	    }
+#endif
+	    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 0
+	    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 );
+		}
+	    }
+#endif
+	    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 ) {
+#if 0
+	std::cout << "resolver visiting functiondecl ";
+	functionDecl->print( std::cout );
+	std::cout << std::endl;
+#endif
+	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 );
+    }
+
+    void Resolver::visit( ListInit *listInit ) {
+	// no cast necessary
+    }
 } // namespace ResolvExpr
Index: translator/ResolvExpr/Resolver.h
===================================================================
--- translator/ResolvExpr/Resolver.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/Resolver.h	(revision d9a0e763800888addddd70d8848a8f432b825e4b)
@@ -1,11 +1,4 @@
-/*
- * 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
+#ifndef RESOLVER_H
+#define RESOLVER_H
 
 #include "SynTree/SynTree.h"
@@ -13,9 +6,7 @@
 
 namespace ResolvExpr {
-
-void resolve( std::list< Declaration* > translationUnit );
-Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer );
-
+    void resolve( std::list< Declaration * > translationUnit );
+    Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer );
 } // namespace ResolvExpr
 
-#endif /* #ifndef RESOLVEXPR_RESOLVER_H */
+#endif // RESOLVER_H
