Changes in src/GenPoly/Box.cc [4573e3c:eada3cf]
- File:
-
- 1 edited
-
src/GenPoly/Box.cc (modified) (40 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r4573e3c reada3cf 32 32 #include "Common/UniqueName.h" // for UniqueName 33 33 #include "Common/utility.h" // for toString 34 #include "DeclMutator.h" // for DeclMutator 34 35 #include "FindFunction.h" // for findFunction, findAndReplace... 35 36 #include "GenPoly/ErasableScopedMap.h" // for ErasableScopedMap<>::const_i... … … 38 39 #include "Lvalue.h" // for generalizedLvalue 39 40 #include "Parser/LinkageSpec.h" // for C, Spec, Cforall, Intrinsic 41 #include "PolyMutator.h" // for PolyMutator 40 42 #include "ResolvExpr/TypeEnvironment.h" // for EqvClass 41 43 #include "ResolvExpr/typeops.h" // for typesCompatible … … 60 62 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 61 63 62 class BoxPass { 63 protected: 64 BoxPass() : scopeTyVars( TypeDecl::Data{} ) {} 65 TyVarMap scopeTyVars; 64 /// Adds layout-generation functions to polymorphic types 65 class LayoutFunctionBuilder final : public DeclMutator { 66 unsigned int functionNesting; // current level of nested functions 67 public: 68 LayoutFunctionBuilder() : functionNesting( 0 ) {} 69 70 using DeclMutator::mutate; 71 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override; 72 virtual Declaration *mutate( StructDecl *structDecl ) override; 73 virtual Declaration *mutate( UnionDecl *unionDecl ) override; 66 74 }; 67 75 68 /// Adds layout-generation functions to polymorphic types69 class LayoutFunctionBuilder final : public WithDeclsToAdd, public WithVisitorRef<LayoutFunctionBuilder>, public WithShortCircuiting {70 unsigned int functionNesting = 0; // current level of nested functions71 public:72 void previsit( FunctionDecl *functionDecl );73 void previsit( StructDecl *structDecl );74 void previsit( UnionDecl *unionDecl );75 };76 77 76 /// 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 78 class Pass1 final : public BoxPass, public WithTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting{77 class Pass1 final : public PolyMutator { 79 78 public: 80 79 Pass1(); 81 80 82 void premutate( FunctionDecl * functionDecl ); 83 void premutate( TypeDecl * typeDecl ); 84 void premutate( CommaExpr * commaExpr ); 85 Expression * postmutate( ApplicationExpr * appExpr ); 86 Expression * postmutate( UntypedExpr *expr ); 87 void premutate( AddressExpr * addrExpr ); 88 Expression * postmutate( AddressExpr * addrExpr ); 89 void premutate( ReturnStmt * returnStmt ); 90 void premutate( PointerType * pointerType ); 91 void premutate( FunctionType * functionType ); 92 93 void beginScope(); 94 void endScope(); 81 using PolyMutator::mutate; 82 virtual Expression *mutate( ApplicationExpr *appExpr ) override; 83 virtual Expression *mutate( AddressExpr *addrExpr ) override; 84 virtual Expression *mutate( UntypedExpr *expr ) override; 85 virtual DeclarationWithType* mutate( FunctionDecl *functionDecl ) override; 86 virtual TypeDecl *mutate( TypeDecl *typeDecl ) override; 87 virtual Expression *mutate( CommaExpr *commaExpr ) override; 88 virtual Expression *mutate( ConditionalExpr *condExpr ) override; 89 virtual Statement * mutate( ReturnStmt *returnStmt ) override; 90 virtual Type *mutate( PointerType *pointerType ) override; 91 virtual Type * mutate( FunctionType *functionType ) override; 92 93 virtual void doBeginScope() override; 94 virtual void doEndScope() override; 95 95 private: 96 96 /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application … … 129 129 /// * Moves polymorphic returns in function types to pointer-type parameters 130 130 /// * adds type size and assertion parameters to parameter lists 131 struct Pass2 final : public BoxPass, public WithGuards { 132 void handleAggDecl(); 133 134 DeclarationWithType * postmutate( FunctionDecl *functionDecl ); 135 void premutate( StructDecl *structDecl ); 136 void premutate( UnionDecl *unionDecl ); 137 void premutate( TraitDecl *unionDecl ); 138 void premutate( TypeDecl *typeDecl ); 139 void premutate( PointerType *pointerType ); 140 void premutate( FunctionType *funcType ); 131 class Pass2 final : public PolyMutator { 132 public: 133 template< typename DeclClass > 134 DeclClass *handleDecl( DeclClass *decl ); 135 template< typename AggDecl > 136 AggDecl * handleAggDecl( AggDecl * aggDecl ); 137 138 typedef PolyMutator Parent; 139 using Parent::mutate; 140 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override; 141 virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) override; 142 virtual StructDecl *mutate( StructDecl *structDecl ) override; 143 virtual UnionDecl *mutate( UnionDecl *unionDecl ) override; 144 virtual TraitDecl *mutate( TraitDecl *unionDecl ) override; 145 virtual TypeDecl *mutate( TypeDecl *typeDecl ) override; 146 virtual TypedefDecl *mutate( TypedefDecl *typedefDecl ) override; 147 virtual Type *mutate( PointerType *pointerType ) override; 148 virtual Type *mutate( FunctionType *funcType ) override; 141 149 142 150 private: … … 150 158 /// * Calculates polymorphic offsetof expressions from offset array 151 159 /// * Inserts dynamic calculation of polymorphic type layouts where needed 152 class PolyGenericCalculator final : public BoxPass, publicWithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution {160 class PolyGenericCalculator final : public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution { 153 161 public: 154 162 PolyGenericCalculator(); … … 189 197 ScopedSet< std::string > knownOffsets; ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName 190 198 UniqueName bufNamer; ///< Namer for VLA buffers 199 TyVarMap scopeTyVars; 191 200 }; 192 201 193 202 /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, sizeof expressions of polymorphic types with the proper variable, and strips fields from generic struct declarations. 194 struct Pass3 final : public BoxPass, public WithGuards { 203 class Pass3 final : public PolyMutator { 204 public: 195 205 template< typename DeclClass > 196 void handleDecl( DeclClass * decl, Type * type ); 197 198 void premutate( ObjectDecl * objectDecl ); 199 void premutate( FunctionDecl * functionDecl ); 200 void premutate( TypedefDecl * typedefDecl ); 201 void premutate( StructDecl * structDecl ); 202 void premutate( UnionDecl * unionDecl ); 203 void premutate( TypeDecl * typeDecl ); 204 void premutate( PointerType * pointerType ); 205 void premutate( FunctionType * funcType ); 206 DeclClass *handleDecl( DeclClass *decl, Type *type ); 207 208 using PolyMutator::mutate; 209 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override; 210 virtual Declaration *mutate( StructDecl *structDecl ) override; 211 virtual Declaration *mutate( UnionDecl *unionDecl ) override; 212 virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) override; 213 virtual TypedefDecl *mutate( TypedefDecl *objectDecl ) override; 214 virtual TypeDecl *mutate( TypeDecl *objectDecl ) override; 215 virtual Type *mutate( PointerType *pointerType ) override; 216 virtual Type *mutate( FunctionType *funcType ) override; 217 private: 206 218 }; 207 219 } // anonymous namespace … … 235 247 236 248 void box( std::list< Declaration *>& translationUnit ) { 237 PassVisitor<LayoutFunctionBuilder>layoutBuilder;238 Pass Visitor<Pass1>pass1;239 Pass Visitor<Pass2>pass2;249 LayoutFunctionBuilder layoutBuilder; 250 Pass1 pass1; 251 Pass2 pass2; 240 252 PassVisitor<PolyGenericCalculator> polyCalculator; 241 Pass Visitor<Pass3>pass3;242 243 acceptAll( translationUnit, layoutBuilder);244 mutate All( translationUnit, pass1 );245 mutate All( translationUnit, pass2 );253 Pass3 pass3; 254 255 layoutBuilder.mutateDeclarationList( translationUnit ); 256 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 257 mutateTranslationUnit/*All*/( translationUnit, pass2 ); 246 258 mutateAll( translationUnit, polyCalculator ); 247 mutate All( translationUnit, pass3 );259 mutateTranslationUnit/*All*/( translationUnit, pass3 ); 248 260 } 249 261 250 262 ////////////////////////////////// LayoutFunctionBuilder //////////////////////////////////////////// 251 263 252 void LayoutFunctionBuilder::previsit( FunctionDecl *functionDecl ) { 253 visit_children = false; 254 maybeAccept( functionDecl->get_functionType(), *visitor ); 264 DeclarationWithType *LayoutFunctionBuilder::mutate( FunctionDecl *functionDecl ) { 265 functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) ); 255 266 ++functionNesting; 256 maybeAccept( functionDecl->get_statements(), *visitor);267 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) ); 257 268 --functionNesting; 269 return functionDecl; 258 270 } 259 271 … … 344 356 } 345 357 346 void LayoutFunctionBuilder::previsit( StructDecl *structDecl ) {358 Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) { 347 359 // do not generate layout function for "empty" tag structs 348 visit_children = false; 349 if ( structDecl->get_members().empty() ) return; 360 if ( structDecl->get_members().empty() ) return structDecl; 350 361 351 362 // get parameters that can change layout, exiting early if none 352 363 std::list< TypeDecl* > otypeParams = takeOtypeOnly( structDecl->get_parameters() ); 353 if ( otypeParams.empty() ) return ;364 if ( otypeParams.empty() ) return structDecl; 354 365 355 366 // build layout function signature … … 402 413 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) ); 403 414 404 declsToAddAfter.push_back( layoutDecl ); 415 addDeclarationAfter( layoutDecl ); 416 return structDecl; 405 417 } 406 418 407 void LayoutFunctionBuilder::previsit( UnionDecl *unionDecl ) {419 Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) { 408 420 // do not generate layout function for "empty" tag unions 409 visit_children = false; 410 if ( unionDecl->get_members().empty() ) return; 421 if ( unionDecl->get_members().empty() ) return unionDecl; 411 422 412 423 // get parameters that can change layout, exiting early if none 413 424 std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() ); 414 if ( otypeParams.empty() ) return ;425 if ( otypeParams.empty() ) return unionDecl; 415 426 416 427 // build layout function signature … … 445 456 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) ); 446 457 447 declsToAddAfter.push_back( layoutDecl ); 458 addDeclarationAfter( layoutDecl ); 459 return unionDecl; 448 460 } 449 461 … … 489 501 Pass1::Pass1() : tempNamer( "_temp" ) {} 490 502 491 void Pass1::premutate( FunctionDecl *functionDecl ) {503 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) { 492 504 if ( functionDecl->get_statements() ) { // empty routine body ? 493 505 // std::cerr << "mutating function: " << functionDecl->get_mangleName() << std::endl; 494 GuardScope( scopeTyVars ); 495 GuardValue( retval ); 506 doBeginScope(); 507 scopeTyVars.beginScope(); 508 509 DeclarationWithType *oldRetval = retval; 496 510 497 511 // process polymorphic return value 498 512 retval = nullptr; 499 FunctionType *functionType = functionDecl->type; 500 if ( isDynRet( functionType ) && functionDecl->linkage != LinkageSpec::C ) { 501 retval = functionType->returnVals.front(); 513 if ( isDynRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() != LinkageSpec::C ) { 514 retval = functionDecl->get_functionType()->get_returnVals().front(); 502 515 503 516 // give names to unnamed return values 504 if ( retval-> name== "" ) {505 retval-> name = "_retparm";506 retval-> linkage = LinkageSpec::C;517 if ( retval->get_name() == "" ) { 518 retval->set_name( "_retparm" ); 519 retval->set_linkage( LinkageSpec::C ); 507 520 } // if 508 521 } // if 509 522 510 makeTyVarMap( functionType, scopeTyVars ); 511 512 std::list< DeclarationWithType *> ¶mList = functionType->parameters; 523 FunctionType *functionType = functionDecl->get_functionType(); 524 makeTyVarMap( functionDecl->get_functionType(), scopeTyVars ); 525 526 std::list< DeclarationWithType *> ¶mList = functionType->get_parameters(); 513 527 std::list< FunctionType *> functions; 514 for ( Type::ForallList::iterator tyVar = functionType-> forall.begin(); tyVar != functionType->forall.end(); ++tyVar ) {515 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)-> assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert ) {528 for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) { 529 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) { 516 530 findFunction( (*assert)->get_type(), functions, scopeTyVars, needsAdapter ); 517 531 } // for … … 528 542 } // if 529 543 } // for 544 545 functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) ); 546 547 scopeTyVars.endScope(); 548 retval = oldRetval; 549 doEndScope(); 530 550 // std::cerr << "end function: " << functionDecl->get_mangleName() << std::endl; 531 551 } // if 532 } 533 534 void Pass1::premutate( TypeDecl *typeDecl ) { 552 return functionDecl; 553 } 554 555 TypeDecl *Pass1::mutate( TypeDecl *typeDecl ) { 535 556 addToTyVarMap( typeDecl, scopeTyVars ); 536 } 537 538 void Pass1::premutate( CommaExpr *commaExpr ) { 557 return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) ); 558 } 559 560 Expression *Pass1::mutate( CommaExpr *commaExpr ) { 539 561 // Attempting to find application expressions that were mutated by the copy constructor passes 540 562 // to use an explicit return variable, so that the variable can be reused as a parameter to the … … 552 574 } 553 575 } 576 577 commaExpr->set_arg1( maybeMutate( commaExpr->get_arg1(), *this ) ); 578 commaExpr->set_arg2( maybeMutate( commaExpr->get_arg2(), *this ) ); 579 return commaExpr; 580 } 581 582 Expression *Pass1::mutate( ConditionalExpr *condExpr ) { 583 condExpr->set_arg1( maybeMutate( condExpr->get_arg1(), *this ) ); 584 condExpr->set_arg2( maybeMutate( condExpr->get_arg2(), *this ) ); 585 condExpr->set_arg3( maybeMutate( condExpr->get_arg3(), *this ) ); 586 return condExpr; 587 554 588 } 555 589 … … 600 634 601 635 // add size/align for generic types to parameter list 602 if ( ! appExpr->get_function()-> result) return;636 if ( ! appExpr->get_function()->has_result() ) return; 603 637 FunctionType *funcType = getFunctionType( appExpr->get_function()->get_result() ); 604 638 assert( funcType ); … … 625 659 ObjectDecl *Pass1::makeTemporary( Type *type ) { 626 660 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, type, 0 ); 627 stmtsToAdd Before.push_back( new DeclStmt( noLabels, newObj ) );661 stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) ); 628 662 return newObj; 629 663 } … … 714 748 715 749 void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) { 716 assertf( arg->result, "arg does not have result: %s", toString( arg ).c_str() ); 717 if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return; 718 719 if ( arg->result->get_lvalue() ) { 720 // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations. 721 // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) { 722 // if ( dynamic_cast<ArrayType *>( varExpr->var->get_type() ) ){ 723 // // temporary hack - don't box arrays, because &arr is not the same as &arr[0] 724 // return; 725 // } 726 // } 727 arg = generalizedLvalue( new AddressExpr( arg ) ); 728 if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) { 729 // silence warnings by casting boxed parameters when the actual type does not match up with the formal type. 730 arg = new CastExpr( arg, param->clone() ); 731 } 732 } else { 733 // use type computed in unification to declare boxed variables 734 Type * newType = param->clone(); 750 assertf( arg->has_result(), "arg does not have result: %s", toString( arg ).c_str() ); 751 if ( isPolyType( param, exprTyVars ) ) { 752 Type * newType = arg->get_result()->clone(); 735 753 if ( env ) env->apply( newType ); 736 ObjectDecl *newObj = ObjectDecl::newObject( tempNamer.newName(), newType, nullptr ); 737 newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right??? 738 stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) ); 739 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax? 740 assign->get_args().push_back( new VariableExpr( newObj ) ); 741 assign->get_args().push_back( arg ); 742 stmtsToAddBefore.push_back( new ExprStmt( noLabels, assign ) ); 743 arg = new AddressExpr( new VariableExpr( newObj ) ); 754 std::unique_ptr<Type> manager( newType ); 755 if ( isPolyType( newType ) ) { 756 // if the argument's type is polymorphic, we don't need to box again! 757 return; 758 } else if ( arg->get_result()->get_lvalue() ) { 759 // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations. 760 // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) { 761 // if ( dynamic_cast<ArrayType *>( varExpr->var->get_type() ) ){ 762 // // temporary hack - don't box arrays, because &arr is not the same as &arr[0] 763 // return; 764 // } 765 // } 766 arg = generalizedLvalue( new AddressExpr( arg ) ); 767 if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) { 768 // silence warnings by casting boxed parameters when the actual type does not match up with the formal type. 769 arg = new CastExpr( arg, param->clone() ); 770 } 771 } else { 772 // use type computed in unification to declare boxed variables 773 Type * newType = param->clone(); 774 if ( env ) env->apply( newType ); 775 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, newType, 0 ); 776 newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right??? 777 stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) ); 778 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax? 779 assign->get_args().push_back( new VariableExpr( newObj ) ); 780 assign->get_args().push_back( arg ); 781 stmtsToAdd.push_back( new ExprStmt( noLabels, assign ) ); 782 arg = new AddressExpr( new VariableExpr( newObj ) ); 783 } // if 744 784 } // if 745 }746 747 // find instances of polymorphic type parameters748 struct PolyFinder {749 const TyVarMap * tyVars = nullptr;750 bool found = false;751 752 void previsit( TypeInstType * t ) {753 if ( isPolyType( t, *tyVars ) ) {754 found = true;755 }756 }757 };758 759 // true if there is an instance of a polymorphic type parameter in t760 bool hasPolymorphism( Type * t, const TyVarMap &tyVars ) {761 PassVisitor<PolyFinder> finder;762 finder.pass.tyVars = &tyVars;763 maybeAccept( t, finder );764 return finder.pass.found;765 785 } 766 786 … … 769 789 /// this gets rid of warnings from gcc. 770 790 void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) { 771 // type contains polymorphism, but isn't exactly a polytype, in which case it 772 // has some real actual type (e.g. unsigned int) and casting to void * is wrong 773 if ( hasPolymorphism( formal, tyVars ) && ! isPolyType( formal, tyVars ) ) { 791 if ( getFunctionType( formal ) ) { 774 792 Type * newType = formal->clone(); 775 793 newType = ScrubTyVars::scrub( newType, tyVars ); … … 779 797 780 798 void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 781 for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function-> parameters.end(); ++param, ++arg ) {782 assertf( arg != appExpr-> args.end(), "boxParams: missing argument for param %s to %s in %s", toString( *param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() );799 for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) { 800 assertf( arg != appExpr->get_args().end(), "boxParams: missing argument for param %s to %s in %s", toString( *param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() ); 783 801 addCast( *arg, (*param)->get_type(), exprTyVars ); 784 802 boxParam( (*param)->get_type(), *arg, exprTyVars ); … … 789 807 std::list< Expression *>::iterator cur = arg; 790 808 for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) { 791 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)-> assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert ) {809 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) { 792 810 InferredParams::const_iterator inferParam = appExpr->get_inferParams().find( (*assert)->get_uniqueId() ); 793 assertf( inferParam != appExpr->get_inferParams().end(), "addInferredParams missing inferred parameter: %s in: %s", toString( *assert ).c_str(), toString( appExpr ).c_str() ); 811 if ( inferParam == appExpr->get_inferParams().end() ) { 812 std::cerr << "looking for assertion: " << (*assert) << std::endl << appExpr << std::endl; 813 } 814 assertf( inferParam != appExpr->get_inferParams().end(), "NOTE: Explicit casts of polymorphic functions to compatible monomorphic functions are currently unsupported" ); 794 815 Expression *newExpr = inferParam->second.expr->clone(); 795 816 addCast( newExpr, (*assert)->get_type(), tyVars ); … … 801 822 802 823 void makeRetParm( FunctionType *funcType ) { 803 DeclarationWithType *retParm = funcType-> returnVals.front();824 DeclarationWithType *retParm = funcType->get_returnVals().front(); 804 825 805 826 // make a new parameter that is a pointer to the type of the old return value … … 814 835 // actually make the adapter type 815 836 FunctionType *adapter = adaptee->clone(); 837 // if ( ! adapter->get_returnVals().empty() && isPolyType( adapter->get_returnVals().front()->get_type(), tyVars ) ) { 816 838 if ( isDynRet( adapter, tyVars ) ) { 817 839 makeRetParm( adapter ); … … 939 961 std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) ); 940 962 adapter = answer.first; 941 stmtsToAdd Before.push_back( new DeclStmt( noLabels, newAdapter ) );963 stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) ); 942 964 } // if 943 965 assert( adapter != adapters.end() ); … … 977 999 if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic ) { 978 1000 if ( varExpr->get_var()->get_name() == "?[?]" ) { 979 assert( appExpr-> result);1001 assert( appExpr->has_result() ); 980 1002 assert( appExpr->get_args().size() == 2 ); 981 1003 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result(), scopeTyVars, env ); … … 1011 1033 } // if 1012 1034 } else if ( varExpr->get_var()->get_name() == "*?" ) { 1013 assert( appExpr-> result);1035 assert( appExpr->has_result() ); 1014 1036 assert( ! appExpr->get_args().empty() ); 1015 1037 if ( isPolyType( appExpr->get_result(), scopeTyVars, env ) ) { … … 1028 1050 } // if 1029 1051 } else if ( varExpr->get_var()->get_name() == "?++" || varExpr->get_var()->get_name() == "?--" ) { 1030 assert( appExpr-> result);1052 assert( appExpr->has_result() ); 1031 1053 assert( appExpr->get_args().size() == 1 ); 1032 1054 if ( Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ) ) { … … 1048 1070 } // if 1049 1071 } else if ( varExpr->get_var()->get_name() == "++?" || varExpr->get_var()->get_name() == "--?" ) { 1050 assert( appExpr-> result);1072 assert( appExpr->has_result() ); 1051 1073 assert( appExpr->get_args().size() == 1 ); 1052 1074 if ( Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ) ) { … … 1054 1076 } // if 1055 1077 } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) { 1056 assert( appExpr-> result);1078 assert( appExpr->has_result() ); 1057 1079 assert( appExpr->get_args().size() == 2 ); 1058 1080 Type *baseType1 = isPolyPtr( appExpr->get_args().front()->get_result(), scopeTyVars, env ); … … 1080 1102 } // if 1081 1103 } else if ( varExpr->get_var()->get_name() == "?+=?" || varExpr->get_var()->get_name() == "?-=?" ) { 1082 assert( appExpr-> result);1104 assert( appExpr->has_result() ); 1083 1105 assert( appExpr->get_args().size() == 2 ); 1084 1106 Type *baseType = isPolyPtr( appExpr->get_result(), scopeTyVars, env ); … … 1096 1118 } 1097 1119 1098 Expression *Pass1:: postmutate( ApplicationExpr *appExpr ) {1120 Expression *Pass1::mutate( ApplicationExpr *appExpr ) { 1099 1121 // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl; 1100 1122 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) { … … 1102 1124 // } 1103 1125 // std::cerr << "\n"; 1104 1105 assert( appExpr->function->result ); 1106 FunctionType * function = getFunctionType( appExpr->function->result ); 1107 assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->function->result ).c_str() ); 1126 appExpr->get_function()->acceptMutator( *this ); 1127 mutateAll( appExpr->get_args(), *this ); 1128 1129 assert( appExpr->get_function()->has_result() ); 1130 FunctionType * function = getFunctionType( appExpr->get_function()->get_result() ); 1131 assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->get_function()->get_result() ).c_str() ); 1108 1132 1109 1133 if ( Expression *newExpr = handleIntrinsics( appExpr ) ) { … … 1158 1182 } 1159 1183 1160 Expression * Pass1::postmutate( UntypedExpr *expr ) {1161 if ( expr-> result && isPolyType( expr->result, scopeTyVars, env ) ) {1162 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr-> function) ) {1184 Expression *Pass1::mutate( UntypedExpr *expr ) { 1185 if ( expr->has_result() && isPolyType( expr->get_result(), scopeTyVars, env ) ) { 1186 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) { 1163 1187 if ( name->get_name() == "*?" ) { 1164 Expression *ret = expr-> args.front();1165 expr-> args.clear();1188 Expression *ret = expr->get_args().front(); 1189 expr->get_args().clear(); 1166 1190 delete expr; 1167 return ret ;1191 return ret->acceptMutator( *this ); 1168 1192 } // if 1169 1193 } // if 1170 1194 } // if 1171 return expr; 1172 } 1173 1174 void Pass1::premutate( AddressExpr * ) { visit_children = false; } 1175 Expression * Pass1::postmutate( AddressExpr * addrExpr ) { 1176 assert( addrExpr->get_arg()->result && ! addrExpr->get_arg()->get_result()->isVoid() ); 1195 return PolyMutator::mutate( expr ); 1196 } 1197 1198 Expression *Pass1::mutate( AddressExpr *addrExpr ) { 1199 assert( addrExpr->get_arg()->has_result() && ! addrExpr->get_arg()->get_result()->isVoid() ); 1177 1200 1178 1201 bool needs = false; 1179 1202 if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->get_arg() ) ) { 1180 if ( expr-> result&& isPolyType( expr->get_result(), scopeTyVars, env ) ) {1203 if ( expr->has_result() && isPolyType( expr->get_result(), scopeTyVars, env ) ) { 1181 1204 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) { 1182 1205 if ( name->get_name() == "*?" ) { 1183 1206 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) { 1184 assert( appExpr->get_function()-> result);1207 assert( appExpr->get_function()->has_result() ); 1185 1208 FunctionType *function = getFunctionType( appExpr->get_function()->get_result() ); 1186 1209 assert( function ); … … 1193 1216 // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward 1194 1217 // out of the if condition. 1195 addrExpr-> arg = addrExpr->get_arg()->acceptMutator( *visitor);1218 addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) ); 1196 1219 // ... but must happen after mutate, since argument might change (e.g. intrinsic *?, ?[?]) - re-evaluate above comment 1197 1220 bool polytype = isPolyType( addrExpr->get_arg()->get_result(), scopeTyVars, env ); … … 1208 1231 } 1209 1232 1210 void Pass1::premutate( ReturnStmt *returnStmt ) { 1211 if ( retval && returnStmt->expr ) { 1212 assert( returnStmt->expr->result && ! returnStmt->expr->result->isVoid() ); 1213 delete returnStmt->expr; 1214 returnStmt->expr = nullptr; 1233 Statement * Pass1::mutate( ReturnStmt *returnStmt ) { 1234 if ( retval && returnStmt->get_expr() ) { 1235 assert( returnStmt->get_expr()->has_result() && ! returnStmt->get_expr()->get_result()->isVoid() ); 1236 delete returnStmt->get_expr(); 1237 returnStmt->set_expr( 0 ); 1238 } else { 1239 returnStmt->set_expr( mutateExpression( returnStmt->get_expr() ) ); 1215 1240 } // if 1216 } 1217 1218 void Pass1::premutate( PointerType *pointerType ) { 1219 GuardScope( scopeTyVars ); 1241 return returnStmt; 1242 } 1243 1244 Type * Pass1::mutate( PointerType *pointerType ) { 1245 scopeTyVars.beginScope(); 1220 1246 makeTyVarMap( pointerType, scopeTyVars ); 1221 } 1222 1223 void Pass1::premutate( FunctionType *functionType ) { 1224 GuardScope( scopeTyVars ); 1247 1248 Type *ret = Mutator::mutate( pointerType ); 1249 1250 scopeTyVars.endScope(); 1251 return ret; 1252 } 1253 1254 Type * Pass1::mutate( FunctionType *functionType ) { 1255 scopeTyVars.beginScope(); 1225 1256 makeTyVarMap( functionType, scopeTyVars ); 1226 } 1227 1228 void Pass1::beginScope() { 1257 1258 Type *ret = Mutator::mutate( functionType ); 1259 1260 scopeTyVars.endScope(); 1261 return ret; 1262 } 1263 1264 void Pass1::doBeginScope() { 1229 1265 adapters.beginScope(); 1230 1266 } 1231 1267 1232 void Pass1:: endScope() {1268 void Pass1::doEndScope() { 1233 1269 adapters.endScope(); 1234 1270 } … … 1257 1293 } 1258 1294 1259 DeclarationWithType * Pass2::postmutate( FunctionDecl *functionDecl ) { 1295 template< typename DeclClass > 1296 DeclClass * Pass2::handleDecl( DeclClass *decl ) { 1297 DeclClass *ret = static_cast< DeclClass *>( Parent::mutate( decl ) ); 1298 1299 return ret; 1300 } 1301 1302 DeclarationWithType * Pass2::mutate( FunctionDecl *functionDecl ) { 1303 functionDecl = strict_dynamic_cast< FunctionDecl * > ( handleDecl( functionDecl ) ); 1260 1304 FunctionType * ftype = functionDecl->get_functionType(); 1261 1305 if ( ! ftype->get_returnVals().empty() && functionDecl->get_statements() ) { … … 1281 1325 } 1282 1326 1283 void Pass2::premutate( StructDecl * ) { 1327 ObjectDecl * Pass2::mutate( ObjectDecl *objectDecl ) { 1328 return handleDecl( objectDecl ); 1329 } 1330 1331 template< typename AggDecl > 1332 AggDecl * Pass2::handleAggDecl( AggDecl * aggDecl ) { 1284 1333 // prevent tyVars from leaking into containing scope 1285 GuardScope( scopeTyVars ); 1286 } 1287 1288 void Pass2::premutate( UnionDecl * ) { 1289 // prevent tyVars from leaking into containing scope 1290 GuardScope( scopeTyVars ); 1291 } 1292 1293 void Pass2::premutate( TraitDecl * ) { 1294 // prevent tyVars from leaking into containing scope 1295 GuardScope( scopeTyVars ); 1296 } 1297 1298 void Pass2::premutate( TypeDecl *typeDecl ) { 1334 scopeTyVars.beginScope(); 1335 Parent::mutate( aggDecl ); 1336 scopeTyVars.endScope(); 1337 return aggDecl; 1338 } 1339 1340 StructDecl * Pass2::mutate( StructDecl *aggDecl ) { 1341 return handleAggDecl( aggDecl ); 1342 } 1343 1344 UnionDecl * Pass2::mutate( UnionDecl *aggDecl ) { 1345 return handleAggDecl( aggDecl ); 1346 } 1347 1348 TraitDecl * Pass2::mutate( TraitDecl *aggDecl ) { 1349 return handleAggDecl( aggDecl ); 1350 } 1351 1352 TypeDecl * Pass2::mutate( TypeDecl *typeDecl ) { 1299 1353 addToTyVarMap( typeDecl, scopeTyVars ); 1300 } 1301 1302 void Pass2::premutate( PointerType *pointerType ) { 1303 GuardScope( scopeTyVars ); 1354 if ( typeDecl->get_base() ) { 1355 return handleDecl( typeDecl ); 1356 } else { 1357 return dynamic_cast<TypeDecl*>( Parent::mutate( typeDecl ) ); 1358 } 1359 } 1360 1361 TypedefDecl * Pass2::mutate( TypedefDecl *typedefDecl ) { 1362 return handleDecl( typedefDecl ); 1363 } 1364 1365 Type * Pass2::mutate( PointerType *pointerType ) { 1366 scopeTyVars.beginScope(); 1304 1367 makeTyVarMap( pointerType, scopeTyVars ); 1305 } 1306 1307 void Pass2::premutate( FunctionType *funcType ) { 1308 GuardScope( scopeTyVars ); 1368 1369 Type *ret = Parent::mutate( pointerType ); 1370 1371 scopeTyVars.endScope(); 1372 return ret; 1373 } 1374 1375 Type *Pass2::mutate( FunctionType *funcType ) { 1376 scopeTyVars.beginScope(); 1377 1309 1378 makeTyVarMap( funcType, scopeTyVars ); 1310 1379 … … 1345 1414 // move all assertions into parameter list 1346 1415 for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) { 1416 // *assert = (*assert)->acceptMutator( *this ); 1347 1417 // assertion parameters may not be used in body, pass along with unused attribute. 1348 1418 (*assert)->get_attributes().push_back( new Attribute( "unused" ) ); … … 1380 1450 } 1381 1451 } 1452 1382 1453 seenTypes.insert( typeName ); 1383 1454 } … … 1387 1458 funcType->get_parameters().splice( last, inferredParams ); 1388 1459 addAdapters( funcType ); 1460 mutateAll( funcType->get_returnVals(), *this ); 1461 mutateAll( funcType->get_parameters(), *this ); 1462 1463 scopeTyVars.endScope(); 1464 return funcType; 1389 1465 } 1390 1466 … … 1392 1468 1393 1469 PolyGenericCalculator::PolyGenericCalculator() 1394 : knownLayouts(), knownOffsets(), bufNamer( "_buf" ) {}1470 : knownLayouts(), knownOffsets(), bufNamer( "_buf" ), scopeTyVars( TypeDecl::Data{} ) {} 1395 1471 1396 1472 void PolyGenericCalculator::beginTypeScope( Type *ty ) { … … 1753 1829 1754 1830 template< typename DeclClass > 1755 void Pass3::handleDecl( DeclClass * decl, Type *type ) {1756 GuardScope( scopeTyVars);1831 DeclClass * Pass3::handleDecl( DeclClass *decl, Type *type ) { 1832 scopeTyVars.beginScope(); 1757 1833 makeTyVarMap( type, scopeTyVars ); 1834 1835 DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) ); 1836 // ScrubTyVars::scrub( decl, scopeTyVars ); 1758 1837 ScrubTyVars::scrubAll( decl ); 1759 } 1760 1761 void Pass3::premutate( ObjectDecl * objectDecl ) { 1762 handleDecl( objectDecl, objectDecl->type ); 1763 } 1764 1765 void Pass3::premutate( FunctionDecl * functionDecl ) { 1766 handleDecl( functionDecl, functionDecl->type ); 1767 } 1768 1769 void Pass3::premutate( TypedefDecl * typedefDecl ) { 1770 handleDecl( typedefDecl, typedefDecl->base ); 1838 1839 scopeTyVars.endScope(); 1840 return ret; 1841 } 1842 1843 ObjectDecl * Pass3::mutate( ObjectDecl *objectDecl ) { 1844 return handleDecl( objectDecl, objectDecl->get_type() ); 1845 } 1846 1847 DeclarationWithType * Pass3::mutate( FunctionDecl *functionDecl ) { 1848 return handleDecl( functionDecl, functionDecl->get_functionType() ); 1849 } 1850 1851 TypedefDecl * Pass3::mutate( TypedefDecl *typedefDecl ) { 1852 return handleDecl( typedefDecl, typedefDecl->get_base() ); 1771 1853 } 1772 1854 1773 1855 /// Strips the members from a generic aggregate 1774 void stripGenericMembers(AggregateDecl * decl) {1775 if ( ! decl-> parameters.empty() ) decl->members.clear();1776 } 1777 1778 void Pass3::premutate( StructDecl *structDecl ) {1856 void stripGenericMembers(AggregateDecl* decl) { 1857 if ( ! decl->get_parameters().empty() ) decl->get_members().clear(); 1858 } 1859 1860 Declaration *Pass3::mutate( StructDecl *structDecl ) { 1779 1861 stripGenericMembers( structDecl ); 1780 } 1781 1782 void Pass3::premutate( UnionDecl * unionDecl ) { 1862 return structDecl; 1863 } 1864 1865 Declaration *Pass3::mutate( UnionDecl *unionDecl ) { 1783 1866 stripGenericMembers( unionDecl ); 1784 } 1785 1786 void Pass3::premutate( TypeDecl * typeDecl ) { 1867 return unionDecl; 1868 } 1869 1870 TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) { 1871 // Initializer *init = 0; 1872 // std::list< Expression *> designators; 1873 // addToTyVarMap( typeDecl, scopeTyVars ); 1874 // if ( typeDecl->get_base() ) { 1875 // init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators ); 1876 // } 1877 // return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init ); 1878 1787 1879 addToTyVarMap( typeDecl, scopeTyVars ); 1788 } 1789 1790 void Pass3::premutate( PointerType * pointerType ) { 1791 GuardScope( scopeTyVars ); 1880 return dynamic_cast<TypeDecl*>( Mutator::mutate( typeDecl ) ); 1881 } 1882 1883 Type * Pass3::mutate( PointerType *pointerType ) { 1884 scopeTyVars.beginScope(); 1792 1885 makeTyVarMap( pointerType, scopeTyVars ); 1793 } 1794 1795 void Pass3::premutate( FunctionType * functionType ) { 1796 GuardScope( scopeTyVars ); 1886 1887 Type *ret = Mutator::mutate( pointerType ); 1888 1889 scopeTyVars.endScope(); 1890 return ret; 1891 } 1892 1893 Type * Pass3::mutate( FunctionType *functionType ) { 1894 scopeTyVars.beginScope(); 1797 1895 makeTyVarMap( functionType, scopeTyVars ); 1896 1897 Type *ret = Mutator::mutate( functionType ); 1898 1899 scopeTyVars.endScope(); 1900 return ret; 1798 1901 } 1799 1902 } // anonymous namespace
Note:
See TracChangeset
for help on using the changeset viewer.