Changes in src/InitTweak/FixInit.cc [31f379c:9a063c8]
- File:
-
- 1 edited
-
src/InitTweak/FixInit.cc (modified) (23 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixInit.cc
r31f379c r9a063c8 49 49 namespace InitTweak { 50 50 namespace { 51 typedef std::unordered_map< Expression *, TypeSubstitution * > EnvMap;52 53 51 class InsertImplicitCalls final : public GenPoly::PolyMutator { 54 52 public: 55 53 /// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which 56 54 /// function calls need their parameters to be copy constructed 57 static void insert( std::list< Declaration * > & translationUnit, EnvMap & envMap ); 58 59 InsertImplicitCalls( EnvMap & envMap ) : envMap( envMap ) {} 60 typedef GenPoly::PolyMutator Parent; 61 using Parent::mutate; 55 static void insert( std::list< Declaration * > & translationUnit ); 56 57 using GenPoly::PolyMutator::mutate; 62 58 virtual Expression * mutate( ApplicationExpr * appExpr ) override; 63 virtual Expression * mutate( StmtExpr * stmtExpr ) override;64 65 // collects environments for relevant nodes66 EnvMap & envMap;67 59 }; 68 60 … … 72 64 /// generate/resolve copy construction expressions for each, and generate/resolve destructors for both 73 65 /// arguments and return value temporaries 74 static void resolveImplicitCalls( std::list< Declaration * > & translationUnit , const EnvMap & envMap);66 static void resolveImplicitCalls( std::list< Declaration * > & translationUnit ); 75 67 76 68 typedef SymTab::Indexer Parent; 77 69 using Parent::visit; 78 70 79 ResolveCopyCtors( const EnvMap & envMap ) : envMap( envMap ) {}80 81 71 virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) override; 82 virtual void visit( UniqueExpr * unqExpr ) override; 83 virtual void visit( StmtExpr * stmtExpr ) override; 72 virtual void visit( UniqueExpr * unqExpr ); 84 73 85 74 /// create and resolve ctor/dtor expression: fname(var, [cpArg]) … … 90 79 void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ); 91 80 void destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr ); 92 81 private: 93 82 TypeSubstitution * env; 94 const EnvMap & envMap;95 83 }; 96 84 … … 186 174 static void fixInitializers( std::list< Declaration * > &translationUnit ); 187 175 188 typedef GenPoly::PolyMutator Parent; 189 using Parent::mutate; 176 using GenPoly::PolyMutator::mutate; 190 177 virtual DeclarationWithType * mutate( ObjectDecl *objDecl ) override; 191 178 … … 199 186 static void fixCopyCtors( std::list< Declaration * > &translationUnit ); 200 187 201 typedef GenPoly::PolyMutator Parent; 202 using Parent::mutate; 188 using GenPoly::PolyMutator::mutate; 203 189 virtual Expression * mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) override; 204 190 virtual Expression * mutate( UniqueExpr * unqExpr ) override; 205 virtual Expression * mutate( StmtExpr * stmtExpr ) override;206 191 }; 207 192 … … 263 248 InitTweak::fixGlobalInit( translationUnit, filename, inLibrary ); 264 249 265 EnvMap envMap; 266 267 InsertImplicitCalls::insert( translationUnit, envMap ); 268 ResolveCopyCtors::resolveImplicitCalls( translationUnit, envMap ); 250 251 InsertImplicitCalls::insert( translationUnit ); 252 ResolveCopyCtors::resolveImplicitCalls( translationUnit ); 269 253 InsertDtors::insert( translationUnit ); 270 254 FixInit::fixInitializers( translationUnit ); … … 285 269 286 270 namespace { 287 void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit , EnvMap & envMap) {288 InsertImplicitCalls inserter ( envMap );271 void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit ) { 272 InsertImplicitCalls inserter; 289 273 mutateAll( translationUnit, inserter ); 290 274 } 291 275 292 void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit , const EnvMap & envMap) {293 ResolveCopyCtors resolver ( envMap );276 void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit ) { 277 ResolveCopyCtors resolver; 294 278 acceptAll( translationUnit, resolver ); 295 279 } … … 342 326 343 327 Expression * InsertImplicitCalls::mutate( ApplicationExpr * appExpr ) { 344 appExpr = dynamic_cast< ApplicationExpr * >( Parent::mutate( appExpr ) );328 appExpr = dynamic_cast< ApplicationExpr * >( Mutator::mutate( appExpr ) ); 345 329 assert( appExpr ); 346 330 347 331 if ( VariableExpr * function = dynamic_cast< VariableExpr * > ( appExpr->get_function() ) ) { 348 if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic) {332 if ( LinkageSpec::isBuiltin( function->get_var()->get_linkage() ) ) { 349 333 // optimization: don't need to copy construct in order to call intrinsic functions 350 334 return appExpr; … … 355 339 Type * t1 = ftype->get_parameters().front()->get_type(); 356 340 Type * t2 = ftype->get_parameters().back()->get_type(); 357 PointerType * ptrType = safe_dynamic_cast< PointerType * > ( t1 ); 341 PointerType * ptrType = dynamic_cast< PointerType * > ( t1 ); 342 assert( ptrType ); 358 343 359 344 if ( ResolvExpr::typesCompatible( ptrType->get_base(), t2, SymTab::Indexer() ) ) { … … 372 357 // wrap each function call so that it is easy to identify nodes that have to be copy constructed 373 358 ImplicitCopyCtorExpr * expr = new ImplicitCopyCtorExpr( appExpr ); 374 // save the type substitution into the envMapso that it is easy to find.359 // save the type substitution onto the new node so that it is easy to find. 375 360 // Ensure it is not deleted with the ImplicitCopyCtorExpr by removing it before deletion. 376 361 // The substitution is needed to obtain the type of temporary variables so that copy constructor … … 381 366 // constructor calls together. 382 367 assert( env ); 383 e nvMap[expr] = env;368 expr->set_env( env ); 384 369 return expr; 385 }386 387 Expression * InsertImplicitCalls::mutate( StmtExpr * stmtExpr ) {388 assert( env );389 envMap[stmtExpr] = env;390 return Parent::mutate( stmtExpr );391 370 } 392 371 … … 413 392 assert( resolved ); 414 393 if ( resolved->get_env() ) { 415 // Extract useful information and discard new environments. Keeping them causes problems in PolyMutator passes.416 394 env->add( *resolved->get_env() ); 417 delete resolved->get_env();418 resolved->set_env( nullptr );419 395 } // if 420 396 … … 425 401 void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ) { 426 402 static UniqueName tempNamer("_tmp_cp"); 427 assert( env ); 428 CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *env << std::endl; ) 403 CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *impCpCtorExpr->get_env() << std::endl; ) 429 404 assert( arg->has_result() ); 430 405 Type * result = arg->get_result(); … … 433 408 // type may involve type variables, so apply type substitution to get temporary variable's actual type 434 409 result = result->clone(); 435 env->apply( result );410 impCpCtorExpr->get_env()->apply( result ); 436 411 ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 ); 437 412 tmp->get_type()->set_isConst( false ); … … 462 437 CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; ) 463 438 Parent::visit( impCpCtorExpr ); 464 env = envMap.at(impCpCtorExpr); 465 assert( env ); 439 env = impCpCtorExpr->get_env(); // xxx - maybe we really should just have a PolyIndexer... 466 440 467 441 ApplicationExpr * appExpr = impCpCtorExpr->get_callExpr(); … … 474 448 // each return value from the call needs to be connected with an ObjectDecl at the call site, which is 475 449 // initialized with the return value and is destructed later 476 // xxx - handle named return values? 450 // xxx - handle multiple return values 451 ApplicationExpr * callExpr = impCpCtorExpr->get_callExpr(); 452 // xxx - is this right? callExpr may not have the right environment, because it was attached at a higher 453 // level. Trying to pass that environment along. 454 callExpr->set_env( impCpCtorExpr->get_env()->clone() ); 477 455 Type * result = appExpr->get_result(); 478 456 if ( ! result->isVoid() ) { 479 457 static UniqueName retNamer("_tmp_cp_ret"); 480 458 result = result->clone(); 481 env->apply( result );459 impCpCtorExpr->get_env()->apply( result ); 482 460 ObjectDecl * ret = new ObjectDecl( retNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 ); 483 461 ret->get_type()->set_isConst( false ); … … 490 468 } // for 491 469 CP_CTOR_PRINT( std::cerr << "after Resolving: " << impCpCtorExpr << std::endl; ) 492 }493 494 void ResolveCopyCtors::visit( StmtExpr * stmtExpr ) {495 Parent::visit( stmtExpr );496 env = envMap.at(stmtExpr);497 assert( stmtExpr->get_result() );498 Type * result = stmtExpr->get_result();499 if ( ! result->isVoid() ) {500 static UniqueName retNamer("_tmp_stmtexpr_ret");501 502 // create variable that will hold the result of the stmt expr503 result = result->clone();504 env->apply( result );505 ObjectDecl * ret = new ObjectDecl( retNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 );506 ret->get_type()->set_isConst( false );507 stmtExpr->get_returnDecls().push_front( ret );508 509 // must have a non-empty body, otherwise it wouldn't have a result510 CompoundStmt * body = stmtExpr->get_statements();511 assert( ! body->get_kids().empty() );512 // must be an ExprStmt, otherwise it wouldn't have a result513 ExprStmt * last = safe_dynamic_cast< ExprStmt * >( body->get_kids().back() );514 last->set_expr( makeCtorDtor( "?{}", ret, last->get_expr() ) );515 516 stmtExpr->get_dtors().push_front( makeCtorDtor( "^?{}", new AddressExpr( new VariableExpr( ret ) ) ) );517 } // if518 519 470 } 520 471 … … 541 492 } 542 493 494 543 495 Expression * FixCopyCtors::mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) { 544 496 CP_CTOR_PRINT( std::cerr << "FixCopyCtors: " << impCpCtorExpr << std::endl; ) 545 497 546 impCpCtorExpr = safe_dynamic_cast< ImplicitCopyCtorExpr * >( Parent::mutate( impCpCtorExpr ) ); 498 impCpCtorExpr = dynamic_cast< ImplicitCopyCtorExpr * >( Mutator::mutate( impCpCtorExpr ) ); 499 assert( impCpCtorExpr ); 500 547 501 std::list< ObjectDecl * > & tempDecls = impCpCtorExpr->get_tempDecls(); 548 502 std::list< ObjectDecl * > & returnDecls = impCpCtorExpr->get_returnDecls(); … … 604 558 retExpr = UntypedExpr::createDeref( retExpr ); 605 559 } // if 606 // move env from callExpr to retExpr 607 retExpr->set_env( callExpr->get_env() ); 608 callExpr->set_env( nullptr ); 560 retExpr->set_env( env->clone() ); 609 561 return retExpr; 610 562 } else { … … 613 565 } 614 566 615 Expression * FixCopyCtors::mutate( StmtExpr * stmtExpr ) {616 stmtExpr = safe_dynamic_cast< StmtExpr * >( Parent::mutate( stmtExpr ) );617 assert( stmtExpr->get_result() );618 Type * result = stmtExpr->get_result();619 if ( ! result->isVoid() ) {620 for ( ObjectDecl * obj : stmtExpr->get_returnDecls() ) {621 stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) );622 } // for623 // add destructors after current statement624 for ( Expression * dtor : stmtExpr->get_dtors() ) {625 stmtsToAddAfter.push_back( new ExprStmt( noLabels, dtor ) );626 } // for627 // must have a non-empty body, otherwise it wouldn't have a result628 CompoundStmt * body = stmtExpr->get_statements();629 assert( ! body->get_kids().empty() );630 assert( ! stmtExpr->get_returnDecls().empty() );631 body->get_kids().push_back( new ExprStmt( noLabels, new VariableExpr( stmtExpr->get_returnDecls().front() ) ) );632 }633 stmtExpr->get_returnDecls().clear();634 stmtExpr->get_dtors().clear();635 return stmtExpr;636 }637 638 567 Expression * FixCopyCtors::mutate( UniqueExpr * unqExpr ) { 639 568 static std::unordered_map< int, UniqueExpr * > unqMap; 640 569 static std::unordered_set< int > addDeref; 641 570 // has to be done to clean up ImplicitCopyCtorExpr nodes, even when this node was skipped in previous passes 571 unqExpr = safe_dynamic_cast< UniqueExpr * >( Parent::mutate( unqExpr ) ); 642 572 if ( unqMap.count( unqExpr->get_id() ) ) { 643 573 // take data from other UniqueExpr to ensure consistency … … 652 582 return unqExpr; 653 583 } 654 unqExpr = safe_dynamic_cast< UniqueExpr * >( Parent::mutate( unqExpr ) ); // stmtexprs contained should not be separately fixed, so this must occur after the lookup655 584 unqMap[unqExpr->get_id()] = unqExpr; 656 585 if ( UntypedExpr * deref = dynamic_cast< UntypedExpr * >( unqExpr->get_expr() ) ) { … … 670 599 // first recursively handle pieces of ObjectDecl so that they aren't missed by other visitors when the init 671 600 // is removed from the ObjectDecl 672 objDecl = dynamic_cast< ObjectDecl * >( Parent::mutate( objDecl ) ); 601 objDecl = dynamic_cast< ObjectDecl * >( Mutator::mutate( objDecl ) ); 602 673 603 if ( ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() ) ) { 674 604 // a decision should have been made by the resolver, so ctor and init are not both non-NULL … … 974 904 // insert and resolve default/copy constructor call for each field that's unhandled 975 905 std::list< Statement * > stmt; 976 UntypedExpr * deref = UntypedExpr::createDeref( new VariableExpr( thisParam ) ); 906 UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) ); 907 deref->get_args().push_back( new VariableExpr( thisParam ) ); 977 908 978 909 Expression * arg2 = 0;
Note:
See TracChangeset
for help on using the changeset viewer.