Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CastCost.cc

    r7d01cf44 r00ac42e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 06:57:43 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Thu Aug  8 16:12:00 2019
    13 // Update Count     : 8
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue Feb  2 15:34:36 2016
     13// Update Count     : 7
    1414//
    1515
    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( const Type * dest, bool srcIsLvalue,
    40                         const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
     35                CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
    4136
    4237                using ConversionCost::previsit;
    4338                using ConversionCost::postvisit;
    44                 void postvisit( const BasicType * basicType );
    45                 void postvisit( const PointerType * pointerType );
     39                void postvisit( BasicType * basicType );
     40                void postvisit( PointerType * pointerType );
    4641        };
    4742
    48         Cost castCost( const Type * src, const Type * dest, bool srcIsLvalue,
    49                         const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    50                 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) {
    51                         if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {
     43        Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     44                if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
     45                        if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
    5246                                if ( eqvClass->type ) {
    53                                         return castCost( src, eqvClass->type, srcIsLvalue, indexer, env );
     47                                        return castCost( src, eqvClass->type, indexer, env );
    5448                                } else {
    5549                                        return Cost::infinity;
    5650                                }
    57                         } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) {
     51                        } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) {
    5852                                // all typedefs should be gone by this point
    59                                 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( namedType );
     53                                TypeDecl *type = strict_dynamic_cast< TypeDecl* >( namedType );
    6054                                if ( type->base ) {
    61                                         return castCost( src, type->base, srcIsLvalue, indexer, env ) + Cost::safe;
     55                                        return castCost( src, type->base, indexer, env ) + Cost::safe;
    6256                                } // if
    6357                        } // if
     
    7670                        PRINT( std::cerr << "compatible!" << std::endl; )
    7771                        return Cost::zero;
    78                 } else if ( dynamic_cast< const VoidType * >( dest ) ) {
     72                } else if ( dynamic_cast< VoidType* >( dest ) ) {
    7973                        return Cost::safe;
    80                 } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) {
     74                } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
    8175                        PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
    82                         return convertToReferenceCost( src, refType, srcIsLvalue, indexer, env, [](const Type * t1, const Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
     76                        return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
    8377                                return ptrsCastable( t1, t2, env, indexer );
    8478                        });
    8579                } else {
    86                         PassVisitor<CastCost_old> converter(
    87                                 dest, srcIsLvalue, indexer, env,
    88                                 (Cost (*)( const Type *, const Type *, bool, const SymTab::Indexer &, const TypeEnvironment & ))
    89                                         castCost );
     80                        PassVisitor<CastCost> converter( dest, indexer, env, castCost );
    9081                        src->accept( converter );
    9182                        if ( converter.pass.get_cost() == Cost::infinity ) {
     
    9889        }
    9990
    100         CastCost_old::CastCost_old( const Type * dest, bool srcIsLvalue,
    101                         const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
    102                 : ConversionCost( dest, srcIsLvalue, indexer, env, costFunc ) {
     91        CastCost::CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
     92                : ConversionCost( dest, indexer, env, costFunc ) {
    10393        }
    10494
    105         void CastCost_old::postvisit( const BasicType * basicType ) {
    106                 const PointerType * destAsPointer = dynamic_cast< const PointerType * >( dest );
     95        void CastCost::postvisit( BasicType *basicType ) {
     96                PointerType *destAsPointer = dynamic_cast< PointerType* >( dest );
    10797                if ( destAsPointer && basicType->isInteger() ) {
    108                         // necessary for, e.g. unsigned long => void *
     98                        // necessary for, e.g. unsigned long => void*
    10999                        cost = Cost::unsafe;
    110100                } else {
    111                         cost = conversionCost( basicType, dest, srcIsLvalue, indexer, env );
     101                        cost = conversionCost( basicType, dest, indexer, env );
    112102                } // if
    113103        }
    114104
    115         void CastCost_old::postvisit( const PointerType * pointerType ) {
    116                 if ( const PointerType * destAsPtr = dynamic_cast< const PointerType * >( dest ) ) {
    117                         if ( pointerType->tq <= destAsPtr->tq && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
     105        void CastCost::postvisit( PointerType *pointerType ) {
     106                if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
     107                        if ( pointerType->get_qualifiers() <= destAsPtr->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
    118108                                cost = Cost::safe;
    119109                        } else {
     
    128118                                } // if
    129119                        } // if
    130                 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
     120                } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
    131121                        if ( destAsBasic->isInteger() ) {
    132                                 // necessary for, e.g. void * => unsigned long
     122                                // necessary for, e.g. void* => unsigned long
    133123                                cost = Cost::unsafe;
    134124                        } // if
    135125                }
    136126        }
    137 
    138 namespace {
    139         struct CastCost_new : public ConversionCost_new {
    140                 using ConversionCost_new::previsit;
    141                 using ConversionCost_new::postvisit;
    142 
    143                 CastCost_new(
    144                         const ast::Type * dst, const ast::SymbolTable & symtab,
    145                         const ast::TypeEnvironment & env, CostCalculation costFunc )
    146                 : ConversionCost_new( dst, symtab, env, costFunc ) {}
    147 
    148                 void postvisit( const ast::BasicType * basicType ) {
    149                         auto ptr = dynamic_cast< const ast::PointerType * >( dst );
    150                         if ( ptr && basicType->isInteger() ) {
    151                                 // needed for, e.g. unsigned long => void *
    152                                 cost = Cost::unsafe;
    153                         } else {
    154                                 cost = conversionCost( basicType, dst, symtab, env );
    155                         }
    156                 }
    157 
    158                 void postvisit( const ast::PointerType * pointerType ) {
    159                         if ( auto ptr = dynamic_cast< const ast::PointerType * >( dst ) ) {
    160                                 if (
    161                                         pointerType->qualifiers <= ptr->qualifiers
    162                                         && typesCompatibleIgnoreQualifiers( pointerType->base, ptr->base, symtab, env )
    163                                 ) {
    164                                         cost = Cost::safe;
    165                                 } else {
    166                                         ast::TypeEnvironment newEnv{ env };
    167                                         if ( auto wParams = pointerType->base.as< ast::ParameterizedType >() ) {
    168                                                 newEnv.add( wParams->forall );
    169                                         }
    170                                         int castResult = ptrsCastable( pointerType->base, ptr->base, symtab, newEnv );
    171                                         if ( castResult > 0 ) {
    172                                                 cost = Cost::safe;
    173                                         } else if ( castResult < 0 ) {
    174                                                 cost = Cost::infinity;
    175                                         }
    176                                 }
    177                         } else if ( auto basic = dynamic_cast< const ast::BasicType * >( dst ) ) {
    178                                 if ( basic->isInteger() ) {
    179                                         // necessary for, e.g. void * => unsigned long
    180                                         cost = Cost::unsafe;
    181                                 }
    182                         }
    183                 }
    184         };
    185 } // anonymous namespace
    186 
    187 Cost castCost(
    188         const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
    189         const ast::TypeEnvironment & env
    190 ) {
    191         if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
    192                 if ( const ast::EqvClass * eqvClass = env.lookup( typeInst->name ) ) {
    193                         // check cast cost against bound type, if present
    194                         if ( eqvClass->bound ) {
    195                                 return castCost( src, eqvClass->bound, symtab, env );
    196                         } else {
    197                                 return Cost::infinity;
    198                         }
    199                 } else if ( const ast::NamedTypeDecl * named = symtab.lookupType( typeInst->name ) ) {
    200                         // all typedefs should be gone by now
    201                         auto type = strict_dynamic_cast< const ast::TypeDecl * >( named );
    202                         if ( type->base ) {
    203                                 return castCost( src, type->base, symtab, env ) + Cost::safe;
    204                         }
    205                 }
    206         }
    207 
    208         PRINT(
    209                 std::cerr << "castCost ::: src is ";
    210                 ast::print( std::cerr, src );
    211                 std::cerr << std::endl << "dest is ";
    212                 ast::print( std::cerr, dst );
    213                 std::cerr << std::endl << "env is" << std::endl;
    214                 ast::print( std::cerr, env, 2 );
    215         )
    216 
    217         if ( typesCompatibleIgnoreQualifiers( src, dst, symtab, env ) ) {
    218                 PRINT( std::cerr << "compatible!" << std::endl; )
    219                 return Cost::zero;
    220         } else if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
    221                 return Cost::safe;
    222         } else if ( auto refType = dynamic_cast< const ast::ReferenceType * >( dst ) ) {
    223                 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
    224                 #warning cast on ptrsCastable artifact of having two functions, remove when port done
    225                 return convertToReferenceCost(
    226                         src, refType, symtab, env,
    227                         ( int (*)(
    228                                 const ast::Type *, const ast::Type *, const ast::SymbolTable &,
    229                                 const ast::TypeEnvironment & )
    230                         ) ptrsCastable );
    231         } else {
    232                 #warning cast on castCost artifact of having two functions, remove when port done
    233                 ast::Pass< CastCost_new > converter{
    234                         dst, symtab, env,
    235                         ( Cost (*)(
    236                                 const ast::Type *, const ast::Type *, const ast::SymbolTable &,
    237                                 const ast::TypeEnvironment & )
    238                         ) castCost };
    239                 src->accept( converter );
    240                 return converter.pass.cost;
    241         }
    242 }
    243 
    244127} // namespace ResolvExpr
    245128
Note: See TracChangeset for help on using the changeset viewer.