Changeset dc2334c


Ignore:
Timestamp:
Sep 25, 2017, 5:49:16 PM (4 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
cf90b88
Parents:
92b3de1
Message:

Convert FixCopyCtors? to PassVisitor?

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    r92b3de1 rdc2334c  
    185185                };
    186186
    187                 class FixCopyCtors final : public GenPoly::PolyMutator {
     187                class FixCopyCtors final : public WithStmtsToAdd, public WithShortCircuiting, public WithVisitorRef<FixCopyCtors> {
    188188                  public:
    189189                        FixCopyCtors( UnqCount & unqCount ) : unqCount( unqCount ){}
     
    192192                        static void fixCopyCtors( std::list< Declaration * > &translationUnit, UnqCount & unqCount );
    193193
    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 );
    199197
    200198                        UnqCount & unqCount;
     
    312310
    313311                void FixCopyCtors::fixCopyCtors( std::list< Declaration * > & translationUnit, UnqCount & unqCount ) {
    314                         FixCopyCtors fixer( unqCount );
     312                        PassVisitor<FixCopyCtors> fixer( unqCount );
    315313                        mutateAll( translationUnit, fixer );
    316314                }
     
    512510                }
    513511
    514                 Expression * FixCopyCtors::mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) {
     512                Expression * FixCopyCtors::postmutate( ImplicitCopyCtorExpr * impCpCtorExpr ) {
    515513                        CP_CTOR_PRINT( std::cerr << "FixCopyCtors: " << impCpCtorExpr << std::endl; )
    516514
    517                         impCpCtorExpr = strict_dynamic_cast< ImplicitCopyCtorExpr * >( Parent::mutate( impCpCtorExpr ) );
    518515                        std::list< ObjectDecl * > & tempDecls = impCpCtorExpr->get_tempDecls();
    519516                        std::list< ObjectDecl * > & returnDecls = impCpCtorExpr->get_returnDecls();
     
    522519                        // add all temporary declarations and their constructors
    523520                        for ( ObjectDecl * obj : tempDecls ) {
    524                                 stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) );
     521                                stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) );
    525522                        } // for
    526523                        for ( ObjectDecl * obj : returnDecls ) {
    527                                 stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) );
     524                                stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) );
    528525                        } // for
    529526
     
    533530                        } // for
    534531
    535                         // xxx - update to work with multiple return values
    536532                        ObjectDecl * returnDecl = returnDecls.empty() ? nullptr : returnDecls.front();
    537533                        Expression * callExpr = impCpCtorExpr->get_callExpr();
     
    566562                }
    567563
    568                 Expression * FixCopyCtors::mutate( StmtExpr * stmtExpr ) {
     564                void FixCopyCtors::premutate( StmtExpr * stmtExpr ) {
    569565                        // function call temporaries should be placed at statement-level, rather than nested inside of a new statement expression,
    570566                        // since temporaries can be shared across sub-expressions, e.g.
    571567                        //   [A, A] f();
    572568                        //   g([A] x, [A] y);
    573                         //   f(g());
     569                        //   g(f());
    574570                        // 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;
    575574                        std::list< Statement * > & stmts = stmtExpr->get_statements()->get_kids();
    576575                        for ( Statement *& stmt : stmts ) {
    577                                 stmt = stmt->acceptMutator( *this );
     576                                stmt = stmt->acceptMutator( *visitor );
    578577                        } // for
    579                         // stmtExpr = strict_dynamic_cast< StmtExpr * >( Parent::mutate( stmtExpr ) );
    580578                        assert( stmtExpr->get_result() );
    581579                        Type * result = stmtExpr->get_result();
    582580                        if ( ! result->isVoid() ) {
    583581                                for ( ObjectDecl * obj : stmtExpr->get_returnDecls() ) {
    584                                         stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) );
     582                                        stmtsToAddBefore.push_back( new DeclStmt( noLabels, obj ) );
    585583                                } // for
    586584                                // add destructors after current statement
     
    589587                                } // for
    590588                                // 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() );
    593590                                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() ) ) );
    595592                                stmtExpr->get_returnDecls().clear();
    596593                                stmtExpr->get_dtors().clear();
     
    598595                        assert( stmtExpr->get_returnDecls().empty() );
    599596                        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;
    604601                        unqCount[ unqExpr->get_id() ]--;
    605602                        static std::unordered_map< int, std::list< Statement * > > dtors;
    606603                        static std::unordered_map< int, UniqueExpr * > unqMap;
    607                         static std::unordered_set< int > addDeref;
    608604                        // has to be done to clean up ImplicitCopyCtorExpr nodes, even when this node was skipped in previous passes
    609605                        if ( unqMap.count( unqExpr->get_id() ) ) {
     
    616612                                        stmtsToAddAfter.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] );
    617613                                }
    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 );
    625617                        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 );
    627619                        unqMap[unqExpr->get_id()] = unqExpr;
    628620                        if ( unqCount[ unqExpr->get_id() ] == 0 ) {  // insert destructor after the last use of the unique expression
    629621                                stmtsToAddAfter.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] );
    630622                        } 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;
    644626                }
    645627
Note: See TracChangeset for help on using the changeset viewer.