Changeset ae1b9ea
- Timestamp:
- Oct 19, 2017, 11:15:36 AM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- a365e0d
- Parents:
- aabc60c
- git-author:
- Rob Schluntz <rschlunt@…> (10/17/17 17:10:04)
- git-committer:
- Rob Schluntz <rschlunt@…> (10/19/17 11:15:36)
- Location:
- src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
raabc60c rae1b9ea 715 715 void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) { 716 716 assertf( arg->result, "arg does not have result: %s", toString( arg ).c_str() ); 717 if ( isPolyType( param, exprTyVars ) ) { 718 Type * newType = arg->get_result()->clone(); 717 if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return; 718 719 if ( arg->result->get_lvalue() ) { 720 // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations. 721 // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) { 722 // if ( dynamic_cast<ArrayType *>( varExpr->var->get_type() ) ){ 723 // // temporary hack - don't box arrays, because &arr is not the same as &arr[0] 724 // return; 725 // } 726 // } 727 arg = generalizedLvalue( new AddressExpr( arg ) ); 728 if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) { 729 // silence warnings by casting boxed parameters when the actual type does not match up with the formal type. 730 arg = new CastExpr( arg, param->clone() ); 731 } 732 } else { 733 // use type computed in unification to declare boxed variables 734 Type * newType = param->clone(); 719 735 if ( env ) env->apply( newType ); 720 std::unique_ptr<Type> manager( newType ); 721 if ( isPolyType( newType ) ) { 722 // if the argument's type is polymorphic, we don't need to box again! 723 return; 724 } else if ( arg->get_result()->get_lvalue() ) { 725 // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations. 726 // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) { 727 // if ( dynamic_cast<ArrayType *>( varExpr->var->get_type() ) ){ 728 // // temporary hack - don't box arrays, because &arr is not the same as &arr[0] 729 // return; 730 // } 731 // } 732 arg = generalizedLvalue( new AddressExpr( arg ) ); 733 if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) { 734 // silence warnings by casting boxed parameters when the actual type does not match up with the formal type. 735 arg = new CastExpr( arg, param->clone() ); 736 } 737 } else { 738 // use type computed in unification to declare boxed variables 739 Type * newType = param->clone(); 740 if ( env ) env->apply( newType ); 741 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, newType, 0 ); 742 newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right??? 743 stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) ); 744 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax? 745 assign->get_args().push_back( new VariableExpr( newObj ) ); 746 assign->get_args().push_back( arg ); 747 stmtsToAddBefore.push_back( new ExprStmt( noLabels, assign ) ); 748 arg = new AddressExpr( new VariableExpr( newObj ) ); 749 } // if 736 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, newType, 0 ); 737 newObj->get_type()->get_qualifiers() = Type::Qualifiers(); // TODO: is this right??? 738 stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) ); 739 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); // TODO: why doesn't this just use initialization syntax? 740 assign->get_args().push_back( new VariableExpr( newObj ) ); 741 assign->get_args().push_back( arg ); 742 stmtsToAddBefore.push_back( new ExprStmt( noLabels, assign ) ); 743 arg = new AddressExpr( new VariableExpr( newObj ) ); 750 744 } // if 751 745 } -
src/GenPoly/GenPoly.cc
raabc60c rae1b9ea 432 432 } 433 433 434 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, TypeSubstitution * env ) { 435 // is parameter is not polymorphic, don't need to box 436 if ( ! isPolyType( param, exprTyVars ) ) return false; 437 Type * newType = arg->clone(); 438 if ( env ) env->apply( newType ); 439 std::unique_ptr<Type> manager( newType ); 440 // if the argument's type is polymorphic, we don't need to box again! 441 return ! isPolyType( newType ); 442 } 443 444 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, TypeSubstitution * env ) { 445 FunctionType * function = getFunctionType( appExpr->function->result ); 446 assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->function->result ).c_str() ); 447 TyVarMap exprTyVars( TypeDecl::Data{} ); 448 makeTyVarMap( function, exprTyVars ); 449 return needsBoxing( param, arg, exprTyVars, env ); 450 } 451 434 452 void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) { 435 453 // xxx - should this actually be insert? -
src/GenPoly/GenPoly.h
raabc60c rae1b9ea 80 80 bool typesPolyCompatible( Type *aty, Type *bty ); 81 81 82 /// true if arg requires boxing given exprTyVars 83 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, TypeSubstitution * env ); 84 85 /// true if arg requires boxing in the call to appExpr 86 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, TypeSubstitution * env ); 87 82 88 /// Adds the type variable `tyVar` to `tyVarMap` 83 89 void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ); -
src/InitTweak/FixInit.cc
raabc60c rae1b9ea 93 93 /// true if type does not need to be copy constructed to ensure correctness 94 94 bool skipCopyConstruct( Type * type ); 95 void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr );95 void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr, Type * formal ); 96 96 void destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr ); 97 97 … … 260 260 261 261 GenStructMemberCalls::generate( translationUnit ); 262 262 263 // xxx - ctor expansion currently has to be after FixCopyCtors, because there is currently a 263 264 // hack in the way untyped assignments are generated, where the first argument cannot have … … 384 385 } 385 386 386 void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ) {387 void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr, Type * formal ) { 387 388 static UniqueName tempNamer("_tmp_cp"); 388 389 assert( env ); 389 390 CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *env << std::endl; ) 390 391 assert( arg->result ); 391 Type * result = arg-> get_result();392 Type * result = arg->result; 392 393 if ( skipCopyConstruct( result ) ) return; // skip certain non-copyable types 393 394 394 // type may involve type variables, so apply type substitution to get temporary variable's actual type 395 // type may involve type variables, so apply type substitution to get temporary variable's actual type. 396 // Use applyFree so that types bound in function pointers are not substituted, e.g. in forall(dtype T) void (*)(T). 395 397 result = result->clone(); 396 env->apply ( result );398 env->applyFree( result ); 397 399 ObjectDecl * tmp = ObjectDecl::newObject( "__tmp", result, nullptr ); 398 400 tmp->get_type()->set_const( false ); … … 405 407 // if the chosen constructor is intrinsic, the copy is unnecessary, so 406 408 // don't create the temporary and don't call the copy constructor 407 VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() ); 408 assert( function ); 409 if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) return; 409 VariableExpr * function = strict_dynamic_cast< VariableExpr * >( appExpr->function ); 410 if ( function->var->linkage == LinkageSpec::Intrinsic ) { 411 // arguments that need to be boxed need a temporary regardless of whether the copy constructor is intrinsic, 412 // so that the object isn't changed inside of the polymorphic function 413 if ( ! GenPoly::needsBoxing( formal, result, impCpCtorExpr->callExpr, env ) ) return; 414 } 410 415 } 411 416 … … 415 420 // replace argument to function call with temporary 416 421 arg = new CommaExpr( cpCtor, new VariableExpr( tmp ) ); 417 impCpCtorExpr-> get_tempDecls().push_back( tmp );418 impCpCtorExpr-> get_dtors().push_front( makeCtorDtor( "^?{}", tmp ) );422 impCpCtorExpr->tempDecls.push_back( tmp ); 423 impCpCtorExpr->dtors.push_front( makeCtorDtor( "^?{}", tmp ) ); 419 424 } 420 425 … … 426 431 CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; ) 427 432 428 ApplicationExpr * appExpr = impCpCtorExpr-> get_callExpr();433 ApplicationExpr * appExpr = impCpCtorExpr->callExpr; 429 434 430 435 // take each argument and attempt to copy construct it. 431 for ( Expression * & arg : appExpr->get_args() ) { 432 copyConstructArg( arg, impCpCtorExpr ); 436 FunctionType * ftype = GenPoly::getFunctionType( appExpr->function->result ); 437 assert( ftype ); 438 auto & params = ftype->parameters; 439 auto iter = params.begin(); 440 for ( Expression * & arg : appExpr->args ) { 441 Type * formal = nullptr; 442 if ( iter != params.end() ) { 443 DeclarationWithType * param = *iter++; 444 formal = param->get_type(); 445 } 446 447 copyConstructArg( arg, impCpCtorExpr, formal ); 433 448 } // for 434 449 … … 436 451 // initialized with the return value and is destructed later 437 452 // xxx - handle named return values? 438 Type * result = appExpr-> get_result();453 Type * result = appExpr->result; 439 454 if ( ! result->isVoid() ) { 440 455 static UniqueName retNamer("_tmp_cp_ret"); … … 442 457 env->apply( result ); 443 458 ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr ); 444 ret-> get_type()->set_const( false );445 impCpCtorExpr-> get_returnDecls().push_back( ret );459 ret->type->set_const( false ); 460 impCpCtorExpr->returnDecls.push_back( ret ); 446 461 CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; ) 447 462 if ( ! dynamic_cast< ReferenceType * >( result ) ) {
Note: See TracChangeset
for help on using the changeset viewer.