Changes in src/GenPoly/Box.cc [cf16f94:ffad73a]
- File:
-
- 1 edited
-
src/GenPoly/Box.cc (modified) (35 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
rcf16f94 rffad73a 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 ue Dec 15 15:30:31201513 // Update Count : 21511 // Last Modified By : Rob Schluntz 12 // Last Modified On : Thu Nov 26 17:01:55 2015 13 // Update Count : 191 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" … … 50 51 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 51 52 53 /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call 52 54 class Pass1 : public PolyMutator { 53 55 public: 54 56 Pass1(); 55 virtual Expression * mutate( ApplicationExpr *appExpr );56 virtual Expression * mutate( AddressExpr *addrExpr );57 virtual Expression * mutate( UntypedExpr *expr );58 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );59 virtual TypeDecl * mutate( TypeDecl *typeDecl );60 virtual Expression * mutate( CommaExpr *commaExpr );61 virtual Expression * mutate( ConditionalExpr *condExpr );62 virtual Statement * mutate( ReturnStmt *returnStmt);63 virtual Type * mutate( PointerType *pointerType );64 virtual Type * mutate( FunctionType *functionType );57 virtual Expression *mutate( ApplicationExpr *appExpr ); 58 virtual Expression *mutate( AddressExpr *addrExpr ); 59 virtual Expression *mutate( UntypedExpr *expr ); 60 virtual DeclarationWithType* mutate( FunctionDecl *functionDecl ); 61 virtual TypeDecl *mutate( TypeDecl *typeDecl ); 62 virtual Expression *mutate( CommaExpr *commaExpr ); 63 virtual Expression *mutate( ConditionalExpr *condExpr ); 64 virtual Statement *mutate(ReturnStmt *catchStmt); 65 virtual Type *mutate( PointerType *pointerType ); 66 virtual Type *mutate( FunctionType *pointerType ); 65 67 66 68 virtual void doBeginScope(); … … 88 90 }; 89 91 92 /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well 90 93 class Pass2 : public PolyMutator { 91 94 public: 92 Pass2();93 95 template< typename DeclClass > 94 96 DeclClass *handleDecl( DeclClass *decl, Type *type ); … … 105 107 }; 106 108 109 /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, and sizeof expressions of polymorphic types with the proper variable 107 110 class Pass3 : public PolyMutator { 108 111 public: … … 152 155 // with the same mangled name, so we need to further mangle the names. 153 156 for ( std::list< DeclarationWithType *>::iterator retval = function->get_returnVals().begin(); retval != function->get_returnVals().end(); ++retval ) { 154 if ( isPoly Val( (*retval)->get_type(), tyVars ) ) {157 if ( isPolyType( (*retval)->get_type(), tyVars ) ) { 155 158 name << "P"; 156 159 } else { … … 161 164 std::list< DeclarationWithType *> ¶mList = function->get_parameters(); 162 165 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) { 163 if ( isPoly Val( (*arg)->get_type(), tyVars ) ) {166 if ( isPolyType( (*arg)->get_type(), tyVars ) ) { 164 167 name << "P"; 165 168 } else { … … 178 181 } 179 182 180 Pass1::Pass1() 181 : useRetval( false ), tempNamer( "_temp" ) { 183 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) { 182 184 adapters.push(AdapterMap()); 183 185 } … … 190 192 if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) { 191 193 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) { 192 if ( TypeInstType *typeInst2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) { 193 if ( typeInst->get_name() == typeInst2->get_name() ) { 194 name = typeInst->get_name(); 195 return true; 196 } // if 197 } // if 194 name = typeInst->get_name(); 195 return true; 198 196 } // if 199 197 } // if … … 313 311 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) ); 314 312 arg++; 313 arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) ); 314 arg++; 315 315 } else { 316 316 throw SemanticError( "unbound type variable in application ", appExpr ); … … 326 326 } 327 327 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 } // if 334 } // if 335 if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) { 336 return typeInst; 337 } else { 338 return 0; 339 } // if 328 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) { 329 if ( useRetval ) { 330 assert( retval ); 331 arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) ); 332 arg++; 340 333 } else { 341 return 0; 342 } // if 343 } 344 345 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ) { 346 // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous. 347 // if ( useRetval ) { 348 // assert( retval ); 349 // arg = appExpr->get_args().insert( arg, new VariableExpr( retval ) ); 350 // arg++; 351 // } else { 352 353 // Create temporary to hold return value of polymorphic function and produce that temporary as a result 354 // using a comma expression. Possibly change comma expression into statement expression "{}" for multiple 355 // return values. 356 ObjectDecl *newObj = makeTemporary( retType->clone() ); 357 Expression *paramExpr = new VariableExpr( newObj ); 358 // If the type of the temporary is not polymorphic, box temporary by taking its address; otherwise the 359 // temporary is already boxed and can be used directly. 360 if ( ! isPolyType( newObj->get_type(), env, scopeTyVars ) ) { 361 paramExpr = new AddressExpr( paramExpr ); 362 } // if 363 arg = appExpr->get_args().insert( arg, paramExpr ); // add argument to function call 364 arg++; 365 // Build a comma expression to call the function and emulate a normal return. 366 CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) ); 367 commaExpr->set_env( appExpr->get_env() ); 368 appExpr->set_env( 0 ); 369 return commaExpr; 370 // } // if 371 // return appExpr; 334 ObjectDecl *newObj = makeTemporary( retType->clone() ); 335 Expression *paramExpr = new VariableExpr( newObj ); 336 if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) { 337 paramExpr = new AddressExpr( paramExpr ); 338 } // if 339 arg = appExpr->get_args().insert( arg, paramExpr ); 340 arg++; 341 /// stmtsToAdd.push_back( new ExprStmt( noLabels, appExpr ) ); 342 CommaExpr *commaExpr = new CommaExpr( appExpr, new VariableExpr( newObj ) ); 343 commaExpr->set_env( appExpr->get_env() ); 344 appExpr->set_env( 0 ); 345 return commaExpr; 346 } // if 347 return appExpr; 372 348 } 373 349 … … 384 360 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) { 385 361 Expression *ret = appExpr; 386 if ( ! function->get_returnVals().empty() && isPoly Val( function->get_returnVals().front()->get_type(), tyVars ) ) {362 if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) { 387 363 ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg ); 388 364 } // if … … 398 374 void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) { 399 375 assert( ! arg->get_results().empty() ); 400 // /if ( ! dynamic_cast< PointerType *>( arg->get_results().front() ) ) {376 // if ( ! dynamic_cast< PointerType *>( arg->get_results().front() ) ) { 401 377 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( param ); 402 378 if ( typeInst && exprTyVars.find( typeInst->get_name() ) != exprTyVars.end() ) { … … 418 394 } // if 419 395 } // if 420 // /}396 // } 421 397 } 422 398 … … 424 400 Type *newType = formal->clone(); 425 401 std::list< FunctionType *> functions; 426 // instead of functions needing adapters, this really ought to look for any function mentioning a427 // polymorphic type402 // instead of functions needing adapters, this really ought to look for 403 // any function mentioning a polymorphic type 428 404 findAndReplaceFunction( newType, functions, tyVars, needsAdapter ); 429 405 if ( ! functions.empty() ) { … … 476 452 // actually make the adapter type 477 453 FunctionType *adapter = adaptee->clone(); 478 if ( ! adapter->get_returnVals().empty() && isPoly Val( adapter->get_returnVals().front()->get_type(), tyVars ) ) {454 if ( ! adapter->get_returnVals().empty() && isPolyType( adapter->get_returnVals().front()->get_type(), tyVars ) ) { 479 455 makeRetParm( adapter ); 480 456 } // if … … 486 462 assert( param ); 487 463 assert( arg ); 488 /// std::cout << "arg type is "; 489 /// arg->get_type()->print( std::cout ); 490 /// std::cout << "param type is "; 491 /// param->get_type()->print( std::cout ); 492 /// std::cout << " tyVars are: "; 493 /// printTyVarMap( std::cout, tyVars ); 494 if ( isPolyVal( realParam->get_type(), tyVars ) ) { 495 /// if ( dynamic_cast< PointerType *>( arg->get_type() ) ) { 496 /// return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() ); 497 /// } else { 464 if ( isPolyType( realParam->get_type(), tyVars ) ) { 465 // if ( dynamic_cast< PointerType *>( arg->get_type() ) ) { 466 // return new CastExpr( new VariableExpr( param ), arg->get_type()->clone() ); 467 // } else { 498 468 if ( dynamic_cast<TypeInstType *>(arg->get_type()) == NULL ) { 499 469 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); … … 502 472 return deref; 503 473 } // if 504 // /}474 // } 505 475 } // if 506 476 return new VariableExpr( param ); … … 549 519 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars ); 550 520 bodyStmt = new ExprStmt( noLabels, adapteeApp ); 551 } else if ( isPoly Val( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {521 } else if ( isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) { 552 522 if ( (*param)->get_name() == "" ) { 553 523 (*param)->set_name( "_ret" ); … … 621 591 } // passAdapters 622 592 623 TypeInstType *isPolyPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) { 624 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) { 625 return isPolyType( ptr->get_base(), env, tyVars ); 626 } else if ( env ) { 627 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) { 628 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 629 return isPolyPtr( newType, env, tyVars ); 630 } // if 631 } // if 632 } // if 633 return 0; 634 } 635 636 TypeInstType *isPolyPtrPtr( Type *type, const TypeSubstitution *env, const TyVarMap &tyVars ) { 637 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) { 638 return isPolyPtr( ptr->get_base(), env, tyVars ); 639 } else if ( env ) { 640 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( type ) ) { 641 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 642 return isPolyPtrPtr( newType, env, tyVars ); 643 } // if 644 } // if 645 } // if 646 return 0; 647 } 648 649 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, std::string polyName, bool isIncr ) { 593 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) { 650 594 NameExpr *opExpr; 651 595 if ( isIncr ) { … … 660 604 addAssign->get_args().push_back( appExpr->get_args().front() ); 661 605 } // if 662 addAssign->get_args().push_back( new NameExpr( polyName) );606 addAssign->get_args().push_back( new NameExpr( sizeofName( polyType ) ) ); 663 607 addAssign->get_results().front() = appExpr->get_results().front()->clone(); 664 608 if ( appExpr->get_env() ) { … … 677 621 assert( ! appExpr->get_results().empty() ); 678 622 assert( appExpr->get_args().size() == 2 ); 679 Type InstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars);680 Type InstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars);681 assert( ! typeInst1 || ! typeInst2 );623 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env ); 624 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env ); 625 assert( ! baseType1 || ! baseType2 ); 682 626 UntypedExpr *ret = 0; 683 if ( typeInst1 || typeInst2 ) {627 if ( baseType1 || baseType2 ) { 684 628 ret = new UntypedExpr( new NameExpr( "?+?" ) ); 685 629 } // if 686 if ( typeInst1 ) {630 if ( baseType1 ) { 687 631 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 688 632 multiply->get_args().push_back( appExpr->get_args().back() ); 689 multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );633 multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) ); 690 634 ret->get_args().push_back( appExpr->get_args().front() ); 691 635 ret->get_args().push_back( multiply ); 692 } else if ( typeInst2 ) {636 } else if ( baseType2 ) { 693 637 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 694 638 multiply->get_args().push_back( appExpr->get_args().front() ); 695 multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );639 multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) ); 696 640 ret->get_args().push_back( multiply ); 697 641 ret->get_args().push_back( appExpr->get_args().back() ); 698 642 } // if 699 if ( typeInst1 || typeInst2 ) {643 if ( baseType1 || baseType2 ) { 700 644 ret->get_results().push_front( appExpr->get_results().front()->clone() ); 701 645 if ( appExpr->get_env() ) { … … 710 654 assert( ! appExpr->get_results().empty() ); 711 655 assert( ! appExpr->get_args().empty() ); 712 if ( isPolyType( appExpr->get_results().front(), env, scopeTyVars) ) {656 if ( isPolyType( appExpr->get_results().front(), scopeTyVars, env ) ) { 713 657 Expression *ret = appExpr->get_args().front(); 714 658 delete ret->get_results().front(); … … 725 669 assert( ! appExpr->get_results().empty() ); 726 670 assert( appExpr->get_args().size() == 1 ); 727 if ( Type InstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars) ) {671 if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) { 728 672 Type *tempType = appExpr->get_results().front()->clone(); 729 673 if ( env ) { … … 739 683 assignExpr->get_args().push_back( appExpr->get_args().front()->clone() ); 740 684 } // if 741 CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "?++" ) );685 CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, baseType, varExpr->get_var()->get_name() == "?++" ) ); 742 686 return new CommaExpr( firstComma, tempExpr ); 743 687 } // if … … 745 689 assert( ! appExpr->get_results().empty() ); 746 690 assert( appExpr->get_args().size() == 1 ); 747 if ( Type InstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars) ) {748 return makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "++?" );691 if ( Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ) ) { 692 return makeIncrDecrExpr( appExpr, baseType, varExpr->get_var()->get_name() == "++?" ); 749 693 } // if 750 694 } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) { 751 695 assert( ! appExpr->get_results().empty() ); 752 696 assert( appExpr->get_args().size() == 2 ); 753 Type InstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars);754 Type InstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars);755 if ( typeInst1 && typeInst2 ) {697 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), scopeTyVars, env ); 698 Type *baseType2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), scopeTyVars, env ); 699 if ( baseType1 && baseType2 ) { 756 700 UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) ); 757 701 divide->get_args().push_back( appExpr ); 758 divide->get_args().push_back( new NameExpr( typeInst1->get_name() ) );702 divide->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) ); 759 703 divide->get_results().push_front( appExpr->get_results().front()->clone() ); 760 704 if ( appExpr->get_env() ) { … … 763 707 } // if 764 708 return divide; 765 } else if ( typeInst1 ) {709 } else if ( baseType1 ) { 766 710 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 767 711 multiply->get_args().push_back( appExpr->get_args().back() ); 768 multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );712 multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) ); 769 713 appExpr->get_args().back() = multiply; 770 } else if ( typeInst2 ) {714 } else if ( baseType2 ) { 771 715 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 772 716 multiply->get_args().push_back( appExpr->get_args().front() ); 773 multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );717 multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) ); 774 718 appExpr->get_args().front() = multiply; 775 719 } // if … … 777 721 assert( ! appExpr->get_results().empty() ); 778 722 assert( appExpr->get_args().size() == 2 ); 779 Type InstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars);780 if ( typeInst) {723 Type *baseType = isPolyPtr( appExpr->get_results().front(), scopeTyVars, env ); 724 if ( baseType ) { 781 725 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 782 726 multiply->get_args().push_back( appExpr->get_args().back() ); 783 multiply->get_args().push_back( new NameExpr( typeInst->get_name() ) );727 multiply->get_args().push_back( new NameExpr( sizeofName( baseType ) ) ); 784 728 appExpr->get_args().back() = multiply; 785 729 } // if … … 848 792 849 793 Expression *Pass1::mutate( UntypedExpr *expr ) { 850 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), env, scopeTyVars) ) {794 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), scopeTyVars, env ) ) { 851 795 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) { 852 796 if ( name->get_name() == "*?" ) { … … 863 807 Expression *Pass1::mutate( AddressExpr *addrExpr ) { 864 808 assert( ! addrExpr->get_arg()->get_results().empty() ); 865 866 bool needs = false;867 if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) {868 if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), env, scopeTyVars ) ) {869 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {870 if ( name->get_name() == "*?" ) {871 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) {872 assert( ! appExpr->get_function()->get_results().empty() );873 PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() );874 assert( pointer );875 FunctionType *function = dynamic_cast< FunctionType *>( pointer->get_base() );876 assert( function );877 needs = needsAdapter( function, scopeTyVars );878 } // if879 } // if880 } // if881 } // if882 } // if883 809 addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) ); 884 if ( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars ) || needs) {810 if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) ) { 885 811 Expression *ret = addrExpr->get_arg(); 886 812 delete ret->get_results().front(); … … 894 820 } 895 821 896 Statement * Pass1::mutate( ReturnStmt *returnStmt ) { 897 if ( retval && returnStmt->get_expr() ) { 898 assert( ! returnStmt->get_expr()->get_results().empty() ); 899 // ***** Code Removal ***** After introducing a temporary variable for all return expressions, the following code appears superfluous. 900 // if ( returnStmt->get_expr()->get_results().front()->get_isLvalue() ) { 901 // a cast expr on a polymorphic return value is either redundant or invalid 902 while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( returnStmt->get_expr() ) ) { 903 returnStmt->set_expr( castExpr->get_arg() ); 904 returnStmt->get_expr()->set_env( castExpr->get_env() ); 905 castExpr->set_env( 0 ); 906 castExpr->set_arg( 0 ); 907 delete castExpr; 908 } // while 909 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ); 910 assert( typeInst ); 911 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 912 if ( assignIter == assignOps.end() ) { 913 throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() ); 914 } // if 915 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) ); 916 Expression *retParm = new NameExpr( retval->get_name() ); 917 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); 918 assignExpr->get_args().push_back( retParm ); 919 assignExpr->get_args().push_back( returnStmt->get_expr() ); 920 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) ); 921 // } else { 922 // std::cerr << "THOMAS " << std::endl; 923 // useRetval = true; 924 // stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( returnStmt->get_expr() ) ) ); 925 // useRetval = false; 926 // } // if 927 returnStmt->set_expr( 0 ); 822 Statement * Pass1::mutate(ReturnStmt *retStmt) { 823 // a cast expr on a polymorphic return value is either redundant or invalid 824 while ( CastExpr *castExpr = dynamic_cast< CastExpr *>( retStmt->get_expr() ) ) { 825 retStmt->set_expr( castExpr->get_arg() ); 826 retStmt->get_expr()->set_env( castExpr->get_env() ); 827 castExpr->set_env( 0 ); 828 castExpr->set_arg( 0 ); 829 delete castExpr; 830 } 831 if ( retval && retStmt->get_expr() ) { 832 assert( ! retStmt->get_expr()->get_results().empty() ); 833 if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) { 834 /// retStmt->set_expr( mutateExpression( retStmt->get_expr() ) ); 835 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ); 836 assert( typeInst ); 837 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 838 if ( assignIter == assignOps.end() ) { 839 throw SemanticError( "Attempt to return dtype or ftype object in ", retStmt->get_expr() ); 840 } // if 841 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) ); 842 Expression *retParm = new NameExpr( retval->get_name() ); 843 retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) ); 844 assignExpr->get_args().push_back( retParm ); 845 assignExpr->get_args().push_back( retStmt->get_expr() ); 846 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( assignExpr ) ) ); 847 } else { 848 useRetval = true; 849 stmtsToAdd.push_back( new ExprStmt( noLabels, mutateExpression( retStmt->get_expr() ) ) ); 850 useRetval = false; 851 } // if 852 retStmt->set_expr( 0 ); 928 853 } else { 929 ret urnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) );930 } // if 931 return ret urnStmt;854 retStmt->set_expr( mutateExpression( retStmt->get_expr() ) ); 855 } // if 856 return retStmt; 932 857 } 933 858 … … 962 887 963 888 ////////////////////////////////////////// Pass2 //////////////////////////////////////////////////// 964 965 Pass2::Pass2() {}966 889 967 890 void Pass2::addAdapters( FunctionType *functionType ) { … … 1037 960 std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin(); 1038 961 std::list< DeclarationWithType *> inferredParams; 1039 ObjectDecl *newObj = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );1040 // /ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );962 ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 ); 963 // ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 ); 1041 964 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { 1042 ObjectDecl * thisParm;1043 // add all size parameters to parameter list965 ObjectDecl *sizeParm, *alignParm; 966 // add all size and alignment parameters to parameter list 1044 967 if ( (*tyParm)->get_kind() == TypeDecl::Any ) { 1045 thisParm = newObj->clone(); 1046 thisParm->set_name( (*tyParm)->get_name() ); 1047 last = funcType->get_parameters().insert( last, thisParm ); 968 TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm ); 969 970 sizeParm = newObj.clone(); 971 sizeParm->set_name( sizeofName( &parmType ) ); 972 last = funcType->get_parameters().insert( last, sizeParm ); 973 ++last; 974 975 alignParm = newObj.clone(); 976 alignParm->set_name( alignofName( &parmType ) ); 977 last = funcType->get_parameters().insert( last, alignParm ); 1048 978 ++last; 1049 979 } 1050 980 // move all assertions into parameter list 1051 981 for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) { 1052 // /*assert = (*assert)->acceptMutator( *this );982 // *assert = (*assert)->acceptMutator( *this ); 1053 983 inferredParams.push_back( *assert ); 1054 984 } 1055 985 (*tyParm)->get_assertions().clear(); 1056 986 } 1057 delete newObj;1058 987 funcType->get_parameters().splice( last, inferredParams ); 1059 988 addAdapters( funcType ); … … 1092 1021 1093 1022 TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) { 1094 // /Initializer *init = 0;1095 // /std::list< Expression *> designators;1096 // /scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();1097 // /if ( typeDecl->get_base() ) {1098 // /init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );1099 // /}1100 // /return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );1023 // Initializer *init = 0; 1024 // std::list< Expression *> designators; 1025 // scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); 1026 // if ( typeDecl->get_base() ) { 1027 // init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators ); 1028 // } 1029 // return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init ); 1101 1030 1102 1031 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); … … 1126 1055 Statement *Pass3::mutate( DeclStmt *declStmt ) { 1127 1056 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) { 1128 if ( isPoly Val( objectDecl->get_type(), scopeTyVars ) ) {1129 // change initialization of a polymorphic value object to allocate storage with alloca1130 TypeInstType *typeInst = dynamic_cast< TypeInstType *>( objectDecl->get_type() );1131 assert( typeInst);1057 if ( isPolyType( objectDecl->get_type(), scopeTyVars ) ) { 1058 // change initialization of a polymorphic value object 1059 // to allocate storage with alloca 1060 Type *declType = objectDecl->get_type(); 1132 1061 UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) ); 1133 alloc->get_args().push_back( new NameExpr( typeInst->get_name() ) );1062 alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) ); 1134 1063 1135 1064 delete objectDecl->get_init();
Note:
See TracChangeset
for help on using the changeset viewer.