Changes in src/GenPoly/Box.cc [e56cfdb0:698664b3]
- File:
-
- 1 edited
-
src/GenPoly/Box.cc (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
re56cfdb0 r698664b3 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : T hu Nov 19 17:40:51201513 // Update Count : 13311 // Last Modified By : Rob Schluntz 12 // Last Modified On : Tue Aug 11 16:22:35 2015 13 // Update Count : 89 14 14 // 15 15 … … 47 47 namespace { 48 48 const std::list<Label> noLabels; 49 50 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );51 49 52 50 class Pass1 : public PolyMutator { … … 80 78 ObjectDecl *makeTemporary( Type *type ); 81 79 82 typedef std::map< std::string, DeclarationWithType*> AdapterMap;80 typedef std::map< std::string, FunctionDecl *> AdapterMap; 83 81 std::map< std::string, DeclarationWithType *> assignOps; 84 82 std::stack< AdapterMap > adapters; … … 146 144 } 147 145 146 bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars ) { 147 bool doTransform = false; 148 if ( ! function->get_returnVals().empty() ) { 149 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( function->get_returnVals().front()->get_type() ) ) { 150 151 // figure out if the return type is specified by a type parameter 152 for ( std::list< TypeDecl *>::const_iterator tyVar = function->get_forall().begin(); tyVar != function->get_forall().end(); ++tyVar ) { 153 if ( (*tyVar)->get_name() == typeInst->get_name() ) { 154 doTransform = true; 155 name = typeInst->get_name(); 156 break; 157 } // if 158 } // for 159 if ( ! doTransform && otherTyVars.find( typeInst->get_name() ) != otherTyVars.end() ) { 160 doTransform = true; 161 } // if 162 } // if 163 } // if 164 return doTransform; 165 } 166 167 bool isPolyRet( FunctionType *function, std::string &name ) { 168 TyVarMap dummyTyVars; 169 return isPolyRet( function, name, dummyTyVars ); 170 } 171 172 bool isPolyRet( FunctionType *function, const TyVarMap &otherTyVars ) { 173 std::string dummyString; 174 return isPolyRet( function, dummyString, otherTyVars ); 175 } 176 148 177 Pass1::Pass1() 149 178 : useRetval( false ), tempNamer( "_temp" ) { 150 adapters.push(AdapterMap());151 179 } 152 180 … … 182 210 183 211 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) { 184 if ( functionDecl->get_statements() ) { // empty routine body ? 185 doBeginScope(); 212 if ( functionDecl->get_statements() ) { 186 213 TyVarMap oldtyVars = scopeTyVars; 187 214 DeclarationWithType *oldRetval = retval; 188 215 bool oldUseRetval = useRetval; 189 190 // process polymorphic return value 216 191 217 retval = 0; 192 218 std::string typeName; … … 201 227 } // if 202 228 203 FunctionType *functionType = functionDecl->get_functionType(); 229 scopeTyVars.clear(); 230 /// std::cerr << "clear\n"; 204 231 makeTyVarMap( functionDecl->get_functionType(), scopeTyVars ); 205 232 findAssignOps( functionDecl->get_functionType()->get_forall() ); 206 207 std::list< DeclarationWithType *> ¶mList = functionType->get_parameters();208 std::list< FunctionType *> functions;209 for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {210 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {211 findFunction( (*assert)->get_type(), functions, scopeTyVars, needsAdapter );212 } // for213 } // for214 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {215 findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter );216 } // for217 AdapterMap & adapters = Pass1::adapters.top();218 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {219 std::string mangleName = SymTab::Mangler::mangle( *funType );220 if ( isPolyRet( *funType, scopeTyVars ) ) {221 // if the return type involved polymorphic types, then the adapter will need to take those222 // polymorphic types as pointers. Therefore, there can be two different functions with the same223 // mangled name, so we need the mangled names to be different.224 mangleName += "polyret_";225 } // if226 if ( adapters.find( mangleName ) == adapters.end() ) {227 std::string adapterName = makeAdapterName( mangleName );228 adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, new ObjectDecl( adapterName, DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0 ) ) );229 } // if230 } // for231 232 233 functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) ); 233 234 234 235 scopeTyVars = oldtyVars; 235 //std::cerr << "end FunctionDecl: ";236 //for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {237 //std::cerr << i->first << " ";238 //}239 //std::cerr << "\n";236 /// std::cerr << "end FunctionDecl: "; 237 /// for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) { 238 /// std::cerr << i->first << " "; 239 /// } 240 /// std::cerr << "\n"; 240 241 retval = oldRetval; 241 242 useRetval = oldUseRetval; 242 doEndScope();243 // doEndScope(); 243 244 } // if 244 245 return functionDecl; … … 348 349 } // if 349 350 std::string mangleName = SymTab::Mangler::mangle( function ); 350 if ( isPolyRet( function, tyVars ) ) {351 mangleName += "polyret_";352 } // if353 351 std::string adapterName = makeAdapterName( mangleName ); 354 352 … … 459 457 /// return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() ); 460 458 /// } else { 461 if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) { 462 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 463 deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) ); 464 deref->get_results().push_back( arg->get_type()->clone() ); 465 return deref; 466 } // if 459 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 460 deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) ); 461 deref->get_results().push_back( arg->get_type()->clone() ); 462 return deref; 467 463 /// } 468 464 } // if … … 548 544 } // for 549 545 550 // parameter function types for which an appropriate adapter has been generated. we cannot use the types 551 // after applying substitutions, since two different parameter types may be unified to the same type 546 // parameter function types for which an appropriate adapter has been generated. 547 // we cannot use the types after applying substitutions, since two different 548 // parameter types may be unified to the same type 552 549 std::set< std::string > adaptersDone; 553 550 … … 557 554 std::string mangleName = SymTab::Mangler::mangle( realFunction ); 558 555 559 // only attempt to create an adapter or pass one as a parameter if we haven't already done so for this560 // pre-substitution parameter function type.556 // only attempt to create an adapter or pass one as a parameter if we haven't 557 // already done so for this pre-substitution parameter function type. 561 558 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) { 559 std::string mangleName = SymTab::Mangler::mangle( realFunction ); 562 560 adaptersDone.insert( adaptersDone.begin(), mangleName ); 563 561 564 // apply substitution to type variables to figure out what the adapter's type should look like 562 // apply substitution to type variables to figure out what the 563 // adapter's type should look like 565 564 assert( env ); 566 565 env->apply( realFunction ); 567 566 mangleName = SymTab::Mangler::mangle( realFunction ); 568 567 569 if ( isPolyRet( originalFunction, exprTyVars ) ) { 570 mangleName += "polyret_"; 568 if ( needsAdapter( realFunction, exprTyVars, true ) ) { 569 // the function still contains type variables, which means we are in a polymorphic 570 // context and the adapter function is a parameter - call the parameter and don't 571 // create a new adapter. 572 appExpr->get_args().push_front( new NameExpr( makeAdapterName ( mangleName ) ) ); 573 } else { 574 if ( isPolyRet( originalFunction, exprTyVars ) ) { 575 // if the return type involved polymorphic types, then 576 // the adapter will need to take those polymorphic types 577 // as pointers. Therefore, there can be two different 578 // functions with the same mangled name, so we need two adapter map 579 // stacks and also we need the mangled names to be different. 580 mangleName += "polyret_"; 581 } 582 583 AdapterMap & adapters = Pass1::adapters.top(); 584 AdapterMap::iterator adapter = adapters.find( mangleName ); 585 if ( adapter == adapters.end() ) { 586 // adapter has not been created yet in the current scope, so define it 587 FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars ); 588 adapter = adapters.insert( adapters.begin(), std::pair< std::string, FunctionDecl *>( mangleName, newAdapter ) ); 589 stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) ); 590 } // if 591 assert( adapter != adapters.end() ); 592 593 // add the appropriate adapter as a parameter 594 appExpr->get_args().push_front( new VariableExpr( adapter->second ) ); 571 595 } // if 572 573 AdapterMap & adapters = Pass1::adapters.top();574 AdapterMap::iterator adapter = adapters.find( mangleName );575 if ( adapter == adapters.end() ) {576 // adapter has not been created yet in the current scope, so define it577 FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars );578 adapter = adapters.insert( adapters.begin(), std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );579 stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) );580 } // if581 assert( adapter != adapters.end() );582 583 // add the appropriate adapter as a parameter584 appExpr->get_args().push_front( new VariableExpr( adapter->second ) );585 596 } // if 586 597 } // for 587 } // passAdapters598 } 588 599 589 600 TypeInstType *isPolyPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) { … … 758 769 759 770 Expression *Pass1::mutate( ApplicationExpr *appExpr ) { 760 //std::cerr << "mutate appExpr: ";761 //for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {762 //std::cerr << i->first << " ";763 //}764 //std::cerr << "\n";771 /// std::cerr << "mutate appExpr: "; 772 /// for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) { 773 /// std::cerr << i->first << " "; 774 /// } 775 /// std::cerr << "\n"; 765 776 bool oldUseRetval = useRetval; 766 777 useRetval = false; … … 788 799 ret = addPolyRetParam( appExpr, function, typeName, arg ); 789 800 } else if ( needsAdapter( function, scopeTyVars ) ) { 790 //std::cerr << "needs adapter: ";791 //for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {792 //std::cerr << i->first << " ";793 //}794 //std::cerr << "\n";801 /// std::cerr << "needs adapter: "; 802 /// for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) { 803 /// std::cerr << i->first << " "; 804 /// } 805 /// std::cerr << "\n"; 795 806 // change the application so it calls the adapter rather than the passed function 796 807 ret = applyAdapter( appExpr, function, arg, scopeTyVars ); … … 902 913 // actually, maybe this could (should?) push 903 914 // a copy of the current map 904 adapters.push( adapters.top());915 adapters.push(AdapterMap()); 905 916 } 906 917 … … 924 935 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) { 925 936 std::string mangleName = SymTab::Mangler::mangle( *funType ); 926 if ( isPolyRet( *funType, scopeTyVars ) ) {927 mangleName += "polyret_";928 } // if929 937 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) { 930 938 std::string adapterName = makeAdapterName( mangleName ); … … 992 1000 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { 993 1001 ObjectDecl *thisParm; 994 // add all size parameters to parameter list995 1002 if ( (*tyParm)->get_kind() == TypeDecl::Any ) { 996 1003 thisParm = newObj->clone(); … … 999 1006 ++last; 1000 1007 } 1001 // move all assertions into parameter list1002 1008 for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) { 1003 1009 /// *assert = (*assert)->acceptMutator( *this );
Note:
See TracChangeset
for help on using the changeset viewer.