Changeset 5b2f5bb for src/InitTweak
- Timestamp:
- Mar 30, 2016, 3:48:55 PM (9 years ago)
- 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
- Location:
- src/InitTweak
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixInit.cc
r4cc4286 r5b2f5bb 10 10 // Created On : Wed Jan 13 16:29:30 2016 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Tue Jan 19 16:36:59201612 // Last Modified On : Wed Mar 30 14:34:46 2016 13 13 // Update Count : 30 14 14 // … … 37 37 38 38 virtual CompoundStmt * mutate( CompoundStmt * compoundStmt ); 39 40 private: 41 std::list< Statement * > dtorStmts; 39 42 }; 40 43 … … 52 55 // a decision should have been made by the resolver, so ctor and init are not both non-NULL 53 56 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() ); 57 60 objDecl->set_init( NULL ); 58 61 ctorInit->set_ctor( NULL ); 62 ctorInit->set_dtor( NULL ); // xxx - only destruct when constructing? Probably not? 59 63 } else if ( Initializer * init = ctorInit->get_init() ) { 60 64 objDecl->set_init( init ); … … 70 74 71 75 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 ); 72 83 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 ) { 74 85 // remove if instrinsic destructor statement 75 86 // xxx - test user manually calling intrinsic functions - what happens? 76 87 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 ); 87 100 } 101 } else { 102 // could also be a compound statement with a loop, in the case of an array 103 statements.push_back( *it ); 88 104 } 89 ++it;90 105 } 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; 93 110 } 94 111 -
src/InitTweak/RemoveInit.cc
r4cc4286 r5b2f5bb 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Tue Feb 09 15:12:29201612 // Last Modified On : Wed Mar 30 15:45:12 2016 13 13 // Update Count : 166 14 14 // … … 72 72 virtual Declaration* mutate( TypedefDecl *typeDecl ); 73 73 74 virtual CompoundStmt * mutate( CompoundStmt * compoundStmt );75 76 74 protected: 77 75 bool inFunction; 78 79 // to be added before block ends - use push_front so order is correct80 std::list< Statement * > destructorStmts;81 76 }; 82 77 … … 199 194 // call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array 200 195 // 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() ) ); 203 214 } else { 204 215 // it's sufficient to attempt to call the ctor/dtor for the given object and its initializer … … 209 220 // if ctor does exist, want to use ctor expression instead of init 210 221 // 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() ) ); 213 225 } 214 226 } else { … … 234 246 } 235 247 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 block239 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, since246 // return/break/goto should trigger destructor when block is left.247 statements.splice( statements.end(), destructorStmts );248 } // if249 250 destructorStmts = oldDestructorStmts;251 return ret;252 }253 254 248 // should not traverse into any of these declarations to find objects 255 249 // that need to be constructed or destructed
Note: See TracChangeset
for help on using the changeset viewer.