Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CastCost.cc

    r3c89751 rc8e4d2f8  
    1616#include <cassert>                       // for assert
    1717
    18 #include "AST/Print.hpp"
    19 #include "AST/SymbolTable.hpp"
    20 #include "AST/Type.hpp"
    21 #include "AST/TypeEnvironment.hpp"
    2218#include "ConversionCost.h"              // for ConversionCost
    2319#include "Cost.h"                        // for Cost, Cost::infinity
     
    3531
    3632namespace ResolvExpr {
    37         struct CastCost_old : public ConversionCost {
     33        struct CastCost : public ConversionCost {
    3834          public:
    39                 CastCost_old( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
     35                CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
    4036
    4137                using ConversionCost::previsit;
     
    8278                        });
    8379                } else {
    84                         PassVisitor<CastCost_old> converter(
     80                        #warning cast on castCost artifact of having two functions, remove when port done
     81                        PassVisitor<CastCost> converter(
    8582                                dest, indexer, env,
    8683                                (Cost (*)( Type *, Type *, const SymTab::Indexer &, const TypeEnvironment & ))
     
    9693        }
    9794
    98         CastCost_old::CastCost_old( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
     95        CastCost::CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
    9996                : ConversionCost( dest, indexer, env, costFunc ) {
    10097        }
    10198
    102         void CastCost_old::postvisit( BasicType *basicType ) {
     99        void CastCost::postvisit( BasicType *basicType ) {
    103100                PointerType *destAsPointer = dynamic_cast< PointerType* >( dest );
    104101                if ( destAsPointer && basicType->isInteger() ) {
     
    110107        }
    111108
    112         void CastCost_old::postvisit( PointerType *pointerType ) {
     109        void CastCost::postvisit( PointerType *pointerType ) {
    113110                if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
    114111                        if ( pointerType->get_qualifiers() <= destAsPtr->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
     
    133130        }
    134131
    135 namespace {
    136         struct CastCost_new : public ConversionCost_new {
    137                 using ConversionCost_new::previsit;
    138                 using ConversionCost_new::postvisit;
    139 
    140                 CastCost_new(
    141                         const ast::Type * dst, const ast::SymbolTable & symtab,
    142                         const ast::TypeEnvironment & env, CostCalculation costFunc )
    143                 : ConversionCost_new( dst, symtab, env, costFunc ) {}
    144 
    145                 void postvisit( const ast::BasicType * basicType ) {
    146                         auto ptr = dynamic_cast< const ast::PointerType * >( dst );
    147                         if ( ptr && basicType->isInteger() ) {
    148                                 // needed for, e.g. unsigned long => void *
    149                                 cost = Cost::unsafe;
    150                         } else {
    151                                 cost = conversionCost( basicType, dst, symtab, env );
    152                         }
    153                 }
    154 
    155                 void postvisit( const ast::PointerType * pointerType ) {
    156                         if ( auto ptr = dynamic_cast< const ast::PointerType * >( dst ) ) {
    157                                 if (
    158                                         pointerType->qualifiers <= ptr->qualifiers
    159                                         && typesCompatibleIgnoreQualifiers( pointerType->base, ptr->base, symtab, env )
    160                                 ) {
    161                                         cost = Cost::safe;
    162                                 } else {
    163                                         ast::TypeEnvironment newEnv{ env };
    164                                         if ( auto wParams = pointerType->base.as< ast::ParameterizedType >() ) {
    165                                                 newEnv.add( wParams->forall );
    166                                         }
    167                                         int castResult = ptrsCastable( pointerType->base, ptr->base, symtab, newEnv );
    168                                         if ( castResult > 0 ) {
    169                                                 cost = Cost::safe;
    170                                         } else if ( castResult < 0 ) {
    171                                                 cost = Cost::infinity;
    172                                         }
    173                                 }
    174                         } else if ( auto basic = dynamic_cast< const ast::BasicType * >( dst ) ) {
    175                                 if ( basic->isInteger() ) {
    176                                         // necessary for, e.g. void * => unsigned long
    177                                         cost = Cost::unsafe;
    178                                 }
    179                         }
    180                 }
    181         };
    182 } // anonymous namespace
    183 
    184 Cost castCost(
    185         const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
    186         const ast::TypeEnvironment & env
    187 ) {
    188         if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
    189                 if ( const ast::EqvClass * eqvClass = env.lookup( typeInst->name ) ) {
    190                         // check cast cost against bound type, if present
    191                         if ( eqvClass->bound ) {
    192                                 return castCost( src, eqvClass->bound, symtab, env );
    193                         } else {
    194                                 return Cost::infinity;
    195                         }
    196                 } else if ( const ast::NamedTypeDecl * named = symtab.lookupType( typeInst->name ) ) {
    197                         // all typedefs should be gone by now
    198                         auto type = strict_dynamic_cast< const ast::TypeDecl * >( named );
    199                         if ( type->base ) {
    200                                 return castCost( src, type->base, symtab, env ) + Cost::safe;
    201                         }
    202                 }
     132        Cost castCost(
     133                const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
     134                const ast::TypeEnvironment & env
     135        ) {
     136                #warning unimplmented
     137                (void)src; (void)dst; (void)symtab; (void)env;
     138                assert(false);
     139                return Cost::zero;
    203140        }
    204 
    205         PRINT(
    206                 std::cerr << "castCost ::: src is ";
    207                 ast::print( std::cerr, src );
    208                 std::cerr << std::endl << "dest is ";
    209                 ast::print( std::cerr, dst );
    210                 std::cerr << std::endl << "env is" << std::endl;
    211                 ast::print( std::cerr, env, 2 );
    212         )
    213 
    214         if ( typesCompatibleIgnoreQualifiers( src, dst, symtab, env ) ) {
    215                 PRINT( std::cerr << "compatible!" << std::endl; )
    216                 return Cost::zero;
    217         } else if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
    218                 return Cost::safe;
    219         } else if ( auto refType = dynamic_cast< const ast::ReferenceType * >( dst ) ) {
    220                 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
    221                 #warning cast on ptrsCastable artifact of having two functions, remove when port done
    222                 return convertToReferenceCost(
    223                         src, refType, symtab, env,
    224                         ( int (*)(
    225                                 const ast::Type *, const ast::Type *, const ast::SymbolTable &,
    226                                 const ast::TypeEnvironment & )
    227                         ) ptrsCastable );
    228         } else {
    229                 #warning cast on castCost artifact of having two functions, remove when port done
    230                 ast::Pass< CastCost_new > converter{
    231                         dst, symtab, env,
    232                         ( Cost (*)(
    233                                 const ast::Type *, const ast::Type *, const ast::SymbolTable &,
    234                                 const ast::TypeEnvironment & )
    235                         ) castCost };
    236                 src->accept( converter );
    237                 return converter.pass.cost;
    238         }
    239 }
    240 
    241141} // namespace ResolvExpr
    242142
Note: See TracChangeset for help on using the changeset viewer.