Changeset dc2334c
- Timestamp:
- Sep 25, 2017, 5:49:16 PM (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:
- cf90b88
- Parents:
- 92b3de1
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixInit.cc
r92b3de1 rdc2334c 185 185 }; 186 186 187 class FixCopyCtors final : public GenPoly::PolyMutator{187 class FixCopyCtors final : public WithStmtsToAdd, public WithShortCircuiting, public WithVisitorRef<FixCopyCtors> { 188 188 public: 189 189 FixCopyCtors( UnqCount & unqCount ) : unqCount( unqCount ){} … … 192 192 static void fixCopyCtors( std::list< Declaration * > &translationUnit, UnqCount & unqCount ); 193 193 194 typedef GenPoly::PolyMutator Parent; 195 using Parent::mutate; 196 virtual Expression * mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) override; 197 virtual Expression * mutate( UniqueExpr * unqExpr ) override; 198 virtual Expression * mutate( StmtExpr * stmtExpr ) override; 194 Expression * postmutate( ImplicitCopyCtorExpr * impCpCtorExpr ); 195 void premutate( StmtExpr * stmtExpr ); 196 void premutate( UniqueExpr * unqExpr ); 199 197 200 198 UnqCount & unqCount; … … 312 310 313 311 void FixCopyCtors::fixCopyCtors( std::list< Declaration * > & translationUnit, UnqCount & unqCount ) { 314 FixCopyCtorsfixer( unqCount );312 PassVisitor<FixCopyCtors> fixer( unqCount ); 315 313 mutateAll( translationUnit, fixer ); 316 314 } … … 512 510 } 513 511 514 Expression * FixCopyCtors:: mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) {512 Expression * FixCopyCtors::postmutate( ImplicitCopyCtorExpr * impCpCtorExpr ) { 515 513 CP_CTOR_PRINT( std::cerr << "FixCopyCtors: " << impCpCtorExpr << std::endl; ) 516 514 517 impCpCtorExpr = strict_dynamic_cast< ImplicitCopyCtorExpr * >( Parent::mutate( impCpCtorExpr ) );518 515 std::list< ObjectDecl * > & tempDecls = impCpCtorExpr->get_tempDecls(); 519 516 std::list< ObjectDecl * > & returnDecls = impCpCtorExpr->get_returnDecls(); … … 522 519 // add all temporary declarations and their constructors 523 520 for ( ObjectDecl * obj : tempDecls ) { 524 stmtsToAdd .push_back( new DeclStmt( noLabels, obj ) );521 stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) ); 525 522 } // for 526 523 for ( ObjectDecl * obj : returnDecls ) { 527 stmtsToAdd .push_back( new DeclStmt( noLabels, obj ) );524 stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) ); 528 525 } // for 529 526 … … 533 530 } // for 534 531 535 // xxx - update to work with multiple return values536 532 ObjectDecl * returnDecl = returnDecls.empty() ? nullptr : returnDecls.front(); 537 533 Expression * callExpr = impCpCtorExpr->get_callExpr(); … … 566 562 } 567 563 568 Expression * FixCopyCtors::mutate( StmtExpr * stmtExpr ) {564 void FixCopyCtors::premutate( StmtExpr * stmtExpr ) { 569 565 // function call temporaries should be placed at statement-level, rather than nested inside of a new statement expression, 570 566 // since temporaries can be shared across sub-expressions, e.g. 571 567 // [A, A] f(); 572 568 // g([A] x, [A] y); 573 // f(g());569 // g(f()); 574 570 // f is executed once, so the return temporary is shared across the tuple constructors for x and y. 571 // Explicitly mutating children instead of mutating the inner compound statment forces the temporaries to be added 572 // to the outer context, rather than inside of the statement expression. 573 visit_children = false; 575 574 std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids(); 576 575 for ( Statement *& stmt : stmts ) { 577 stmt = stmt->acceptMutator( * this);576 stmt = stmt->acceptMutator( *visitor ); 578 577 } // for 579 // stmtExpr = strict_dynamic_cast< StmtExpr * >( Parent::mutate( stmtExpr ) );580 578 assert( stmtExpr->get_result() ); 581 579 Type * result = stmtExpr->get_result(); 582 580 if ( ! result->isVoid() ) { 583 581 for ( ObjectDecl * obj : stmtExpr->get_returnDecls() ) { 584 stmtsToAdd .push_back( new DeclStmt( noLabels, obj ) );582 stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) ); 585 583 } // for 586 584 // add destructors after current statement … … 589 587 } // for 590 588 // must have a non-empty body, otherwise it wouldn't have a result 591 CompoundStmt * body = stmtExpr->get_statements(); 592 assert( ! body->get_kids().empty() ); 589 assert( ! stmts.empty() ); 593 590 assert( ! stmtExpr->get_returnDecls().empty() ); 594 body->get_kids().push_back( new ExprStmt( noLabels, new VariableExpr( stmtExpr->get_returnDecls().front() ) ) );591 stmts.push_back( new ExprStmt( noLabels, new VariableExpr( stmtExpr->get_returnDecls().front() ) ) ); 595 592 stmtExpr->get_returnDecls().clear(); 596 593 stmtExpr->get_dtors().clear(); … … 598 595 assert( stmtExpr->get_returnDecls().empty() ); 599 596 assert( stmtExpr->get_dtors().empty() ); 600 return stmtExpr;601 } 602 603 Expression * FixCopyCtors::mutate( UniqueExpr * unqExpr ) {597 } 598 599 void FixCopyCtors::premutate( UniqueExpr * unqExpr ) { 600 visit_children = false; 604 601 unqCount[ unqExpr->get_id() ]--; 605 602 static std::unordered_map< int, std::list< Statement * > > dtors; 606 603 static std::unordered_map< int, UniqueExpr * > unqMap; 607 static std::unordered_set< int > addDeref;608 604 // has to be done to clean up ImplicitCopyCtorExpr nodes, even when this node was skipped in previous passes 609 605 if ( unqMap.count( unqExpr->get_id() ) ) { … … 616 612 stmtsToAddAfter.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] ); 617 613 } 618 if ( addDeref.count( unqExpr->get_id() ) ) { 619 // other UniqueExpr was dereferenced because it was an lvalue return, so this one should be too 620 return UntypedExpr::createDeref( unqExpr ); 621 } 622 return unqExpr; 623 } 624 FixCopyCtors fixer( unqCount ); 614 return; 615 } 616 PassVisitor<FixCopyCtors> fixer( unqCount ); 625 617 unqExpr->set_expr( unqExpr->get_expr()->acceptMutator( fixer ) ); // stmtexprs contained should not be separately fixed, so this must occur after the lookup 626 stmtsToAdd .splice( stmtsToAdd.end(), fixer.stmtsToAdd);618 stmtsToAddBefore.splice( stmtsToAddBefore.end(), fixer.pass.stmtsToAddBefore ); 627 619 unqMap[unqExpr->get_id()] = unqExpr; 628 620 if ( unqCount[ unqExpr->get_id() ] == 0 ) { // insert destructor after the last use of the unique expression 629 621 stmtsToAddAfter.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] ); 630 622 } else { // remember dtors for last instance of unique expr 631 dtors[ unqExpr->get_id() ] = fixer.stmtsToAddAfter; 632 } 633 if ( UntypedExpr * deref = dynamic_cast< UntypedExpr * >( unqExpr->get_expr() ) ) { 634 // unique expression is now a dereference, because the inner expression is an lvalue returning function call. 635 // Normalize the expression by dereferencing the unique expression, rather than the inner expression 636 // (i.e. move the dereference out a level) 637 assert( getFunctionName( deref ) == "*?" ); 638 unqExpr->set_expr( getCallArg( deref, 0 ) ); 639 getCallArg( deref, 0 ) = unqExpr; 640 addDeref.insert( unqExpr->get_id() ); 641 return deref; 642 } 643 return unqExpr; 623 dtors[ unqExpr->get_id() ] = fixer.pass.stmtsToAddAfter; 624 } 625 return; 644 626 } 645 627
Note: See TracChangeset
for help on using the changeset viewer.