Changes in src/InitTweak/FixInit.cc [b6fe7e6:f0121d7]
- File:
-
- 1 edited
-
src/InitTweak/FixInit.cc (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixInit.cc
rb6fe7e6 rf0121d7 35 35 #include "GenPoly/DeclMutator.h" 36 36 #include "SynTree/AddStmtVisitor.h" 37 #include "CodeGen/GenType.h" // for warning s38 39 bool ctordtorp = false; 40 bool ctorp = false; 41 bool cpctorp = false; 42 bool dtorp = false; 37 #include "CodeGen/GenType.h" // for warning/error messages 38 39 bool ctordtorp = false; // print all debug 40 bool ctorp = false; // print ctor debug 41 bool cpctorp = false; // print copy ctor debug 42 bool dtorp = false; // print dtor debug 43 43 #define PRINT( text ) if ( ctordtorp ) { text } 44 44 #define CP_CTOR_PRINT( text ) if ( ctordtorp || cpctorp ) { text } … … 47 47 namespace InitTweak { 48 48 namespace { 49 const std::list<Label> noLabels;50 const std::list<Expression*> noDesignators;51 52 49 class InsertImplicitCalls : public GenPoly::PolyMutator { 53 50 public: … … 69 66 70 67 /// create and resolve ctor/dtor expression: fname(var, [cpArg]) 71 ApplicationExpr * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL ); 68 Expression * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL ); 69 Expression * makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg = NULL ); 72 70 /// true if type does not need to be copy constructed to ensure correctness 73 bool skipCopyConstruct( Type * ); 71 bool skipCopyConstruct( Type * type ); 72 void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ); 73 void destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr ); 74 74 private: 75 75 TypeSubstitution * env; … … 357 357 } 358 358 359 ApplicationExpr* ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {359 Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) { 360 360 assert( var ); 361 return makeCtorDtor( fname, new AddressExpr( new VariableExpr( var ) ), cpArg ); 362 } 363 364 Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg ) { 365 assert( thisArg ); 361 366 UntypedExpr * untyped = new UntypedExpr( new NameExpr( fname ) ); 362 untyped->get_args().push_back( new AddressExpr( new VariableExpr( var ) ));367 untyped->get_args().push_back( thisArg ); 363 368 if (cpArg) untyped->get_args().push_back( cpArg->clone() ); 364 369 … … 367 372 // (VariableExpr and already resolved expression) 368 373 CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; ) 369 ApplicationExpr * resolved = dynamic_cast< ApplicationExpr * >( ResolvExpr::findVoidExpression( untyped, *this ) ); 374 Expression * resolved = ResolvExpr::findVoidExpression( untyped, *this ); 375 assert( resolved ); 370 376 if ( resolved->get_env() ) { 371 377 env->add( *resolved->get_env() ); 372 378 } // if 373 379 374 assert( resolved );375 380 delete untyped; 376 381 return resolved; 377 382 } 378 383 384 void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ) { 385 static UniqueName tempNamer("_tmp_cp"); 386 CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *impCpCtorExpr->get_env() << std::endl; ) 387 assert( arg->has_result() ); 388 Type * result = arg->get_result(); 389 if ( skipCopyConstruct( result ) ) return; // skip certain non-copyable types 390 391 // type may involve type variables, so apply type substitution to get temporary variable's actual type 392 result = result->clone(); 393 impCpCtorExpr->get_env()->apply( result ); 394 ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 ); 395 tmp->get_type()->set_isConst( false ); 396 397 // create and resolve copy constructor 398 CP_CTOR_PRINT( std::cerr << "makeCtorDtor for an argument" << std::endl; ) 399 Expression * cpCtor = makeCtorDtor( "?{}", tmp, arg ); 400 401 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( cpCtor ) ) { 402 // if the chosen constructor is intrinsic, the copy is unnecessary, so 403 // don't create the temporary and don't call the copy constructor 404 VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() ); 405 assert( function ); 406 if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) return; 407 } 408 409 // replace argument to function call with temporary 410 arg = new CommaExpr( cpCtor, new VariableExpr( tmp ) ); 411 impCpCtorExpr->get_tempDecls().push_back( tmp ); 412 impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", tmp ) ); 413 } 414 415 void ResolveCopyCtors::destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr ) { 416 impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", new AddressExpr( ret ) ) ); 417 } 418 379 419 void ResolveCopyCtors::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) { 380 static UniqueName tempNamer("_tmp_cp");381 static UniqueName retNamer("_tmp_cp_ret");382 383 420 CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; ) 384 421 Visitor::visit( impCpCtorExpr ); … … 389 426 // take each argument and attempt to copy construct it. 390 427 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 428 copyConstructArg( arg, impCpCtorExpr ); 416 429 } // for 417 430 … … 423 436 // level. Trying to pass that environment along. 424 437 callExpr->set_env( impCpCtorExpr->get_env()->clone() ); 425 for ( Type * result : appExpr->get_results() ) { 438 Type * result = appExpr->get_result(); 439 if ( ! result->isVoid() ) { 440 static UniqueName retNamer("_tmp_cp_ret"); 426 441 result = result->clone(); 427 442 impCpCtorExpr->get_env()->apply( result ); … … 430 445 impCpCtorExpr->get_returnDecls().push_back( ret ); 431 446 CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; ) 432 impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ));447 destructRet( new VariableExpr( ret ) , impCpCtorExpr ); 433 448 } // for 434 449 CP_CTOR_PRINT( std::cerr << "after Resolving: " << impCpCtorExpr << std::endl; ) … … 479 494 // know the result type of the assignment is the type of the LHS (minus the pointer), so 480 495 // add that onto the assignment expression so that later steps have the necessary information 481 assign-> add_result( returnDecl->get_type()->clone() );496 assign->set_result( returnDecl->get_type()->clone() ); 482 497 483 498 Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) ); 484 if ( callExpr->get_result s().front()->get_isLvalue() ) {499 if ( callExpr->get_result()->get_isLvalue() ) { 485 500 // lvalue returning functions are funny. Lvalue.cc inserts a *? in front of any lvalue returning 486 501 // non-intrinsic function. Add an AddressExpr to the call to negate the derefence and change the … … 500 515 UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) ); 501 516 deref->get_args().push_back( retExpr ); 502 deref-> add_result( resultType );517 deref->set_result( resultType ); 503 518 retExpr = deref; 504 519 } // if … … 939 954 Expression * FixCtorExprs::mutate( ConstructorExpr * ctorExpr ) { 940 955 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_results().front()->clone(), nullptr ); 956 // xxx - is the size check necessary? 957 assert( ctorExpr->has_result() && ctorExpr->get_result()->size() == 1 ); 958 ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, ctorExpr->get_result()->clone(), nullptr ); 943 959 addDeclaration( tmp ); 944 960 … … 952 968 assign->get_args().push_back( new VariableExpr( tmp ) ); 953 969 assign->get_args().push_back( firstArg ); 954 cloneAll( ctorExpr->get_results(), assign->get_results() );970 assign->set_result( ctorExpr->get_result()->clone() ); 955 971 firstArg = assign; 956 972
Note:
See TracChangeset
for help on using the changeset viewer.