Changeset 39786813 for src/InitTweak


Ignore:
Timestamp:
Mar 31, 2016, 2:33:49 PM (9 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
a5a71d0
Parents:
e0323a2
Message:

generate appropriate destructor calls before return, break, and continue statements (todo: goto, labelled break/continue)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    re0323a2 r39786813  
    1010// Created On       : Wed Jan 13 16:29:30 2016
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Thu Mar 31 10:08:49 2016
     12// Last Modified On : Thu Mar 31 13:54:58 2016
    1313// Update Count     : 30
    1414//
     
    3838
    3939                virtual CompoundStmt * mutate( CompoundStmt * compoundStmt );
     40                virtual Statement * mutate( ReturnStmt * returnStmt );
     41                virtual Statement * mutate( BranchStmt * branchStmt );
    4042
    4143          private:
    42                 std::list< Statement * > dtorStmts;
     44                // stack of list of statements - used to differentiate scopes
     45                std::list< std::list< Statement * > > dtorStmts;
    4346        };
    4447
     
    103106                                } else {
    104107                                        stmtsToAddAfter.push_back( ctor );
    105                                         dtorStmts.push_front( ctorInit->get_dtor() );
     108                                        dtorStmts.back().push_front( ctorInit->get_dtor() );
    106109                                }
    107110                                objDecl->set_init( NULL );
     
    120123        }
    121124
    122         CompoundStmt * FixInit::mutate( CompoundStmt * compoundStmt ) {
    123                 // mutate statements - this will also populate dtorStmts list
    124                 // don't want to dump all destructors when block is left,
    125                 // just the destructors associated with variables defined in this block
    126                 std::list< Statement * > oldDestructorStmts = dtorStmts;
    127                 dtorStmts = std::list<Statement *>();
    128 
    129                 compoundStmt = PolyMutator::mutate( compoundStmt );
    130                 std::list< Statement * > & statements = compoundStmt->get_kids();
    131                 for ( std::list< Statement * >::iterator it = dtorStmts.begin(); it != dtorStmts.end(); ++it ) {
     125        template<typename Iterator, typename OutputIterator>
     126        void insertDtors( Iterator begin, Iterator end, OutputIterator out ) {
     127                for ( Iterator it = begin ; it != end ; ++it ) {
    132128                        // remove if instrinsic destructor statement
    133129                        // xxx - test user manually calling intrinsic functions - what happens?
     
    140136                                // will call all member dtors, and some members may have a user defined dtor.
    141137                                if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
    142                                         // don't ned to call intrinsic dtor, because it does nothing
    143                                         delete *it;
     138                                        // don't need to call intrinsic dtor, because it does nothing
    144139                                } else {
    145140                                        // non-intrinsic dtors must be called
    146                                         statements.push_back( *it );
     141                                        *out++ = (*it)->clone();
    147142                                }
    148143                        } else {
    149144                                // could also be a compound statement with a loop, in the case of an array
    150                                 statements.push_back( *it );
     145                                *out++ = (*it)->clone();
    151146                        }
    152147                }
     148        }
     149
     150
     151        CompoundStmt * FixInit::mutate( CompoundStmt * compoundStmt ) {
     152                // mutate statements - this will also populate dtorStmts list.
     153                // don't want to dump all destructors when block is left,
     154                // just the destructors associated with variables defined in this block,
     155                // so push a new list to the top of the stack so that we can differentiate scopes
     156                dtorStmts.push_back( std::list<Statement *>() );
     157
     158                compoundStmt = PolyMutator::mutate( compoundStmt );
     159                std::list< Statement * > & statements = compoundStmt->get_kids();
     160
     161                insertDtors( dtorStmts.back().begin(), dtorStmts.back().end(), back_inserter( statements ) );
     162
     163                deleteAll( dtorStmts.back() );
     164                dtorStmts.pop_back();
     165                return compoundStmt;
     166        }
     167
     168        Statement * FixInit::mutate( ReturnStmt * returnStmt ) {
     169                for ( std::list< std::list< Statement * > >::reverse_iterator list = dtorStmts.rbegin(); list != dtorStmts.rend(); ++list ) {
     170                        insertDtors( list->begin(), list->end(), back_inserter( stmtsToAdd ) );
     171                }
     172                return returnStmt;
     173        }
     174
     175        Statement * FixInit::mutate( BranchStmt * branchStmt ) {
    153176                // TODO: adding to the end of a block isn't sufficient, since
    154177                // return/break/goto should trigger destructor when block is left.
    155                 dtorStmts = oldDestructorStmts;
    156                 return compoundStmt;
    157         }
     178                switch( branchStmt->get_type() ) {
     179                        case BranchStmt::Continue:
     180                        case BranchStmt::Break:
     181                                insertDtors( dtorStmts.back().begin(), dtorStmts.back().end(), back_inserter( stmtsToAdd ) );
     182                                break;
     183                        case BranchStmt::Goto:
     184                                // xxx
     185                                // if goto leaves a block, generate dtors for every block it leaves
     186                                // if goto is in same block but earlier statement, destruct every object that was defined after the statement
     187                                break;
     188                        default:
     189                                assert( false );
     190                }
     191                return branchStmt;
     192        }
     193
    158194
    159195} // namespace InitTweak
Note: See TracChangeset for help on using the changeset viewer.