Changes in src/ControlStruct/MLEMutator.cc [9d6317f:720a007]
- File:
-
- 1 edited
-
src/ControlStruct/MLEMutator.cc (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/MLEMutator.cc
r9d6317f r720a007 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Wed Jan 22 11:50:00 202013 // Update Count : 2 2311 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Mar 8 17:08:25 2018 13 // Update Count : 219 14 14 // 15 15 … … 33 33 34 34 namespace ControlStruct { 35 M ultiLevelExitMutator::~MultiLevelExitMutator() {35 MLEMutator::~MLEMutator() { 36 36 delete targetTable; 37 37 targetTable = 0; 38 38 } 39 39 namespace { 40 bool isLoop( const MultiLevelExitMutator::Entry & e ) { 41 return dynamic_cast< WhileStmt * >( e.get_controlStructure() ) 42 || dynamic_cast< ForStmt * >( e.get_controlStructure() ); 43 } 44 bool isSwitch( const MultiLevelExitMutator::Entry & e ) { 45 return dynamic_cast< SwitchStmt *>( e.get_controlStructure() ); 46 } 47 48 bool isBreakTarget( const MultiLevelExitMutator::Entry & e ) { 49 return isLoop( e ) || isSwitch( e ) 50 || dynamic_cast< CompoundStmt *>( e.get_controlStructure() ); 51 } 52 bool isContinueTarget( const MultiLevelExitMutator::Entry & e ) { 53 return isLoop( e ); 54 } 55 bool isFallthroughTarget( const MultiLevelExitMutator::Entry & e ) { 56 return dynamic_cast< CaseStmt *>( e.get_controlStructure() ); 57 } 58 bool isFallthroughDefaultTarget( const MultiLevelExitMutator::Entry & e ) { 59 return isSwitch( e ); 60 } 40 bool isLoop( const MLEMutator::Entry & e ) { return dynamic_cast< WhileStmt * >( e.get_controlStructure() ) || dynamic_cast< ForStmt * >( e.get_controlStructure() ); } 41 bool isSwitch( const MLEMutator::Entry & e ) { return dynamic_cast< SwitchStmt *>( e.get_controlStructure() ); } 42 43 bool isBreakTarget( const MLEMutator::Entry & e ) { return isLoop( e ) || isSwitch( e ) || dynamic_cast< CompoundStmt *>( e.get_controlStructure() ); } 44 bool isContinueTarget( const MLEMutator::Entry & e ) { return isLoop( e ); } 45 bool isFallthroughTarget( const MLEMutator::Entry & e ) { return dynamic_cast< CaseStmt *>( e.get_controlStructure() );; } 46 bool isFallthroughDefaultTarget( const MLEMutator::Entry & e ) { return isSwitch( e ); } 61 47 } // namespace 62 63 void MultiLevelExitMutator::premutate( FunctionDecl * ) {64 visit_children = false;65 }66 48 67 49 // break labels have to come after the statement they break out of, so mutate a statement, then if they inform us 68 50 // through the breakLabel field tha they need a place to jump to on a break statement, add the break label to the 69 51 // body of statements 70 void M ultiLevelExitMutator::fixBlock( std::list< Statement * > &kids, bool caseClause ) {52 void MLEMutator::fixBlock( std::list< Statement * > &kids, bool caseClause ) { 71 53 SemanticErrorException errors; 72 54 … … 99 81 } 100 82 101 void M ultiLevelExitMutator::premutate( CompoundStmt *cmpndStmt ) {83 void MLEMutator::premutate( CompoundStmt *cmpndStmt ) { 102 84 visit_children = false; 103 85 bool labeledBlock = !(cmpndStmt->labels.empty()); … … 136 118 } 137 119 } 138 assertf( false, "Could not find label '%s' on statement %s", 139 originalTarget.get_name().c_str(), toString( stmt ).c_str() ); 140 } 141 142 143 Statement *MultiLevelExitMutator::postmutate( BranchStmt *branchStmt ) 144 throw ( SemanticErrorException ) { 120 assertf( false, "Could not find label '%s' on statement %s", originalTarget.get_name().c_str(), toString( stmt ).c_str() ); 121 } 122 123 124 Statement *MLEMutator::postmutate( BranchStmt *branchStmt ) throw ( SemanticErrorException ) { 145 125 std::string originalTarget = branchStmt->originalTarget; 146 126 … … 250 230 } 251 231 252 Statement *MultiLevelExitMutator::mutateLoop( Statement *bodyLoop, Entry &e ) { 232 Statement *MLEMutator::mutateLoop( Statement *bodyLoop, Entry &e ) { 233 // ensure loop body is a block 234 CompoundStmt *newBody; 235 if ( ! (newBody = dynamic_cast<CompoundStmt *>( bodyLoop )) ) { 236 newBody = new CompoundStmt(); 237 newBody->get_kids().push_back( bodyLoop ); 238 } // if 239 253 240 // only generate these when needed 254 if( !e.isContUsed() && !e.isBreakUsed() ) return bodyLoop;255 256 // ensure loop body is a block257 CompoundStmt * newBody = new CompoundStmt();258 newBody->get_kids().push_back( bodyLoop );259 241 260 242 if ( e.isContUsed() ) { … … 273 255 274 256 template< typename LoopClass > 275 void M ultiLevelExitMutator::prehandleLoopStmt( LoopClass * loopStmt ) {257 void MLEMutator::prehandleLoopStmt( LoopClass * loopStmt ) { 276 258 // remember this as the most recent enclosing loop, then mutate the body of the loop -- this will determine 277 259 // whether brkLabel and contLabel are used with branch statements and will recursively do the same to nested … … 284 266 285 267 template< typename LoopClass > 286 Statement * M ultiLevelExitMutator::posthandleLoopStmt( LoopClass * loopStmt ) {268 Statement * MLEMutator::posthandleLoopStmt( LoopClass * loopStmt ) { 287 269 assert( ! enclosingControlStructures.empty() ); 288 270 Entry &e = enclosingControlStructures.back(); … … 295 277 } 296 278 297 void M ultiLevelExitMutator::premutate( WhileStmt * whileStmt ) {279 void MLEMutator::premutate( WhileStmt * whileStmt ) { 298 280 return prehandleLoopStmt( whileStmt ); 299 281 } 300 282 301 void M ultiLevelExitMutator::premutate( ForStmt * forStmt ) {283 void MLEMutator::premutate( ForStmt * forStmt ) { 302 284 return prehandleLoopStmt( forStmt ); 303 285 } 304 286 305 Statement * M ultiLevelExitMutator::postmutate( WhileStmt * whileStmt ) {287 Statement * MLEMutator::postmutate( WhileStmt * whileStmt ) { 306 288 return posthandleLoopStmt( whileStmt ); 307 289 } 308 290 309 Statement * M ultiLevelExitMutator::postmutate( ForStmt * forStmt ) {291 Statement * MLEMutator::postmutate( ForStmt * forStmt ) { 310 292 return posthandleLoopStmt( forStmt ); 311 293 } 312 294 313 void M ultiLevelExitMutator::premutate( IfStmt * ifStmt ) {295 void MLEMutator::premutate( IfStmt * ifStmt ) { 314 296 // generate a label for breaking out of a labeled if 315 297 bool labeledBlock = !(ifStmt->get_labels().empty()); … … 321 303 } 322 304 323 Statement * M ultiLevelExitMutator::postmutate( IfStmt * ifStmt ) {305 Statement * MLEMutator::postmutate( IfStmt * ifStmt ) { 324 306 bool labeledBlock = !(ifStmt->get_labels().empty()); 325 307 if ( labeledBlock ) { … … 331 313 } 332 314 333 void MultiLevelExitMutator::premutate( TryStmt * tryStmt ) { 334 // generate a label for breaking out of a labeled if 335 bool labeledBlock = !(tryStmt->get_labels().empty()); 336 if ( labeledBlock ) { 337 Label brkLabel = generator->newLabel("blockBreak", tryStmt); 338 enclosingControlStructures.push_back( Entry( tryStmt, brkLabel ) ); 339 GuardAction( [this]() { enclosingControlStructures.pop_back(); } ); 340 } // if 341 } 342 343 Statement * MultiLevelExitMutator::postmutate( TryStmt * tryStmt ) { 344 bool labeledBlock = !(tryStmt->get_labels().empty()); 345 if ( labeledBlock ) { 346 if ( ! enclosingControlStructures.back().useBreakExit().empty() ) { 347 set_breakLabel( enclosingControlStructures.back().useBreakExit() ); 348 } // if 349 } // if 350 return tryStmt; 351 } 352 353 void MultiLevelExitMutator::premutate( FinallyStmt * ) { 354 GuardAction([this, old = std::move(enclosingControlStructures)]() { 355 enclosingControlStructures = std::move(old); 356 }); 357 enclosingControlStructures = std::list<Entry>(); 358 GuardValue( inFinally ); 359 inFinally = true; 360 } 361 362 void MultiLevelExitMutator::premutate( ReturnStmt *returnStmt ) { 363 if ( inFinally ) { 364 SemanticError( returnStmt->location, "'return' may not appear in a finally clause" ); 365 } 366 } 367 368 void MultiLevelExitMutator::premutate( CaseStmt *caseStmt ) { 315 void MLEMutator::premutate( CaseStmt *caseStmt ) { 369 316 visit_children = false; 370 317 … … 405 352 } 406 353 407 void M ultiLevelExitMutator::premutate( SwitchStmt *switchStmt ) {354 void MLEMutator::premutate( SwitchStmt *switchStmt ) { 408 355 // generate a label for breaking out of a labeled switch 409 356 Label brkLabel = generator->newLabel("switchBreak", switchStmt); … … 431 378 } 432 379 433 Statement * M ultiLevelExitMutator::postmutate( SwitchStmt * switchStmt ) {380 Statement * MLEMutator::postmutate( SwitchStmt * switchStmt ) { 434 381 Entry &e = enclosingControlStructures.back(); 435 382 assert ( e == switchStmt );
Note:
See TracChangeset
for help on using the changeset viewer.