Changeset 7e23d0a for src/GenPoly/Box.cc
- Timestamp:
- Nov 25, 2015, 2:53:26 PM (8 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:
- 32d281d, 704c9dd
- Parents:
- 02ec390 (diff), 5189888 (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r02ec390 r7e23d0a 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : T ue Aug 11 16:22:35201513 // Update Count : 8911 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Nov 19 17:40:51 2015 13 // Update Count : 133 14 14 // 15 15 … … 47 47 namespace { 48 48 const std::list<Label> noLabels; 49 50 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 49 51 50 52 class Pass1 : public PolyMutator { … … 78 80 ObjectDecl *makeTemporary( Type *type ); 79 81 80 typedef std::map< std::string, FunctionDecl*> AdapterMap;82 typedef std::map< std::string, DeclarationWithType *> AdapterMap; 81 83 std::map< std::string, DeclarationWithType *> assignOps; 82 84 std::stack< AdapterMap > adapters; … … 144 146 } 145 147 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 parameter152 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 } // if158 } // for159 if ( ! doTransform && otherTyVars.find( typeInst->get_name() ) != otherTyVars.end() ) {160 doTransform = true;161 } // if162 } // if163 } // if164 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 177 148 Pass1::Pass1() 178 149 : useRetval( false ), tempNamer( "_temp" ) { 150 adapters.push(AdapterMap()); 179 151 } 180 152 … … 210 182 211 183 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) { 212 if ( functionDecl->get_statements() ) { 184 if ( functionDecl->get_statements() ) { // empty routine body ? 185 doBeginScope(); 213 186 TyVarMap oldtyVars = scopeTyVars; 214 187 DeclarationWithType *oldRetval = retval; 215 188 bool oldUseRetval = useRetval; 216 189 190 // process polymorphic return value 217 191 retval = 0; 218 192 std::string typeName; … … 227 201 } // if 228 202 229 scopeTyVars.clear(); 230 /// std::cerr << "clear\n"; 203 FunctionType *functionType = functionDecl->get_functionType(); 231 204 makeTyVarMap( functionDecl->get_functionType(), scopeTyVars ); 232 205 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 } // for 213 } // for 214 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) { 215 findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter ); 216 } // for 217 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 those 222 // polymorphic types as pointers. Therefore, there can be two different functions with the same 223 // mangled name, so we need the mangled names to be different. 224 mangleName += "polyret_"; 225 } // if 226 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 } // if 230 } // for 231 233 232 functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) ); 234 233 235 234 scopeTyVars = oldtyVars; 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";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"; 241 240 retval = oldRetval; 242 241 useRetval = oldUseRetval; 243 //doEndScope();242 doEndScope(); 244 243 } // if 245 244 return functionDecl; … … 349 348 } // if 350 349 std::string mangleName = SymTab::Mangler::mangle( function ); 350 if ( isPolyRet( function, tyVars ) ) { 351 mangleName += "polyret_"; 352 } // if 351 353 std::string adapterName = makeAdapterName( mangleName ); 352 354 … … 457 459 /// return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() ); 458 460 /// } else { 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; 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 463 467 /// } 464 468 } // if … … 544 548 } // for 545 549 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 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 549 552 std::set< std::string > adaptersDone; 550 553 … … 554 557 std::string mangleName = SymTab::Mangler::mangle( realFunction ); 555 558 556 // only attempt to create an adapter or pass one as a parameter if we haven't 557 // already done so for thispre-substitution parameter function type.559 // only attempt to create an adapter or pass one as a parameter if we haven't already done so for this 560 // pre-substitution parameter function type. 558 561 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) { 559 std::string mangleName = SymTab::Mangler::mangle( realFunction );560 562 adaptersDone.insert( adaptersDone.begin(), mangleName ); 561 563 562 // apply substitution to type variables to figure out what the 563 // adapter's type should look like 564 // apply substitution to type variables to figure out what the adapter's type should look like 564 565 assert( env ); 565 566 env->apply( realFunction ); 566 567 mangleName = SymTab::Mangler::mangle( realFunction ); 567 568 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 ) ); 595 } // if 569 if ( isPolyRet( originalFunction, exprTyVars ) ) { 570 mangleName += "polyret_"; 571 } // 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 it 577 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 } // if 581 assert( adapter != adapters.end() ); 582 583 // add the appropriate adapter as a parameter 584 appExpr->get_args().push_front( new VariableExpr( adapter->second ) ); 596 585 } // if 597 586 } // for 598 } 587 } // passAdapters 599 588 600 589 TypeInstType *isPolyPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) { … … 769 758 770 759 Expression *Pass1::mutate( ApplicationExpr *appExpr ) { 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";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"; 776 765 bool oldUseRetval = useRetval; 777 766 useRetval = false; … … 799 788 ret = addPolyRetParam( appExpr, function, typeName, arg ); 800 789 } else if ( needsAdapter( function, scopeTyVars ) ) { 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";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"; 806 795 // change the application so it calls the adapter rather than the passed function 807 796 ret = applyAdapter( appExpr, function, arg, scopeTyVars ); … … 913 902 // actually, maybe this could (should?) push 914 903 // a copy of the current map 915 adapters.push( AdapterMap());904 adapters.push(adapters.top()); 916 905 } 917 906 … … 935 924 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) { 936 925 std::string mangleName = SymTab::Mangler::mangle( *funType ); 926 if ( isPolyRet( *funType, scopeTyVars ) ) { 927 mangleName += "polyret_"; 928 } // if 937 929 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) { 938 930 std::string adapterName = makeAdapterName( mangleName ); … … 1000 992 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { 1001 993 ObjectDecl *thisParm; 994 // add all size parameters to parameter list 1002 995 if ( (*tyParm)->get_kind() == TypeDecl::Any ) { 1003 996 thisParm = newObj->clone(); … … 1006 999 ++last; 1007 1000 } 1001 // move all assertions into parameter list 1008 1002 for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) { 1009 1003 /// *assert = (*assert)->acceptMutator( *this );
Note: See TracChangeset
for help on using the changeset viewer.