Changeset 63be3387 for src/GenPoly/Box.cc
- Timestamp:
- Nov 14, 2022, 11:52:44 AM (3 years ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- 7d9598d8
- Parents:
- b77f0e1 (diff), 19a8c40 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
rb77f0e1 r63be3387 58 58 namespace GenPoly { 59 59 namespace { 60 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );60 FunctionType *makeAdapterType( FunctionType const *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;72 70 public: 73 void previsit( FunctionDecl *functionDecl );74 71 void previsit( StructDecl *structDecl ); 75 72 void previsit( UnionDecl *unionDecl ); … … 100 97 void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ); 101 98 /// passes extra type parameters into a polymorphic function application 102 void passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 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 ); 103 102 /// wraps a function application with a new temporary for the out-parameter return value 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 ); 103 /// The new out-parameter is the new first parameter. 104 Expression *addRetParam( ApplicationExpr *appExpr, Type *retType ); 110 105 /// wraps a function application returning a polymorphic type with a new temporary for the out-parameter return value 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 ); 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 ); 116 121 /// Stores assignment operators from assertion list in local map of assignment operations 117 122 void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars ); 118 FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ); 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 ); 119 127 /// Replaces intrinsic operator functions with their arithmetic desugaring 120 128 Expression *handleIntrinsics( ApplicationExpr *appExpr ); … … 182 190 ObjectDecl *makeVar( const std::string &name, Type *type, Initializer *init = 0 ); 183 191 /// returns true if the type has a dynamic layout; such a layout will be stored in appropriately-named local variables when the function returns 184 bool findGeneric( Type *ty );192 bool findGeneric( Type const *ty ); 185 193 /// adds type parameters to the layout call; will generate the appropriate parameters if needed 186 194 void addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams ); … … 221 229 } // anonymous namespace 222 230 223 /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging224 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 prelude235 }236 237 *i = dynamic_cast< Declaration* >( (*i)->acceptMutator( mutator ) );238 assert( *i );239 } // if240 } catch( SemanticErrorException &e ) {241 errors.append( e );242 } // try243 } // for244 if ( ! errors.isEmpty() ) {245 throw errors;246 } // if247 }248 249 231 void box( std::list< Declaration *>& translationUnit ) { 250 232 PassVisitor<LayoutFunctionBuilder> layoutBuilder; … … 263 245 ////////////////////////////////// LayoutFunctionBuilder //////////////////////////////////////////// 264 246 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 273 247 /// Get a list of type declarations that will affect a layout function 274 248 std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) { 275 249 std::list< TypeDecl * > otypeDecls; 276 250 277 for ( std::list< TypeDecl* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl) {278 if ( (*decl)->isComplete() ) {279 otypeDecls.push_back( *decl );251 for ( TypeDecl * const decl : decls ) { 252 if ( decl->isComplete() ) { 253 otypeDecls.push_back( decl ); 280 254 } 281 255 } … … 288 262 BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 289 263 290 for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param) {291 TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param );264 for ( TypeDecl * const param : otypeParams ) { 265 TypeInstType paramType( Type::Qualifiers(), param->get_name(), param ); 292 266 std::string paramName = mangleType( ¶mType ); 293 267 layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( paramName ), Type::StorageClasses(), LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) ); … … 297 271 298 272 /// Builds a layout function declaration 299 FunctionDecl *buildLayoutFunctionDecl( AggregateDecl *typeDecl, unsigned int functionNesting, FunctionType *layoutFnType ) {273 FunctionDecl *buildLayoutFunctionDecl( AggregateDecl *typeDecl, bool isInFunction, FunctionType *layoutFnType ) { 300 274 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units 301 275 // because each unit generates copies of the default routines for each aggregate. 302 276 FunctionDecl *layoutDecl = new FunctionDecl( layoutofName( typeDecl ), 303 functionNesting > 0? Type::StorageClasses() : Type::StorageClasses( Type::Static ),277 isInFunction ? Type::StorageClasses() : Type::StorageClasses( Type::Static ), 304 278 LinkageSpec::AutoGen, layoutFnType, new CompoundStmt(), 305 279 std::list< Attribute * >(), Type::FuncSpecifiers( Type::Inline ) ); 306 280 layoutDecl->fixUniqueId(); 307 281 return layoutDecl; 308 }309 310 /// Makes a unary operation311 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;315 282 } 316 283 … … 380 347 381 348 // build function decl 382 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl, functionNesting, layoutFnType );349 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl, isInFunction(), layoutFnType ); 383 350 384 351 // calculate struct layout in function body … … 387 354 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant::from_ulong( 0 ) ) ) ); 388 355 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) ); 389 unsigned long n_members = 0; 390 bool firstMember = true; 391 for ( Declaration* member : structDecl->get_members() ) { 392 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( member ); 356 for ( auto index_member : enumerate( structDecl->members ) ) { 357 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( index_member.val ); 393 358 assert( dwt ); 394 359 Type *memberType = dwt->get_type(); 395 360 396 if ( firstMember ) { 397 firstMember = false; 398 } else { 361 if ( 0 < index_member.idx ) { 399 362 // make sure all members after the first (automatically aligned at 0) are properly padded for alignment 400 363 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) ); … … 402 365 403 366 // place current size in the current offset index 404 addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from_ulong( n_members) ) ),367 addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from_ulong( index_member.idx ) ) ), 405 368 derefVar( sizeParam ) ) ); 406 ++n_members;407 369 408 370 // add member size to current size … … 439 401 440 402 // build function decl 441 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl, functionNesting, layoutFnType );403 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl, isInFunction(), layoutFnType ); 442 404 443 405 // calculate union layout in function body 444 406 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) ); 445 407 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant::from_ulong( 1 ) ) ) ); 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 );408 for ( Declaration * const member : unionDecl->members ) { 409 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( member ); 448 410 assert( dwt ); 449 411 Type *memberType = dwt->get_type(); … … 464 426 465 427 namespace { 466 std::string makePolyMonoSuffix( FunctionType * function, const TyVarMap &tyVars ) {428 std::string makePolyMonoSuffix( FunctionType const * function, const TyVarMap &tyVars ) { 467 429 std::stringstream name; 468 430 … … 473 435 // to take those polymorphic types as pointers. Therefore, there can be two different functions 474 436 // with the same mangled name, so we need to further mangle the names. 475 for ( std::list< DeclarationWithType *>::iterator retval = function->get_returnVals().begin(); retval != function->get_returnVals().end(); ++retval) {476 if ( isPolyType( (*retval)->get_type(), tyVars ) ) {437 for ( DeclarationWithType const * const ret : function->returnVals ) { 438 if ( isPolyType( ret->get_type(), tyVars ) ) { 477 439 name << "P"; 478 440 } else { … … 481 443 } 482 444 name << "_"; 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 ) ) { 445 for ( DeclarationWithType const * const arg : function->parameters ) { 446 if ( isPolyType( arg->get_type(), tyVars ) ) { 486 447 name << "P"; 487 448 } else { … … 492 453 } 493 454 494 std::string mangleAdapterName( FunctionType * function, const TyVarMap &tyVars ) {455 std::string mangleAdapterName( FunctionType const * function, const TyVarMap &tyVars ) { 495 456 return SymTab::Mangler::mangle( function ) + makePolyMonoSuffix( function, tyVars ); 496 457 } … … 499 460 return "_adapter" + mangleName; 500 461 } 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 types 465 Type *replaceWithConcrete( Type *type, TypeSubstitution const * env, bool doClone = true ); 501 466 502 467 Pass1::Pass1() : tempNamer( "_temp" ) {} … … 524 489 525 490 std::list< DeclarationWithType *> ¶mList = functionType->parameters; 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 );491 std::list< FunctionType const *> functions; 492 for ( TypeDecl * const tyVar : functionType->forall ) { 493 for ( DeclarationWithType * const assert : tyVar->assertions ) { 494 findFunction( assert->get_type(), functions, scopeTyVars, needsAdapter ); 530 495 } // for 531 496 } // for 532 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg) {533 findFunction( (*arg)->get_type(), functions, scopeTyVars, needsAdapter );497 for ( DeclarationWithType * const arg : paramList ) { 498 findFunction( arg->get_type(), functions, scopeTyVars, needsAdapter ); 534 499 } // for 535 500 536 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType) {537 std::string mangleName = mangleAdapterName( *funType, scopeTyVars );501 for ( FunctionType const * const funType : functions ) { 502 std::string mangleName = mangleAdapterName( funType, scopeTyVars ); 538 503 if ( adapters.find( mangleName ) == adapters.end() ) { 539 504 std::string adapterName = makeAdapterName( mangleName ); 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 ) ) );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 ) ) ); 541 506 } // if 542 507 } // for … … 593 558 } 594 559 595 void Pass1::passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 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(); 596 563 // pass size/align for type variables 597 for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm) {564 for ( std::pair<std::string, TypeDecl::Data> const & tyParam : exprTyVars ) { 598 565 ResolvExpr::EqvClass eqvClass; 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 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++; 611 576 } // if 612 577 } // for 613 578 614 579 // add size/align for generic types to parameter list 615 if ( ! appExpr->get_function()->result ) return ;580 if ( ! appExpr->get_function()->result ) return arg; 616 581 FunctionType *funcType = getFunctionType( appExpr->get_function()->get_result() ); 617 582 assert( funcType ); 618 583 584 // These iterators don't advance in unison. 619 585 std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); 620 586 std::list< Expression* >::const_iterator fnArg = arg; … … 623 589 // a polymorphic return type may need to be added to the argument list 624 590 if ( polyRetType ) { 625 Type *concRetType = replaceWithConcrete( appExpr, polyRetType);591 Type *concRetType = replaceWithConcrete( polyRetType, env ); 626 592 passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes ); 627 593 ++fnArg; // skip the return parameter in the argument list … … 634 600 passArgTypeVars( appExpr, (*fnParm)->get_type(), argType, arg, exprTyVars, seenTypes ); 635 601 } 602 return arg; 636 603 } 637 604 … … 642 609 } 643 610 644 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, Type *retType , std::list< Expression *>::iterator &arg) {611 Expression *Pass1::addRetParam( ApplicationExpr *appExpr, Type *retType ) { 645 612 // Create temporary to hold return value of polymorphic function and produce that temporary as a result 646 613 // using a comma expression. … … 662 629 paramExpr = new AddressExpr( paramExpr ); 663 630 } // if 664 arg = appExpr->args.insert( arg, paramExpr ); // add argument to function call665 a rg++;631 // Add argument to function call. 632 appExpr->args.push_front( paramExpr ); 666 633 // Build a comma expression to call the function and emulate a normal return. 667 634 CommaExpr *commaExpr = new CommaExpr( appExpr, retExpr ); … … 671 638 } 672 639 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 ); 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 ); 676 644 assertf(paramType, "Aggregate parameters should be type expressions"); 677 paramType->set_type( replaceWithConcrete( appExpr, paramType->get_type(), false ) ); 678 } 679 } 680 681 Type *Pass1::replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone ) { 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 ); 682 652 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) { 683 653 Type *concrete = env->lookup( typeInst->get_name() ); … … 690 660 structType = structType->clone(); 691 661 } 692 replaceParametersWithConcrete( appExpr, structType->get_parameters());662 replaceParametersWithConcrete( structType->get_parameters(), env ); 693 663 return structType; 694 664 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) { … … 696 666 unionType = unionType->clone(); 697 667 } 698 replaceParametersWithConcrete( appExpr, unionType->get_parameters());668 replaceParametersWithConcrete( unionType->get_parameters(), env ); 699 669 return unionType; 700 670 } … … 702 672 } 703 673 704 Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, Type *dynType, std::list< Expression *>::iterator &arg ) { 705 assert( env ); 706 Type *concrete = replaceWithConcrete( appExpr, dynType ); 674 Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, Type *dynType ) { 675 Type *concrete = replaceWithConcrete( dynType, env ); 707 676 // add out-parameter for return value 708 return addRetParam( appExpr, concrete , arg);709 } 710 711 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function , std::list< Expression *>::iterator &arg, const TyVarMap &tyVars) {677 return addRetParam( appExpr, concrete ); 678 } 679 680 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function ) { 712 681 Expression *ret = appExpr; 713 682 // if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) { 714 if ( isDynRet( function, tyVars ) ) {715 ret = addRetParam( appExpr, function->returnVals.front()->get_type() , arg);683 if ( isDynRet( function, scopeTyVars ) ) { 684 ret = addRetParam( appExpr, function->returnVals.front()->get_type() ); 716 685 } // if 717 std::string mangleName = mangleAdapterName( function, tyVars );686 std::string mangleName = mangleAdapterName( function, scopeTyVars ); 718 687 std::string adapterName = makeAdapterName( mangleName ); 719 688 … … 724 693 725 694 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 variables747 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 } // if758 695 } 759 696 … … 791 728 } 792 729 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 ); 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; 798 770 } // for 799 771 } 800 772 801 void Pass1::addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {773 void Pass1::addInferredParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *functionType, const TyVarMap &tyVars ) { 802 774 std::list< Expression *>::iterator cur = arg; 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() );775 for ( TypeDecl * 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() ); 807 779 Expression *newExpr = inferParam->second.expr->clone(); 808 addCast( newExpr, (*assert)->get_type(), tyVars ); 809 boxParam( (*assert)->get_type(), newExpr, tyVars ); 780 boxParam( newExpr, assert->get_type(), tyVars ); 810 781 appExpr->get_args().insert( cur, newExpr ); 811 782 } // for … … 824 795 } 825 796 826 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ) {797 FunctionType *makeAdapterType( FunctionType const *adaptee, const TyVarMap &tyVars ) { 827 798 // actually make the adapter type 828 799 FunctionType *adapter = adaptee->clone(); … … 834 805 } 835 806 836 Expression *makeAdapterArg( DeclarationWithType *param, DeclarationWithType *arg, DeclarationWithType *realParam, const TyVarMap &tyVars ) { 807 Expression *makeAdapterArg( 808 DeclarationWithType *param, 809 DeclarationWithType const *arg, 810 DeclarationWithType const *realParam, 811 const TyVarMap &tyVars ) { 837 812 assert( param ); 838 813 assert( arg ); 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 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; 846 820 } // if 847 821 return new VariableExpr( param ); 848 822 } 849 823 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 ) { 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 ) { 851 831 UniqueName paramNamer( "_p" ); 852 832 for ( ; param != paramEnd; ++param, ++arg, ++realParam ) { … … 859 839 } 860 840 861 FunctionDecl *Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) {841 FunctionDecl *Pass1::makeAdapter( FunctionType const *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) { 862 842 FunctionType *adapterType = makeAdapterType( adaptee, tyVars ); 863 843 adapterType = ScrubTyVars::scrub( adapterType, tyVars ); … … 876 856 Statement *bodyStmt; 877 857 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 ) ); 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 ) ); 889 867 } // for 890 868 } // for 891 869 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();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(); 895 873 param++; // skip adaptee parameter in the adapter type 896 874 if ( realType->get_returnVals().empty() ) { … … 898 876 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars ); 899 877 bodyStmt = new ExprStmt( adapteeApp ); 900 } else if ( isDynType( adaptee-> get_returnVals().front()->get_type(), tyVars ) ) {878 } else if ( isDynType( adaptee->returnVals.front()->get_type(), tyVars ) ) { 901 879 // return type T 902 880 if ( (*param)->get_name() == "" ) { … … 923 901 void Pass1::passAdapters( ApplicationExpr * appExpr, FunctionType * functionType, const TyVarMap & exprTyVars ) { 924 902 // collect a list of function types passed as parameters or implicit parameters (assertions) 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 ); 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 ); 930 907 } // for 931 908 } // for 932 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg) {933 findFunction( (*arg)->get_type(), functions, exprTyVars, needsAdapter );909 for ( DeclarationWithType * const arg : functionType->get_parameters() ) { 910 findFunction( arg->get_type(), functions, exprTyVars, needsAdapter ); 934 911 } // for 935 912 … … 938 915 std::set< std::string > adaptersDone; 939 916 940 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType) {941 FunctionType *originalFunction = (*funType)->clone();942 FunctionType *realFunction = (*funType)->clone();917 for ( FunctionType const * const funType : functions ) { 918 FunctionType *originalFunction = funType->clone(); 919 FunctionType *realFunction = funType->clone(); 943 920 std::string mangleName = SymTab::Mangler::mangle( realFunction ); 944 921 … … 958 935 if ( adapter == adapters.end() ) { 959 936 // adapter has not been created yet in the current scope, so define it 960 FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars );937 FunctionDecl *newAdapter = makeAdapter( funType, realFunction, mangleName, exprTyVars ); 961 938 std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) ); 962 939 adapter = answer.first; … … 972 949 973 950 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) { 974 NameExpr *opExpr; 975 if ( isIncr ) { 976 opExpr = new NameExpr( "?+=?" ); 977 } else { 978 opExpr = new NameExpr( "?-=?" ); 979 } // if 951 NameExpr *opExpr = new NameExpr( ( isIncr ) ? "?+=?" : "?-=?" ); 980 952 UntypedExpr *addAssign = new UntypedExpr( opExpr ); 981 953 if ( AddressExpr *address = dynamic_cast< AddressExpr *>( appExpr->get_args().front() ) ) { … … 1120 1092 Expression *Pass1::postmutate( ApplicationExpr *appExpr ) { 1121 1093 // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl; 1122 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i) {1123 // std::cerr << i->first << " ";1094 // for ( auto tyVar : scopeTyVars ) { 1095 // std::cerr << tyVar.first << " "; 1124 1096 // } 1125 1097 // std::cerr << "\n"; … … 1134 1106 1135 1107 Expression *ret = appExpr; 1136 1137 std::list< Expression *>::iterator arg = appExpr->get_args().begin();1138 1108 std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin(); 1139 1109 … … 1156 1126 // std::cerr << "dynRetType: " << dynRetType << std::endl; 1157 1127 Type *concRetType = appExpr->get_result()->isVoid() ? nullptr : appExpr->get_result(); 1158 ret = addDynRetParam( appExpr, concRetType , arg); // xxx - used to use dynRetType instead of concRetType1128 ret = addDynRetParam( appExpr, concRetType ); // xxx - used to use dynRetType instead of concRetType 1159 1129 } else if ( needsAdapter( function, scopeTyVars ) && ! needsAdapter( function, exprTyVars) ) { // xxx - exprTyVars is used above...? 1160 1130 // 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. … … 1164 1134 // std::cerr << *env << std::endl; 1165 1135 // change the application so it calls the adapter rather than the passed function 1166 ret = applyAdapter( appExpr, function , arg, scopeTyVars);1136 ret = applyAdapter( appExpr, function ); 1167 1137 } // if 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 ); 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 1177 1147 passAdapters( appExpr, function, exprTyVars ); 1178 1148 … … 1180 1150 } 1181 1151 1182 Expression * Pass1::postmutate( UntypedExpr *expr) {1152 bool isPolyDeref( UntypedExpr const * expr, TyVarMap const & scopeTyVars, TypeSubstitution const * env ) { 1183 1153 if ( expr->result && isPolyType( expr->result, scopeTyVars, env ) ) { 1184 if ( NameExpr *name = dynamic_cast< NameExpr*>( expr->function ) ) {1154 if ( auto name = dynamic_cast<NameExpr const *>( expr->function ) ) { 1185 1155 if ( name->name == "*?" ) { 1186 Expression *ret = expr->args.front(); 1187 expr->args.clear(); 1188 delete expr; 1189 return ret; 1156 return true; 1190 1157 } // if 1191 1158 } // if 1192 1159 } // 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 } 1193 1170 return expr; 1194 1171 } … … 1200 1177 bool needs = false; 1201 1178 if ( UntypedExpr *expr = dynamic_cast< UntypedExpr *>( addrExpr->arg ) ) { 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 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 ); 1212 1185 } // if 1213 1186 } // if … … 1260 1233 void Pass2::addAdapters( FunctionType *functionType ) { 1261 1234 std::list< DeclarationWithType *> ¶mList = functionType->parameters; 1262 std::list< FunctionType *> functions;1263 for ( std::list< DeclarationWithType *>::iterator arg = paramList.begin(); arg != paramList.end(); ++arg) {1264 Type *orig = (*arg)->get_type();1235 std::list< FunctionType const *> functions; 1236 for ( DeclarationWithType * const arg : functionType->parameters ) { 1237 Type *orig = arg->get_type(); 1265 1238 findAndReplaceFunction( orig, functions, scopeTyVars, needsAdapter ); 1266 (*arg)->set_type( orig );1239 arg->set_type( orig ); 1267 1240 } 1268 1241 std::set< std::string > adaptersDone; 1269 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType) {1270 std::string mangleName = mangleAdapterName( *funType, scopeTyVars );1242 for ( FunctionType const * const funType : functions ) { 1243 std::string mangleName = mangleAdapterName( funType, scopeTyVars ); 1271 1244 if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) { 1272 1245 std::string adapterName = makeAdapterName( mangleName ); 1273 1246 // adapter may not be used in body, pass along with unused attribute. 1274 paramList.push_front( new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0, { new Attribute( "unused" ) } ) );1247 paramList.push_front( new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( funType, scopeTyVars ) ), 0, { new Attribute( "unused" ) } ) ); 1275 1248 adaptersDone.insert( adaptersDone.begin(), mangleName ); 1276 1249 } … … 1349 1322 ObjectDecl newPtr( "", Type::StorageClasses(), LinkageSpec::C, 0, 1350 1323 new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 ); 1351 for ( Type ::ForallList::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm) {1324 for ( TypeDecl * const tyParam : funcType->get_forall() ) { 1352 1325 ObjectDecl *sizeParm, *alignParm; 1353 1326 // add all size and alignment parameters to parameter list 1354 if ( (*tyParm)->isComplete() ) {1355 TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm );1327 if ( tyParam->isComplete() ) { 1328 TypeInstType parmType( Type::Qualifiers(), tyParam->get_name(), tyParam ); 1356 1329 std::string parmName = mangleType( &parmType ); 1357 1330 … … 1367 1340 } 1368 1341 // move all assertions into parameter list 1369 for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert) {1342 for ( DeclarationWithType * const assert : tyParam->get_assertions() ) { 1370 1343 // assertion parameters may not be used in body, pass along with unused attribute. 1371 (*assert)->get_attributes().push_back( new Attribute( "unused" ) );1372 inferredParams.push_back( *assert );1373 } 1374 (*tyParm)->get_assertions().clear();1344 assert->get_attributes().push_back( new Attribute( "unused" ) ); 1345 inferredParams.push_back( assert ); 1346 } 1347 tyParam->get_assertions().clear(); 1375 1348 } 1376 1349 1377 1350 // add size/align for generic parameter types to parameter list 1378 1351 std::set< std::string > seenTypes; // sizeofName for generic types we've seen 1379 for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm) {1380 Type *polyType = isPolyType( (*fnParm)->get_type(), scopeTyVars );1352 for ( DeclarationWithType * const fnParam : funcType->get_parameters() ) { 1353 Type *polyType = isPolyType( fnParam->get_type(), scopeTyVars ); 1381 1354 if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) { 1382 1355 std::string typeName = mangleType( polyType ); … … 1482 1455 1483 1456 if(!expect_func_type) { 1484 GuardAction( [this]() {1485 knownLayouts.endScope();1486 knownOffsets.endScope();1487 });1488 1457 // If this is the first function type we see 1489 1458 // Then it's the type of the declaration and we care about it 1490 knownLayouts.beginScope(); 1491 knownOffsets.beginScope(); 1459 GuardScope( *this ); 1492 1460 } 1493 1461 … … 1497 1465 1498 1466 // make sure that any type information passed into the function is accounted for 1499 for ( std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); fnParm != funcType->get_parameters().end(); ++fnParm) {1467 for ( DeclarationWithType * const fnParam : funcType->get_parameters() ) { 1500 1468 // condition here duplicates that in Pass2::mutate( FunctionType* ) 1501 Type *polyType = isPolyType( (*fnParm)->get_type(), scopeTyVars );1469 Type *polyType = isPolyType( fnParam->get_type(), scopeTyVars ); 1502 1470 if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) { 1503 1471 knownLayouts.insert( mangleType( polyType ) ); … … 1507 1475 1508 1476 /// converts polymorphic type T into a suitable monomorphic representation, currently: __attribute__((aligned(8)) char[size_T] 1509 Type * polyToMonoType( Type * declType ) {1477 Type * polyToMonoType( Type const * declType ) { 1510 1478 Type * charType = new BasicType( Type::Qualifiers(), BasicType::Kind::Char); 1511 1479 Expression * size = new NameExpr( sizeofName( mangleType(declType) ) ); … … 1572 1540 /// Finds the member in the base list that matches the given declaration; returns its index, or -1 if not present 1573 1541 long findMember( DeclarationWithType *memberDecl, std::list< Declaration* > &baseDecls ) { 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() ) 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() ) 1577 1546 continue; 1578 1547 1579 1548 if ( memberDecl->get_name().empty() ) { 1580 1549 // plan-9 field: match on unique_id 1581 if ( memberDecl->get_uniqueId() == (*decl)->get_uniqueId() )1550 if ( memberDecl->get_uniqueId() == decl->get_uniqueId() ) 1582 1551 return i; 1583 1552 else … … 1585 1554 } 1586 1555 1587 DeclarationWithType *declWithType = strict_dynamic_cast< DeclarationWithType* >( *decl );1556 DeclarationWithType *declWithType = strict_dynamic_cast< DeclarationWithType* >( decl ); 1588 1557 1589 1558 if ( memberDecl->get_mangleName().empty() || declWithType->get_mangleName().empty() ) { … … 1603 1572 1604 1573 /// Returns an index expression into the offset array for a type 1605 Expression *makeOffsetIndex( Type *objectType, long i ) {1574 Expression *makeOffsetIndex( Type const *objectType, long i ) { 1606 1575 ConstantExpr *fieldIndex = new ConstantExpr( Constant::from_ulong( i ) ); 1607 1576 UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) ); … … 1696 1665 1697 1666 void PolyGenericCalculator::addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams ) { 1698 for ( std::list< Type* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param) {1699 if ( findGeneric( *param ) ) {1667 for ( Type * const param : otypeParams ) { 1668 if ( findGeneric( param ) ) { 1700 1669 // push size/align vars for a generic parameter back 1701 std::string paramName = mangleType( *param );1670 std::string paramName = mangleType( param ); 1702 1671 layoutCall->get_args().push_back( new NameExpr( sizeofName( paramName ) ) ); 1703 1672 layoutCall->get_args().push_back( new NameExpr( alignofName( paramName ) ) ); 1704 1673 } else { 1705 layoutCall->get_args().push_back( new SizeofExpr( (*param)->clone() ) );1706 layoutCall->get_args().push_back( new AlignofExpr( (*param)->clone() ) );1674 layoutCall->get_args().push_back( new SizeofExpr( param->clone() ) ); 1675 layoutCall->get_args().push_back( new AlignofExpr( param->clone() ) ); 1707 1676 } 1708 1677 } … … 1710 1679 1711 1680 /// returns true if any of the otype parameters have a dynamic layout and puts all otype parameters in the output list 1712 bool findGenericParams( std::list< TypeDecl* > &baseParams, std::list< Expression* >&typeParams, std::list< Type* > &out ) {1681 bool findGenericParams( std::list< TypeDecl* > const &baseParams, std::list< Expression* > const &typeParams, std::list< Type* > &out ) { 1713 1682 bool hasDynamicLayout = false; 1714 1683 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 ) {1684 for ( auto paramPair : group_iterate( baseParams, typeParams ) ) { 1685 TypeDecl * baseParam = std::get<0>( paramPair ); 1686 Expression * typeParam = std::get<1>( paramPair ); 1718 1687 // skip non-otype parameters 1719 if ( ! (*baseParam)->isComplete() ) continue;1720 TypeExpr *typeExpr = dynamic_cast< TypeExpr* >( *typeParam );1688 if ( ! baseParam->isComplete() ) continue; 1689 TypeExpr *typeExpr = dynamic_cast< TypeExpr* >( typeParam ); 1721 1690 assert( typeExpr && "all otype parameters should be type expressions" ); 1722 1691 … … 1725 1694 if ( isPolyType( type ) ) hasDynamicLayout = true; 1726 1695 } 1727 assert( baseParam == baseParams.end() && typeParam == typeParams.end() );1728 1696 1729 1697 return hasDynamicLayout; 1730 1698 } 1731 1699 1732 bool PolyGenericCalculator::findGeneric( Type *ty ) {1700 bool PolyGenericCalculator::findGeneric( Type const *ty ) { 1733 1701 ty = replaceTypeInst( ty, env ); 1734 1702 1735 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) {1703 if ( auto typeInst = dynamic_cast< TypeInstType const * >( ty ) ) { 1736 1704 if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() ) { 1737 1705 // NOTE assumes here that getting put in the scopeTyVars included having the layout variables set … … 1739 1707 } 1740 1708 return false; 1741 } else if ( StructInstType *structTy = dynamic_cast< StructInstType* >( ty ) ) {1709 } else if ( auto structTy = dynamic_cast< StructInstType const * >( ty ) ) { 1742 1710 // check if this type already has a layout generated for it 1743 1711 std::string typeName = mangleType( ty ); … … 1746 1714 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized 1747 1715 std::list< Type* > otypeParams; 1748 if ( ! findGenericParams( *structTy->get_baseParameters(), structTy-> get_parameters(), otypeParams ) ) return false;1716 if ( ! findGenericParams( *structTy->get_baseParameters(), structTy->parameters, otypeParams ) ) return false; 1749 1717 1750 1718 // insert local variables for layout and generate call to layout function … … 1776 1744 1777 1745 return true; 1778 } else if ( UnionInstType *unionTy = dynamic_cast< UnionInstType* >( ty ) ) {1746 } else if ( auto unionTy = dynamic_cast< UnionInstType const * >( ty ) ) { 1779 1747 // check if this type already has a layout generated for it 1780 1748 std::string typeName = mangleType( ty ); … … 1783 1751 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized 1784 1752 std::list< Type* > otypeParams; 1785 if ( ! findGenericParams( *unionTy->get_baseParameters(), unionTy-> get_parameters(), otypeParams ) ) return false;1753 if ( ! findGenericParams( *unionTy->get_baseParameters(), unionTy->parameters, otypeParams ) ) return false; 1786 1754 1787 1755 // insert local variables for layout and generate call to layout function … … 1881 1849 // build initializer list for offset array 1882 1850 std::list< Initializer* > inits; 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 } 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 ) ) ); 1889 1855 } 1890 1856 … … 1965 1931 // compile-command: "make install" // 1966 1932 // End: // 1933
Note:
See TracChangeset
for help on using the changeset viewer.