Changeset 9ed3237


Ignore:
Timestamp:
Nov 18, 2015, 1:06:24 PM (9 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
0ddb713
Parents:
84b08d4 (diff), ba407ce (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 'override-autogen' into ctor

Location:
src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r84b08d4 r9ed3237  
    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() );
     416                                        assert( inferParam != appExpr->get_inferParams().end() && "NOTE: Explicit casts of polymorphic functions to compatible monomorphic functions are currently unsupported" );
    417417                                        Expression *newExpr = inferParam->second.expr->clone();
    418418                                        addCast( newExpr, (*assert)->get_type(), tyVars );
  • src/GenPoly/Specialize.cc

    r84b08d4 r9ed3237  
    4545
    4646          private:
     47                Expression *createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams = 0 );
    4748                Expression *doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams = 0 );
    4849                void handleExplicitParams( ApplicationExpr *appExpr );
     
    6162        }
    6263
     64        /// Looks up open variables in actual type, returning true if any of them are bound in the environment or formal type.
    6365        bool needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {
    6466                if ( env ) {
     
    8587        }
    8688
     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       
    87152        Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) {
    88                 assert( ! actual->get_results().empty() );
    89153                if ( needsSpecialization( formalType, actual->get_results().front(), env ) ) {
    90                         PointerType *ptrType;
    91154                        FunctionType *funType;
    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 );
     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 );
    127162                                } else {
    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 ) );
     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                                }
    133166                        } else {
    134167                                return actual;
     
    142175                // create thunks for the explicit parameters
    143176                assert( ! appExpr->get_function()->get_results().empty() );
    144                 PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
    145                 assert( pointer );
    146                 FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
     177                FunctionType *function = getFunctionType( appExpr->get_function()->get_results().front() );
     178                assert( function );
    147179                std::list< DeclarationWithType* >::iterator formal;
    148180                std::list< Expression* >::iterator actual;
     
    175207        Expression * Specialize::mutate( CastExpr *castExpr ) {
    176208                castExpr->get_arg()->acceptMutator( *this );
    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() ) );         
    181                 }
    182                 return castExpr;
     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;
     215                }
    183216        }
    184217
  • src/ResolvExpr/AlternativeFinder.cc

    r84b08d4 r9ed3237  
    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 );
    700704                        Cost thisCost = castCostList( (*i).expr->get_results().begin(), candidate_end,
    701                                                                                   castExpr->get_results().begin(), castExpr->get_results().end(), indexer, i->env );
     705                                                                                  castExpr->get_results().begin(), castExpr->get_results().end(),
     706                                                                                  indexer, i->env );
    702707                        if ( thisCost != Cost::infinity ) {
    703708                                // count one safe conversion for each value that is thrown away
  • src/SynTree/Type.h

    r84b08d4 r9ed3237  
    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

    r84b08d4 r9ed3237  
    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.