- Timestamp:
- Nov 18, 2015, 1:06:12 PM (9 years ago)
- 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, string, with_gc
- Children:
- 9ed3237, f066321
- Parents:
- 50eac1b (diff), 4673385 (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. - Location:
- src
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r50eac1b rba407ce 414 414 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) { 415 415 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" ); 417 417 Expression *newExpr = inferParam->second.expr->clone(); 418 418 addCast( newExpr, (*assert)->get_type(), tyVars ); -
src/GenPoly/Specialize.cc
r50eac1b rba407ce 45 45 46 46 private: 47 Expression *createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams = 0 ); 47 48 Expression *doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams = 0 ); 48 49 void handleExplicitParams( ApplicationExpr *appExpr ); … … 61 62 } 62 63 64 /// Looks up open variables in actual type, returning true if any of them are bound in the environment or formal type. 63 65 bool needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) { 64 66 if ( env ) { … … 85 87 } 86 88 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 87 152 Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) { 88 assert( ! actual->get_results().empty() );89 153 if ( needsSpecialization( formalType, actual->get_results().front(), env ) ) { 90 PointerType *ptrType;91 154 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 ); 127 162 } 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 } 133 166 } else { 134 167 return actual; … … 142 175 // create thunks for the explicit parameters 143 176 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 ); 147 179 std::list< DeclarationWithType* >::iterator formal; 148 180 std::list< Expression* >::iterator actual; … … 175 207 Expression * Specialize::mutate( CastExpr *castExpr ) { 176 208 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 } 183 216 } 184 217 -
src/ResolvExpr/AlternativeFinder.cc
r50eac1b rba407ce 698 698 std::list< Type* >::iterator candidate_end = (*i).expr->get_results().begin(); 699 699 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 ); 700 704 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 ); 702 707 if ( thisCost != Cost::infinity ) { 703 708 // count one safe conversion for each value that is thrown away -
src/SynTree/Type.h
r50eac1b rba407ce 418 418 return isConst == other.isConst 419 419 && isVolatile == other.isVolatile 420 && isRestrict == other.isRestrict421 // && isLvalue == other.isLvalue420 // && isRestrict == other.isRestrict 421 // && isLvalue == other.isLvalue 422 422 && isAtomic == other.isAtomic; 423 423 } … … 426 426 return isConst != other.isConst 427 427 || isVolatile != other.isVolatile 428 || isRestrict != other.isRestrict429 // || isLvalue != other.isLvalue428 // || isRestrict != other.isRestrict 429 // || isLvalue != other.isLvalue 430 430 || isAtomic != other.isAtomic; 431 431 } … … 434 434 return isConst <= other.isConst 435 435 && isVolatile <= other.isVolatile 436 && isRestrict <= other.isRestrict437 // && isLvalue >= other.isLvalue436 // && isRestrict <= other.isRestrict 437 // && isLvalue >= other.isLvalue 438 438 && isAtomic == other.isAtomic; 439 439 } … … 442 442 return isConst >= other.isConst 443 443 && isVolatile >= other.isVolatile 444 && isRestrict >= other.isRestrict445 // && isLvalue <= other.isLvalue444 // && isRestrict >= other.isRestrict 445 // && isLvalue <= other.isLvalue 446 446 && isAtomic == other.isAtomic; 447 447 } -
src/main.cc
r50eac1b rba407ce 271 271 GenPoly::copyParams( translationUnit ); 272 272 OPTPRINT( "convertSpecializations" ) 273 GenPoly::convertSpecializations( translationUnit ); 273 GenPoly::convertSpecializations( translationUnit ); 274 274 OPTPRINT( "convertLvalue" ) 275 275 GenPoly::convertLvalue( translationUnit );
Note: See TracChangeset
for help on using the changeset viewer.