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

#include "ResolveTypeof.h"
#include "Alternative.h"
#include "AlternativeFinder.h"
#include "Resolver.h"
#include "TypeEnvironment.h"
#include "SynTree/Expression.h"
#include "SynTree/Type.h"

namespace ResolvExpr {

namespace {
#if 0
  void
  printAlts( const AltList &list, std::ostream &os, int indent = 0 )
  {
    for( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {
      i->print( os, indent );
      os << std::endl;
    }
  }
#endif
}

class ResolveTypeof : public Mutator
{
public:
  ResolveTypeof( const SymTab::Indexer &indexer ) : indexer( indexer ) {}
  Type *mutate( TypeofType *typeofType );

private:
  const SymTab::Indexer &indexer;
};

Type *
resolveTypeof( Type *type, const SymTab::Indexer &indexer )
{
  ResolveTypeof mutator( indexer );
  return type->acceptMutator( mutator );
}

Type *
ResolveTypeof::mutate( TypeofType *typeofType )
{
///   std::cout << "resolving typeof: ";
///   typeofType->print( std::cout );
///   std::cout << std::endl;
  if( typeofType->get_expr() ) {
    Expression *newExpr = resolveInVoidContext( typeofType->get_expr(), indexer );
    assert( newExpr->get_results().size() > 0 );
    Type *newType;
    if( newExpr->get_results().size() > 1 ) {
      TupleType *tupleType = new TupleType( Type::Qualifiers() );
      cloneAll( newExpr->get_results(), tupleType->get_types() );
      newType = tupleType;
    } else {
      newType = newExpr->get_results().front()->clone();
    }
    delete typeofType;
    return newType;
  }
  return typeofType;
}

} // namespace ResolvExpr
