Changeset 7030dab for src/ControlStruct/MLEMutator.cc
- Timestamp:
- Apr 6, 2020, 4:46:28 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- e3bc51c
- Parents:
- 71d6bd8 (diff), 057298e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/MLEMutator.cc
r71d6bd8 r7030dab 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Tue Oct 22 17:22:44 201913 // Update Count : 22 011 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Jan 22 11:50:00 2020 13 // Update Count : 223 14 14 // 15 15 … … 33 33 34 34 namespace ControlStruct { 35 M LEMutator::~MLEMutator() {35 MultiLevelExitMutator::~MultiLevelExitMutator() { 36 36 delete targetTable; 37 37 targetTable = 0; 38 38 } 39 39 namespace { 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 ); } 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 } 47 61 } // namespace 62 63 void MultiLevelExitMutator::premutate( FunctionDecl * ) { 64 visit_children = false; 65 } 48 66 49 67 // break labels have to come after the statement they break out of, so mutate a statement, then if they inform us 50 68 // through the breakLabel field tha they need a place to jump to on a break statement, add the break label to the 51 69 // body of statements 52 void M LEMutator::fixBlock( std::list< Statement * > &kids, bool caseClause ) {70 void MultiLevelExitMutator::fixBlock( std::list< Statement * > &kids, bool caseClause ) { 53 71 SemanticErrorException errors; 54 72 … … 81 99 } 82 100 83 void M LEMutator::premutate( CompoundStmt *cmpndStmt ) {101 void MultiLevelExitMutator::premutate( CompoundStmt *cmpndStmt ) { 84 102 visit_children = false; 85 103 bool labeledBlock = !(cmpndStmt->labels.empty()); … … 118 136 } 119 137 } 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 ) { 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 ) { 125 145 std::string originalTarget = branchStmt->originalTarget; 126 146 … … 230 250 } 231 251 232 Statement *MLEMutator::mutateLoop( Statement *bodyLoop, Entry &e ) { 252 Statement *MultiLevelExitMutator::mutateLoop( Statement *bodyLoop, Entry &e ) { 253 // only generate these when needed 254 if( !e.isContUsed() && !e.isBreakUsed() ) return bodyLoop; 255 233 256 // 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 240 // only generate these when needed 257 CompoundStmt * newBody = new CompoundStmt(); 258 newBody->get_kids().push_back( bodyLoop ); 241 259 242 260 if ( e.isContUsed() ) { … … 255 273 256 274 template< typename LoopClass > 257 void M LEMutator::prehandleLoopStmt( LoopClass * loopStmt ) {275 void MultiLevelExitMutator::prehandleLoopStmt( LoopClass * loopStmt ) { 258 276 // remember this as the most recent enclosing loop, then mutate the body of the loop -- this will determine 259 277 // whether brkLabel and contLabel are used with branch statements and will recursively do the same to nested … … 266 284 267 285 template< typename LoopClass > 268 Statement * M LEMutator::posthandleLoopStmt( LoopClass * loopStmt ) {286 Statement * MultiLevelExitMutator::posthandleLoopStmt( LoopClass * loopStmt ) { 269 287 assert( ! enclosingControlStructures.empty() ); 270 288 Entry &e = enclosingControlStructures.back(); … … 277 295 } 278 296 279 void M LEMutator::premutate( WhileStmt * whileStmt ) {297 void MultiLevelExitMutator::premutate( WhileStmt * whileStmt ) { 280 298 return prehandleLoopStmt( whileStmt ); 281 299 } 282 300 283 void M LEMutator::premutate( ForStmt * forStmt ) {301 void MultiLevelExitMutator::premutate( ForStmt * forStmt ) { 284 302 return prehandleLoopStmt( forStmt ); 285 303 } 286 304 287 Statement * M LEMutator::postmutate( WhileStmt * whileStmt ) {305 Statement * MultiLevelExitMutator::postmutate( WhileStmt * whileStmt ) { 288 306 return posthandleLoopStmt( whileStmt ); 289 307 } 290 308 291 Statement * M LEMutator::postmutate( ForStmt * forStmt ) {309 Statement * MultiLevelExitMutator::postmutate( ForStmt * forStmt ) { 292 310 return posthandleLoopStmt( forStmt ); 293 311 } 294 312 295 void M LEMutator::premutate( IfStmt * ifStmt ) {313 void MultiLevelExitMutator::premutate( IfStmt * ifStmt ) { 296 314 // generate a label for breaking out of a labeled if 297 315 bool labeledBlock = !(ifStmt->get_labels().empty()); … … 303 321 } 304 322 305 Statement * M LEMutator::postmutate( IfStmt * ifStmt ) {323 Statement * MultiLevelExitMutator::postmutate( IfStmt * ifStmt ) { 306 324 bool labeledBlock = !(ifStmt->get_labels().empty()); 307 325 if ( labeledBlock ) { … … 313 331 } 314 332 315 void M LEMutator::premutate( TryStmt * tryStmt ) {333 void MultiLevelExitMutator::premutate( TryStmt * tryStmt ) { 316 334 // generate a label for breaking out of a labeled if 317 335 bool labeledBlock = !(tryStmt->get_labels().empty()); … … 323 341 } 324 342 325 Statement * M LEMutator::postmutate( TryStmt * tryStmt ) {343 Statement * MultiLevelExitMutator::postmutate( TryStmt * tryStmt ) { 326 344 bool labeledBlock = !(tryStmt->get_labels().empty()); 327 345 if ( labeledBlock ) { … … 333 351 } 334 352 335 void MLEMutator::premutate( CaseStmt *caseStmt ) { 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 ) { 336 369 visit_children = false; 337 370 … … 372 405 } 373 406 374 void M LEMutator::premutate( SwitchStmt *switchStmt ) {407 void MultiLevelExitMutator::premutate( SwitchStmt *switchStmt ) { 375 408 // generate a label for breaking out of a labeled switch 376 409 Label brkLabel = generator->newLabel("switchBreak", switchStmt); … … 398 431 } 399 432 400 Statement * M LEMutator::postmutate( SwitchStmt * switchStmt ) {433 Statement * MultiLevelExitMutator::postmutate( SwitchStmt * switchStmt ) { 401 434 Entry &e = enclosingControlStructures.back(); 402 435 assert ( e == switchStmt );
Note:
See TracChangeset
for help on using the changeset viewer.