Changeset 5c52b06
- Timestamp:
- Feb 16, 2016, 5:31:06 PM (9 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
- Children:
- 9407ed8
- Parents:
- bed4d37c
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
rbed4d37c r5c52b06 73 73 /// Makes a new temporary array holding the offsets of the fields of `type`, and returns a new variable expression referencing it 74 74 Expression *makeOffsetArray( StructInstType *type ); 75 /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application 76 void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ); 75 77 /// passes extra type parameters into a polymorphic function application 76 void passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars );78 void passTypeVars( ApplicationExpr *appExpr, ReferenceToType *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 77 79 /// wraps a function application with a new temporary for the out-parameter return value 78 80 Expression *addRetParam( ApplicationExpr *appExpr, FunctionType *function, Type *retType, std::list< Expression *>::iterator &arg ); … … 398 400 } 399 401 400 void Pass1::passTypeVars( ApplicationExpr *appExpr, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 402 void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) { 403 Type *polyBase = hasPolyBase( parmType, exprTyVars ); 404 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) { 405 std::string sizeName = sizeofName( polyBase ); 406 if ( seenTypes.count( sizeName ) ) return; 407 408 arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) ); 409 arg++; 410 arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) ); 411 arg++; 412 if ( dynamic_cast< StructInstType* >( polyBase ) ) { 413 if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) { 414 arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) ); 415 arg++; 416 } else { 417 throw SemanticError( "Cannot pass non-struct type for generic struct" ); 418 } 419 } 420 421 seenTypes.insert( sizeName ); 422 } 423 } 424 425 void Pass1::passTypeVars( ApplicationExpr *appExpr, ReferenceToType *polyRetType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 401 426 // pass size/align for type variables 402 427 for ( TyVarMap::const_iterator tyParm = exprTyVars.begin(); tyParm != exprTyVars.end(); ++tyParm ) { … … 424 449 std::list< Expression* >::const_iterator fnArg = arg; 425 450 std::set< std::string > seenTypes; //< names for generic types we've seen 451 452 // a polymorphic return type may need to be added to the argument list 453 if ( polyRetType ) { 454 Type *concRetType = replaceWithConcrete( appExpr, polyRetType ); 455 passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes ); 456 } 457 458 // add type information args for presently unseen types in parameter list 426 459 for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) { 427 Type *polyBase = hasPolyBase( (*fnParm)->get_type(), exprTyVars ); 428 if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) { 429 std::string sizeName = sizeofName( polyBase ); 430 if ( seenTypes.count( sizeName ) ) continue; 431 432 VariableExpr *fnArgBase = getBaseVar( *fnArg ); 433 assert( fnArgBase && ! fnArgBase->get_results().empty() ); 434 Type *argBaseType = fnArgBase->get_results().front(); 435 arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) ); 436 arg++; 437 arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) ); 438 arg++; 439 if ( dynamic_cast< StructInstType* >( polyBase ) ) { 440 if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) { 441 arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) ); 442 arg++; 443 } else { 444 throw SemanticError( "Cannot pass non-struct type for generic struct" ); 445 } 446 } 447 448 seenTypes.insert( sizeName ); 449 } 460 VariableExpr *fnArgBase = getBaseVar( *fnArg ); 461 if ( ! fnArgBase || fnArgBase->get_results().empty() ) continue; 462 passArgTypeVars( appExpr, (*fnParm)->get_type(), fnArgBase->get_results().front(), arg, exprTyVars, seenTypes ); 450 463 } 451 464 } … … 470 483 ObjectDecl *newObj = makeTemporary( retType->clone() ); 471 484 Expression *paramExpr = new VariableExpr( newObj ); 472 // If the type of the temporary is not polymorphic, box temporary by taking its address; otherwise the 473 // temporary is already boxed and can be used directly. 485 486 // If the type of the temporary is not polymorphic, box temporary by taking its address; 487 // otherwise the temporary is already boxed and can be used directly. 474 488 if ( ! isPolyType( newObj->get_type(), scopeTyVars, env ) ) { 475 489 paramExpr = new AddressExpr( paramExpr ); … … 520 534 assert( env ); 521 535 Type *concrete = replaceWithConcrete( appExpr, polyType ); 536 // add out-parameter for return value 522 537 return addRetParam( appExpr, function, concrete, arg ); 523 538 } … … 917 932 std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin(); 918 933 919 if ( ReferenceToType *polyType = isPolyRet( function ) ) { 920 ret = addPolyRetParam( appExpr, function, polyType, arg ); 934 TyVarMap exprTyVars; 935 makeTyVarMap( function, exprTyVars ); 936 ReferenceToType *polyRetType = 0; 937 938 if ( polyRetType = isPolyRet( function ) ) { 939 ret = addPolyRetParam( appExpr, function, polyRetType, arg ); 921 940 } else if ( needsAdapter( function, scopeTyVars ) ) { 922 941 // std::cerr << "needs adapter: "; … … 930 949 arg = appExpr->get_args().begin(); 931 950 932 TyVarMap exprTyVars; 933 makeTyVarMap( function, exprTyVars ); 934 935 passTypeVars( appExpr, arg, exprTyVars ); 951 passTypeVars( appExpr, polyRetType, arg, exprTyVars ); 936 952 addInferredParams( appExpr, function, arg, exprTyVars ); 937 953 … … 1229 1245 } 1230 1246 1231 // add size/align for generic types to parameter list1247 // add size/align for generic parameter types to parameter list 1232 1248 std::set< std::string > seenTypes; // sizeofName for generic types we've seen 1233 1249 for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) { … … 1429 1445 delete offsetofExpr; 1430 1446 return offsetInd; 1431 } else if ( UnionInstType *unionType =dynamic_cast< UnionInstType* >( ty ) ) {1447 } else if ( dynamic_cast< UnionInstType* >( ty ) ) { 1432 1448 // all union members are at offset zero 1433 1449 delete offsetofExpr;
Note: See TracChangeset
for help on using the changeset viewer.