Changes in / [ba407ce:50eac1b]


Ignore:
Location:
src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    rba407ce r50eac1b  
    414414                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {
    415415                                        InferredParams::const_iterator inferParam = appExpr->get_inferParams().find( (*assert)->get_uniqueId() );
    416                                         assert( inferParam != appExpr->get_inferParams().end() && "NOTE: Explicit casts of polymorphic functions to compatible monomorphic functions are currently unsupported" );
     416                                        assert( inferParam != appExpr->get_inferParams().end() );
    417417                                        Expression *newExpr = inferParam->second.expr->clone();
    418418                                        addCast( newExpr, (*assert)->get_type(), tyVars );
  • src/GenPoly/Specialize.cc

    rba407ce r50eac1b  
    4545
    4646          private:
    47                 Expression *createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams = 0 );
    4847                Expression *doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams = 0 );
    4948                void handleExplicitParams( ApplicationExpr *appExpr );
     
    6261        }
    6362
    64         /// Looks up open variables in actual type, returning true if any of them are bound in the environment or formal type.
    6563        bool needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {
    6664                if ( env ) {
     
    8785        }
    8886
    89         /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise
    90         FunctionType * getFunctionType( Type *ty ) {
    91                 PointerType *ptrType;
    92                 if ( ( ptrType = dynamic_cast< PointerType* >( ty ) ) ) {
    93                         return dynamic_cast< FunctionType* >( ptrType->get_base() ); // pointer if FunctionType, NULL otherwise
    94                 } else {
    95                         return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise
    96                 }
    97         }
    98 
    99         /// Generates a thunk that calls `actual` with type `funType` and returns its address
    100         Expression * Specialize::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) {
    101                 FunctionType *newType = funType->clone();
    102                 if ( env ) {
    103                         TypeSubstitution newEnv( *env );
    104                         // it is important to replace only occurrences of type variables that occur free in the
    105                         // thunk's type
    106                         newEnv.applyFree( newType );
    107                 } // if
    108                 // create new thunk with same signature as formal type (C linkage, empty body)
    109                 FunctionDecl *thunkFunc = new FunctionDecl( thunkNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, newType, new CompoundStmt( std::list< std::string >() ), false, false );
    110                 thunkFunc->fixUniqueId();
    111 
    112                 // thread thunk parameters into call to actual function, naming thunk parameters as we go
    113                 UniqueName paramNamer( paramPrefix );
    114                 ApplicationExpr *appExpr = new ApplicationExpr( actual );
    115                 for ( std::list< DeclarationWithType* >::iterator param = thunkFunc->get_functionType()->get_parameters().begin(); param != thunkFunc->get_functionType()->get_parameters().end(); ++param ) {
    116                         (*param )->set_name( paramNamer.newName() );
    117                         appExpr->get_args().push_back( new VariableExpr( *param ) );
    118                 } // for
    119                 appExpr->set_env( maybeClone( env ) );
    120                 if ( inferParams ) {
    121                         appExpr->get_inferParams() = *inferParams;
    122                 } // if
    123 
    124                 // handle any specializations that may still be present
    125                 std::string oldParamPrefix = paramPrefix;
    126                 paramPrefix += "p";
    127                 // save stmtsToAdd in oldStmts
    128                 std::list< Statement* > oldStmts;
    129                 oldStmts.splice( oldStmts.end(), stmtsToAdd );
    130                 handleExplicitParams( appExpr );
    131                 paramPrefix = oldParamPrefix;
    132                 // write any statements added for recursive specializations into the thunk body
    133                 thunkFunc->get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd );
    134                 // restore oldStmts into stmtsToAdd
    135                 stmtsToAdd.splice( stmtsToAdd.end(), oldStmts );
    136 
    137                 // add return (or valueless expression) to the thunk
    138                 Statement *appStmt;
    139                 if ( funType->get_returnVals().empty() ) {
    140                         appStmt = new ExprStmt( noLabels, appExpr );
    141                 } else {
    142                         appStmt = new ReturnStmt( noLabels, appExpr );
    143                 } // if
    144                 thunkFunc->get_statements()->get_kids().push_back( appStmt );
    145 
    146                 // add thunk definition to queue of statements to add
    147                 stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) );
    148                 // return address of thunk function as replacement expression
    149                 return new AddressExpr( new VariableExpr( thunkFunc ) );
    150         }
    151        
    15287        Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) {
     88                assert( ! actual->get_results().empty() );
    15389                if ( needsSpecialization( formalType, actual->get_results().front(), env ) ) {
     90                        PointerType *ptrType;
    15491                        FunctionType *funType;
    155                         if ( ( funType = getFunctionType( formalType ) ) ) {
    156                                 ApplicationExpr *appExpr;
    157                                 VariableExpr *varExpr;
    158                                 if ( ( appExpr = dynamic_cast<ApplicationExpr*>( actual ) ) ) {
    159                                         return createThunkFunction( funType, appExpr->get_function(), inferParams );
    160                                 } else if ( ( varExpr = dynamic_cast<VariableExpr*>( actual ) ) ) {
    161                                         return createThunkFunction( funType, varExpr, inferParams );
     92                        if ( ( ptrType = dynamic_cast< PointerType* >( formalType ) ) && ( funType = dynamic_cast< FunctionType* >( ptrType->get_base() ) ) ) {
     93                                FunctionType *newType = funType->clone();
     94                                if ( env ) {
     95                                        TypeSubstitution newEnv( *env );
     96                                        // it is important to replace only occurrences of type variables that occur free in the
     97                                        // thunk's type
     98                                        newEnv.applyFree( newType );
     99                                } // if
     100                                FunctionDecl *thunkFunc = new FunctionDecl( thunkNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, newType, new CompoundStmt( std::list< std::string >() ), false, false );
     101                                thunkFunc->fixUniqueId();
     102
     103                                UniqueName paramNamer( paramPrefix );
     104                                ApplicationExpr *appExpr = new ApplicationExpr( actual );
     105                                for ( std::list< DeclarationWithType* >::iterator param = thunkFunc->get_functionType()->get_parameters().begin(); param != thunkFunc->get_functionType()->get_parameters().end(); ++param ) {
     106                                        (*param )->set_name( paramNamer.newName() );
     107                                        appExpr->get_args().push_back( new VariableExpr( *param ) );
     108                                } // for
     109                                appExpr->set_env( maybeClone( env ) );
     110                                if ( inferParams ) {
     111                                        appExpr->get_inferParams() = *inferParams;
     112                                } // if
     113
     114                                // handle any specializations that may still be present
     115                                std::string oldParamPrefix = paramPrefix;
     116                                paramPrefix += "p";
     117                                std::list< Statement* > oldStmts;
     118                                oldStmts.splice( oldStmts.end(), stmtsToAdd );
     119                                handleExplicitParams( appExpr );
     120                                paramPrefix = oldParamPrefix;
     121                                thunkFunc->get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd );
     122                                stmtsToAdd.splice( stmtsToAdd.end(), oldStmts );
     123
     124                                Statement *appStmt;
     125                                if ( funType->get_returnVals().empty() ) {
     126                                        appStmt = new ExprStmt( noLabels, appExpr );
    162127                                } else {
    163                                         // This likely won't work, as anything that could build an ApplicationExpr probably hit one of the previous two branches
    164                                         return createThunkFunction( funType, actual, inferParams );
    165                                 }
     128                                        appStmt = new ReturnStmt( noLabels, appExpr );
     129                                } // if
     130                                thunkFunc->get_statements()->get_kids().push_back( appStmt );
     131                                stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) );
     132                                return new AddressExpr( new VariableExpr( thunkFunc ) );
    166133                        } else {
    167134                                return actual;
     
    175142                // create thunks for the explicit parameters
    176143                assert( ! appExpr->get_function()->get_results().empty() );
    177                 FunctionType *function = getFunctionType( appExpr->get_function()->get_results().front() );
    178                 assert( function );
     144                PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
     145                assert( pointer );
     146                FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
    179147                std::list< DeclarationWithType* >::iterator formal;
    180148                std::list< Expression* >::iterator actual;
     
    207175        Expression * Specialize::mutate( CastExpr *castExpr ) {
    208176                castExpr->get_arg()->acceptMutator( *this );
    209                 Expression *specialized = doSpecialization( castExpr->get_results().front(), castExpr->get_arg() );
    210                 if ( specialized != castExpr->get_arg() ) {
    211                         // assume here that the specialization incorporates the cast
    212                         return specialized;
    213                 } else {
    214                         return castExpr;
     177                if ( ! castExpr->get_results().empty() ) {
     178                        // this may not be the correct condition, but previously the next statement
     179                        // was happening unchecked, causing a crash on a cast to void
     180                        castExpr->set_arg( doSpecialization( castExpr->get_results().front(), castExpr->get_arg() ) );         
    215181                }
     182                return castExpr;
    216183        }
    217184
  • src/ResolvExpr/AlternativeFinder.cc

    rba407ce r50eac1b  
    698698                        std::list< Type* >::iterator candidate_end = (*i).expr->get_results().begin();
    699699                        std::advance( candidate_end, castExpr->get_results().size() );
    700                         // unification run for side-effects
    701                         unifyList( castExpr->get_results().begin(), castExpr->get_results().end(),
    702                                            (*i).expr->get_results().begin(), candidate_end,
    703                                    i->env, needAssertions, haveAssertions, openVars, indexer );
    704700                        Cost thisCost = castCostList( (*i).expr->get_results().begin(), candidate_end,
    705                                                                                   castExpr->get_results().begin(), castExpr->get_results().end(),
    706                                                                                   indexer, i->env );
     701                                                                                  castExpr->get_results().begin(), castExpr->get_results().end(), indexer, i->env );
    707702                        if ( thisCost != Cost::infinity ) {
    708703                                // count one safe conversion for each value that is thrown away
  • src/SynTree/Type.h

    rba407ce r50eac1b  
    418418        return isConst == other.isConst
    419419                && isVolatile == other.isVolatile
    420 //              && isRestrict == other.isRestrict
    421 //              && isLvalue == other.isLvalue
     420                && isRestrict == other.isRestrict
     421//      && isLvalue == other.isLvalue
    422422                && isAtomic == other.isAtomic;
    423423}
     
    426426        return isConst != other.isConst
    427427                || isVolatile != other.isVolatile
    428 //              || isRestrict != other.isRestrict
    429 //              || isLvalue != other.isLvalue
     428                || isRestrict != other.isRestrict
     429//      || isLvalue != other.isLvalue
    430430                || isAtomic != other.isAtomic;
    431431}
     
    434434        return isConst <= other.isConst
    435435                && isVolatile <= other.isVolatile
    436 //              && isRestrict <= other.isRestrict
    437 //              && isLvalue >= other.isLvalue
     436                && isRestrict <= other.isRestrict
     437//      && isLvalue >= other.isLvalue
    438438                && isAtomic == other.isAtomic;
    439439}
     
    442442        return isConst >= other.isConst
    443443                && isVolatile >= other.isVolatile
    444 //              && isRestrict >= other.isRestrict
    445 //              && isLvalue <= other.isLvalue
     444                && isRestrict >= other.isRestrict
     445//      && isLvalue <= other.isLvalue
    446446                && isAtomic == other.isAtomic;
    447447}
  • src/main.cc

    rba407ce r50eac1b  
    271271                GenPoly::copyParams( translationUnit );
    272272                OPTPRINT( "convertSpecializations" )
    273                 GenPoly::convertSpecializations( translationUnit );
     273                GenPoly::convertSpecializations( translationUnit );             
    274274                OPTPRINT( "convertLvalue" )
    275275                GenPoly::convertLvalue( translationUnit );
Note: See TracChangeset for help on using the changeset viewer.