Ignore:
Timestamp:
Sep 19, 2022, 8:11:02 PM (3 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, ast-experimental, master, pthread-emulation
Children:
aa9f215
Parents:
ebf8ca5 (diff), ae1d151 (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:

fix merge conflict

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/GenPoly.cc

    rebf8ca5 r23a08aa0  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jun 29 21:45:53 2016
    13 // Update Count     : 14
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Sep 14  9:24:00 2022
     13// Update Count     : 15
    1414//
    1515
     
    8383                }
    8484
     85                bool hasDynParams( const std::vector<ast::ptr<ast::Expr>> & params, const TyVarMap &tyVars, const ast::TypeSubstitution *typeSubs ) {
     86                        for ( ast::ptr<ast::Expr> const & param : params ) {
     87                                auto paramType = param.as<ast::TypeExpr>();
     88                                assertf( paramType, "Aggregate parameters should be type expressions." );
     89                                if ( isDynType( paramType->type, tyVars, typeSubs ) ) {
     90                                        return true;
     91                                }
     92                        }
     93                        return false;
     94                }
     95
    8596                /// Checks a parameter list for inclusion of polymorphic parameters; will substitute according to env if present
    8697                bool includesPolyParams( std::list< Expression* >& params, const TypeSubstitution *env ) {
     
    198209                }
    199210                return 0;
     211        }
     212
     213        const ast::BaseInstType *isDynType( const ast::Type *type, const TyVarMap &tyVars, const ast::TypeSubstitution *typeSubs ) {
     214                type = replaceTypeInst( type, typeSubs );
     215
     216                if ( auto inst = dynamic_cast<ast::TypeInstType const *>( type ) ) {
     217                        auto var = tyVars.find( inst->name );
     218                        if ( var != tyVars.end() && var->second.isComplete ) {
     219                                return inst;
     220                        }
     221                } else if ( auto inst = dynamic_cast<ast::StructInstType const *>( type ) ) {
     222                        if ( hasDynParams( inst->params, tyVars, typeSubs ) ) {
     223                                return inst;
     224                        }
     225                } else if ( auto inst = dynamic_cast<ast::UnionInstType const *>( type ) ) {
     226                        if ( hasDynParams( inst->params, tyVars, typeSubs ) ) {
     227                                return inst;
     228                        }
     229                }
     230                return nullptr;
    200231        }
    201232
     
    378409                inline D* as( B* p ) { return reinterpret_cast<D*>(p); }
    379410
     411                template<typename D, typename B>
     412                inline D const * as( B const * p ) {
     413                        return reinterpret_cast<D const *>( p );
     414                }
     415
    380416                /// Flattens a declaration list
    381417                template<typename Output>
     
    391427                        for ( Type* ty : src ) {
    392428                                ResolvExpr::flatten( ty, out );
     429                        }
     430                }
     431
     432                void flattenList( vector<ast::ptr<ast::Type>> const & src,
     433                                vector<ast::ptr<ast::Type>> & out ) {
     434                        for ( auto const & type : src ) {
     435                                ResolvExpr::flatten( type, out );
    393436                        }
    394437                }
     
    409452                                // if ( is<VoidType>( aparam->get_type() ) || is<VoidType>( bparam->get_type() ) ) continue;
    410453                                if ( ! typesPolyCompatible( aparam->get_type(), bparam->get_type() ) ) return false;
     454                        }
     455
     456                        return true;
     457                }
     458
     459                bool paramListsPolyCompatible(
     460                                std::vector<ast::ptr<ast::Expr>> const & lparams,
     461                                std::vector<ast::ptr<ast::Expr>> const & rparams ) {
     462                        if ( lparams.size() != rparams.size() ) {
     463                                return false;
     464                        }
     465
     466                        for ( auto lparam = lparams.begin(), rparam = rparams.begin() ;
     467                                        lparam != lparams.end() ; ++lparam, ++rparam ) {
     468                                ast::TypeExpr const * lexpr = lparam->as<ast::TypeExpr>();
     469                                assertf( lexpr, "Aggregate parameters should be type expressions" );
     470                                ast::TypeExpr const * rexpr = rparam->as<ast::TypeExpr>();
     471                                assertf( rexpr, "Aggregate parameters should be type expressions" );
     472
     473                                // xxx - might need to let VoidType be a wildcard here too; could have some voids
     474                                // stuffed in for dtype-statics.
     475                                // if ( is<VoidType>( lexpr->type() ) || is<VoidType>( bparam->get_type() ) ) continue;
     476                                if ( !typesPolyCompatible( lexpr->type, rexpr->type ) ) {
     477                                        return false;
     478                                }
    411479                        }
    412480
     
    505573        }
    506574
     575bool typesPolyCompatible( ast::Type const * lhs, ast::Type const * rhs ) {
     576        type_index const lid = typeid(*lhs);
     577
     578        // Polymorphic types always match:
     579        if ( type_index(typeid(ast::TypeInstType)) == lid ) return true;
     580
     581        type_index const rid = typeid(*rhs);
     582        if ( type_index(typeid(ast::TypeInstType)) == rid ) return true;
     583
     584        // All other types only match if they are the same type:
     585        if ( lid != rid ) return false;
     586
     587        // So remaining types can be examined case by case.
     588        // Recurse through type structure (conditions borrowed from Unify.cc).
     589
     590        if ( type_index(typeid(ast::BasicType)) == lid ) {
     591                return as<ast::BasicType>(lhs)->kind == as<ast::BasicType>(rhs)->kind;
     592        } else if ( type_index(typeid(ast::PointerType)) == lid ) {
     593                ast::PointerType const * l = as<ast::PointerType>(lhs);
     594                ast::PointerType const * r = as<ast::PointerType>(rhs);
     595
     596                // void pointers should match any other pointer type.
     597                return is<ast::VoidType>( l->base.get() )
     598                        || is<ast::VoidType>( r->base.get() )
     599                        || typesPolyCompatible( l->base.get(), r->base.get() );
     600        } else if ( type_index(typeid(ast::ReferenceType)) == lid ) {
     601                ast::ReferenceType const * l = as<ast::ReferenceType>(lhs);
     602                ast::ReferenceType const * r = as<ast::ReferenceType>(rhs);
     603
     604                // void references should match any other reference type.
     605                return is<ast::VoidType>( l->base.get() )
     606                        || is<ast::VoidType>( r->base.get() )
     607                        || typesPolyCompatible( l->base.get(), r->base.get() );
     608        } else if ( type_index(typeid(ast::ArrayType)) == lid ) {
     609                ast::ArrayType const * l = as<ast::ArrayType>(lhs);
     610                ast::ArrayType const * r = as<ast::ArrayType>(rhs);
     611
     612                if ( l->isVarLen ) {
     613                        if ( !r->isVarLen ) return false;
     614                } else {
     615                        if ( r->isVarLen ) return false;
     616
     617                        auto lc = l->dimension.as<ast::ConstantExpr>();
     618                        auto rc = r->dimension.as<ast::ConstantExpr>();
     619                        if ( lc && rc && lc->intValue() != rc->intValue() ) {
     620                                return false;
     621                        }
     622                }
     623
     624                return typesPolyCompatible( l->base.get(), r->base.get() );
     625        } else if ( type_index(typeid(ast::FunctionType)) == lid ) {
     626                ast::FunctionType const * l = as<ast::FunctionType>(lhs);
     627                ast::FunctionType const * r = as<ast::FunctionType>(rhs);
     628
     629                std::vector<ast::ptr<ast::Type>> lparams, rparams;
     630                flattenList( l->params, lparams );
     631                flattenList( r->params, rparams );
     632                if ( lparams.size() != rparams.size() ) return false;
     633                for ( unsigned i = 0; i < lparams.size(); ++i ) {
     634                        if ( !typesPolyCompatible( lparams[i], rparams[i] ) ) return false;
     635                }
     636
     637                std::vector<ast::ptr<ast::Type>> lrets, rrets;
     638                flattenList( l->returns, lrets );
     639                flattenList( r->returns, rrets );
     640                if ( lrets.size() != rrets.size() ) return false;
     641                for ( unsigned i = 0; i < lrets.size(); ++i ) {
     642                        if ( !typesPolyCompatible( lrets[i], rrets[i] ) ) return false;
     643                }
     644                return true;
     645        } else if ( type_index(typeid(ast::StructInstType)) == lid ) {
     646                ast::StructInstType const * l = as<ast::StructInstType>(lhs);
     647                ast::StructInstType const * r = as<ast::StructInstType>(rhs);
     648
     649                if ( l->name != r->name ) return false;
     650                return paramListsPolyCompatible( l->params, r->params );
     651        } else if ( type_index(typeid(ast::UnionInstType)) == lid ) {
     652                ast::UnionInstType const * l = as<ast::UnionInstType>(lhs);
     653                ast::UnionInstType const * r = as<ast::UnionInstType>(rhs);
     654
     655                if ( l->name != r->name ) return false;
     656                return paramListsPolyCompatible( l->params, r->params );
     657        } else if ( type_index(typeid(ast::EnumInstType)) == lid ) {
     658                ast::EnumInstType const * l = as<ast::EnumInstType>(lhs);
     659                ast::EnumInstType const * r = as<ast::EnumInstType>(rhs);
     660
     661                return l->name == r->name;
     662        } else if ( type_index(typeid(ast::TraitInstType)) == lid ) {
     663                ast::TraitInstType const * l = as<ast::TraitInstType>(lhs);
     664                ast::TraitInstType const * r = as<ast::TraitInstType>(rhs);
     665
     666                return l->name == r->name;
     667        } else if ( type_index(typeid(ast::TupleType)) == lid ) {
     668                ast::TupleType const * l = as<ast::TupleType>(lhs);
     669                ast::TupleType const * r = as<ast::TupleType>(rhs);
     670
     671                std::vector<ast::ptr<ast::Type>> ltypes, rtypes;
     672                flattenList( l->types, ( ltypes ) );
     673                flattenList( r->types, ( rtypes ) );
     674                if ( ltypes.size() != rtypes.size() ) return false;
     675
     676                for ( unsigned i = 0 ; i < ltypes.size() ; ++i ) {
     677                        if ( !typesPolyCompatible( ltypes[i], rtypes[i] ) ) return false;
     678                }
     679                return true;
     680        // The remaining types (VoidType, VarArgsType, ZeroType & OneType)
     681        // have no variation so will always be equal.
     682        } else {
     683                return true;
     684        }
     685}
     686
    507687        namespace {
    508688                // temporary hack to avoid re-implementing anything related to TyVarMap
Note: See TracChangeset for help on using the changeset viewer.