Changeset ae63a18 for src/GenPoly
- Timestamp:
- Dec 18, 2015, 2:56:11 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:
- 8762501
- Parents:
- baf7fee (diff), c23f807 (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/GenPoly
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
rbaf7fee rae63a18 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Box.cc -- 7 // Box.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 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 : 2 0112 // Last Modified On : Fri Dec 18 14:53:08 2015 13 // Update Count : 217 14 14 // 15 15 … … 28 28 #include "Parser/ParseNode.h" 29 29 30 #include "SynTree/Constant.h" 30 31 #include "SynTree/Type.h" 31 32 #include "SynTree/Expression.h" … … 61 62 virtual Expression *mutate( CommaExpr *commaExpr ); 62 63 virtual Expression *mutate( ConditionalExpr *condExpr ); 63 virtual Statement * mutate(ReturnStmt *catchStmt);64 virtual Statement * mutate( ReturnStmt *returnStmt ); 64 65 virtual Type *mutate( PointerType *pointerType ); 65 virtual Type * mutate( FunctionType *pointerType );66 66 virtual Type * mutate( FunctionType *functionType ); 67 67 68 virtual void doBeginScope(); 68 69 virtual void doEndScope(); … … 92 93 class Pass2 : public PolyMutator { 93 94 public: 94 Pass2();95 95 template< typename DeclClass > 96 96 DeclClass *handleDecl( DeclClass *decl, Type *type ); … … 103 103 private: 104 104 void addAdapters( FunctionType *functionType ); 105 105 106 106 std::map< UniqueId, std::string > adapterName; 107 107 }; … … 151 151 // the correct thing in some situations. It's not clear to me why this wasn't working. 152 152 153 // if the return type or a parameter type involved polymorphic types, then the adapter will need 154 // to take those polymorphic types as pointers. Therefore, there can be two different functions 153 // if the return type or a parameter type involved polymorphic types, then the adapter will need 154 // to take those polymorphic types as pointers. Therefore, there can be two different functions 155 155 // with the same mangled name, so we need to further mangle the names. 156 156 for ( std::list< DeclarationWithType *>::iterator retval = function->get_returnVals().begin(); retval != function->get_returnVals().end(); ++retval ) { 157 if ( isPoly Val( (*retval)->get_type(), tyVars ) ) {157 if ( isPolyType( (*retval)->get_type(), tyVars ) ) { 158 158 name << "P"; 159 159 } else { … … 164 164 std::list< DeclarationWithType *> ¶mList = function->get_parameters(); 165 165 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) { 166 if ( isPoly Val( (*arg)->get_type(), tyVars ) ) {166 if ( isPolyType( (*arg)->get_type(), tyVars ) ) { 167 167 name << "P"; 168 168 } else { 169 name << "M"; 169 name << "M"; 170 170 } 171 171 } // for … … 181 181 } 182 182 183 Pass1::Pass1() 184 : useRetval( false ), tempNamer( "_temp" ) { 183 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) { 185 184 adapters.push(AdapterMap()); 186 185 } … … 194 193 if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) { 195 194 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) { 196 name = typeInst->get_name(); 197 return true; 195 if ( TypeInstType *typeInst2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) { 196 if ( typeInst->get_name() == typeInst2->get_name() ) { 197 name = typeInst->get_name(); 198 return true; 199 } // if 200 } // if 198 201 } // if 199 202 } // if … … 231 234 if ( isPolyRet( functionDecl->get_functionType(), typeName ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) { 232 235 retval = functionDecl->get_functionType()->get_returnVals().front(); 233 236 234 237 // give names to unnamed return values 235 238 if ( retval->get_name() == "" ) { … … 238 241 } // if 239 242 } // if 240 243 241 244 FunctionType *functionType = functionDecl->get_functionType(); 242 245 makeTyVarMap( functionDecl->get_functionType(), scopeTyVars ); … … 263 266 264 267 functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) ); 265 268 266 269 scopeTyVars = oldtyVars; 267 270 assignOps = oldassignOps; … … 279 282 280 283 TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) { 281 /// std::cerr << "add " << typeDecl->get_name() << "\n";282 284 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); 283 285 return Mutator::mutate( typeDecl ); … … 305 307 306 308 void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 309 // pass size/align for type variables 307 310 for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) { 308 311 ResolvExpr::EqvClass eqvClass; … … 313 316 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) ); 314 317 arg++; 318 arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) ); 319 arg++; 315 320 } else { 316 321 throw SemanticError( "unbound type variable in application ", appExpr ); … … 318 323 } // if 319 324 } // for 325 326 // add size/align for generic types to parameter list 327 //assert( ! appExpr->get_function()->get_results().empty() ); 328 if ( appExpr->get_function()->get_results().empty() ) return; 329 FunctionType *funcType = getFunctionType( appExpr->get_function()->get_results().front() ); 330 assert( funcType ); 331 332 std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); 333 std::list< Expression* >::const_iterator fnArg = arg; 334 std::set< std::string > seenTypes; //< names for generic types we've seen 335 for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) { 336 Type *parmType = (*fnParm)->get_type(); 337 if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, exprTyVars ) ) { 338 std::string sizeName = sizeofName( parmType ); 339 if ( seenTypes.count( sizeName ) ) continue; 340 341 assert( ! (*fnArg)->get_results().empty() ); 342 Type *argType = (*fnArg)->get_results().front(); 343 arg = appExpr->get_args().insert( arg, new SizeofExpr( argType->clone() ) ); 344 arg++; 345 arg = appExpr->get_args().insert( arg, new AlignofExpr( argType->clone() ) ); 346 arg++; 347 348 seenTypes.insert( sizeName ); 349 } 350 } 320 351 } 321 352 … … 326 357 } 327 358 328 TypeInstType *isPolyType( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) {329 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) {330 if ( env ) {331 if ( Type *newType = env->lookup( typeInst->get_name() ) ) {332 return isPolyType( newType, env, tyVars );333 } // if334 } // if335 if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {336 return typeInst;337 } else {338 return 0;339 } // if340 } else {341 return 0;342 } // if343 }344 345 359 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) { 346 if ( useRetval ) { 347 assert( retval ); 348 arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) ); 349 arg++; 350 } else { 351 ObjectDecl *newObj = makeTemporary( retType->clone() ); 352 Expression *paramExpr = new VariableExpr( newObj ); 353 if ( ! isPolyType( newObj->get_type(), env, scopeTyVars ) ) { 354 paramExpr = new AddressExpr( paramExpr ); 355 } // if 356 arg = appExpr->get_args().insert( arg, paramExpr ); 357 arg++; 358 /// stmtsToAdd.push_back( new ExprStmt( noLabels, appExpr ) ); 359 CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) ); 360 commaExpr->set_env( appExpr->get_env() ); 361 appExpr->set_env( 0 ); 362 return commaExpr; 363 } // if 364 return appExpr; 360 // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous. 361 // if ( useRetval ) { 362 // assert( retval ); 363 // arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) ); 364 // arg++; 365 // } else { 366 367 // Create temporary to hold return value of polymorphic function and produce that temporary as a result 368 // using a comma expression. Possibly change comma expression into statement expression "{}" for multiple 369 // return values. 370 ObjectDecl *newObj = makeTemporary( retType->clone() ); 371 Expression *paramExpr = new VariableExpr( newObj ); 372 // If the type of the temporary is not polymorphic, box temporary by taking its address; otherwise the 373 // temporary is already boxed and can be used directly. 374 if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) { 375 paramExpr = new AddressExpr( paramExpr ); 376 } // if 377 arg = appExpr->get_args().insert( arg, paramExpr ); // add argument to function call 378 arg++; 379 // Build a comma expression to call the function and emulate a normal return. 380 CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) ); 381 commaExpr->set_env( appExpr->get_env() ); 382 appExpr->set_env( 0 ); 383 return commaExpr; 384 // } // if 385 // return appExpr; 365 386 } 366 387 … … 377 398 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) { 378 399 Expression *ret = appExpr; 379 if ( ! function->get_returnVals().empty() && isPoly Val( function->get_returnVals().front()->get_type(), tyVars ) ) {400 if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) { 380 401 ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg ); 381 402 } // if … … 385 406 appExpr->get_args().push_front( appExpr->get_function() ); 386 407 appExpr->set_function( new NameExpr( adapterName ) ); 387 408 388 409 return ret; 389 410 } … … 391 412 void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) { 392 413 assert( ! arg->get_results().empty() ); 393 // /if ( ! dynamic_cast< PointerType *>( arg->get_results().front() ) ) {414 // if ( ! dynamic_cast< PointerType *>( arg->get_results().front() ) ) { 394 415 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( param ); 395 416 if ( typeInst && exprTyVars.find( typeInst->get_name() ) != exprTyVars.end() ) { … … 411 432 } // if 412 433 } // if 413 // /}434 // } 414 435 } 415 436 … … 428 449 429 450 void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 430 /// std::cout << "function is ";431 /// function->print( std::cout );432 451 for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) { 433 /// std::cout << "parameter is ";434 /// (*param)->print( std::fcout );435 /// std::cout << std::endl << "argument is ";436 /// (*arg)->print( std::cout );437 452 assert( arg != appExpr->get_args().end() ); 438 453 addCast( *arg, (*param)->get_type(), exprTyVars ); … … 469 484 // actually make the adapter type 470 485 FunctionType *adapter = adaptee->clone(); 471 if ( ! adapter->get_returnVals().empty() && isPoly Val( adapter->get_returnVals().front()->get_type(), tyVars ) ) {486 if ( ! adapter->get_returnVals().empty() && isPolyType( adapter->get_returnVals().front()->get_type(), tyVars ) ) { 472 487 makeRetParm( adapter ); 473 488 } // if … … 479 494 assert( param ); 480 495 assert( arg ); 481 /// std::cout << "arg type is "; 482 /// arg->get_type()->print( std::cout ); 483 /// std::cout << "param type is "; 484 /// param->get_type()->print( std::cout ); 485 /// std::cout << " tyVars are: "; 486 /// printTyVarMap( std::cout, tyVars ); 487 if ( isPolyVal( realParam->get_type(), tyVars ) ) { 488 /// if ( dynamic_cast< PointerType *>( arg->get_type() ) ) { 489 /// return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() ); 490 /// } else { 496 if ( isPolyType( realParam->get_type(), tyVars ) ) { 497 // if ( dynamic_cast< PointerType *>( arg->get_type() ) ) { 498 // return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() ); 499 // } else { 491 500 if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) { 492 501 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); … … 495 504 return deref; 496 505 } // if 497 // /}506 // } 498 507 } // if 499 508 return new VariableExpr( param ); … … 520 529 ApplicationExpr *adapteeApp = new ApplicationExpr( new CastExpr( new VariableExpr( adapteeDecl ), new PointerType( Type::Qualifiers(), realType ) ) ); 521 530 Statement *bodyStmt; 522 531 523 532 std::list< TypeDecl *>::iterator tyArg = realType->get_forall().begin(); 524 533 std::list< TypeDecl *>::iterator tyParam = adapterType->get_forall().begin(); … … 534 543 } // for 535 544 } // for 536 545 537 546 std::list< DeclarationWithType *>::iterator arg = realType->get_parameters().begin(); 538 547 std::list< DeclarationWithType *>::iterator param = adapterType->get_parameters().begin(); … … 542 551 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars ); 543 552 bodyStmt = new ExprStmt( noLabels, adapteeApp ); 544 } else if ( isPoly Val( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {553 } else if ( isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) { 545 554 if ( (*param)->get_name() == "" ) { 546 555 (*param)->set_name( "_ret" ); … … 591 600 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) { 592 601 adaptersDone.insert( adaptersDone.begin(), mangleName ); 593 602 594 603 // apply substitution to type variables to figure out what the adapter's type should look like 595 604 assert( env ); 596 605 env->apply( realFunction ); 597 mangleName = SymTab::Mangler::mangle( realFunction ); 606 mangleName = SymTab::Mangler::mangle( realFunction ); 598 607 mangleName += makePolyMonoSuffix( originalFunction, exprTyVars ); 599 608 … … 614 623 } // passAdapters 615 624 616 TypeInstType *isPolyPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) { 617 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) { 618 return isPolyType( ptr->get_base(), env, tyVars ); 619 } else if ( env ) { 620 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) { 621 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 622 return isPolyPtr( newType, env, tyVars ); 623 } // if 624 } // if 625 } // if 626 return 0; 627 } 628 629 TypeInstType *isPolyPtrPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) { 630 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) { 631 return isPolyPtr( ptr->get_base(), env, tyVars ); 632 } else if ( env ) { 633 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) { 634 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 635 return isPolyPtrPtr( newType, env, tyVars ); 636 } // if 637 } // if 638 } // if 639 return 0; 640 } 641 642 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, std::string polyName, bool isIncr ) { 625 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) { 643 626 NameExpr *opExpr; 644 627 if ( isIncr ) { … … 653 636 addAssign->get_args().push_back( appExpr->get_args().front() ); 654 637 } // if 655 addAssign->get_args().push_back( new NameExpr( polyName) );638 addAssign->get_args().push_back( new NameExpr( sizeofName( polyType ) ) ); 656 639 addAssign->get_results().front() = appExpr->get_results().front()->clone(); 657 640 if ( appExpr->get_env() ) { … … 670 653 assert( ! appExpr->get_results().empty() ); 671 654 assert( appExpr->get_args().size() == 2 ); 672 Type InstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars);673 Type InstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars);674 assert( ! typeInst1 || ! typeInst2 );// the arguments cannot both be polymorphic pointers655 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env ); 656 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env ); 657 assert( ! baseType1 || ! baseType2 ); // the arguments cannot both be polymorphic pointers 675 658 UntypedExpr *ret = 0; 676 if ( typeInst1 || typeInst2 ) { // one of the arguments is a polymorphic pointer659 if ( baseType1 || baseType2 ) { // one of the arguments is a polymorphic pointer 677 660 ret = new UntypedExpr( new NameExpr( "?+?" ) ); 678 661 } // if 679 if ( typeInst1 ) {662 if ( baseType1 ) { 680 663 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 681 664 multiply->get_args().push_back( appExpr->get_args().back() ); 682 multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );665 multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) ); 683 666 ret->get_args().push_back( appExpr->get_args().front() ); 684 667 ret->get_args().push_back( multiply ); 685 } else if ( typeInst2 ) {668 } else if ( baseType2 ) { 686 669 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 687 670 multiply->get_args().push_back( appExpr->get_args().front() ); 688 multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );671 multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) ); 689 672 ret->get_args().push_back( multiply ); 690 673 ret->get_args().push_back( appExpr->get_args().back() ); 691 674 } // if 692 if ( typeInst1 || typeInst2 ) {675 if ( baseType1 || baseType2 ) { 693 676 ret->get_results().push_front( appExpr->get_results().front()->clone() ); 694 677 if ( appExpr->get_env() ) { … … 703 686 assert( ! appExpr->get_results().empty() ); 704 687 assert( ! appExpr->get_args().empty() ); 705 if ( isPolyType( appExpr->get_results().front(), env, scopeTyVars) ) {688 if ( isPolyType( appExpr->get_results().front(), scopeTyVars, env ) ) { 706 689 Expression *ret = appExpr->get_args().front(); 707 690 delete ret->get_results().front(); … … 718 701 assert( ! appExpr->get_results().empty() ); 719 702 assert( appExpr->get_args().size() == 1 ); 720 if ( Type InstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars) ) {703 if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) { 721 704 Type *tempType = appExpr->get_results().front()->clone(); 722 705 if ( env ) { … … 732 715 assignExpr->get_args().push_back( appExpr->get_args().front()->clone() ); 733 716 } // if 734 CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "?++" ) );717 CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, baseType, varExpr->get_var()->get_name() == "?++" ) ); 735 718 return new CommaExpr( firstComma, tempExpr ); 736 719 } // if … … 738 721 assert( ! appExpr->get_results().empty() ); 739 722 assert( appExpr->get_args().size() == 1 ); 740 if ( Type InstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars) ) {741 return makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "++?" );723 if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) { 724 return makeIncrDecrExpr( appExpr, baseType, varExpr->get_var()->get_name() == "++?" ); 742 725 } // if 743 726 } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) { 744 727 assert( ! appExpr->get_results().empty() ); 745 728 assert( appExpr->get_args().size() == 2 ); 746 Type InstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars);747 Type InstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars);748 if ( typeInst1 && typeInst2 ) {729 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env ); 730 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env ); 731 if ( baseType1 && baseType2 ) { 749 732 UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) ); 750 733 divide->get_args().push_back( appExpr ); 751 divide->get_args().push_back( new NameExpr( typeInst1->get_name() ) );734 divide->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) ); 752 735 divide->get_results().push_front( appExpr->get_results().front()->clone() ); 753 736 if ( appExpr->get_env() ) { … … 756 739 } // if 757 740 return divide; 758 } else if ( typeInst1 ) {741 } else if ( baseType1 ) { 759 742 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 760 743 multiply->get_args().push_back( appExpr->get_args().back() ); 761 multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );744 multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) ); 762 745 appExpr->get_args().back() = multiply; 763 } else if ( typeInst2 ) {746 } else if ( baseType2 ) { 764 747 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 765 748 multiply->get_args().push_back( appExpr->get_args().front() ); 766 multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );749 multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) ); 767 750 appExpr->get_args().front() = multiply; 768 751 } // if … … 770 753 assert( ! appExpr->get_results().empty() ); 771 754 assert( appExpr->get_args().size() == 2 ); 772 Type InstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars);773 if ( typeInst) {755 Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ); 756 if ( baseType ) { 774 757 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 775 758 multiply->get_args().push_back( appExpr->get_args().back() ); 776 multiply->get_args().push_back( new NameExpr( typeInst->get_name() ) );759 multiply->get_args().push_back( new NameExpr( sizeofName( baseType ) ) ); 777 760 appExpr->get_args().back() = multiply; 778 761 } // if … … 795 778 mutateAll( appExpr->get_args(), *this ); 796 779 useRetval = oldUseRetval; 797 780 798 781 assert( ! appExpr->get_function()->get_results().empty() ); 799 782 PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() ); … … 801 784 FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() ); 802 785 assert( function ); 803 786 804 787 if ( Expression *newExpr = handleIntrinsics( appExpr ) ) { 805 788 return newExpr; 806 789 } // if 807 790 808 791 Expression *ret = appExpr; 809 792 810 793 std::list< Expression *>::iterator arg = appExpr->get_args().begin(); 811 794 std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin(); 812 795 813 796 std::string typeName; 814 797 if ( isPolyRet( function, typeName ) ) { … … 824 807 } // if 825 808 arg = appExpr->get_args().begin(); 826 809 827 810 TyVarMap exprTyVars; 828 811 makeTyVarMap( function, exprTyVars ); 829 812 830 813 passTypeVars( appExpr, arg, exprTyVars ); 831 814 addInferredParams( appExpr, function, arg, exprTyVars ); 832 815 833 816 arg = paramBegin; 834 817 835 818 boxParams( appExpr, function, arg, exprTyVars ); 836 819 … … 841 824 842 825 Expression *Pass1::mutate( UntypedExpr *expr ) { 843 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), env, scopeTyVars) ) {826 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) { 844 827 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) { 845 828 if ( name->get_name() == "*?" ) { … … 856 839 Expression *Pass1::mutate( AddressExpr *addrExpr ) { 857 840 assert( ! addrExpr->get_arg()->get_results().empty() ); 841 842 bool needs = false; 843 if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) { 844 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) { 845 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) { 846 if ( name->get_name() == "*?" ) { 847 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) { 848 assert( ! appExpr->get_function()->get_results().empty() ); 849 PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() ); 850 assert( pointer ); 851 FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() ); 852 assert( function ); 853 needs = needsAdapter( function, scopeTyVars ); 854 } // if 855 } // if 856 } // if 857 } // if 858 } // if 858 859 addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) ); 859 if ( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars )) {860 if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) || needs ) { 860 861 Expression *ret = addrExpr->get_arg(); 861 862 delete ret->get_results().front(); … … 869 870 } 870 871 871 Statement * Pass1::mutate(ReturnStmt *retStmt) { 872 // by this point, a cast expr on a polymorphic return value is redundant 873 while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( retStmt->get_expr() ) ) { 874 retStmt->set_expr( castExpr->get_arg() ); 875 retStmt->get_expr()->set_env( castExpr->get_env() ); 876 castExpr->set_env( 0 ); 877 castExpr->set_arg( 0 ); 878 delete castExpr; 879 } 880 if ( retval && retStmt->get_expr() ) { 881 assert( ! retStmt->get_expr()->get_results().empty() ); 882 if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) { 883 /// retStmt->set_expr( mutateExpression( retStmt->get_expr() ) ); 884 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ); 885 assert( typeInst ); 886 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 887 if ( assignIter == assignOps.end() ) { 888 throw SemanticError( "Attempt to return dtype or ftype object in ", retStmt->get_expr() ); 889 } // if 890 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) ); 891 Expression *retParm = new NameExpr( retval->get_name() ); 892 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); 893 assignExpr->get_args().push_back( retParm ); 894 assignExpr->get_args().push_back( retStmt->get_expr() ); 895 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) ); 896 } else { 897 useRetval = true; 898 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( retStmt->get_expr() ) ) ); 899 useRetval = false; 872 Statement * Pass1::mutate( ReturnStmt *returnStmt ) { 873 if ( retval && returnStmt->get_expr() ) { 874 assert( ! returnStmt->get_expr()->get_results().empty() ); 875 // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous. 876 // if ( returnStmt->get_expr()->get_results().front()->get_isLvalue() ) { 877 // by this point, a cast expr on a polymorphic return value is redundant 878 while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( returnStmt->get_expr() ) ) { 879 returnStmt->set_expr( castExpr->get_arg() ); 880 returnStmt->get_expr()->set_env( castExpr->get_env() ); 881 castExpr->set_env( 0 ); 882 castExpr->set_arg( 0 ); 883 delete castExpr; 884 } //while 885 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ); 886 assert( typeInst ); 887 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 888 if ( assignIter == assignOps.end() ) { 889 throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() ); 900 890 } // if 901 retStmt->set_expr( 0 ); 891 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) ); 892 Expression *retParm = new NameExpr( retval->get_name() ); 893 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); 894 assignExpr->get_args().push_back( retParm ); 895 assignExpr->get_args().push_back( returnStmt->get_expr() ); 896 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) ); 897 // } else { 898 // useRetval = true; 899 // stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( returnStmt->get_expr() ) ) ); 900 // useRetval = false; 901 // } // if 902 returnStmt->set_expr( 0 ); 902 903 } else { 903 ret Stmt->set_expr( mutateExpression( retStmt->get_expr() ) );904 } // if 905 return ret Stmt;904 returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) ); 905 } // if 906 return returnStmt; 906 907 } 907 908 … … 909 910 TyVarMap oldtyVars = scopeTyVars; 910 911 makeTyVarMap( pointerType, scopeTyVars ); 911 912 912 913 Type *ret = Mutator::mutate( pointerType ); 913 914 914 915 scopeTyVars = oldtyVars; 915 916 return ret; … … 919 920 TyVarMap oldtyVars = scopeTyVars; 920 921 makeTyVarMap( functionType, scopeTyVars ); 921 922 922 923 Type *ret = Mutator::mutate( functionType ); 923 924 924 925 scopeTyVars = oldtyVars; 925 926 return ret; … … 936 937 937 938 ////////////////////////////////////////// Pass2 //////////////////////////////////////////////////// 938 939 Pass2::Pass2() {}940 939 941 940 void Pass2::addAdapters( FunctionType *functionType ) { … … 956 955 } 957 956 } 958 // /deleteAll( functions );957 // deleteAll( functions ); 959 958 } 960 959 … … 990 989 TyVarMap oldtyVars = scopeTyVars; 991 990 makeTyVarMap( pointerType, scopeTyVars ); 992 991 993 992 Type *ret = Mutator::mutate( pointerType ); 994 993 995 994 scopeTyVars = oldtyVars; 996 995 return ret; … … 1000 999 TyVarMap oldtyVars = scopeTyVars; 1001 1000 makeTyVarMap( funcType, scopeTyVars ); 1002 1001 1002 // move polymorphic return type to parameter list 1003 1003 std::string typeName; 1004 1004 if ( isPolyRet( funcType, typeName ) ) { … … 1008 1008 funcType->get_returnVals().pop_front(); 1009 1009 } 1010 1010 1011 // add size/align and assertions for type parameters to parameter list 1011 1012 std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin(); 1012 1013 std::list< DeclarationWithType *> inferredParams; 1013 ObjectDecl *newObj = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );1014 ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 ); 1014 1015 // ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 ); 1015 1016 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { 1016 ObjectDecl * thisParm;1017 // add all size parameters to parameter list1017 ObjectDecl *sizeParm, *alignParm; 1018 // add all size and alignment parameters to parameter list 1018 1019 if ( (*tyParm)->get_kind() == TypeDecl::Any ) { 1019 thisParm = newObj->clone(); 1020 thisParm->set_name( (*tyParm)->get_name() ); 1021 last = funcType->get_parameters().insert( last, thisParm ); 1020 TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm ); 1021 1022 sizeParm = newObj.clone(); 1023 sizeParm->set_name( sizeofName( &parmType ) ); 1024 last = funcType->get_parameters().insert( last, sizeParm ); 1025 ++last; 1026 1027 alignParm = newObj.clone(); 1028 alignParm->set_name( alignofName( &parmType ) ); 1029 last = funcType->get_parameters().insert( last, alignParm ); 1022 1030 ++last; 1023 1031 } … … 1029 1037 (*tyParm)->get_assertions().clear(); 1030 1038 } 1031 delete newObj; 1039 1040 // add size/align for generic types to parameter list 1041 std::set< std::string > seenTypes; //< sizeofName for generic types we've seen 1042 for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) { 1043 Type *parmType = (*fnParm)->get_type(); 1044 if ( ! dynamic_cast< TypeInstType* >( parmType ) && isPolyType( parmType, scopeTyVars ) ) { 1045 std::string sizeName = sizeofName( parmType ); 1046 if ( seenTypes.count( sizeName ) ) continue; 1047 1048 ObjectDecl *sizeParm, *alignParm; 1049 sizeParm = newObj.clone(); 1050 sizeParm->set_name( sizeName ); 1051 last = funcType->get_parameters().insert( last, sizeParm ); 1052 ++last; 1053 1054 alignParm = newObj.clone(); 1055 alignParm->set_name( alignofName( parmType ) ); 1056 last = funcType->get_parameters().insert( last, alignParm ); 1057 ++last; 1058 1059 seenTypes.insert( sizeName ); 1060 } 1061 } 1062 1063 // splice assertion parameters into parameter list 1032 1064 funcType->get_parameters().splice( last, inferredParams ); 1033 1065 addAdapters( funcType ); 1034 1066 mutateAll( funcType->get_returnVals(), *this ); 1035 1067 mutateAll( funcType->get_parameters(), *this ); 1036 1068 1037 1069 scopeTyVars = oldtyVars; 1038 1070 return funcType; … … 1045 1077 TyVarMap oldtyVars = scopeTyVars; 1046 1078 makeTyVarMap( type, scopeTyVars ); 1047 1079 1048 1080 DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) ); 1049 1081 ScrubTyVars::scrub( decl, scopeTyVars ); … … 1081 1113 TyVarMap oldtyVars = scopeTyVars; 1082 1114 makeTyVarMap( pointerType, scopeTyVars ); 1083 1115 1084 1116 Type *ret = Mutator::mutate( pointerType ); 1085 1117 1086 1118 scopeTyVars = oldtyVars; 1087 1119 return ret; … … 1091 1123 TyVarMap oldtyVars = scopeTyVars; 1092 1124 makeTyVarMap( functionType, scopeTyVars ); 1093 1125 1094 1126 Type *ret = Mutator::mutate( functionType ); 1095 1127 1096 1128 scopeTyVars = oldtyVars; 1097 1129 return ret; … … 1100 1132 Statement *Pass3::mutate( DeclStmt *declStmt ) { 1101 1133 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) { 1102 if ( isPoly Val( objectDecl->get_type(), scopeTyVars ) ) {1134 if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) { 1103 1135 // change initialization of a polymorphic value object 1104 1136 // to allocate storage with alloca 1105 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( objectDecl->get_type() ); 1106 assert( typeInst ); 1137 Type *declType = objectDecl->get_type(); 1107 1138 UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) ); 1108 alloc->get_args().push_back( new NameExpr( typeInst->get_name() ) );1139 alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) ); 1109 1140 1110 1141 delete objectDecl->get_init(); -
src/GenPoly/GenPoly.cc
rbaf7fee rae63a18 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 : Tue Nov 24 15:23:08 201513 // Update Count : 1 111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Dec 15 16:11:18 2015 13 // Update Count : 13 14 14 // 15 15 16 16 #include "GenPoly.h" 17 18 #include "SymTab/Mangler.h" 19 #include "SynTree/Expression.h" 17 20 #include "SynTree/Type.h" 18 21 … … 21 24 22 25 namespace GenPoly { 23 /// A function needs an adapter if it returns a polymorphic value or if any of its24 /// parameters have polymorphic type25 26 bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) { 26 if ( ! adaptee->get_returnVals().empty() && isPoly Val( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {27 if ( ! adaptee->get_returnVals().empty() && isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) { 27 28 return true; 28 29 } // if 29 30 for ( std::list< DeclarationWithType* >::const_iterator innerArg = adaptee->get_parameters().begin(); innerArg != adaptee->get_parameters().end(); ++innerArg ) { 30 if ( isPoly Val( (*innerArg)->get_type(), tyVars ) ) {31 if ( isPolyType( (*innerArg)->get_type(), tyVars ) ) { 31 32 return true; 32 33 } // if … … 66 67 } 67 68 68 bool isPolyVal( Type *type, const TyVarMap &tyVars ) { 69 namespace { 70 /// Checks a parameter list for polymorphic parameters; will substitute according to env if present 71 bool hasPolyParams( std::list< Expression* >& params, const TypeSubstitution *env ) { 72 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) { 73 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 74 assert(paramType && "Aggregate parameters should be type expressions"); 75 if ( isPolyType( paramType->get_type(), env ) ) return true; 76 } 77 return false; 78 } 79 80 /// Checks a parameter list for polymorphic parameters from tyVars; will substitute according to env if present 81 bool hasPolyParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) { 82 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) { 83 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 84 assert(paramType && "Aggregate parameters should be type expressions"); 85 if ( isPolyType( paramType->get_type(), tyVars, env ) ) return true; 86 } 87 return false; 88 } 89 } 90 91 Type *isPolyType( Type *type, const TypeSubstitution *env ) { 69 92 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) { 93 if ( env ) { 94 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 95 return isPolyType( newType, env ); 96 } // if 97 } // if 98 return type; 99 } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) { 100 if ( hasPolyParams( structType->get_parameters(), env ) ) return type; 101 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) { 102 if ( hasPolyParams( unionType->get_parameters(), env ) ) return type; 103 } 104 return 0; 105 } 106 107 Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) { 108 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) { 109 if ( env ) { 110 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 111 return isPolyType( newType, tyVars, env ); 112 } // if 113 } // if 70 114 if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) { 71 return true; 115 return type; 116 } 117 } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) { 118 if ( hasPolyParams( structType->get_parameters(), tyVars, env ) ) return type; 119 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) { 120 if ( hasPolyParams( unionType->get_parameters(), tyVars, env ) ) return type; 121 } 122 return 0; 123 } 124 125 Type *isPolyPtr( Type *type, const TypeSubstitution *env ) { 126 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) { 127 return isPolyType( ptr->get_base(), env ); 128 } else if ( env ) { 129 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) { 130 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 131 return isPolyPtr( newType, env ); 132 } // if 72 133 } // if 73 134 } // if 74 return false; 135 return 0; 136 } 137 138 Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) { 139 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) { 140 return isPolyType( ptr->get_base(), tyVars, env ); 141 } else if ( env ) { 142 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) { 143 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 144 return isPolyPtr( newType, tyVars, env ); 145 } // if 146 } // if 147 } // if 148 return 0; 75 149 } 76 150 77 bool isPolyObj( Type *type, const TyVarMap &tyVars ) { 78 if ( isPolyVal( type, tyVars ) ) { 79 return true; 80 } else if ( PointerType *pt = dynamic_cast<PointerType*>( type ) ) { 81 return isPolyObj( pt->get_base(), tyVars ); 151 FunctionType * getFunctionType( Type *ty ) { 152 PointerType *ptrType; 153 if ( ( ptrType = dynamic_cast< PointerType* >( ty ) ) ) { 154 return dynamic_cast< FunctionType* >( ptrType->get_base() ); // pointer if FunctionType, NULL otherwise 82 155 } else { 83 return false;156 return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise 84 157 } 85 158 } … … 91 164 os << std::endl; 92 165 } 166 167 std::string sizeofName( Type *ty ) { 168 return std::string( "_sizeof_" ) + SymTab::Mangler::mangleType( ty ); 169 } 170 171 std::string alignofName( Type *ty ) { 172 return std::string( "_alignof_" ) + SymTab::Mangler::mangleType( ty ); 173 } 93 174 } // namespace GenPoly 94 175 -
src/GenPoly/GenPoly.h
rbaf7fee rae63a18 20 20 #include <string> 21 21 #include <iostream> 22 22 23 #include "SynTree/Declaration.h" 24 #include "SynTree/TypeSubstitution.h" 23 25 24 26 namespace GenPoly { 25 27 typedef std::map< std::string, TypeDecl::Kind > TyVarMap; 26 28 29 /// A function needs an adapter if it returns a polymorphic value or if any of its 30 /// parameters have polymorphic type 27 31 bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVarr ); 32 33 /// true iff function has polymorphic return type 28 34 bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars ); 29 35 bool isPolyRet( FunctionType *function, std::string &name ); 30 36 bool isPolyRet( FunctionType *function, const TyVarMap &otherTyVars ); 31 // bool isPolyFun( FunctionType *fun, const TyVarMap &tyVars );32 bool isPolyVal( Type *type, const TyVarMap &tyVars );33 37 34 // true if type variable or any number of pointers to type variable 35 bool isPolyObj( Type *type, const TyVarMap &tyVars ); 38 /// returns polymorphic type if is polymorphic type, NULL otherwise; will look up substitution in env if provided 39 Type *isPolyType( Type *type, const TypeSubstitution *env = 0 ); 40 41 /// returns polymorphic type if is polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided 42 Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 ); 43 44 /// returns polymorphic type if is pointer to polymorphic type, NULL otherwise; will look up substitution in env if provided 45 Type *isPolyPtr( Type *type, const TypeSubstitution *env = 0 ); 46 47 /// returns polymorphic type if is pointer to polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided 48 Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 ); 49 50 /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise 51 FunctionType * getFunctionType( Type *ty ); 52 53 /// Prints type variable map 36 54 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ); 55 56 /// Gets the name of the sizeof parameter for the type 57 std::string sizeofName( Type *ty ); 58 59 /// Gets the name of the alignof parameter for the type 60 std::string alignofName( Type *ty ); 37 61 } // namespace GenPoly 38 62 -
src/GenPoly/InstantiateGeneric.cc
rbaf7fee rae63a18 77 77 std::list< Type* > params; ///< Instantiation parameters 78 78 }; 79 79 80 80 /// Maps a concrete type to the instantiated struct type, accounting for scope 81 81 class InstantiationMap { … … 143 143 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately 144 144 class Instantiate : public DeclMutator { 145 /// Map of (generic type, parameter list) pairs to concrete type instantiations 145 146 InstantiationMap instantiations; 147 /// Namer for concrete types 146 148 UniqueName typeNamer; 147 149 … … 149 151 Instantiate() : DeclMutator(), instantiations(), typeNamer("_conc_") {} 150 152 151 // virtual Declaration* mutate( StructDecl *aggregateDecl );152 // virtual Declaration* mutate( UnionDecl *aggregateDecl );153 154 153 virtual Type* mutate( StructInstType *inst ); 155 154 virtual Type* mutate( UnionInstType *inst ); 155 156 // virtual Expression* mutate( MemberExpr *memberExpr ); 156 157 157 158 virtual void doBeginScope(); … … 166 167 /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type 167 168 bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) { 168 bool allConcrete = true; // will finish the substitution list even if they're not all concrete169 bool allConcrete = true; // will finish the substitution list even if they're not all concrete 169 170 170 171 // substitute concrete types for given parameters, and incomplete types for placeholders … … 172 173 std::list< Expression* >::const_iterator param = params.begin(); 173 174 for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) { 174 switch ( (*baseParam)->get_kind() ) {175 case TypeDecl::Any: { // any type is a valid substitution here; complete types can be used to instantiate generics175 // switch ( (*baseParam)->get_kind() ) { 176 // case TypeDecl::Any: { // any type is a valid substitution here; complete types can be used to instantiate generics 176 177 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 177 178 assert(paramType && "Aggregate parameters should be type expressions"); … … 179 180 // check that the substituted type isn't a type variable itself 180 181 if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) { 181 allConcrete = false;182 allConcrete = false; 182 183 } 183 break; 184 } 185 case TypeDecl::Dtype: // dtype can be consistently replaced with void [only pointers, which become void*] 186 out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) ); 187 break; 188 case TypeDecl::Ftype: // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype] 189 out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) ); 190 break; 191 } 192 } 193 194 // if not enough parameters given, substitute remaining incomplete types for placeholders 195 for ( ; baseParam != baseParams.end(); ++baseParam ) { 196 switch ( (*baseParam)->get_kind() ) { 197 case TypeDecl::Any: // no more substitutions here, fail early 198 return false; 199 case TypeDecl::Dtype: // dtype can be consistently replaced with void [only pointers, which become void*] 200 out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) ); 201 break; 202 case TypeDecl::Ftype: // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype] 203 out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) ); 204 break; 205 } 206 } 207 208 return allConcrete; 209 } 210 184 // break; 185 // } 186 // case TypeDecl::Dtype: // dtype can be consistently replaced with void [only pointers, which become void*] 187 // out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) ); 188 // break; 189 // case TypeDecl::Ftype: // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype] 190 // out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) ); 191 // break; 192 // } 193 } 194 195 // if any parameters left over, not done 196 if ( baseParam != baseParams.end() ) return false; 197 // // if not enough parameters given, substitute remaining incomplete types for placeholders 198 // for ( ; baseParam != baseParams.end(); ++baseParam ) { 199 // switch ( (*baseParam)->get_kind() ) { 200 // case TypeDecl::Any: // no more substitutions here, fail early 201 // return false; 202 // case TypeDecl::Dtype: // dtype can be consistently replaced with void [only pointers, which become void*] 203 // out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) ); 204 // break; 205 // case TypeDecl::Ftype: // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype] 206 // out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) ); 207 // break; 208 // } 209 // } 210 211 return allConcrete; 212 } 213 211 214 /// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out 212 215 void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs, … … 288 291 return newInst; 289 292 } 293 294 // /// Gets the base struct or union declaration for a member expression; NULL if not applicable 295 // AggregateDecl* getMemberBaseDecl( MemberExpr *memberExpr ) { 296 // // get variable for member aggregate 297 // VariableExpr *varExpr = dynamic_cast< VariableExpr* >( memberExpr->get_aggregate() ); 298 // if ( ! varExpr ) return NULL; 299 // 300 // // get object for variable 301 // ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() ); 302 // if ( ! objectDecl ) return NULL; 303 // 304 // // get base declaration from object type 305 // Type *objectType = objectDecl->get_type(); 306 // StructInstType *structType = dynamic_cast< StructInstType* >( objectType ); 307 // if ( structType ) return structType->get_baseStruct(); 308 // UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ); 309 // if ( unionType ) return unionType->get_baseUnion(); 310 // 311 // return NULL; 312 // } 313 // 314 // /// Finds the declaration with the given name, returning decls.end() if none such 315 // std::list< Declaration* >::const_iterator findDeclNamed( const std::list< Declaration* > &decls, const std::string &name ) { 316 // for( std::list< Declaration* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) { 317 // if ( (*decl)->get_name() == name ) return decl; 318 // } 319 // return decls.end(); 320 // } 321 // 322 // Expression* Instantiate::mutate( MemberExpr *memberExpr ) { 323 // // mutate, exiting early if no longer MemberExpr 324 // Expression *expr = Mutator::mutate( memberExpr ); 325 // memberExpr = dynamic_cast< MemberExpr* >( expr ); 326 // if ( ! memberExpr ) return expr; 327 // 328 // // get declaration of member and base declaration of member, exiting early if not found 329 // AggregateDecl *memberBase = getMemberBaseDecl( memberExpr ); 330 // if ( ! memberBase ) return memberExpr; 331 // DeclarationWithType *memberDecl = memberExpr->get_member(); 332 // std::list< Declaration* >::const_iterator baseIt = findDeclNamed( memberBase->get_members(), memberDecl->get_name() ); 333 // if ( baseIt == memberBase->get_members().end() ) return memberExpr; 334 // DeclarationWithType *baseDecl = dynamic_cast< DeclarationWithType* >( *baseIt ); 335 // if ( ! baseDecl ) return memberExpr; 336 // 337 // // check if stated type of the member is not the type of the member's declaration; if so, need a cast 338 // // this *SHOULD* be safe, I don't think anything but the void-replacements I put in for dtypes would make it past the typechecker 339 // SymTab::Indexer dummy; 340 // if ( ResolvExpr::typesCompatible( memberDecl->get_type(), baseDecl->get_type(), dummy ) ) return memberExpr; 341 // else return new CastExpr( memberExpr, memberDecl->get_type() ); 342 // } 290 343 291 344 void Instantiate::doBeginScope() { 292 345 DeclMutator::doBeginScope(); 293 // push a new concrete type scope294 346 instantiations.beginScope(); 295 347 } … … 297 349 void Instantiate::doEndScope() { 298 350 DeclMutator::doEndScope(); 299 // pop the last concrete type scope300 351 instantiations.endScope(); 301 352 } -
src/GenPoly/Lvalue.cc
rbaf7fee rae63a18 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 19 07:41:33 201513 // Update Count : 112 // Last Modified On : Tue Dec 15 15:33:13 2015 13 // Update Count : 3 14 14 // 15 15 … … 122 122 if ( retval && retStmt->get_expr() ) { 123 123 assert( ! retStmt->get_expr()->get_results().empty() ); 124 while ( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) {125 retStmt->set_expr( castExpr->get_arg() );126 retStmt->get_expr()->set_env( castExpr->get_env() );127 castExpr->set_env( 0 );128 castExpr->set_arg( 0 );129 delete castExpr;130 } // while131 124 if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) { 125 // ***** Code Removal ***** because casts may be stripped already 126 127 // strip casts because not allowed to take address of cast 128 // while ( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) { 129 // retStmt->set_expr( castExpr->get_arg() ); 130 // retStmt->get_expr()->set_env( castExpr->get_env() ); 131 // castExpr->set_env( 0 ); 132 // castExpr->set_arg( 0 ); 133 // delete castExpr; 134 // } // while 132 135 retStmt->set_expr( new AddressExpr( retStmt->get_expr()->acceptMutator( *this ) ) ); 133 136 } else { -
src/GenPoly/ScrubTyVars.cc
rbaf7fee rae63a18 13 13 // Update Count : 2 14 14 // 15 16 #include <sstream> 17 #include <string> 15 18 16 19 #include "GenPoly.h" … … 42 45 43 46 Expression * ScrubTyVars::mutate( SizeofExpr *szeof ) { 44 // sizeof( T ) => T parameter, which is the size of T45 if ( Type InstType *typeInst = dynamic_cast< TypeInstType * >( szeof->get_type() ) ) {46 Expression *expr = new NameExpr( typeInst->get_name() );47 // sizeof( T ) => _sizeof_T parameter, which is the size of T 48 if ( Type *polyType = isPolyType( szeof->get_type() ) ) { 49 Expression *expr = new NameExpr( sizeofName( polyType ) ); 47 50 return expr; 48 51 } else { 49 52 return Mutator::mutate( szeof ); 53 } // if 54 } 55 56 Expression * ScrubTyVars::mutate( AlignofExpr *algnof ) { 57 // alignof( T ) => _alignof_T parameter, which is the alignment of T 58 if ( Type *polyType = isPolyType( algnof->get_type() ) ) { 59 Expression *expr = new NameExpr( alignofName( polyType ) ); 60 return expr; 61 } else { 62 return Mutator::mutate( algnof ); 50 63 } // if 51 64 } -
src/GenPoly/ScrubTyVars.h
rbaf7fee rae63a18 16 16 #ifndef _SCRUBTYVARS_H 17 17 #define _SCRUBTYVARS_H 18 19 #include <string> 18 20 19 21 #include "GenPoly.h" … … 36 38 virtual Type* mutate( TypeInstType *typeInst ); 37 39 Expression* mutate( SizeofExpr *szeof ); 40 Expression* mutate( AlignofExpr *algnof ); 38 41 virtual Type* mutate( PointerType *pointer ); 39 42 private: -
src/GenPoly/Specialize.cc
rbaf7fee rae63a18 17 17 18 18 #include "Specialize.h" 19 #include "GenPoly.h" 19 20 #include "PolyMutator.h" 20 21 … … 87 88 } 88 89 89 /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise90 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 otherwise94 } else {95 return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise96 }97 }98 99 90 /// Generates a thunk that calls `actual` with type `funType` and returns its address 100 91 Expression * Specialize::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) {
Note: See TracChangeset
for help on using the changeset viewer.