/*
 * This file is part of the Cforall project
 *
 * $Id: GenPoly.cc,v 1.4 2005/08/29 20:14:13 rcbilson Exp $
 *
 */

#include "GenPoly.h"
#include "SynTree/Type.h"


namespace GenPoly {

bool
isPolyVal( Type *type, const TyVarMap &tyVars )
{
  if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
    if( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
      return true;
    }
  }
  return false;
}

// A function needs an adapter if it returns a polymorphic value or if any of its
// parameters have polymorphic type
bool
needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars )
{
  bool needsAdapter = false;
  if( !adaptee->get_returnVals().empty() && isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
    needsAdapter = true;
  }
  for( std::list< DeclarationWithType* >::const_iterator innerArg = adaptee->get_parameters().begin(); !needsAdapter && innerArg != adaptee->get_parameters().end(); ++innerArg ) {
    if( isPolyVal( (*innerArg)->get_type(), tyVars ) ) {
      needsAdapter = true;
    }
  }
  
  return needsAdapter;
}

void 
printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap )
{
  for( TyVarMap::const_iterator i = tyVarMap.begin(); i != tyVarMap.end(); ++i ) {
    os << i->first << " (" << i->second << ") ";
  }
  os << std::endl;
}

} // namespace GenPoly
