Changeset b3212de


Ignore:
Timestamp:
Nov 1, 2022, 2:05:16 PM (2 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
ADT, ast-experimental, master
Children:
75f6a5f
Parents:
1dafdfc
Message:

Cleaning old box pass for easier translation. Scattered simplifications, note the moved boxParam method has one new line in it near the beginning.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r1dafdfc rb3212de  
    676676                }
    677677
     678                // find instances of polymorphic type parameters
     679                struct PolyFinder {
     680                        const TyVarMap * tyVars = nullptr;
     681                        bool found = false;
     682
     683                        void previsit( TypeInstType * t ) {
     684                                if ( isPolyType( t, *tyVars ) ) {
     685                                        found = true;
     686                                }
     687                        }
     688                };
     689
     690                // true if there is an instance of a polymorphic type parameter in t
     691                bool hasPolymorphism( Type * t, const TyVarMap &tyVars ) {
     692                        PassVisitor<PolyFinder> finder;
     693                        finder.pass.tyVars = &tyVars;
     694                        maybeAccept( t, finder );
     695                        return finder.pass.found;
     696                }
     697
     698                /// cast parameters to polymorphic functions so that types are replaced with
     699                /// void * if they are type parameters in the formal type.
     700                /// this gets rid of warnings from gcc.
     701                void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) {
     702                        // type contains polymorphism, but isn't exactly a polytype, in which case it
     703                        // has some real actual type (e.g. unsigned int) and casting to void * is wrong
     704                        if ( hasPolymorphism( formal, tyVars ) && ! isPolyType( formal, tyVars ) ) {
     705                                Type * newType = formal->clone();
     706                                newType = ScrubTyVars::scrub( newType, tyVars );
     707                                actual = new CastExpr( actual, newType );
     708                        } // if
     709                }
     710
    678711                void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) {
    679712                        assertf( arg->result, "arg does not have result: %s", toString( arg ).c_str() );
     713                        addCast( arg, param, exprTyVars );
    680714                        if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return;
    681715
     
    708742                }
    709743
    710                 // find instances of polymorphic type parameters
    711                 struct PolyFinder {
    712                         const TyVarMap * tyVars = nullptr;
    713                         bool found = false;
    714 
    715                         void previsit( TypeInstType * t ) {
    716                                 if ( isPolyType( t, *tyVars ) ) {
    717                                         found = true;
    718                                 }
    719                         }
    720                 };
    721 
    722                 // true if there is an instance of a polymorphic type parameter in t
    723                 bool hasPolymorphism( Type * t, const TyVarMap &tyVars ) {
    724                         PassVisitor<PolyFinder> finder;
    725                         finder.pass.tyVars = &tyVars;
    726                         maybeAccept( t, finder );
    727                         return finder.pass.found;
    728                 }
    729 
    730                 /// cast parameters to polymorphic functions so that types are replaced with
    731                 /// void * if they are type parameters in the formal type.
    732                 /// this gets rid of warnings from gcc.
    733                 void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) {
    734                         // type contains polymorphism, but isn't exactly a polytype, in which case it
    735                         // has some real actual type (e.g. unsigned int) and casting to void * is wrong
    736                         if ( hasPolymorphism( formal, tyVars ) && ! isPolyType( formal, tyVars ) ) {
    737                                 Type * newType = formal->clone();
    738                                 newType = ScrubTyVars::scrub( newType, tyVars );
    739                                 actual = new CastExpr( actual, newType );
    740                         } // if
    741                 }
    742 
    743744                void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) {
    744745                        for ( DeclarationWithType * param : function->parameters ) {
    745746                                assertf( arg != appExpr->args.end(), "boxParams: missing argument for param %s to %s in %s", toString( param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() );
    746                                 addCast( *arg, param->get_type(), exprTyVars );
    747747                                boxParam( param->get_type(), *arg, exprTyVars );
    748748                                ++arg;
     
    757757                                        assertf( inferParam != appExpr->inferParams.end(), "addInferredParams missing inferred parameter: %s in: %s", toString( assert ).c_str(), toString( appExpr ).c_str() );
    758758                                        Expression *newExpr = inferParam->second.expr->clone();
    759                                         addCast( newExpr, assert->get_type(), tyVars );
    760759                                        boxParam( assert->get_type(), newExpr, tyVars );
    761760                                        appExpr->get_args().insert( cur, newExpr );
     
    788787                        assert( param );
    789788                        assert( arg );
    790                         if ( isPolyType( realParam->get_type(), tyVars ) ) {
    791                                 if ( ! isPolyType( arg->get_type() ) ) {
    792                                         UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    793                                         deref->args.push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
    794                                         deref->result = arg->get_type()->clone();
    795                                         return deref;
    796                                 } // if
     789                        if ( isPolyType( realParam->get_type(), tyVars )
     790                                        && ! isPolyType( arg->get_type() ) ) {
     791                                UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
     792                                deref->args.push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
     793                                deref->result = arg->get_type()->clone();
     794                                return deref;
    797795                        } // if
    798796                        return new VariableExpr( param );
     
    11301128                }
    11311129
    1132                 Expression * Pass1::postmutate( UntypedExpr *expr ) {
     1130                bool isPolyDeref( UntypedExpr * expr, TyVarMap const & scopeTyVars, TypeSubstitution const * env ) {
    11331131                        if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) {
    11341132                                if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) {
    11351133                                        if ( name->name == "*?" ) {
    1136                                                 Expression *ret = expr->args.front();
    1137                                                 expr->args.clear();
    1138                                                 delete expr;
    1139                                                 return ret;
     1134                                                return true;
    11401135                                        } // if
    11411136                                } // if
    11421137                        } // if
     1138                        return false;
     1139                }
     1140
     1141                Expression * Pass1::postmutate( UntypedExpr *expr ) {
     1142                        if ( isPolyDeref( expr, scopeTyVars, env ) ) {
     1143                                Expression *ret = expr->args.front();
     1144                                expr->args.clear();
     1145                                delete expr;
     1146                                return ret;
     1147                        }
    11431148                        return expr;
    11441149                }
     
    11501155                        bool needs = false;
    11511156                        if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->arg ) ) {
    1152                                 if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) {
    1153                                         if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) {
    1154                                                 if ( name->name == "*?" ) {
    1155                                                         if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->args.front() ) ) {
    1156                                                                 assert( appExpr->function->result );
    1157                                                                 FunctionType *function = getFunctionType( appExpr->function->result );
    1158                                                                 assert( function );
    1159                                                                 needs = needsAdapter( function, scopeTyVars );
    1160                                                         } // if
    1161                                                 } // if
     1157                                if ( isPolyDeref( expr, scopeTyVars, env ) ) {
     1158                                        if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->args.front() ) ) {
     1159                                                assert( appExpr->function->result );
     1160                                                FunctionType *function = getFunctionType( appExpr->function->result );
     1161                                                assert( function );
     1162                                                needs = needsAdapter( function, scopeTyVars );
    11621163                                        } // if
    11631164                                } // if
     
    14321433
    14331434                        if(!expect_func_type) {
    1434                                 GuardAction( [this]() {
    1435                                         knownLayouts.endScope();
    1436                                         knownOffsets.endScope();
    1437                                 });
    14381435                                // If this is the first function type we see
    14391436                                // Then it's the type of the declaration and we care about it
    1440                                 knownLayouts.beginScope();
    1441                                 knownOffsets.beginScope();
     1437                                GuardScope( *this );
    14421438                        }
    14431439
Note: See TracChangeset for help on using the changeset viewer.