Ignore:
Timestamp:
Oct 24, 2020, 9:42:38 AM (4 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
a3f36dc
Parents:
76d73fc (diff), e7d6968 (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/GenPoly/GenPoly.cc

    r76d73fc rc532847  
    4646                }
    4747
     48                bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const ast::TypeSubstitution * env) {
     49                        for (auto &param : params) {
     50                                auto paramType = param.strict_as<ast::TypeExpr>();
     51                                if (isPolyType(paramType->type, env)) return true;
     52                        }
     53                        return false;
     54                }
     55
    4856                /// Checks a parameter list for polymorphic parameters from tyVars; will substitute according to env if present
    4957                bool hasPolyParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     
    5664                }
    5765
     66                bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const TyVarMap & tyVars, const ast::TypeSubstitution * env) {
     67                        for (auto &param : params) {
     68                                auto paramType = param.strict_as<ast::TypeExpr>();
     69                                if (isPolyType(paramType->type, tyVars, env)) return true;
     70                        }
     71                        return false;
     72                }
     73
    5874                /// Checks a parameter list for dynamic-layout parameters from tyVars; will substitute according to env if present
    5975                bool hasDynParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) {
     
    92108                        Type *newType = env->lookup( typeInst->get_name() );
    93109                        if ( newType ) return newType;
     110                }
     111                return type;
     112        }
     113
     114        const ast::Type * replaceTypeInst(const ast::Type * type, const ast::TypeSubstitution * env) {
     115                if (!env) return type;
     116                if (auto typeInst = dynamic_cast<const ast::TypeInstType*> (type)) {
     117                        auto newType = env->lookup(typeInst->name);
     118                        if (newType) return newType;
    94119                }
    95120                return type;
     
    111136        }
    112137
     138        const ast::Type * isPolyType(const ast::Type * type, const ast::TypeSubstitution * env) {
     139                type = replaceTypeInst( type, env );
     140
     141                if ( dynamic_cast< const ast::TypeInstType * >( type ) ) {
     142                        return type;
     143                } else if ( auto arrayType = dynamic_cast< const ast::ArrayType * >( type ) ) {
     144                        return isPolyType( arrayType->base, env );
     145                } else if ( auto structType = dynamic_cast< const ast::StructInstType* >( type ) ) {
     146                        if ( hasPolyParams( structType->params, env ) ) return type;
     147                } else if ( auto unionType = dynamic_cast< const ast::UnionInstType* >( type ) ) {
     148                        if ( hasPolyParams( unionType->params, env ) ) return type;
     149                }
     150                return 0;
     151        }
     152
    113153        Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
    114154                type = replaceTypeInst( type, env );
     
    126166                }
    127167                return 0;
     168        }
     169
     170        const ast::Type * isPolyType(const ast::Type * type, const TyVarMap & tyVars, const ast::TypeSubstitution * env) {
     171                type = replaceTypeInst( type, env );
     172
     173                if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( type ) ) {
     174                        return tyVars.find(typeInst->name) != tyVars.end() ? type : nullptr;
     175                } else if ( auto arrayType = dynamic_cast< const ast::ArrayType * >( type ) ) {
     176                        return isPolyType( arrayType->base, env );
     177                } else if ( auto structType = dynamic_cast< const ast::StructInstType* >( type ) ) {
     178                        if ( hasPolyParams( structType->params, env ) ) return type;
     179                } else if ( auto unionType = dynamic_cast< const ast::UnionInstType* >( type ) ) {
     180                        if ( hasPolyParams( unionType->params, env ) ) return type;
     181                }
     182                return nullptr;
    128183        }
    129184
     
    449504        }
    450505
     506        namespace {
     507                // temporary hack to avoid re-implementing anything related to TyVarMap
     508                // does this work? these two structs have identical definitions.
     509                inline TypeDecl::Data convData(const ast::TypeDecl::Data & data) {
     510                        return *reinterpret_cast<const TypeDecl::Data *>(&data);
     511                }
     512        }
     513
    451514        bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env ) {
    452515                // is parameter is not polymorphic, don't need to box
     
    459522        }
    460523
     524        bool needsBoxing( const ast::Type * param, const ast::Type * arg, const TyVarMap &exprTyVars, const ast::TypeSubstitution * env) {
     525                // is parameter is not polymorphic, don't need to box
     526                if ( ! isPolyType( param, exprTyVars ) ) return false;
     527                ast::ptr<ast::Type> newType = arg;
     528                if ( env ) env->apply( newType );
     529                // if the argument's type is polymorphic, we don't need to box again!
     530                return ! isPolyType( newType );
     531        }
     532
    461533        bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env ) {
    462534                FunctionType * function = getFunctionType( appExpr->function->result );
     
    467539        }
    468540
     541        bool needsBoxing( const ast::Type * param, const ast::Type * arg, const ast::ApplicationExpr * appExpr, const ast::TypeSubstitution * env) {
     542                const ast::FunctionType * function = getFunctionType(appExpr->func->result);
     543                assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->func->result ).c_str() );
     544                TyVarMap exprTyVars(TypeDecl::Data{});
     545                makeTyVarMap(function, exprTyVars);
     546                return needsBoxing(param, arg, exprTyVars, env);
     547
     548        }
     549
    469550        void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) {
    470551                tyVarMap.insert( tyVar->name, TypeDecl::Data{ tyVar } );
     552        }
     553
     554        void addToTyVarMap( const ast::TypeDecl * tyVar, TyVarMap & tyVarMap) {
     555                tyVarMap.insert(tyVar->name, convData(ast::TypeDecl::Data{tyVar}));
    471556        }
    472557
     
    478563                if ( PointerType *pointer = dynamic_cast< PointerType* >( type ) ) {
    479564                        makeTyVarMap( pointer->get_base(), tyVarMap );
     565                }
     566        }
     567
     568        void makeTyVarMap(const ast::Type * type, TyVarMap & tyVarMap) {
     569                if (auto ptype = dynamic_cast<const ast::ParameterizedType *>(type)) {
     570                        for (auto & tyVar : ptype->forall) {
     571                                assert (tyVar);
     572                                addToTyVarMap(tyVar, tyVarMap);
     573                        }
     574                }
     575                if (auto pointer = dynamic_cast<const ast::PointerType *>(type)) {
     576                        makeTyVarMap(pointer->base, tyVarMap);
    480577                }
    481578        }
Note: See TracChangeset for help on using the changeset viewer.