Changeset 5b2f5bb for src/InitTweak


Ignore:
Timestamp:
Mar 30, 2016, 3:48:55 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:
e0323a2
Parents:
4cc4286
Message:

choose destructor at at object declaration (CtorInit?), overhaul and simplification of resolver code for CtorInit?

Location:
src/InitTweak
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    r4cc4286 r5b2f5bb  
    1010// Created On       : Wed Jan 13 16:29:30 2016
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Jan 19 16:36:59 2016
     12// Last Modified On : Wed Mar 30 14:34:46 2016
    1313// Update Count     : 30
    1414//
     
    3737
    3838                virtual CompoundStmt * mutate( CompoundStmt * compoundStmt );
     39
     40          private:
     41                std::list< Statement * > dtorStmts;
    3942        };
    4043
     
    5255                        // a decision should have been made by the resolver, so ctor and init are not both non-NULL
    5356                        assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() );
    54                         if ( Expression * ctor = ctorInit->get_ctor() ) {
    55                                 ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor );
    56                                 stmtsToAddAfter.push_back( ctorStmt );
     57                        if ( Statement * ctor = ctorInit->get_ctor() ) {
     58                                stmtsToAddAfter.push_back( ctor );
     59                                dtorStmts.push_front( ctorInit->get_dtor() );
    5760                                objDecl->set_init( NULL );
    5861                                ctorInit->set_ctor( NULL );
     62                                ctorInit->set_dtor( NULL );  // xxx - only destruct when constructing? Probably not?
    5963                        } else if ( Initializer * init = ctorInit->get_init() ) {
    6064                                objDecl->set_init( init );
     
    7074
    7175        CompoundStmt * FixInit::mutate( CompoundStmt * compoundStmt ) {
     76                // mutate statements - this will also populate dtorStmts list
     77                // don't want to dump all destructors when block is left,
     78                // just the destructors associated with variables defined in this block
     79                std::list< Statement * > oldDestructorStmts = dtorStmts;
     80                dtorStmts = std::list<Statement *>();
     81
     82                compoundStmt = PolyMutator::mutate( compoundStmt );
    7283                std::list< Statement * > & statements = compoundStmt->get_kids();
    73                 for ( std::list< Statement * >::iterator it = statements.begin(); it != statements.end(); ) {
     84                for ( std::list< Statement * >::iterator it = dtorStmts.begin(); it != dtorStmts.end(); ++it ) {
    7485                        // remove if instrinsic destructor statement
    7586                        // xxx - test user manually calling intrinsic functions - what happens?
    7687                        if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( *it ) ) {
    77                                 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( exprStmt->get_expr() ) ) {
    78                                         if ( VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() ) ) {
    79                                                 // check for Intrinsic only - don't want to remove all overridable dtors because autogenerated dtor
    80                                                 // will call all member dtors, and some members may have a user defined dtor.
    81                                                 if ( function->get_var()->get_name() == "^?{}" && function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
    82                                                         statements.erase(it++);
    83                                                         continue;
    84                                                 } else {
    85                                                 }
    86                                         }
     88                                ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( exprStmt->get_expr() );
     89                                assert( appExpr );
     90                                VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() );
     91                                assert( function );
     92                                // check for Intrinsic only - don't want to remove all overridable dtors because autogenerated dtor
     93                                // will call all member dtors, and some members may have a user defined dtor.
     94                                if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
     95                                        // don't ned to call intrinsic dtor, because it does nothing
     96                                        delete *it;
     97                                } else {
     98                                        // non-intrinsic dtors must be called
     99                                        statements.push_back( *it );
    87100                                }
     101                        } else {
     102                                // could also be a compound statement with a loop, in the case of an array
     103                                statements.push_back( *it );
    88104                        }
    89                         ++it;
    90105                }
    91                 // mutate non-destructor statements
    92                 return PolyMutator::mutate( compoundStmt );
     106                // TODO: adding to the end of a block isn't sufficient, since
     107                // return/break/goto should trigger destructor when block is left.
     108                dtorStmts = oldDestructorStmts;
     109                return compoundStmt;
    93110        }
    94111
  • src/InitTweak/RemoveInit.cc

    r4cc4286 r5b2f5bb  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Feb 09 15:12:29 2016
     12// Last Modified On : Wed Mar 30 15:45:12 2016
    1313// Update Count     : 166
    1414//
     
    7272                virtual Declaration* mutate( TypedefDecl *typeDecl );
    7373
    74                 virtual CompoundStmt * mutate( CompoundStmt * compoundStmt );
    75 
    7674          protected:
    7775                bool inFunction;
    78 
    79                 // to be added before block ends - use push_front so order is correct
    80                 std::list< Statement * > destructorStmts;
    8176        };
    8277
     
    199194                                        // call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array
    200195                                        // TODO: walk initializer and generate appropriate copy ctor if element has initializer
    201                                         SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "?{}", back_inserter( stmtsToAddAfter ) );
    202                                         SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "^?{}", front_inserter( destructorStmts ), false );
     196                                        std::list< Statement * > ctor;
     197                                        std::list< Statement * > dtor;
     198
     199                                        SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "?{}", back_inserter( ctor ) );
     200                                        SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "^?{}", front_inserter( dtor ), false );
     201
     202                                        // Currently makeArrayFunction produces a single Statement - a CompoundStmt
     203                                        // which  wraps everything that needs to happen. As such, it's technically
     204                                        // possible to use a Statement ** in the above calls, but this is inherently
     205                                        // unsafe, so instead we take the slightly less efficient route, but will be
     206                                        // immediately informed if somehow the above assumption is broken. In this case,
     207                                        // we could always wrap the list of statements at this point with a CompoundStmt,
     208                                        // but it seems reasonable at the moment for this to be done by makeArrayFunction
     209                                        // itself
     210                                        assert( ctor.size() == 1 );
     211                                        assert( dtor.size() == 1 );
     212
     213                                        objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) );
    203214                                } else {
    204215                                        // it's sufficient to attempt to call the ctor/dtor for the given object and its initializer
     
    209220                                        // if ctor does exist, want to use ctor expression instead of init
    210221                                        // push this decision to the resolver
    211                                         objDecl->set_init( new ConstructorInit( ctor, objDecl->get_init() ) );
    212                                         destructorStmts.push_front( new ExprStmt( noLabels, dtor ) );
     222                                        ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor );
     223                                        ExprStmt * dtorStmt = new ExprStmt( noLabels, dtor );
     224                                        objDecl->set_init( new ConstructorInit( ctorStmt, dtorStmt, objDecl->get_init() ) );
    213225                                }
    214226                        } else {
     
    234246        }
    235247
    236         CompoundStmt * CtorDtor::mutate( CompoundStmt * compoundStmt ) {
    237                 // don't want to dump all destructors when block is left,
    238                 // just the destructors associated with variables defined in this block
    239                 std::list< Statement * > oldDestructorStmts = destructorStmts;
    240                 destructorStmts = std::list<Statement *>();
    241 
    242                 CompoundStmt * ret = PolyMutator::mutate( compoundStmt );
    243                 std::list< Statement * > &statements = ret->get_kids();
    244                 if ( ! destructorStmts.empty() ) {
    245                         // TODO: adding to the end of a block isn't sufficient, since
    246                         // return/break/goto should trigger destructor when block is left.
    247                         statements.splice( statements.end(), destructorStmts );
    248                 } // if
    249 
    250                 destructorStmts = oldDestructorStmts;
    251                 return ret;
    252         }
    253 
    254248        // should not traverse into any of these declarations to find objects
    255249        // that need to be constructed or destructed
Note: See TracChangeset for help on using the changeset viewer.