Ignore:
Timestamp:
Oct 29, 2019, 4:01:24 PM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
773db65, 9421f3d8
Parents:
7951100 (diff), 8364209 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/PtrsCastable.cc

    r7951100 rb067d9b  
    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( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
    2832
    2933                int get_result() const { return result; }
    3034
    31                 void previsit( Type * ) { visit_children = false; }
    32 
    33                 void postvisit( VoidType * voidType );
    34                 void postvisit( BasicType * basicType );
    35                 void postvisit( PointerType * pointerType );
    36                 void postvisit( ArrayType * arrayType );
    37                 void postvisit( FunctionType * functionType );
    38                 void postvisit( StructInstType * inst );
    39                 void postvisit( UnionInstType * inst );
    40                 void postvisit( EnumInstType * inst );
    41                 void postvisit( TraitInstType * inst );
    42                 void postvisit( TypeInstType * inst );
    43                 void postvisit( TupleType * tupleType );
    44                 void postvisit( VarArgsType * varArgsType );
    45                 void postvisit( ZeroType * zeroType );
    46                 void postvisit( OneType * oneType );
     35                void previsit( const Type * ) { visit_children = false; }
     36
     37                void postvisit( const VoidType * voidType );
     38                void postvisit( const BasicType * basicType );
     39                void postvisit( const PointerType * pointerType );
     40                void postvisit( const ArrayType * arrayType );
     41                void postvisit( const FunctionType * functionType );
     42                void postvisit( const StructInstType * inst );
     43                void postvisit( const UnionInstType * inst );
     44                void postvisit( const EnumInstType * inst );
     45                void postvisit( const TraitInstType * inst );
     46                void postvisit( const TypeInstType * inst );
     47                void postvisit( const TupleType * tupleType );
     48                void postvisit( const VarArgsType * varArgsType );
     49                void postvisit( const ZeroType * zeroType );
     50                void postvisit( const OneType * oneType );
    4751          private:
    48                 Type *dest;
     52                const Type * dest;
    4953                int result;
    5054                const TypeEnvironment &env;
     
    5357
    5458        namespace {
    55                 int objectCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    56                         if ( dynamic_cast< FunctionType* >( src ) ) {
     59                int objectCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     60                        if ( dynamic_cast< const FunctionType* >( src ) ) {
    5761                                return -1;
    58                         } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( src ) ) {
    59                                 if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
    60                                         if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
    61                                                 if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
     62                        } else if ( const TypeInstType * typeInst = dynamic_cast< const TypeInstType* >( src ) ) {
     63                                if ( const NamedTypeDecl * ntDecl = indexer.lookupType( typeInst->name ) ) {
     64                                        if ( const TypeDecl * tyDecl = dynamic_cast< const TypeDecl* >( ntDecl ) ) {
     65                                                if ( tyDecl->kind == TypeDecl::Ftype ) {
    6266                                                        return -1;
    6367                                                } // if
    6468                                        } //if
    65                                 } else if ( const EqvClass *eqvClass = env.lookup( typeInst->get_name() ) ) {
     69                                } else if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) {
    6670                                        if ( eqvClass->data.kind == TypeDecl::Ftype ) {
    6771                                                return -1;
     
    7175                        return 1;
    7276                }
    73                 int functionCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     77                int functionCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    7478                        return -1 * objectCast( src, env, indexer );  // reverse the sense of objectCast
    7579                }
    7680        }
    7781
    78         int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    79                 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
    80                         if ( const EqvClass *eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
     82        int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     83                if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) {
     84                        if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
    8185                                // xxx - should this be ptrsCastable?
    8286                                return ptrsAssignable( src, eqvClass->type, env );
    8387                        } // if
    8488                } // if
    85                 if ( dynamic_cast< VoidType* >( dest ) ) {
     89                if ( dynamic_cast< const VoidType* >( dest ) ) {
    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( const 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( const VoidType * ) {
     103                result = objectCast( dest, env, indexer );
     104        }
     105
     106        void PtrsCastable_old::postvisit( const BasicType * ) {
     107                result = objectCast( dest, env, indexer );
     108        }
     109
     110        void PtrsCastable_old::postvisit( const PointerType * ) {
     111                result = objectCast( dest, env, indexer );
     112        }
     113
     114        void PtrsCastable_old::postvisit( const ArrayType * ) {
     115                result = objectCast( dest, env, indexer );
     116        }
     117
     118        void PtrsCastable_old::postvisit( const 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 * ) {
    128                 if ( dynamic_cast< EnumInstType* >( dest ) ) {
     123        void PtrsCastable_old::postvisit( const StructInstType * ) {
     124                result = objectCast( dest, env, indexer );
     125        }
     126
     127        void PtrsCastable_old::postvisit( const UnionInstType * ) {
     128                result = objectCast( dest, env, indexer );
     129        }
     130
     131        void PtrsCastable_old::postvisit( const EnumInstType * ) {
     132                if ( dynamic_cast< const EnumInstType * >( dest ) ) {
    129133                        result = 1;
    130                 } else if ( BasicType *bt = dynamic_cast< BasicType* >( dest ) ) {
    131                         if ( bt->get_kind() == BasicType::SignedInt ) {
     134                } else if ( const BasicType * bt = dynamic_cast< const BasicType * >( dest ) ) {
     135                        if ( bt->kind == BasicType::SignedInt ) {
    132136                                result = 0;
    133137                        } else {
     
    139143        }
    140144
    141         void PtrsCastable::postvisit( TraitInstType * ) {}
    142 
    143         void PtrsCastable::postvisit(TypeInstType *inst) {
     145        void PtrsCastable_old::postvisit( const TraitInstType * ) {}
     146
     147        void PtrsCastable_old::postvisit( const 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( const TupleType * ) {
     153                result = objectCast( dest, env, indexer );
     154        }
     155
     156        void PtrsCastable_old::postvisit( const VarArgsType * ) {
     157                result = objectCast( dest, env, indexer );
     158        }
     159
     160        void PtrsCastable_old::postvisit( const ZeroType * ) {
     161                result = objectCast( dest, env, indexer );
     162        }
     163
     164        void PtrsCastable_old::postvisit( const 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
Note: See TracChangeset for help on using the changeset viewer.