Changeset 3c89751


Ignore:
Timestamp:
Jun 24, 2019, 3:42:36 PM (2 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
arm-eh, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr
Children:
1335e6f
Parents:
093a5d7
Message:

Port castCost, ptrsCastable

Location:
src/ResolvExpr
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CastCost.cc

    r093a5d7 r3c89751  
    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"
    1822#include "ConversionCost.h"              // for ConversionCost
    1923#include "Cost.h"                        // for Cost, Cost::infinity
     
    3135
    3236namespace ResolvExpr {
    33         struct CastCost : public ConversionCost {
     37        struct CastCost_old : public ConversionCost {
    3438          public:
    35                 CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
     39                CastCost_old( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
    3640
    3741                using ConversionCost::previsit;
     
    7882                        });
    7983                } else {
    80                         #warning cast on castCost artifact of having two functions, remove when port done
    81                         PassVisitor<CastCost> converter(
     84                        PassVisitor<CastCost_old> converter(
    8285                                dest, indexer, env,
    8386                                (Cost (*)( Type *, Type *, const SymTab::Indexer &, const TypeEnvironment & ))
     
    9396        }
    9497
    95         CastCost::CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
     98        CastCost_old::CastCost_old( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
    9699                : ConversionCost( dest, indexer, env, costFunc ) {
    97100        }
    98101
    99         void CastCost::postvisit( BasicType *basicType ) {
     102        void CastCost_old::postvisit( BasicType *basicType ) {
    100103                PointerType *destAsPointer = dynamic_cast< PointerType* >( dest );
    101104                if ( destAsPointer && basicType->isInteger() ) {
     
    107110        }
    108111
    109         void CastCost::postvisit( PointerType *pointerType ) {
     112        void CastCost_old::postvisit( PointerType *pointerType ) {
    110113                if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
    111114                        if ( pointerType->get_qualifiers() <= destAsPtr->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
     
    130133        }
    131134
    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);
     135namespace {
     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
     184Cost 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                }
     203        }
     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; )
    139216                return Cost::zero;
    140         }
     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
    141241} // namespace ResolvExpr
    142242
  • src/ResolvExpr/ConversionCost.h

    r093a5d7 r3c89751  
    7474        const ast::SymbolTable &, const ast::TypeEnvironment &)>;
    7575
    76 // TODO: When the old ConversionCost is removed, get ride of the _new suffix.
     76#warning when the old ConversionCost is removed, get ride of the _new suffix.
    7777class ConversionCost_new : public ast::WithShortCircuiting {
     78protected:
    7879        const ast::Type * dst;
    7980        const ast::SymbolTable & symtab;
  • src/ResolvExpr/PtrsCastable.cc

    r093a5d7 r3c89751  
    1414//
    1515
     16#include "AST/Decl.hpp"
     17#include "AST/Pass.hpp"
     18#include "AST/Type.hpp"
     19#include "AST/TypeEnvironment.hpp"
    1620#include "Common/PassVisitor.h"
    1721#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass, TypeEnvironment
     
    2327
    2428namespace ResolvExpr {
    25         struct PtrsCastable : public WithShortCircuiting  {
     29        struct PtrsCastable_old : public WithShortCircuiting  {
    2630          public:
    27                 PtrsCastable( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
     31                PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
    2832
    2933                int get_result() const { return result; }
     
    8690                        return objectCast( src, env, indexer );
    8791                } else {
    88                         PassVisitor<PtrsCastable> ptrs( dest, env, indexer );
     92                        PassVisitor<PtrsCastable_old> ptrs( dest, env, indexer );
    8993                        src->accept( ptrs );
    9094                        return ptrs.pass.get_result();
     
    9296        }
    9397
    94         PtrsCastable::PtrsCastable( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
     98        PtrsCastable_old::PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
    9599                : dest( dest ), result( 0 ), env( env ), indexer( indexer )     {
    96100        }
    97101
    98         void PtrsCastable::postvisit( VoidType * ) {
    99                 result = objectCast( dest, env, indexer );
    100         }
    101 
    102         void PtrsCastable::postvisit( BasicType * ) {
    103                 result = objectCast( dest, env, indexer );
    104         }
    105 
    106         void PtrsCastable::postvisit( PointerType * ) {
    107                 result = objectCast( dest, env, indexer );
    108         }
    109 
    110         void PtrsCastable::postvisit( ArrayType * ) {
    111                 result = objectCast( dest, env, indexer );
    112         }
    113 
    114         void PtrsCastable::postvisit( FunctionType * ) {
     102        void PtrsCastable_old::postvisit( VoidType * ) {
     103                result = objectCast( dest, env, indexer );
     104        }
     105
     106        void PtrsCastable_old::postvisit( BasicType * ) {
     107                result = objectCast( dest, env, indexer );
     108        }
     109
     110        void PtrsCastable_old::postvisit( PointerType * ) {
     111                result = objectCast( dest, env, indexer );
     112        }
     113
     114        void PtrsCastable_old::postvisit( ArrayType * ) {
     115                result = objectCast( dest, env, indexer );
     116        }
     117
     118        void PtrsCastable_old::postvisit( FunctionType * ) {
    115119                // result = -1;
    116120                result = functionCast( dest, env, indexer );
    117121        }
    118122
    119         void PtrsCastable::postvisit( StructInstType * ) {
    120                 result = objectCast( dest, env, indexer );
    121         }
    122 
    123         void PtrsCastable::postvisit( UnionInstType * ) {
    124                 result = objectCast( dest, env, indexer );
    125         }
    126 
    127         void PtrsCastable::postvisit( EnumInstType * ) {
     123        void PtrsCastable_old::postvisit( StructInstType * ) {
     124                result = objectCast( dest, env, indexer );
     125        }
     126
     127        void PtrsCastable_old::postvisit( UnionInstType * ) {
     128                result = objectCast( dest, env, indexer );
     129        }
     130
     131        void PtrsCastable_old::postvisit( EnumInstType * ) {
    128132                if ( dynamic_cast< EnumInstType* >( dest ) ) {
    129133                        result = 1;
     
    139143        }
    140144
    141         void PtrsCastable::postvisit( TraitInstType * ) {}
    142 
    143         void PtrsCastable::postvisit(TypeInstType *inst) {
     145        void PtrsCastable_old::postvisit( TraitInstType * ) {}
     146
     147        void PtrsCastable_old::postvisit(TypeInstType *inst ) {
    144148                //result = objectCast( inst, env, indexer ) > 0 && objectCast( dest, env, indexer ) > 0 ? 1 : -1;
    145149                result = objectCast( inst, env, indexer ) == objectCast( dest, env, indexer ) ? 1 : -1;
    146150        }
    147151
    148         void PtrsCastable::postvisit( TupleType * ) {
    149                 result = objectCast( dest, env, indexer );
    150         }
    151 
    152         void PtrsCastable::postvisit( VarArgsType * ) {
    153                 result = objectCast( dest, env, indexer );
    154         }
    155 
    156         void PtrsCastable::postvisit( ZeroType * ) {
    157                 result = objectCast( dest, env, indexer );
    158         }
    159 
    160         void PtrsCastable::postvisit( OneType * ) {
    161                 result = objectCast( dest, env, indexer );
    162         }
     152        void PtrsCastable_old::postvisit( TupleType * ) {
     153                result = objectCast( dest, env, indexer );
     154        }
     155
     156        void PtrsCastable_old::postvisit( VarArgsType * ) {
     157                result = objectCast( dest, env, indexer );
     158        }
     159
     160        void PtrsCastable_old::postvisit( ZeroType * ) {
     161                result = objectCast( dest, env, indexer );
     162        }
     163
     164        void PtrsCastable_old::postvisit( OneType * ) {
     165                result = objectCast( dest, env, indexer );
     166        }
     167
     168namespace {
     169        // can this type be cast to an object (1 for yes, -1 for no)
     170        int objectCast(
     171                const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
     172        ) {
     173                if ( dynamic_cast< const ast::FunctionType * >( src ) ) {
     174                        return -1;
     175                } else if ( auto inst = dynamic_cast< const ast::TypeInstType * >( src ) ) {
     176                        if ( const ast::NamedTypeDecl * named = symtab.lookupType( inst->name ) ) {
     177                                if ( auto tyDecl = dynamic_cast< const ast::TypeDecl * >( named ) ) {
     178                                        if ( tyDecl->kind == ast::TypeVar::Ftype ) {
     179                                                return -1;
     180                                        }
     181                                }
     182                        } else if ( const ast::EqvClass * eqvClass = env.lookup( inst->name ) ) {
     183                                if ( eqvClass->data.kind == ast::TypeVar::Ftype ) {
     184                                        return -1;
     185                                }
     186                        }
     187                }
     188
     189                return 1;
     190        }
     191
     192        // can this type be cast to a function (inverse of objectCast)
     193        int functionCast(
     194                const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
     195        ) {
     196                return -1 * objectCast( src, env, symtab );
     197        }
     198
     199        class PtrsCastable_new : public ast::WithShortCircuiting {
     200                const ast::Type * dst;
     201                const ast::TypeEnvironment & env;
     202                const ast::SymbolTable & symtab;
     203        public:
     204                int result;
     205
     206                PtrsCastable_new(
     207                        const ast::Type * d, const ast::TypeEnvironment & e, const ast::SymbolTable & syms )
     208                : dst( d ), env( e ), symtab( syms ), result( 0 ) {}
     209
     210                void previsit( const ast::Type * ) { visit_children = false; }
     211
     212                void postvisit( const ast::VoidType * ) {
     213                        result = objectCast( dst, env, symtab );
     214                }
     215
     216                void postvisit( const ast::BasicType * ) {
     217                        result = objectCast( dst, env, symtab );
     218                }
     219
     220                void postvisit( const ast::PointerType * ) {
     221                        result = objectCast( dst, env, symtab );
     222                }
     223
     224                void postvisit( const ast::ArrayType * ) {
     225                        result = objectCast( dst, env, symtab );
     226                }
     227
     228                void postvisit( const ast::FunctionType * ) {
     229                        result = functionCast( dst, env, symtab );
     230                }
     231
     232                void postvisit( const ast::StructInstType * ) {
     233                        result = objectCast( dst, env, symtab );
     234                }
     235
     236                void postvisit( const ast::UnionInstType * ) {
     237                        result = objectCast( dst, env, symtab );
     238                }
     239
     240                void postvisit( const ast::EnumInstType * ) {
     241                        if ( dynamic_cast< const ast::EnumInstType * >( dst ) ) {
     242                                result = 1;
     243                        } else if ( auto bt = dynamic_cast< const ast::BasicType * >( dst ) ) {
     244                                if ( bt->kind == ast::BasicType::SignedInt ) {
     245                                        result = 0;
     246                                } else {
     247                                        result = 1;
     248                                }
     249                        } else {
     250                                result = objectCast( dst, env, symtab );
     251                        }
     252                }
     253
     254                void postvisit( const ast::TraitInstType * ) {}
     255
     256                void postvisit( const ast::TypeInstType * inst ) {
     257                        // check trait and destination type are both object or both function
     258                        result = objectCast( inst, env, symtab ) == objectCast( dst, env, symtab ) ? 1 : -1;
     259                }
     260
     261                void postvisit( const ast::TupleType * ) {
     262                        result = objectCast( dst, env, symtab );
     263                }
     264
     265                void postvisit( const ast::VarArgsType * ) {
     266                        result = objectCast( dst, env, symtab );
     267                }
     268
     269                void postvisit( const ast::ZeroType * ) {
     270                        result = objectCast( dst, env, symtab );
     271                }
     272
     273                void postvisit( const ast::OneType * ) {
     274                        result = objectCast( dst, env, symtab );
     275                }
     276
     277        };
     278} // anonymous namespace
     279
     280int ptrsCastable(
     281        const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
     282        const ast::TypeEnvironment & env
     283) {
     284        if ( auto inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
     285                if ( const ast::EqvClass * eqvClass = env.lookup( inst->name ) ) {
     286                        return ptrsAssignable( src, eqvClass->bound, env );
     287                }
     288        }
     289
     290        if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
     291                return objectCast( src, env, symtab );
     292        } else {
     293                ast::Pass< PtrsCastable_new > ptrs{ dst, env, symtab };
     294                src->accept( ptrs );
     295                return ptrs.pass.result;
     296        }
     297}
     298
    163299} // namespace ResolvExpr
    164300
  • src/ResolvExpr/Resolver.cc

    r093a5d7 r3c89751  
    13371337                if ( type->dimension ) {
    13381338                        #warning should use new equivalent to Validate::SizeType rather than sizeType here
    1339                         ast::ptr< ast::Type > sizeType =
    1340                                 new ast::BasicType{ ast::BasicType::LongLongUnsignedInt };
     1339                        ast::ptr< ast::Type > sizeType = new ast::BasicType{ ast::BasicType::LongUnsignedInt };
    13411340                        ast::mutate_field(
    13421341                                type, &PtrType::dimension,
  • src/ResolvExpr/typeops.h

    r093a5d7 r3c89751  
    9999        // in PtrsCastable.cc
    100100        int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
     101        int ptrsCastable(
     102                const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
     103                const ast::TypeEnvironment & env );
    101104
    102105        // in Unify.cc
Note: See TracChangeset for help on using the changeset viewer.