Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/MLEMutator.cc

    r9d6317f r720a007  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Jan 22 11:50:00 2020
    13 // Update Count     : 223
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Mar  8 17:08:25 2018
     13// Update Count     : 219
    1414//
    1515
     
    3333
    3434namespace ControlStruct {
    35         MultiLevelExitMutator::~MultiLevelExitMutator() {
     35        MLEMutator::~MLEMutator() {
    3636                delete targetTable;
    3737                targetTable = 0;
    3838        }
    3939        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 ); }
    6147        } // namespace
    62 
    63         void MultiLevelExitMutator::premutate( FunctionDecl * ) {
    64                 visit_children = false;
    65         }
    6648
    6749        // break labels have to come after the statement they break out of, so mutate a statement, then if they inform us
    6850        // through the breakLabel field tha they need a place to jump to on a break statement, add the break label to the
    6951        // body of statements
    70         void MultiLevelExitMutator::fixBlock( std::list< Statement * > &kids, bool caseClause ) {
     52        void MLEMutator::fixBlock( std::list< Statement * > &kids, bool caseClause ) {
    7153                SemanticErrorException errors;
    7254
     
    9981        }
    10082
    101         void MultiLevelExitMutator::premutate( CompoundStmt *cmpndStmt ) {
     83        void MLEMutator::premutate( CompoundStmt *cmpndStmt ) {
    10284                visit_children = false;
    10385                bool labeledBlock = !(cmpndStmt->labels.empty());
     
    136118                        }
    137119                }
    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 ) {
    145125                std::string originalTarget = branchStmt->originalTarget;
    146126
     
    250230        }
    251231
    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
    253240                // only generate these when needed
    254                 if( !e.isContUsed() && !e.isBreakUsed() ) return bodyLoop;
    255 
    256                 // ensure loop body is a block
    257                 CompoundStmt * newBody = new CompoundStmt();
    258                 newBody->get_kids().push_back( bodyLoop );
    259241
    260242                if ( e.isContUsed() ) {
     
    273255
    274256        template< typename LoopClass >
    275         void MultiLevelExitMutator::prehandleLoopStmt( LoopClass * loopStmt ) {
     257        void MLEMutator::prehandleLoopStmt( LoopClass * loopStmt ) {
    276258                // remember this as the most recent enclosing loop, then mutate the body of the loop -- this will determine
    277259                // whether brkLabel and contLabel are used with branch statements and will recursively do the same to nested
     
    284266
    285267        template< typename LoopClass >
    286         Statement * MultiLevelExitMutator::posthandleLoopStmt( LoopClass * loopStmt ) {
     268        Statement * MLEMutator::posthandleLoopStmt( LoopClass * loopStmt ) {
    287269                assert( ! enclosingControlStructures.empty() );
    288270                Entry &e = enclosingControlStructures.back();
     
    295277        }
    296278
    297         void MultiLevelExitMutator::premutate( WhileStmt * whileStmt ) {
     279        void MLEMutator::premutate( WhileStmt * whileStmt ) {
    298280                return prehandleLoopStmt( whileStmt );
    299281        }
    300282
    301         void MultiLevelExitMutator::premutate( ForStmt * forStmt ) {
     283        void MLEMutator::premutate( ForStmt * forStmt ) {
    302284                return prehandleLoopStmt( forStmt );
    303285        }
    304286
    305         Statement * MultiLevelExitMutator::postmutate( WhileStmt * whileStmt ) {
     287        Statement * MLEMutator::postmutate( WhileStmt * whileStmt ) {
    306288                return posthandleLoopStmt( whileStmt );
    307289        }
    308290
    309         Statement * MultiLevelExitMutator::postmutate( ForStmt * forStmt ) {
     291        Statement * MLEMutator::postmutate( ForStmt * forStmt ) {
    310292                return posthandleLoopStmt( forStmt );
    311293        }
    312294
    313         void MultiLevelExitMutator::premutate( IfStmt * ifStmt ) {
     295        void MLEMutator::premutate( IfStmt * ifStmt ) {
    314296                // generate a label for breaking out of a labeled if
    315297                bool labeledBlock = !(ifStmt->get_labels().empty());
     
    321303        }
    322304
    323         Statement * MultiLevelExitMutator::postmutate( IfStmt * ifStmt ) {
     305        Statement * MLEMutator::postmutate( IfStmt * ifStmt ) {
    324306                bool labeledBlock = !(ifStmt->get_labels().empty());
    325307                if ( labeledBlock ) {
     
    331313        }
    332314
    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 ) {
    369316                visit_children = false;
    370317
     
    405352        }
    406353
    407         void MultiLevelExitMutator::premutate( SwitchStmt *switchStmt ) {
     354        void MLEMutator::premutate( SwitchStmt *switchStmt ) {
    408355                // generate a label for breaking out of a labeled switch
    409356                Label brkLabel = generator->newLabel("switchBreak", switchStmt);
     
    431378        }
    432379
    433         Statement * MultiLevelExitMutator::postmutate( SwitchStmt * switchStmt ) {
     380        Statement * MLEMutator::postmutate( SwitchStmt * switchStmt ) {
    434381                Entry &e = enclosingControlStructures.back();
    435382                assert ( e == switchStmt );
Note: See TracChangeset for help on using the changeset viewer.