Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    r233e4d9 r597db97  
    5252        namespace {
    5353                typedef std::unordered_map< Expression *, TypeSubstitution * > EnvMap;
     54                typedef std::unordered_map< int, int > UnqCount;
    5455
    5556                class InsertImplicitCalls final : public GenPoly::PolyMutator {
     
    7475                        /// generate/resolve copy construction expressions for each, and generate/resolve destructors for both
    7576                        /// arguments and return value temporaries
    76                         static void resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap );
     77                        static void resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap, UnqCount & unqCount );
    7778
    7879                        typedef SymTab::Indexer Parent;
    7980                        using Parent::visit;
    8081
    81                         ResolveCopyCtors( const EnvMap & envMap ) : envMap( envMap ) {}
     82                        ResolveCopyCtors( const EnvMap & envMap, UnqCount & unqCount ) : envMap( envMap ), unqCount( unqCount ) {}
    8283
    8384                        virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) override;
     
    9495                        TypeSubstitution * env;
    9596                        const EnvMap & envMap;
     97                        UnqCount & unqCount; // count the number of times each unique expr ID appears
    9698                };
    9799
     
    202204                class FixCopyCtors final : public GenPoly::PolyMutator {
    203205                  public:
     206                        FixCopyCtors( UnqCount & unqCount ) : unqCount( unqCount ){}
    204207                        /// expand ImplicitCopyCtorExpr nodes into the temporary declarations, copy constructors, call expression,
    205208                        /// and destructors
    206                         static void fixCopyCtors( std::list< Declaration * > &translationUnit );
     209                        static void fixCopyCtors( std::list< Declaration * > &translationUnit, UnqCount & unqCount );
    207210
    208211                        typedef GenPoly::PolyMutator Parent;
     
    211214                        virtual Expression * mutate( UniqueExpr * unqExpr ) override;
    212215                        virtual Expression * mutate( StmtExpr * stmtExpr ) override;
     216
     217                        UnqCount & unqCount;
    213218                };
    214219
     
    272277
    273278                EnvMap envMap;
     279                UnqCount unqCount;
    274280
    275281                InsertImplicitCalls::insert( translationUnit, envMap );
    276                 ResolveCopyCtors::resolveImplicitCalls( translationUnit, envMap );
     282                ResolveCopyCtors::resolveImplicitCalls( translationUnit, envMap, unqCount );
    277283                InsertDtors::insert( translationUnit );
    278284                FixInit::fixInitializers( translationUnit );
    279285
    280286                // FixCopyCtors must happen after FixInit, so that destructors are placed correctly
    281                 FixCopyCtors::fixCopyCtors( translationUnit );
     287                FixCopyCtors::fixCopyCtors( translationUnit, unqCount );
    282288
    283289                GenStructMemberCalls::generate( translationUnit );
     
    298304                }
    299305
    300                 void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap ) {
    301                         ResolveCopyCtors resolver( envMap );
     306                void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap, UnqCount & unqCount ) {
     307                        ResolveCopyCtors resolver( envMap, unqCount );
    302308                        acceptAll( translationUnit, resolver );
    303309                }
     
    329335                }
    330336
    331                 void FixCopyCtors::fixCopyCtors( std::list< Declaration * > & translationUnit ) {
    332                         FixCopyCtors fixer;
     337                void FixCopyCtors::fixCopyCtors( std::list< Declaration * > & translationUnit, UnqCount & unqCount ) {
     338                        FixCopyCtors fixer( unqCount );
    333339                        mutateAll( translationUnit, fixer );
    334340                }
     
    520526                void ResolveCopyCtors::visit( UniqueExpr * unqExpr ) {
    521527                        static std::unordered_set< int > vars;
     528                        unqCount[ unqExpr->get_id() ]++;  // count the number of unique expressions for each ID
    522529                        if ( vars.count( unqExpr->get_id() ) ) {
    523530                                // xxx - hack to prevent double-handling of unique exprs, otherwise too many temporary variables and destructors are generated
     
    636643
    637644                Expression * FixCopyCtors::mutate( UniqueExpr * unqExpr ) {
     645                        unqCount[ unqExpr->get_id() ]--;
     646                        static std::unordered_map< int, std::list< Statement * > > dtors;
    638647                        static std::unordered_map< int, UniqueExpr * > unqMap;
    639648                        static std::unordered_set< int > addDeref;
     
    645654                                delete unqExpr->get_result();
    646655                                unqExpr->set_result( maybeClone( unqExpr->get_expr()->get_result() ) );
     656                                if ( unqCount[ unqExpr->get_id() ] == 0 ) {  // insert destructor after the last use of the unique expression
     657                                        stmtsToAdd.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] );
     658                                }
    647659                                if ( addDeref.count( unqExpr->get_id() ) ) {
    648660                                        // other UniqueExpr was dereferenced because it was an lvalue return, so this one should be too
     
    651663                                return unqExpr;
    652664                        }
    653                         unqExpr = safe_dynamic_cast< UniqueExpr * >( Parent::mutate( unqExpr ) ); // stmtexprs contained should not be separately fixed, so this must occur after the lookup
     665                        FixCopyCtors fixer( unqCount );
     666                        unqExpr->set_expr( unqExpr->get_expr()->acceptMutator( fixer ) ); // stmtexprs contained should not be separately fixed, so this must occur after the lookup
     667                        stmtsToAdd.splice( stmtsToAdd.end(), fixer.stmtsToAdd );
    654668                        unqMap[unqExpr->get_id()] = unqExpr;
    655669                        if ( UntypedExpr * deref = dynamic_cast< UntypedExpr * >( unqExpr->get_expr() ) ) {
     
    661675                                getCallArg( deref, 0 ) = unqExpr;
    662676                                addDeref.insert( unqExpr->get_id() );
     677                                if ( unqCount[ unqExpr->get_id() ] == 0 ) {  // insert destructor after the last use of the unique expression
     678                                        stmtsToAdd.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] );
     679                                } else { // remember dtors for last instance of unique expr
     680                                        dtors[ unqExpr->get_id() ] = fixer.stmtsToAddAfter;
     681                                }
    663682                                return deref;
    664683                        }
Note: See TracChangeset for help on using the changeset viewer.