Changes in src/InitTweak/FixInit.cc [b6fe7e6:65660bd]
- File:
-
- 1 edited
-
src/InitTweak/FixInit.cc (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixInit.cc
rb6fe7e6 r65660bd 69 69 70 70 /// create and resolve ctor/dtor expression: fname(var, [cpArg]) 71 ApplicationExpr * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL ); 71 Expression * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL ); 72 Expression * makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg = NULL ); 72 73 /// true if type does not need to be copy constructed to ensure correctness 73 bool skipCopyConstruct( Type * ); 74 bool skipCopyConstruct( Type * type ); 75 void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ); 76 void destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr ); 74 77 private: 75 78 TypeSubstitution * env; … … 357 360 } 358 361 359 ApplicationExpr* ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {362 Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) { 360 363 assert( var ); 364 return makeCtorDtor( fname, new AddressExpr( new VariableExpr( var ) ), cpArg ); 365 } 366 367 Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg ) { 368 assert( thisArg ); 361 369 UntypedExpr * untyped = new UntypedExpr( new NameExpr( fname ) ); 362 untyped->get_args().push_back( new AddressExpr( new VariableExpr( var ) ));370 untyped->get_args().push_back( thisArg ); 363 371 if (cpArg) untyped->get_args().push_back( cpArg->clone() ); 364 372 … … 367 375 // (VariableExpr and already resolved expression) 368 376 CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; ) 369 ApplicationExpr * resolved = dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( untyped, *this ) ); 377 Expression * resolved = ResolvExpr::findVoidExpression( untyped, *this ); 378 assert( resolved ); 370 379 if ( resolved->get_env() ) { 371 380 env->add( *resolved->get_env() ); 372 381 } // if 373 382 374 assert( resolved );375 383 delete untyped; 376 384 return resolved; 377 385 } 378 386 387 void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ) { 388 static UniqueName tempNamer("_tmp_cp"); 389 CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *impCpCtorExpr->get_env() << std::endl; ) 390 assert( arg->has_result() ); 391 Type * result = arg->get_result(); 392 if ( skipCopyConstruct( result ) ) return; // skip certain non-copyable types 393 394 // type may involve type variables, so apply type substitution to get temporary variable's actual type 395 result = result->clone(); 396 impCpCtorExpr->get_env()->apply( result ); 397 ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 ); 398 tmp->get_type()->set_isConst( false ); 399 400 // create and resolve copy constructor 401 CP_CTOR_PRINT( std::cerr << "makeCtorDtor for an argument" << std::endl; ) 402 Expression * cpCtor = makeCtorDtor( "?{}", tmp, arg ); 403 404 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( cpCtor ) ) { 405 // if the chosen constructor is intrinsic, the copy is unnecessary, so 406 // 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; 410 } 411 412 // replace argument to function call with temporary 413 arg = new CommaExpr( cpCtor, new VariableExpr( tmp ) ); 414 impCpCtorExpr->get_tempDecls().push_back( tmp ); 415 impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", tmp ) ); 416 } 417 418 void ResolveCopyCtors::destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr ) { 419 impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", new AddressExpr( ret ) ) ); 420 } 421 379 422 void ResolveCopyCtors::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) { 380 static UniqueName tempNamer("_tmp_cp");381 static UniqueName retNamer("_tmp_cp_ret");382 383 423 CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; ) 384 424 Visitor::visit( impCpCtorExpr ); … … 389 429 // take each argument and attempt to copy construct it. 390 430 for ( Expression * & arg : appExpr->get_args() ) { 391 CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *impCpCtorExpr->get_env() << std::endl; ) 392 // xxx - need to handle tuple arguments 393 assert( ! arg->get_results().empty() ); 394 Type * result = arg->get_results().front(); 395 if ( skipCopyConstruct( result ) ) continue; // skip certain non-copyable types 396 // type may involve type variables, so apply type substitution to get temporary variable's actual type 397 result = result->clone(); 398 impCpCtorExpr->get_env()->apply( result ); 399 ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 ); 400 tmp->get_type()->set_isConst( false ); 401 402 // create and resolve copy constructor 403 CP_CTOR_PRINT( std::cerr << "makeCtorDtor for an argument" << std::endl; ) 404 ApplicationExpr * cpCtor = makeCtorDtor( "?{}", tmp, arg ); 405 406 // if the chosen constructor is intrinsic, the copy is unnecessary, so 407 // don't create the temporary and don't call the copy constructor 408 VariableExpr * function = dynamic_cast< VariableExpr * >( cpCtor->get_function() ); 409 assert( function ); 410 if ( function->get_var()->get_linkage() != LinkageSpec::Intrinsic ) { 411 // replace argument to function call with temporary 412 arg = new CommaExpr( cpCtor, new VariableExpr( tmp ) ); 413 impCpCtorExpr->get_tempDecls().push_back( tmp ); 414 impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", tmp ) ); 415 } // if 431 copyConstructArg( arg, impCpCtorExpr ); 416 432 } // for 417 433 … … 423 439 // level. Trying to pass that environment along. 424 440 callExpr->set_env( impCpCtorExpr->get_env()->clone() ); 425 for ( Type * result : appExpr->get_results() ) { 441 Type * result = appExpr->get_result(); 442 if ( ! result->isVoid() ) { 443 static UniqueName retNamer("_tmp_cp_ret"); 426 444 result = result->clone(); 427 445 impCpCtorExpr->get_env()->apply( result ); … … 430 448 impCpCtorExpr->get_returnDecls().push_back( ret ); 431 449 CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; ) 432 impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ));450 destructRet( new VariableExpr( ret ) , impCpCtorExpr ); 433 451 } // for 434 452 CP_CTOR_PRINT( std::cerr << "after Resolving: " << impCpCtorExpr << std::endl; ) … … 479 497 // know the result type of the assignment is the type of the LHS (minus the pointer), so 480 498 // add that onto the assignment expression so that later steps have the necessary information 481 assign-> add_result( returnDecl->get_type()->clone() );499 assign->set_result( returnDecl->get_type()->clone() ); 482 500 483 501 Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) ); 484 if ( callExpr->get_result s().front()->get_isLvalue() ) {502 if ( callExpr->get_result()->get_isLvalue() ) { 485 503 // lvalue returning functions are funny. Lvalue.cc inserts a *? in front of any lvalue returning 486 504 // non-intrinsic function. Add an AddressExpr to the call to negate the derefence and change the … … 500 518 UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) ); 501 519 deref->get_args().push_back( retExpr ); 502 deref-> add_result( resultType );520 deref->set_result( resultType ); 503 521 retExpr = deref; 504 522 } // if … … 939 957 Expression * FixCtorExprs::mutate( ConstructorExpr * ctorExpr ) { 940 958 static UniqueName tempNamer( "_tmp_ctor_expr" ); 941 assert( ctorExpr-> get_results().size() == 1 );942 ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, ctorExpr->get_result s().front()->clone(), nullptr );959 assert( ctorExpr->has_result() && ctorExpr->get_result()->size() == 1 ); 960 ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, ctorExpr->get_result()->clone(), nullptr ); 943 961 addDeclaration( tmp ); 944 962 … … 952 970 assign->get_args().push_back( new VariableExpr( tmp ) ); 953 971 assign->get_args().push_back( firstArg ); 954 cloneAll( ctorExpr->get_results(), assign->get_results() );972 assign->set_result( ctorExpr->get_result()->clone() ); 955 973 firstArg = assign; 956 974
Note:
See TracChangeset
for help on using the changeset viewer.