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