// // 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. // // CastCost.cc -- // // Author : Richard C. Bilson // Created On : Sun May 17 06:57:43 2015 // Last Modified By : Peter A. Buhr // Last Modified On : Sun May 17 06:59:10 2015 // Update Count : 2 // #include "typeops.h" #include "Cost.h" #include "ConversionCost.h" #include "SynTree/Type.h" #include "SynTree/Visitor.h" #include "SymTab/Indexer.h" namespace ResolvExpr { class CastCost : public ConversionCost { public: CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ); virtual void visit( BasicType *basicType ); virtual void visit( PointerType *pointerType ); }; Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) { EqvClass eqvClass; NamedTypeDecl *namedType; if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) { return castCost( src, eqvClass.type, indexer, env ); } else if ( ( namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) ) { TypeDecl *type = dynamic_cast< TypeDecl* >( namedType ); // all typedefs should be gone by this point assert( type ); if ( type->get_base() ) { return castCost( src, type->get_base(), indexer, env ) + Cost( 0, 0, 1 ); } // if } // if } // if if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) { return Cost( 0, 0, 0 ); } else if ( dynamic_cast< VoidType* >( dest ) ) { return Cost( 0, 0, 1 ); } else { CastCost converter( dest, indexer, env ); src->accept( converter ); if ( converter.get_cost() == Cost::infinity ) { return Cost::infinity; } else { return converter.get_cost() + Cost( 0, 0, 0 ); } // if } // if } CastCost::CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) : ConversionCost( dest, indexer, env ) { } void CastCost::visit( BasicType *basicType ) { if ( dynamic_cast< PointerType* >( dest ) ) { cost = Cost( 1, 0, 0 ); } else { ConversionCost::visit( basicType ); } // if } void CastCost::visit( PointerType *pointerType ) { if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) { if ( pointerType->get_qualifiers() <= destAsPtr->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) { cost = Cost( 0, 0, 1 ); } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) { if ( destAsBasic->isInteger() ) { cost = Cost( 1, 0, 0 ); } // if } else { TypeEnvironment newEnv( env ); newEnv.add( pointerType->get_forall() ); newEnv.add( pointerType->get_base()->get_forall() ); int assignResult = ptrsCastable( pointerType->get_base(), destAsPtr->get_base(), newEnv, indexer ); if ( assignResult > 0 ) { cost = Cost( 0, 0, 1 ); } else if ( assignResult < 0 ) { cost = Cost( 1, 0, 0 ); } // if } // if } // if } } // namespace ResolvExpr // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //