Changes in src/GenPoly/Box.cc [f2b2029:698664b3]
- File:
-
- 1 edited
-
src/GenPoly/Box.cc (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
rf2b2029 r698664b3 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Dec 02 11:52:37201513 // Update Count : 20112 // 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; … … 142 140 143 141 namespace { 144 std::string makePolyMonoSuffix( FunctionType * function, const TyVarMap &tyVars ) {145 std::stringstream name;146 147 // NOTE: this function previously used isPolyObj, which failed to produce148 // the correct thing in some situations. It's not clear to me why this wasn't working.149 150 // if the return type or a parameter type involved polymorphic types, then the adapter will need151 // to take those polymorphic types as pointers. Therefore, there can be two different functions152 // with the same mangled name, so we need to further mangle the names.153 for ( std::list< DeclarationWithType *>::iterator retval = function->get_returnVals().begin(); retval != function->get_returnVals().end(); ++retval ) {154 if ( isPolyVal( (*retval)->get_type(), tyVars ) ) {155 name << "P";156 } else {157 name << "M";158 }159 }160 name << "_";161 std::list< DeclarationWithType *> ¶mList = function->get_parameters();162 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {163 if ( isPolyVal( (*arg)->get_type(), tyVars ) ) {164 name << "P";165 } else {166 name << "M";167 }168 } // for169 return name.str();170 }171 172 std::string mangleAdapterName( FunctionType * function, const TyVarMap &tyVars ) {173 return SymTab::Mangler::mangle( function ) + makePolyMonoSuffix( function, tyVars );174 }175 176 142 std::string makeAdapterName( const std::string &mangleName ) { 177 143 return "_adapter" + mangleName; 178 144 } 179 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 180 177 Pass1::Pass1() 181 178 : useRetval( false ), tempNamer( "_temp" ) { 182 adapters.push(AdapterMap()); 183 } 184 185 // returns true if the given declaration is: (*?=?)(T *, T) for some T (return not checked, but maybe should be) 179 } 180 186 181 bool checkAssignment( DeclarationWithType *decl, std::string &name ) { 187 182 if ( decl->get_name() == "?=?" ) { … … 203 198 204 199 void Pass1::findAssignOps( const std::list< TypeDecl *> &forall ) { 205 // what if a nested function uses an assignment operator? 206 // assignOps.clear(); 200 assignOps.clear(); 207 201 for ( std::list< TypeDecl *>::const_iterator i = forall.begin(); i != forall.end(); ++i ) { 208 202 for ( std::list< DeclarationWithType *>::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) { … … 216 210 217 211 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) { 218 if ( functionDecl->get_statements() ) { // empty routine body ? 219 doBeginScope(); 212 if ( functionDecl->get_statements() ) { 220 213 TyVarMap oldtyVars = scopeTyVars; 221 std::map< std::string, DeclarationWithType *> oldassignOps = assignOps;222 214 DeclarationWithType *oldRetval = retval; 223 215 bool oldUseRetval = useRetval; 224 225 // process polymorphic return value 216 226 217 retval = 0; 227 218 std::string typeName; … … 236 227 } // if 237 228 238 FunctionType *functionType = functionDecl->get_functionType(); 229 scopeTyVars.clear(); 230 /// std::cerr << "clear\n"; 239 231 makeTyVarMap( functionDecl->get_functionType(), scopeTyVars ); 240 232 findAssignOps( functionDecl->get_functionType()->get_forall() ); 241 242 std::list< DeclarationWithType *> ¶mList = functionType->get_parameters();243 std::list< FunctionType *> functions;244 for ( std::list< TypeDecl *>::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {245 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) {246 findFunction( (*assert)->get_type(), functions, scopeTyVars, needsAdapter );247 } // for248 } // for249 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) {250 findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter );251 } // for252 AdapterMap & adapters = Pass1::adapters.top();253 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {254 std::string mangleName = mangleAdapterName( *funType, scopeTyVars );255 if ( adapters.find( mangleName ) == adapters.end() ) {256 std::string adapterName = makeAdapterName( mangleName );257 adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, new ObjectDecl( adapterName, DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0 ) ) );258 } // if259 } // for260 261 233 functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) ); 262 234 263 235 scopeTyVars = oldtyVars; 264 assignOps = oldassignOps; 265 // std::cerr << "end FunctionDecl: "; 266 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) { 267 // std::cerr << i->first << " "; 268 // } 269 // 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"; 270 241 retval = oldRetval; 271 242 useRetval = oldUseRetval; 272 doEndScope();243 // doEndScope(); 273 244 } // if 274 245 return functionDecl; … … 377 348 ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg ); 378 349 } // if 379 std::string mangleName = mangleAdapterName( function, tyVars);350 std::string mangleName = SymTab::Mangler::mangle( function ); 380 351 std::string adapterName = makeAdapterName( mangleName ); 381 352 … … 486 457 /// return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() ); 487 458 /// } else { 488 if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) { 489 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 490 deref->get_args().push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) ); 491 deref->get_results().push_back( arg->get_type()->clone() ); 492 return deref; 493 } // 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; 494 463 /// } 495 464 } // if … … 575 544 } // for 576 545 577 // parameter function types for which an appropriate adapter has been generated. we cannot use the types 578 // 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 579 549 std::set< std::string > adaptersDone; 580 550 … … 584 554 std::string mangleName = SymTab::Mangler::mangle( realFunction ); 585 555 586 // only attempt to create an adapter or pass one as a parameter if we haven't already done so for this587 // 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. 588 558 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) { 559 std::string mangleName = SymTab::Mangler::mangle( realFunction ); 589 560 adaptersDone.insert( adaptersDone.begin(), mangleName ); 590 561 591 // 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 592 564 assert( env ); 593 565 env->apply( realFunction ); 594 mangleName = SymTab::Mangler::mangle( realFunction ); 595 mangleName += makePolyMonoSuffix( originalFunction, exprTyVars ); 596 597 AdapterMap & adapters = Pass1::adapters.top(); 598 AdapterMap::iterator adapter = adapters.find( mangleName ); 599 if ( adapter == adapters.end() ) { 600 // adapter has not been created yet in the current scope, so define it 601 FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars ); 602 adapter = adapters.insert( adapters.begin(), std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) ); 603 stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) ); 566 mangleName = SymTab::Mangler::mangle( realFunction ); 567 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 ) ); 604 595 } // if 605 assert( adapter != adapters.end() );606 607 // add the appropriate adapter as a parameter608 appExpr->get_args().push_front( new VariableExpr( adapter->second ) );609 596 } // if 610 597 } // for 611 } // passAdapters598 } 612 599 613 600 TypeInstType *isPolyPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) { … … 669 656 TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars ); 670 657 TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars ); 671 assert( ! typeInst1 || ! typeInst2 ); // the arguments cannot both be polymorphic pointers658 assert( ! typeInst1 || ! typeInst2 ); 672 659 UntypedExpr *ret = 0; 673 if ( typeInst1 || typeInst2 ) { // one of the arguments is a polymorphic pointer660 if ( typeInst1 || typeInst2 ) { 674 661 ret = new UntypedExpr( new NameExpr( "?+?" ) ); 675 662 } // if … … 782 769 783 770 Expression *Pass1::mutate( ApplicationExpr *appExpr ) { 784 //std::cerr << "mutate appExpr: ";785 //for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {786 //std::cerr << i->first << " ";787 //}788 //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"; 789 776 bool oldUseRetval = useRetval; 790 777 useRetval = false; … … 812 799 ret = addPolyRetParam( appExpr, function, typeName, arg ); 813 800 } else if ( needsAdapter( function, scopeTyVars ) ) { 814 //std::cerr << "needs adapter: ";815 //for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {816 //std::cerr << i->first << " ";817 //}818 //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"; 819 806 // change the application so it calls the adapter rather than the passed function 820 807 ret = applyAdapter( appExpr, function, arg, scopeTyVars ); … … 867 854 868 855 Statement * Pass1::mutate(ReturnStmt *retStmt) { 869 // by this point, a cast expr on a polymorphic return value is redundant856 // a cast expr on a polymorphic return value is either redundant or invalid 870 857 while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( retStmt->get_expr() ) ) { 871 858 retStmt->set_expr( castExpr->get_arg() ); … … 924 911 925 912 void Pass1::doBeginScope() { 926 // push a copy of the current map 927 adapters.push(adapters.top()); 913 // actually, maybe this could (should?) push 914 // a copy of the current map 915 adapters.push(AdapterMap()); 928 916 } 929 917 … … 946 934 std::set< std::string > adaptersDone; 947 935 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) { 948 std::string mangleName = mangleAdapterName( *funType, scopeTyVars);936 std::string mangleName = SymTab::Mangler::mangle( *funType ); 949 937 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) { 950 938 std::string adapterName = makeAdapterName( mangleName ); … … 1012 1000 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { 1013 1001 ObjectDecl *thisParm; 1014 // add all size parameters to parameter list1015 1002 if ( (*tyParm)->get_kind() == TypeDecl::Any ) { 1016 1003 thisParm = newObj->clone(); … … 1019 1006 ++last; 1020 1007 } 1021 // move all assertions into parameter list1022 1008 for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) { 1023 1009 /// *assert = (*assert)->acceptMutator( *this );
Note:
See TracChangeset
for help on using the changeset viewer.