//
// 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.
//
// PolyCost.cc --
//
// Author           : Richard C. Bilson
// Created On       : Sun May 17 09:50:12 2015
// Last Modified By : Peter A. Buhr
// Last Modified On : Sun May 17 09:52:02 2015
// Update Count     : 3
//

#include "SymTab/Indexer.h"   // for Indexer
#include "SynTree/Type.h"     // for TypeInstType, Type
#include "SynTree/Visitor.h"  // for Visitor
#include "TypeEnvironment.h"  // for EqvClass, TypeEnvironment

namespace ResolvExpr {
	class PolyCost : public Visitor {
	  public:
		PolyCost( const TypeEnvironment &env, const SymTab::Indexer &indexer );
		int get_result() const { return result; }
	  private:
		virtual void visit(TypeInstType *aggregateUseType);
		int result;
		const TypeEnvironment &env;
		const SymTab::Indexer &indexer;
	};

	int polyCost( Type *type, const TypeEnvironment & env, const SymTab::Indexer &indexer ) {
		PolyCost coster( env, indexer );
		type->accept( coster );
		return coster.get_result();
	}

	PolyCost::PolyCost( const TypeEnvironment & env, const SymTab::Indexer & indexer ) : result( 0 ), env( env ), indexer( indexer ) {
	}

	void PolyCost::visit(TypeInstType * typeInst) {
		EqvClass eqvClass;
		if ( env.lookup( typeInst->name, eqvClass ) ) {
			if ( eqvClass.type ) {
				if ( TypeInstType * otherTypeInst = dynamic_cast< TypeInstType* >( eqvClass.type ) ) {
					if ( indexer.lookupType( otherTypeInst->name ) ) {
						// bound to opaque type
						result += 1;
					} // if
				} else {
					// bound to concrete type
					result += 1;
				} // if
			} // if
		} // if
	}

} // namespace ResolvExpr

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