Changes in src/GenPoly/Box.cc [271a5d3:8c91088]
- File:
-
- 1 edited
-
src/GenPoly/Box.cc (modified) (62 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r271a5d3 r8c91088 58 58 namespace GenPoly { 59 59 namespace { 60 FunctionType *makeAdapterType( FunctionType const*adaptee, const TyVarMap &tyVars );60 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 61 61 62 62 class BoxPass { … … 68 68 /// Adds layout-generation functions to polymorphic types. 69 69 class LayoutFunctionBuilder final : public WithDeclsToAdd, public WithVisitorRef<LayoutFunctionBuilder>, public WithShortCircuiting { 70 // Current level of nested functions: 71 unsigned int functionNesting = 0; 70 72 public: 73 void previsit( FunctionDecl *functionDecl ); 71 74 void previsit( StructDecl *structDecl ); 72 75 void previsit( UnionDecl *unionDecl ); … … 97 100 void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ); 98 101 /// passes extra type parameters into a polymorphic function application 99 /// Returns an iterator to the first argument after the added 100 /// arguments, which are added at the beginning. 101 std::list< Expression *>::iterator passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, const TyVarMap &exprTyVars ); 102 void passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 102 103 /// wraps a function application with a new temporary for the out-parameter return value 103 /// The new out-parameter is the new first parameter. 104 Expression *addRetParam( ApplicationExpr *appExpr, Type *retType ); 104 Expression *addRetParam( ApplicationExpr *appExpr, Type *retType, std::list< Expression *>::iterator &arg ); 105 /// Replaces all the type parameters of a generic type with their concrete equivalents under the current environment 106 void replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params ); 107 /// Replaces a polymorphic type with its concrete equivalant under the current environment (returns itself if concrete). 108 /// If `doClone` is set to false, will not clone interior types 109 Type *replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone = true ); 105 110 /// wraps a function application returning a polymorphic type with a new temporary for the out-parameter return value 106 Expression *addDynRetParam( ApplicationExpr *appExpr, Type *polyType ); 107 /// Converts a function call into a call of the adapter with the 108 /// original function as the first argument (all other arguments 109 /// are pushed back). May adjust return value. 110 Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function ); 111 /// Modifies the `arg`, replacing it with a boxed expression 112 /// that matches `formal` under the current TyVarMap. 113 void boxParam( Expression *&arg, Type *formal, const TyVarMap &exprTyVars ); 114 /// Box an argument of `appExpr` for each parameter in `function` 115 /// starting at `arg`. 116 /// `exprTyVars` is the function's type variables. 117 void boxParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *function, const TyVarMap &exprTyVars ); 118 /// Boxes each assertion and inserts them into `appExpr` at 119 /// `arg`. `exprTyVars` is the function's type variables. 120 void addInferredParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *functionType, const TyVarMap &tyVars ); 111 Expression *addDynRetParam( ApplicationExpr *appExpr, Type *polyType, std::list< Expression *>::iterator &arg ); 112 Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 113 void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars ); 114 void boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 115 void addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ); 121 116 /// Stores assignment operators from assertion list in local map of assignment operations 122 117 void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars ); 123 /// Creates an adapter definition from `adaptee` to `realType`, using 124 /// `mangleName` as the base name for the adapter. `tyVars` is the map of 125 /// type variables for the function type of the adapted expression. 126 FunctionDecl *makeAdapter( FunctionType const *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ); 118 FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ); 127 119 /// Replaces intrinsic operator functions with their arithmetic desugaring 128 120 Expression *handleIntrinsics( ApplicationExpr *appExpr ); … … 190 182 ObjectDecl *makeVar( const std::string &name, Type *type, Initializer *init = 0 ); 191 183 /// returns true if the type has a dynamic layout; such a layout will be stored in appropriately-named local variables when the function returns 192 bool findGeneric( Type const*ty );184 bool findGeneric( Type *ty ); 193 185 /// adds type parameters to the layout call; will generate the appropriate parameters if needed 194 186 void addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams ); … … 229 221 } // anonymous namespace 230 222 223 /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging 224 template< typename MutatorType > 225 inline void mutateTranslationUnit( std::list< Declaration* > &translationUnit, MutatorType &mutator ) { 226 bool seenIntrinsic = false; 227 SemanticErrorException errors; 228 for ( typename std::list< Declaration* >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) { 229 try { 230 if ( *i ) { 231 if ( (*i)->get_linkage() == LinkageSpec::Intrinsic ) { 232 seenIntrinsic = true; 233 } else if ( seenIntrinsic ) { 234 seenIntrinsic = false; // break on this line when debugging for end of prelude 235 } 236 237 *i = dynamic_cast< Declaration* >( (*i)->acceptMutator( mutator ) ); 238 assert( *i ); 239 } // if 240 } catch( SemanticErrorException &e ) { 241 errors.append( e ); 242 } // try 243 } // for 244 if ( ! errors.isEmpty() ) { 245 throw errors; 246 } // if 247 } 248 231 249 void box( std::list< Declaration *>& translationUnit ) { 232 250 PassVisitor<LayoutFunctionBuilder> layoutBuilder; … … 245 263 ////////////////////////////////// LayoutFunctionBuilder //////////////////////////////////////////// 246 264 265 void LayoutFunctionBuilder::previsit( FunctionDecl *functionDecl ) { 266 visit_children = false; 267 maybeAccept( functionDecl->get_functionType(), *visitor ); 268 ++functionNesting; 269 maybeAccept( functionDecl->get_statements(), *visitor ); 270 --functionNesting; 271 } 272 247 273 /// Get a list of type declarations that will affect a layout function 248 274 std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) { 249 275 std::list< TypeDecl * > otypeDecls; 250 276 251 for ( TypeDecl * const decl : decls) {252 if ( decl->isComplete() ) {253 otypeDecls.push_back( decl );277 for ( std::list< TypeDecl* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) { 278 if ( (*decl)->isComplete() ) { 279 otypeDecls.push_back( *decl ); 254 280 } 255 281 } … … 262 288 BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 263 289 264 for ( TypeDecl * const param : otypeParams) {265 TypeInstType paramType( Type::Qualifiers(), param->get_name(),param );290 for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) { 291 TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param ); 266 292 std::string paramName = mangleType( ¶mType ); 267 293 layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( paramName ), Type::StorageClasses(), LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) ); … … 271 297 272 298 /// Builds a layout function declaration 273 FunctionDecl *buildLayoutFunctionDecl( AggregateDecl *typeDecl, bool isInFunction, FunctionType *layoutFnType ) {299 FunctionDecl *buildLayoutFunctionDecl( AggregateDecl *typeDecl, unsigned int functionNesting, FunctionType *layoutFnType ) { 274 300 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units 275 301 // because each unit generates copies of the default routines for each aggregate. 276 302 FunctionDecl *layoutDecl = new FunctionDecl( layoutofName( typeDecl ), 277 isInFunction? Type::StorageClasses() : Type::StorageClasses( Type::Static ),303 functionNesting > 0 ? Type::StorageClasses() : Type::StorageClasses( Type::Static ), 278 304 LinkageSpec::AutoGen, layoutFnType, new CompoundStmt(), 279 305 std::list< Attribute * >(), Type::FuncSpecifiers( Type::Inline ) ); 280 306 layoutDecl->fixUniqueId(); 281 307 return layoutDecl; 308 } 309 310 /// Makes a unary operation 311 Expression *makeOp( const std::string &name, Expression *arg ) { 312 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) ); 313 expr->args.push_back( arg ); 314 return expr; 282 315 } 283 316 … … 347 380 348 381 // build function decl 349 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl, isInFunction(), layoutFnType );382 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl, functionNesting, layoutFnType ); 350 383 351 384 // calculate struct layout in function body … … 354 387 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant::from_ulong( 0 ) ) ) ); 355 388 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) ); 356 for ( auto index_member : enumerate( structDecl->members ) ) { 357 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( index_member.val ); 389 unsigned long n_members = 0; 390 bool firstMember = true; 391 for ( Declaration* member : structDecl->get_members() ) { 392 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( member ); 358 393 assert( dwt ); 359 394 Type *memberType = dwt->get_type(); 360 395 361 if ( 0 < index_member.idx ) { 396 if ( firstMember ) { 397 firstMember = false; 398 } else { 362 399 // make sure all members after the first (automatically aligned at 0) are properly padded for alignment 363 400 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) ); … … 365 402 366 403 // place current size in the current offset index 367 addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from_ulong( index_member.idx) ) ),404 addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from_ulong( n_members ) ) ), 368 405 derefVar( sizeParam ) ) ); 406 ++n_members; 369 407 370 408 // add member size to current size … … 401 439 402 440 // build function decl 403 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl, isInFunction(), layoutFnType );441 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl, functionNesting, layoutFnType ); 404 442 405 443 // calculate union layout in function body 406 444 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) ); 407 445 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) ); 408 for ( Declaration * const member : unionDecl->members) {409 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( member );446 for ( std::list< Declaration* >::const_iterator member = unionDecl->get_members().begin(); member != unionDecl->get_members().end(); ++member ) { 447 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ); 410 448 assert( dwt ); 411 449 Type *memberType = dwt->get_type(); … … 426 464 427 465 namespace { 428 std::string makePolyMonoSuffix( FunctionType const* function, const TyVarMap &tyVars ) {466 std::string makePolyMonoSuffix( FunctionType * function, const TyVarMap &tyVars ) { 429 467 std::stringstream name; 430 468 … … 435 473 // to take those polymorphic types as pointers. Therefore, there can be two different functions 436 474 // with the same mangled name, so we need to further mangle the names. 437 for ( DeclarationWithType const * const ret : function->returnVals) {438 if ( isPolyType( ret->get_type(), tyVars ) ) {475 for ( std::list< DeclarationWithType *>::iterator retval = function->get_returnVals().begin(); retval != function->get_returnVals().end(); ++retval ) { 476 if ( isPolyType( (*retval)->get_type(), tyVars ) ) { 439 477 name << "P"; 440 478 } else { … … 443 481 } 444 482 name << "_"; 445 for ( DeclarationWithType const * const arg : function->parameters ) { 446 if ( isPolyType( arg->get_type(), tyVars ) ) { 483 std::list< DeclarationWithType *> ¶mList = function->get_parameters(); 484 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) { 485 if ( isPolyType( (*arg)->get_type(), tyVars ) ) { 447 486 name << "P"; 448 487 } else { … … 453 492 } 454 493 455 std::string mangleAdapterName( FunctionType const* function, const TyVarMap &tyVars ) {494 std::string mangleAdapterName( FunctionType * function, const TyVarMap &tyVars ) { 456 495 return SymTab::Mangler::mangle( function ) + makePolyMonoSuffix( function, tyVars ); 457 496 } … … 460 499 return "_adapter" + mangleName; 461 500 } 462 463 /// Replaces a polymorphic type with its concrete equivalant under the current environment (returns itself if concrete).464 /// If `doClone` is set to false, will not clone interior types465 Type *replaceWithConcrete( Type *type, TypeSubstitution const * env, bool doClone = true );466 501 467 502 Pass1::Pass1() : tempNamer( "_temp" ) {} … … 489 524 490 525 std::list< DeclarationWithType *> ¶mList = functionType->parameters; 491 std::list< FunctionType const*> functions;492 for ( Type Decl * const tyVar : functionType->forall) {493 for ( DeclarationWithType * const assert : tyVar->assertions) {494 findFunction( assert->get_type(), functions, scopeTyVars, needsAdapter );526 std::list< FunctionType *> functions; 527 for ( Type::ForallList::iterator tyVar = functionType->forall.begin(); tyVar != functionType->forall.end(); ++tyVar ) { 528 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert ) { 529 findFunction( (*assert)->get_type(), functions, scopeTyVars, needsAdapter ); 495 530 } // for 496 531 } // for 497 for ( DeclarationWithType * const arg : paramList) {498 findFunction( arg->get_type(), functions, scopeTyVars, needsAdapter );532 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) { 533 findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter ); 499 534 } // for 500 535 501 for ( FunctionType const * const funType : functions) {502 std::string mangleName = mangleAdapterName( funType, scopeTyVars );536 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) { 537 std::string mangleName = mangleAdapterName( *funType, scopeTyVars ); 503 538 if ( adapters.find( mangleName ) == adapters.end() ) { 504 539 std::string adapterName = makeAdapterName( mangleName ); 505 adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, nullptr, new PointerType( Type::Qualifiers(), makeAdapterType( funType, scopeTyVars ) ), nullptr ) ) );540 adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, nullptr, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), nullptr ) ) ); 506 541 } // if 507 542 } // for … … 558 593 } 559 594 560 std::list< Expression *>::iterator Pass1::passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, const TyVarMap &exprTyVars ) { 561 assert( env ); 562 std::list< Expression *>::iterator arg = appExpr->args.begin(); 595 void Pass1::passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 563 596 // pass size/align for type variables 564 for ( std::pair<std::string, TypeDecl::Data> const & tyParam : exprTyVars) {597 for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) { 565 598 ResolvExpr::EqvClass eqvClass; 566 if ( tyParam.second.isComplete ) { 567 Type *concrete = env->lookup( tyParam.first ); 568 // If there is an unbound type variable, it should have detected already. 569 assertf( concrete, "Unbound type variable: %s in: %s", 570 toCString( tyParam.first ), toCString( *env ) ); 571 572 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) ); 573 arg++; 574 arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) ); 575 arg++; 599 assert( env ); 600 if ( tyParm->second.isComplete ) { 601 Type *concrete = env->lookup( tyParm->first ); 602 if ( concrete ) { 603 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) ); 604 arg++; 605 arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) ); 606 arg++; 607 } else { 608 // xxx - should this be an assertion? 609 SemanticError( appExpr, toString( *env, "\nunbound type variable: ", tyParm->first, " in application " ) ); 610 } // if 576 611 } // if 577 612 } // for 578 613 579 614 // add size/align for generic types to parameter list 580 if ( ! appExpr->get_function()->result ) return arg;615 if ( ! appExpr->get_function()->result ) return; 581 616 FunctionType *funcType = getFunctionType( appExpr->get_function()->get_result() ); 582 617 assert( funcType ); 583 618 584 // These iterators don't advance in unison.585 619 std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); 586 620 std::list< Expression* >::const_iterator fnArg = arg; … … 589 623 // a polymorphic return type may need to be added to the argument list 590 624 if ( polyRetType ) { 591 Type *concRetType = replaceWithConcrete( polyRetType, env);625 Type *concRetType = replaceWithConcrete( appExpr, polyRetType ); 592 626 passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes ); 593 627 ++fnArg; // skip the return parameter in the argument list … … 600 634 passArgTypeVars( appExpr, (*fnParm)->get_type(), argType, arg, exprTyVars, seenTypes ); 601 635 } 602 return arg;603 636 } 604 637 … … 609 642 } 610 643 611 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, Type *retType ) {644 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, Type *retType, std::list< Expression *>::iterator &arg ) { 612 645 // Create temporary to hold return value of polymorphic function and produce that temporary as a result 613 646 // using a comma expression. … … 629 662 paramExpr = new AddressExpr( paramExpr ); 630 663 } // if 631 // Add argument to function call.632 a ppExpr->args.push_front( paramExpr );664 arg = appExpr->args.insert( arg, paramExpr ); // add argument to function call 665 arg++; 633 666 // Build a comma expression to call the function and emulate a normal return. 634 667 CommaExpr *commaExpr = new CommaExpr( appExpr, retExpr ); … … 638 671 } 639 672 640 /// Replaces all the type parameters of a generic type with their concrete equivalents under the current environment 641 void replaceParametersWithConcrete( std::list< Expression* >& params, TypeSubstitution const * env ) { 642 for ( Expression * const param : params ) { 643 TypeExpr *paramType = dynamic_cast< TypeExpr* >( param ); 673 void Pass1::replaceParametersWithConcrete( ApplicationExpr *appExpr, std::list< Expression* >& params ) { 674 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) { 675 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 644 676 assertf(paramType, "Aggregate parameters should be type expressions"); 645 paramType->set_type( replaceWithConcrete( paramType->get_type(), env, false ) ); 646 } 647 } 648 649 // See forward definition. 650 Type *replaceWithConcrete( Type *type, TypeSubstitution const * env, bool doClone ) { 651 assert( env ); 677 paramType->set_type( replaceWithConcrete( appExpr, paramType->get_type(), false ) ); 678 } 679 } 680 681 Type *Pass1::replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone ) { 652 682 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) { 653 683 Type *concrete = env->lookup( typeInst->get_name() ); … … 660 690 structType = structType->clone(); 661 691 } 662 replaceParametersWithConcrete( structType->get_parameters(), env);692 replaceParametersWithConcrete( appExpr, structType->get_parameters() ); 663 693 return structType; 664 694 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) { … … 666 696 unionType = unionType->clone(); 667 697 } 668 replaceParametersWithConcrete( unionType->get_parameters(), env);698 replaceParametersWithConcrete( appExpr, unionType->get_parameters() ); 669 699 return unionType; 670 700 } … … 672 702 } 673 703 674 Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, Type *dynType ) { 675 Type *concrete = replaceWithConcrete( dynType, env ); 704 Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, Type *dynType, std::list< Expression *>::iterator &arg ) { 705 assert( env ); 706 Type *concrete = replaceWithConcrete( appExpr, dynType ); 676 707 // add out-parameter for return value 677 return addRetParam( appExpr, concrete );678 } 679 680 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function ) {708 return addRetParam( appExpr, concrete, arg ); 709 } 710 711 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) { 681 712 Expression *ret = appExpr; 682 713 // if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) { 683 if ( isDynRet( function, scopeTyVars ) ) {684 ret = addRetParam( appExpr, function->returnVals.front()->get_type() );714 if ( isDynRet( function, tyVars ) ) { 715 ret = addRetParam( appExpr, function->returnVals.front()->get_type(), arg ); 685 716 } // if 686 std::string mangleName = mangleAdapterName( function, scopeTyVars );717 std::string mangleName = mangleAdapterName( function, tyVars ); 687 718 std::string adapterName = makeAdapterName( mangleName ); 688 719 … … 693 724 694 725 return ret; 726 } 727 728 void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) { 729 assertf( arg->result, "arg does not have result: %s", toString( arg ).c_str() ); 730 if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return; 731 732 if ( arg->get_lvalue() ) { 733 // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations. 734 // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) { 735 // if ( dynamic_cast<ArrayType *>( varExpr->var->get_type() ) ){ 736 // // temporary hack - don't box arrays, because &arr is not the same as &arr[0] 737 // return; 738 // } 739 // } 740 arg = generalizedLvalue( new AddressExpr( arg ) ); 741 if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) { 742 // silence warnings by casting boxed parameters when the actual type does not match up with the formal type. 743 arg = new CastExpr( arg, param->clone() ); 744 } 745 } else { 746 // use type computed in unification to declare boxed variables 747 Type * newType = param->clone(); 748 if ( env ) env->apply( newType ); 749 ObjectDecl *newObj = ObjectDecl::newObject( tempNamer.newName(), newType, nullptr ); 750 newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right??? 751 stmtsToAddBefore.push_back( new DeclStmt( newObj ) ); 752 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax? 753 assign->get_args().push_back( new VariableExpr( newObj ) ); 754 assign->get_args().push_back( arg ); 755 stmtsToAddBefore.push_back( new ExprStmt( assign ) ); 756 arg = new AddressExpr( new VariableExpr( newObj ) ); 757 } // if 695 758 } 696 759 … … 728 791 } 729 792 730 void Pass1::boxParam( Expression *&arg, Type *param, const TyVarMap &exprTyVars ) { 731 assertf( arg->result, "arg does not have result: %s", toString( arg ).c_str() ); 732 addCast( arg, param, exprTyVars ); 733 if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return; 734 735 if ( arg->get_lvalue() ) { 736 // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations. 737 // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) { 738 // if ( dynamic_cast<ArrayType *>( varExpr->var->get_type() ) ){ 739 // // temporary hack - don't box arrays, because &arr is not the same as &arr[0] 740 // return; 741 // } 742 // } 743 arg = generalizedLvalue( new AddressExpr( arg ) ); 744 if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) { 745 // silence warnings by casting boxed parameters when the actual type does not match up with the formal type. 746 arg = new CastExpr( arg, param->clone() ); 747 } 748 } else { 749 // use type computed in unification to declare boxed variables 750 Type * newType = param->clone(); 751 if ( env ) env->apply( newType ); 752 ObjectDecl *newObj = makeTemporary( newType ); 753 // TODO: is this right??? (Why wouldn't it be?) 754 newObj->get_type()->get_qualifiers() = Type::Qualifiers(); 755 // TODO: why doesn't this just use initialization syntax? 756 // (Possibly to ensure code is run at the right time.) 757 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); 758 assign->get_args().push_back( new VariableExpr( newObj ) ); 759 assign->get_args().push_back( arg ); 760 stmtsToAddBefore.push_back( new ExprStmt( assign ) ); 761 arg = new AddressExpr( new VariableExpr( newObj ) ); 762 } // if 763 } 764 765 void Pass1::boxParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *function, const TyVarMap &exprTyVars ) { 766 for ( DeclarationWithType * param : function->parameters ) { 767 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() ); 768 boxParam( *arg, param->get_type(), exprTyVars ); 769 ++arg; 793 void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 794 for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->parameters.end(); ++param, ++arg ) { 795 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() ); 796 addCast( *arg, (*param)->get_type(), exprTyVars ); 797 boxParam( (*param)->get_type(), *arg, exprTyVars ); 770 798 } // for 771 799 } 772 800 773 void Pass1::addInferredParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *functionType, const TyVarMap &tyVars ) {801 void Pass1::addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) { 774 802 std::list< Expression *>::iterator cur = arg; 775 for ( Type Decl * const tyVar : functionType->forall) {776 for ( DeclarationWithType * const assert : tyVar->assertions) {777 InferredParams::const_iterator inferParam = appExpr->inferParams.find( assert->get_uniqueId() );778 assertf( inferParam != appExpr->inferParams.end(), "addInferredParams missing inferred parameter: %s in: %s", toString( assert ).c_str(), toString( appExpr ).c_str() );803 for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) { 804 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert ) { 805 InferredParams::const_iterator inferParam = appExpr->inferParams.find( (*assert)->get_uniqueId() ); 806 assertf( inferParam != appExpr->inferParams.end(), "addInferredParams missing inferred parameter: %s in: %s", toString( *assert ).c_str(), toString( appExpr ).c_str() ); 779 807 Expression *newExpr = inferParam->second.expr->clone(); 780 boxParam( newExpr, assert->get_type(), tyVars ); 808 addCast( newExpr, (*assert)->get_type(), tyVars ); 809 boxParam( (*assert)->get_type(), newExpr, tyVars ); 781 810 appExpr->get_args().insert( cur, newExpr ); 782 811 } // for … … 795 824 } 796 825 797 FunctionType *makeAdapterType( FunctionType const*adaptee, const TyVarMap &tyVars ) {826 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ) { 798 827 // actually make the adapter type 799 828 FunctionType *adapter = adaptee->clone(); … … 805 834 } 806 835 807 Expression *makeAdapterArg( 808 DeclarationWithType *param, 809 DeclarationWithType const *arg, 810 DeclarationWithType const *realParam, 811 const TyVarMap &tyVars ) { 836 Expression *makeAdapterArg( DeclarationWithType *param, DeclarationWithType *arg, DeclarationWithType *realParam, const TyVarMap &tyVars ) { 812 837 assert( param ); 813 838 assert( arg ); 814 if ( isPolyType( realParam->get_type(), tyVars ) 815 && ! isPolyType( arg->get_type() ) ) { 816 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 817 deref->args.push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) ); 818 deref->result = arg->get_type()->clone(); 819 return deref; 839 if ( isPolyType( realParam->get_type(), tyVars ) ) { 840 if ( ! isPolyType( arg->get_type() ) ) { 841 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 842 deref->args.push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) ); 843 deref->result = arg->get_type()->clone(); 844 return deref; 845 } // if 820 846 } // if 821 847 return new VariableExpr( param ); 822 848 } 823 849 824 void addAdapterParams( 825 ApplicationExpr *adapteeApp, 826 std::list< DeclarationWithType *>::const_iterator arg, 827 std::list< DeclarationWithType *>::const_iterator param, 828 std::list< DeclarationWithType *>::const_iterator paramEnd, 829 std::list< DeclarationWithType *>::const_iterator realParam, 830 const TyVarMap &tyVars ) { 850 void addAdapterParams( ApplicationExpr *adapteeApp, std::list< DeclarationWithType *>::iterator arg, std::list< DeclarationWithType *>::iterator param, std::list< DeclarationWithType *>::iterator paramEnd, std::list< DeclarationWithType *>::iterator realParam, const TyVarMap &tyVars ) { 831 851 UniqueName paramNamer( "_p" ); 832 852 for ( ; param != paramEnd; ++param, ++arg, ++realParam ) { … … 839 859 } 840 860 841 FunctionDecl *Pass1::makeAdapter( FunctionType const*adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) {861 FunctionDecl *Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) { 842 862 FunctionType *adapterType = makeAdapterType( adaptee, tyVars ); 843 863 adapterType = ScrubTyVars::scrub( adapterType, tyVars ); … … 856 876 Statement *bodyStmt; 857 877 858 for ( auto tys : group_iterate( realType->forall, adapterType->forall, adaptee->forall ) ) { 859 TypeDecl * tyArg = std::get<0>( tys ); 860 TypeDecl * tyParam = std::get<1>( tys ); 861 TypeDecl * realTyParam = std::get<2>( tys ); 862 for ( auto asserts : group_iterate( tyArg->assertions, tyParam->assertions, realTyParam->assertions ) ) { 863 DeclarationWithType * assertArg = std::get<0>( asserts ); 864 DeclarationWithType * assertParam = std::get<1>( asserts ); 865 DeclarationWithType * realAssertParam = std::get<2>( asserts ); 866 adapteeApp->args.push_back( makeAdapterArg( assertParam, assertArg, realAssertParam, tyVars ) ); 878 Type::ForallList::iterator tyArg = realType->get_forall().begin(); 879 Type::ForallList::iterator tyParam = adapterType->get_forall().begin(); 880 Type::ForallList::iterator realTyParam = adaptee->get_forall().begin(); 881 for ( ; tyParam != adapterType->get_forall().end(); ++tyArg, ++tyParam, ++realTyParam ) { 882 assert( tyArg != realType->get_forall().end() ); 883 std::list< DeclarationWithType *>::iterator assertArg = (*tyArg)->get_assertions().begin(); 884 std::list< DeclarationWithType *>::iterator assertParam = (*tyParam)->get_assertions().begin(); 885 std::list< DeclarationWithType *>::iterator realAssertParam = (*realTyParam)->get_assertions().begin(); 886 for ( ; assertParam != (*tyParam)->get_assertions().end(); ++assertArg, ++assertParam, ++realAssertParam ) { 887 assert( assertArg != (*tyArg)->get_assertions().end() ); 888 adapteeApp->get_args().push_back( makeAdapterArg( *assertParam, *assertArg, *realAssertParam, tyVars ) ); 867 889 } // for 868 890 } // for 869 891 870 std::list< DeclarationWithType *>:: const_iterator arg = realType->parameters.begin();871 std::list< DeclarationWithType *>:: const_iterator param = adapterType->parameters.begin();872 std::list< DeclarationWithType *>:: const_iterator realParam = adaptee->parameters.begin();892 std::list< DeclarationWithType *>::iterator arg = realType->get_parameters().begin(); 893 std::list< DeclarationWithType *>::iterator param = adapterType->get_parameters().begin(); 894 std::list< DeclarationWithType *>::iterator realParam = adaptee->get_parameters().begin(); 873 895 param++; // skip adaptee parameter in the adapter type 874 896 if ( realType->get_returnVals().empty() ) { … … 876 898 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars ); 877 899 bodyStmt = new ExprStmt( adapteeApp ); 878 } else if ( isDynType( adaptee-> returnVals.front()->get_type(), tyVars ) ) {900 } else if ( isDynType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) { 879 901 // return type T 880 902 if ( (*param)->get_name() == "" ) { … … 901 923 void Pass1::passAdapters( ApplicationExpr * appExpr, FunctionType * functionType, const TyVarMap & exprTyVars ) { 902 924 // collect a list of function types passed as parameters or implicit parameters (assertions) 903 std::list<FunctionType const *> functions; 904 for ( TypeDecl * const tyVar : functionType->get_forall() ) { 905 for ( DeclarationWithType * const assert : tyVar->get_assertions() ) { 906 findFunction( assert->get_type(), functions, exprTyVars, needsAdapter ); 925 std::list< DeclarationWithType *> ¶mList = functionType->get_parameters(); 926 std::list< FunctionType *> functions; 927 for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) { 928 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->get_assertions().begin(); assert != (*tyVar)->get_assertions().end(); ++assert ) { 929 findFunction( (*assert)->get_type(), functions, exprTyVars, needsAdapter ); 907 930 } // for 908 931 } // for 909 for ( DeclarationWithType * const arg : functionType->get_parameters()) {910 findFunction( arg->get_type(), functions, exprTyVars, needsAdapter );932 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) { 933 findFunction( (*arg)->get_type(), functions, exprTyVars, needsAdapter ); 911 934 } // for 912 935 … … 915 938 std::set< std::string > adaptersDone; 916 939 917 for ( FunctionType const * const funType : functions) {918 FunctionType *originalFunction = funType->clone();919 FunctionType *realFunction = funType->clone();940 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) { 941 FunctionType *originalFunction = (*funType)->clone(); 942 FunctionType *realFunction = (*funType)->clone(); 920 943 std::string mangleName = SymTab::Mangler::mangle( realFunction ); 921 944 … … 935 958 if ( adapter == adapters.end() ) { 936 959 // adapter has not been created yet in the current scope, so define it 937 FunctionDecl *newAdapter = makeAdapter( funType, realFunction, mangleName, exprTyVars );960 FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars ); 938 961 std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) ); 939 962 adapter = answer.first; … … 949 972 950 973 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) { 951 NameExpr *opExpr = new NameExpr( ( isIncr ) ? "?+=?" : "?-=?" ); 974 NameExpr *opExpr; 975 if ( isIncr ) { 976 opExpr = new NameExpr( "?+=?" ); 977 } else { 978 opExpr = new NameExpr( "?-=?" ); 979 } // if 952 980 UntypedExpr *addAssign = new UntypedExpr( opExpr ); 953 981 if ( AddressExpr *address = dynamic_cast< AddressExpr *>( appExpr->get_args().front() ) ) { … … 1092 1120 Expression *Pass1::postmutate( ApplicationExpr *appExpr ) { 1093 1121 // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl; 1094 // for ( auto tyVar : scopeTyVars) {1095 // std::cerr << tyVar.first << " ";1122 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) { 1123 // std::cerr << i->first << " "; 1096 1124 // } 1097 1125 // std::cerr << "\n"; … … 1106 1134 1107 1135 Expression *ret = appExpr; 1136 1137 std::list< Expression *>::iterator arg = appExpr->get_args().begin(); 1108 1138 std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin(); 1109 1139 … … 1126 1156 // std::cerr << "dynRetType: " << dynRetType << std::endl; 1127 1157 Type *concRetType = appExpr->get_result()->isVoid() ? nullptr : appExpr->get_result(); 1128 ret = addDynRetParam( appExpr, concRetType ); // xxx - used to use dynRetType instead of concRetType1158 ret = addDynRetParam( appExpr, concRetType, arg ); // xxx - used to use dynRetType instead of concRetType 1129 1159 } else if ( needsAdapter( function, scopeTyVars ) && ! needsAdapter( function, exprTyVars) ) { // xxx - exprTyVars is used above...? 1130 1160 // xxx - the ! needsAdapter check may be incorrect. It seems there is some situation where an adapter is applied where it shouldn't be, and this fixes it for some cases. More investigation is needed. … … 1134 1164 // std::cerr << *env << std::endl; 1135 1165 // change the application so it calls the adapter rather than the passed function 1136 ret = applyAdapter( appExpr, function );1166 ret = applyAdapter( appExpr, function, arg, scopeTyVars ); 1137 1167 } // if 1138 1139 Type *concRetType = replaceWithConcrete( dynRetType, env ); 1140 std::list< Expression *>::iterator arg =1141 passTypeVars( appExpr, concRetType, exprTyVars ); // xxx - used to use dynRetType instead of concRetType; this changed so that the correct type paramaters are passed for return types (it should be the concrete type's parameters, not the formal type's)1142 addInferredParams( appExpr, arg, function, exprTyVars );1143 1144 // This needs to point at the original first argument.1145 boxParams( appExpr, paramBegin, function, exprTyVars ); 1146 1168 arg = appExpr->get_args().begin(); 1169 1170 Type *concRetType = replaceWithConcrete( appExpr, dynRetType ); 1171 passTypeVars( appExpr, concRetType, arg, exprTyVars ); // xxx - used to use dynRetType instead of concRetType; this changed so that the correct type paramaters are passed for return types (it should be the concrete type's parameters, not the formal type's) 1172 addInferredParams( appExpr, function, arg, exprTyVars ); 1173 1174 arg = paramBegin; 1175 1176 boxParams( appExpr, function, arg, exprTyVars ); 1147 1177 passAdapters( appExpr, function, exprTyVars ); 1148 1178 … … 1150 1180 } 1151 1181 1152 bool isPolyDeref( UntypedExpr const * expr, TyVarMap const & scopeTyVars, TypeSubstitution const * env) {1182 Expression * Pass1::postmutate( UntypedExpr *expr ) { 1153 1183 if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) { 1154 if ( auto name = dynamic_cast<NameExpr const*>( expr->function ) ) {1184 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) { 1155 1185 if ( name->name == "*?" ) { 1156 return true; 1186 Expression *ret = expr->args.front(); 1187 expr->args.clear(); 1188 delete expr; 1189 return ret; 1157 1190 } // if 1158 1191 } // if 1159 1192 } // if 1160 return false;1161 }1162 1163 Expression * Pass1::postmutate( UntypedExpr *expr ) {1164 if ( isPolyDeref( expr, scopeTyVars, env ) ) {1165 Expression *ret = expr->args.front();1166 expr->args.clear();1167 delete expr;1168 return ret;1169 }1170 1193 return expr; 1171 1194 } … … 1177 1200 bool needs = false; 1178 1201 if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->arg ) ) { 1179 if ( isPolyDeref( expr, scopeTyVars, env ) ) { 1180 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->args.front() ) ) { 1181 assert( appExpr->function->result ); 1182 FunctionType *function = getFunctionType( appExpr->function->result ); 1183 assert( function ); 1184 needs = needsAdapter( function, scopeTyVars ); 1202 if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) { 1203 if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->function ) ) { 1204 if ( name->name == "*?" ) { 1205 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->args.front() ) ) { 1206 assert( appExpr->function->result ); 1207 FunctionType *function = getFunctionType( appExpr->function->result ); 1208 assert( function ); 1209 needs = needsAdapter( function, scopeTyVars ); 1210 } // if 1211 } // if 1185 1212 } // if 1186 1213 } // if … … 1233 1260 void Pass2::addAdapters( FunctionType *functionType ) { 1234 1261 std::list< DeclarationWithType *> ¶mList = functionType->parameters; 1235 std::list< FunctionType const*> functions;1236 for ( DeclarationWithType * const arg : functionType->parameters) {1237 Type *orig = arg->get_type();1262 std::list< FunctionType *> functions; 1263 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg ) { 1264 Type *orig = (*arg)->get_type(); 1238 1265 findAndReplaceFunction( orig, functions, scopeTyVars, needsAdapter ); 1239 arg->set_type( orig );1266 (*arg)->set_type( orig ); 1240 1267 } 1241 1268 std::set< std::string > adaptersDone; 1242 for ( FunctionType const * const funType : functions) {1243 std::string mangleName = mangleAdapterName( funType, scopeTyVars );1269 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) { 1270 std::string mangleName = mangleAdapterName( *funType, scopeTyVars ); 1244 1271 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) { 1245 1272 std::string adapterName = makeAdapterName( mangleName ); 1246 1273 // adapter may not be used in body, pass along with unused attribute. 1247 paramList.push_front( new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( funType, scopeTyVars ) ), 0, { new Attribute( "unused" ) } ) );1274 paramList.push_front( new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0, { new Attribute( "unused" ) } ) ); 1248 1275 adaptersDone.insert( adaptersDone.begin(), mangleName ); 1249 1276 } … … 1322 1349 ObjectDecl newPtr( "", Type::StorageClasses(), LinkageSpec::C, 0, 1323 1350 new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 ); 1324 for ( Type Decl * const tyParam : funcType->get_forall()) {1351 for ( Type::ForallList::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { 1325 1352 ObjectDecl *sizeParm, *alignParm; 1326 1353 // add all size and alignment parameters to parameter list 1327 if ( tyParam->isComplete() ) {1328 TypeInstType parmType( Type::Qualifiers(), tyParam->get_name(), tyParam );1354 if ( (*tyParm)->isComplete() ) { 1355 TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm ); 1329 1356 std::string parmName = mangleType( &parmType ); 1330 1357 … … 1340 1367 } 1341 1368 // move all assertions into parameter list 1342 for ( DeclarationWithType * const assert : tyParam->get_assertions()) {1369 for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) { 1343 1370 // assertion parameters may not be used in body, pass along with unused attribute. 1344 assert->get_attributes().push_back( new Attribute( "unused" ) );1345 inferredParams.push_back( assert );1346 } 1347 tyParam->get_assertions().clear();1371 (*assert)->get_attributes().push_back( new Attribute( "unused" ) ); 1372 inferredParams.push_back( *assert ); 1373 } 1374 (*tyParm)->get_assertions().clear(); 1348 1375 } 1349 1376 1350 1377 // add size/align for generic parameter types to parameter list 1351 1378 std::set< std::string > seenTypes; // sizeofName for generic types we've seen 1352 for ( DeclarationWithType * const fnParam : funcType->get_parameters()) {1353 Type *polyType = isPolyType( fnParam->get_type(), scopeTyVars );1379 for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) { 1380 Type *polyType = isPolyType( (*fnParm)->get_type(), scopeTyVars ); 1354 1381 if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) { 1355 1382 std::string typeName = mangleType( polyType ); … … 1455 1482 1456 1483 if(!expect_func_type) { 1484 GuardAction( [this]() { 1485 knownLayouts.endScope(); 1486 knownOffsets.endScope(); 1487 }); 1457 1488 // If this is the first function type we see 1458 1489 // Then it's the type of the declaration and we care about it 1459 GuardScope( *this ); 1490 knownLayouts.beginScope(); 1491 knownOffsets.beginScope(); 1460 1492 } 1461 1493 … … 1465 1497 1466 1498 // make sure that any type information passed into the function is accounted for 1467 for ( DeclarationWithType * const fnParam : funcType->get_parameters()) {1499 for ( std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); fnParm != funcType->get_parameters().end(); ++fnParm ) { 1468 1500 // condition here duplicates that in Pass2::mutate( FunctionType* ) 1469 Type *polyType = isPolyType( fnParam->get_type(), scopeTyVars );1501 Type *polyType = isPolyType( (*fnParm)->get_type(), scopeTyVars ); 1470 1502 if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) { 1471 1503 knownLayouts.insert( mangleType( polyType ) ); … … 1475 1507 1476 1508 /// converts polymorphic type T into a suitable monomorphic representation, currently: __attribute__((aligned(8)) char[size_T] 1477 Type * polyToMonoType( Type const* declType ) {1509 Type * polyToMonoType( Type * declType ) { 1478 1510 Type * charType = new BasicType( Type::Qualifiers(), BasicType::Kind::Char); 1479 1511 Expression * size = new NameExpr( sizeofName( mangleType(declType) ) ); … … 1540 1572 /// Finds the member in the base list that matches the given declaration; returns its index, or -1 if not present 1541 1573 long findMember( DeclarationWithType *memberDecl, std::list< Declaration* > &baseDecls ) { 1542 for ( auto pair : enumerate( baseDecls ) ) { 1543 Declaration * decl = pair.val; 1544 size_t i = pair.idx; 1545 if ( memberDecl->get_name() != decl->get_name() ) 1574 long i = 0; 1575 for(std::list< Declaration* >::const_iterator decl = baseDecls.begin(); decl != baseDecls.end(); ++decl, ++i ) { 1576 if ( memberDecl->get_name() != (*decl)->get_name() ) 1546 1577 continue; 1547 1578 1548 1579 if ( memberDecl->get_name().empty() ) { 1549 1580 // plan-9 field: match on unique_id 1550 if ( memberDecl->get_uniqueId() == decl->get_uniqueId() )1581 if ( memberDecl->get_uniqueId() == (*decl)->get_uniqueId() ) 1551 1582 return i; 1552 1583 else … … 1554 1585 } 1555 1586 1556 DeclarationWithType *declWithType = strict_dynamic_cast< DeclarationWithType* >( decl );1587 DeclarationWithType *declWithType = strict_dynamic_cast< DeclarationWithType* >( *decl ); 1557 1588 1558 1589 if ( memberDecl->get_mangleName().empty() || declWithType->get_mangleName().empty() ) { … … 1572 1603 1573 1604 /// Returns an index expression into the offset array for a type 1574 Expression *makeOffsetIndex( Type const*objectType, long i ) {1605 Expression *makeOffsetIndex( Type *objectType, long i ) { 1575 1606 ConstantExpr *fieldIndex = new ConstantExpr( Constant::from_ulong( i ) ); 1576 1607 UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) ); … … 1665 1696 1666 1697 void PolyGenericCalculator::addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams ) { 1667 for ( Type * const param : otypeParams) {1668 if ( findGeneric( param ) ) {1698 for ( std::list< Type* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) { 1699 if ( findGeneric( *param ) ) { 1669 1700 // push size/align vars for a generic parameter back 1670 std::string paramName = mangleType( param );1701 std::string paramName = mangleType( *param ); 1671 1702 layoutCall->get_args().push_back( new NameExpr( sizeofName( paramName ) ) ); 1672 1703 layoutCall->get_args().push_back( new NameExpr( alignofName( paramName ) ) ); 1673 1704 } else { 1674 layoutCall->get_args().push_back( new SizeofExpr( param->clone() ) );1675 layoutCall->get_args().push_back( new AlignofExpr( param->clone() ) );1705 layoutCall->get_args().push_back( new SizeofExpr( (*param)->clone() ) ); 1706 layoutCall->get_args().push_back( new AlignofExpr( (*param)->clone() ) ); 1676 1707 } 1677 1708 } … … 1679 1710 1680 1711 /// returns true if any of the otype parameters have a dynamic layout and puts all otype parameters in the output list 1681 bool findGenericParams( std::list< TypeDecl* > const &baseParams, std::list< Expression* > const&typeParams, std::list< Type* > &out ) {1712 bool findGenericParams( std::list< TypeDecl* > &baseParams, std::list< Expression* > &typeParams, std::list< Type* > &out ) { 1682 1713 bool hasDynamicLayout = false; 1683 1714 1684 for ( auto paramPair : group_iterate( baseParams, typeParams ) ) {1685 TypeDecl * baseParam = std::get<0>( paramPair);1686 Expression * typeParam = std::get<1>( paramPair );1715 std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin(); 1716 std::list< Expression* >::const_iterator typeParam = typeParams.begin(); 1717 for ( ; baseParam != baseParams.end() && typeParam != typeParams.end(); ++baseParam, ++typeParam ) { 1687 1718 // skip non-otype parameters 1688 if ( ! baseParam->isComplete() ) continue;1689 TypeExpr *typeExpr = dynamic_cast< TypeExpr* >( typeParam );1719 if ( ! (*baseParam)->isComplete() ) continue; 1720 TypeExpr *typeExpr = dynamic_cast< TypeExpr* >( *typeParam ); 1690 1721 assert( typeExpr && "all otype parameters should be type expressions" ); 1691 1722 … … 1694 1725 if ( isPolyType( type ) ) hasDynamicLayout = true; 1695 1726 } 1727 assert( baseParam == baseParams.end() && typeParam == typeParams.end() ); 1696 1728 1697 1729 return hasDynamicLayout; 1698 1730 } 1699 1731 1700 bool PolyGenericCalculator::findGeneric( Type const*ty ) {1732 bool PolyGenericCalculator::findGeneric( Type *ty ) { 1701 1733 ty = replaceTypeInst( ty, env ); 1702 1734 1703 if ( auto typeInst = dynamic_cast< TypeInstType const* >( ty ) ) {1735 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) { 1704 1736 if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() ) { 1705 1737 // NOTE assumes here that getting put in the scopeTyVars included having the layout variables set … … 1707 1739 } 1708 1740 return false; 1709 } else if ( auto structTy = dynamic_cast< StructInstType const* >( ty ) ) {1741 } else if ( StructInstType *structTy = dynamic_cast< StructInstType* >( ty ) ) { 1710 1742 // check if this type already has a layout generated for it 1711 1743 std::string typeName = mangleType( ty ); … … 1714 1746 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized 1715 1747 std::list< Type* > otypeParams; 1716 if ( ! findGenericParams( *structTy->get_baseParameters(), structTy-> parameters, otypeParams ) ) return false;1748 if ( ! findGenericParams( *structTy->get_baseParameters(), structTy->get_parameters(), otypeParams ) ) return false; 1717 1749 1718 1750 // insert local variables for layout and generate call to layout function … … 1744 1776 1745 1777 return true; 1746 } else if ( auto unionTy = dynamic_cast< UnionInstType const* >( ty ) ) {1778 } else if ( UnionInstType *unionTy = dynamic_cast< UnionInstType* >( ty ) ) { 1747 1779 // check if this type already has a layout generated for it 1748 1780 std::string typeName = mangleType( ty ); … … 1751 1783 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized 1752 1784 std::list< Type* > otypeParams; 1753 if ( ! findGenericParams( *unionTy->get_baseParameters(), unionTy-> parameters, otypeParams ) ) return false;1785 if ( ! findGenericParams( *unionTy->get_baseParameters(), unionTy->get_parameters(), otypeParams ) ) return false; 1754 1786 1755 1787 // insert local variables for layout and generate call to layout function … … 1849 1881 // build initializer list for offset array 1850 1882 std::list< Initializer* > inits; 1851 for ( Declaration * const member : baseMembers ) { 1852 DeclarationWithType *memberDecl = dynamic_cast< DeclarationWithType* >( member ); 1853 assertf( memberDecl, "Requesting offset of Non-DWT member: %s", toString( member ).c_str() ); 1854 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) ); 1883 for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) { 1884 if ( DeclarationWithType *memberDecl = dynamic_cast< DeclarationWithType* >( *member ) ) { 1885 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) ); 1886 } else { 1887 assertf( false, "Requesting offset of Non-DWT member: %s", toString( *member ).c_str() ); 1888 } 1855 1889 } 1856 1890 … … 1931 1965 // compile-command: "make install" // 1932 1966 // End: // 1933
Note:
See TracChangeset
for help on using the changeset viewer.