//
// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
//
// The contents of this file are covered under the licence agreement in the
// file "LICENCE" distributed with Cforall.
//
// ScrubTyVars.cc -- 
//
// Author           : Richard C. Bilson
// Created On       : Mon May 18 07:44:20 2015
// Last Modified By : Peter A. Buhr
// Last Modified On : Tue May 19 16:42:42 2015
// Update Count     : 2
//

#include <sstream>
#include <string>

#include "GenPoly.h"
#include "ScrubTyVars.h"

#include "SynTree/Mutator.h"
#include "SynTree/Type.h"
#include "SynTree/Expression.h"

namespace GenPoly {
	Type * ScrubTyVars::mutate( TypeInstType *typeInst ) {
		TyVarMap::const_iterator tyVar = tyVars.find( typeInst->get_name() );
		if ( doAll || tyVar != tyVars.end() ) {
			switch ( tyVar->second ) {
			  case TypeDecl::Any:
			  case TypeDecl::Dtype:
				{
					PointerType *ret = new PointerType( Type::Qualifiers(), new VoidType( typeInst->get_qualifiers() ) );
					delete typeInst;
					return ret;
				}
			  case TypeDecl::Ftype:
				delete typeInst;
				return new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) );
			} // switch
		} // if
		return typeInst;
	}

	Expression * ScrubTyVars::mutate( SizeofExpr *szeof ) {
		// sizeof( T ) => _sizeof_T parameter, which is the size of T
		if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( szeof->get_type() ) ) {
			Expression *expr = new NameExpr( sizeofName( typeInst ) );
			return expr;
		} else {
			return Mutator::mutate( szeof );
		} // if
	}

	Expression * ScrubTyVars::mutate( AlignofExpr *algnof ) {
		// alignof( T ) => _alignof_T parameter, which is the alignment of T
		if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( algnof->get_type() ) ) {
			Expression *expr = new NameExpr( alignofName( typeInst ) );
			return expr;
		} else {
			return Mutator::mutate( algnof );
		} // if
	}

	Type * ScrubTyVars::mutate( PointerType *pointer ) {
		if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( pointer->get_base() ) ) {
			if ( doAll || tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
				Type *ret = mutate( typeInst );
				ret->get_qualifiers() += pointer->get_qualifiers();
				pointer->set_base( 0 );
				delete pointer;
				return ret;
			} // if
		} // if
		return Mutator::mutate( pointer );
	}
} // namespace GenPoly

// Local Variables: //
// tab-width: 4 //
// mode: c++ //
// compile-command: "make install" //
// End: //
