Ignore:
Timestamp:
Apr 6, 2020, 4:46:28 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
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.
Message:

Merge branch 'master' into new-ast

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/MLEMutator.cc

    r71d6bd8 r7030dab  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Oct 22 17:22:44 2019
    13 // Update Count     : 220
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Jan 22 11:50:00 2020
     13// Update Count     : 223
    1414//
    1515
     
    3333
    3434namespace ControlStruct {
    35         MLEMutator::~MLEMutator() {
     35        MultiLevelExitMutator::~MultiLevelExitMutator() {
    3636                delete targetTable;
    3737                targetTable = 0;
    3838        }
    3939        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                }
    4761        } // namespace
     62
     63        void MultiLevelExitMutator::premutate( FunctionDecl * ) {
     64                visit_children = false;
     65        }
    4866
    4967        // break labels have to come after the statement they break out of, so mutate a statement, then if they inform us
    5068        // through the breakLabel field tha they need a place to jump to on a break statement, add the break label to the
    5169        // body of statements
    52         void MLEMutator::fixBlock( std::list< Statement * > &kids, bool caseClause ) {
     70        void MultiLevelExitMutator::fixBlock( std::list< Statement * > &kids, bool caseClause ) {
    5371                SemanticErrorException errors;
    5472
     
    8199        }
    82100
    83         void MLEMutator::premutate( CompoundStmt *cmpndStmt ) {
     101        void MultiLevelExitMutator::premutate( CompoundStmt *cmpndStmt ) {
    84102                visit_children = false;
    85103                bool labeledBlock = !(cmpndStmt->labels.empty());
     
    118136                        }
    119137                }
    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 ) {
    125145                std::string originalTarget = branchStmt->originalTarget;
    126146
     
    230250        }
    231251
    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
    233256                // 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 );
    241259
    242260                if ( e.isContUsed() ) {
     
    255273
    256274        template< typename LoopClass >
    257         void MLEMutator::prehandleLoopStmt( LoopClass * loopStmt ) {
     275        void MultiLevelExitMutator::prehandleLoopStmt( LoopClass * loopStmt ) {
    258276                // remember this as the most recent enclosing loop, then mutate the body of the loop -- this will determine
    259277                // whether brkLabel and contLabel are used with branch statements and will recursively do the same to nested
     
    266284
    267285        template< typename LoopClass >
    268         Statement * MLEMutator::posthandleLoopStmt( LoopClass * loopStmt ) {
     286        Statement * MultiLevelExitMutator::posthandleLoopStmt( LoopClass * loopStmt ) {
    269287                assert( ! enclosingControlStructures.empty() );
    270288                Entry &e = enclosingControlStructures.back();
     
    277295        }
    278296
    279         void MLEMutator::premutate( WhileStmt * whileStmt ) {
     297        void MultiLevelExitMutator::premutate( WhileStmt * whileStmt ) {
    280298                return prehandleLoopStmt( whileStmt );
    281299        }
    282300
    283         void MLEMutator::premutate( ForStmt * forStmt ) {
     301        void MultiLevelExitMutator::premutate( ForStmt * forStmt ) {
    284302                return prehandleLoopStmt( forStmt );
    285303        }
    286304
    287         Statement * MLEMutator::postmutate( WhileStmt * whileStmt ) {
     305        Statement * MultiLevelExitMutator::postmutate( WhileStmt * whileStmt ) {
    288306                return posthandleLoopStmt( whileStmt );
    289307        }
    290308
    291         Statement * MLEMutator::postmutate( ForStmt * forStmt ) {
     309        Statement * MultiLevelExitMutator::postmutate( ForStmt * forStmt ) {
    292310                return posthandleLoopStmt( forStmt );
    293311        }
    294312
    295         void MLEMutator::premutate( IfStmt * ifStmt ) {
     313        void MultiLevelExitMutator::premutate( IfStmt * ifStmt ) {
    296314                // generate a label for breaking out of a labeled if
    297315                bool labeledBlock = !(ifStmt->get_labels().empty());
     
    303321        }
    304322
    305         Statement * MLEMutator::postmutate( IfStmt * ifStmt ) {
     323        Statement * MultiLevelExitMutator::postmutate( IfStmt * ifStmt ) {
    306324                bool labeledBlock = !(ifStmt->get_labels().empty());
    307325                if ( labeledBlock ) {
     
    313331        }
    314332
    315         void MLEMutator::premutate( TryStmt * tryStmt ) {
     333        void MultiLevelExitMutator::premutate( TryStmt * tryStmt ) {
    316334                // generate a label for breaking out of a labeled if
    317335                bool labeledBlock = !(tryStmt->get_labels().empty());
     
    323341        }
    324342
    325         Statement * MLEMutator::postmutate( TryStmt * tryStmt ) {
     343        Statement * MultiLevelExitMutator::postmutate( TryStmt * tryStmt ) {
    326344                bool labeledBlock = !(tryStmt->get_labels().empty());
    327345                if ( labeledBlock ) {
     
    333351        }
    334352
    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 ) {
    336369                visit_children = false;
    337370
     
    372405        }
    373406
    374         void MLEMutator::premutate( SwitchStmt *switchStmt ) {
     407        void MultiLevelExitMutator::premutate( SwitchStmt *switchStmt ) {
    375408                // generate a label for breaking out of a labeled switch
    376409                Label brkLabel = generator->newLabel("switchBreak", switchStmt);
     
    398431        }
    399432
    400         Statement * MLEMutator::postmutate( SwitchStmt * switchStmt ) {
     433        Statement * MultiLevelExitMutator::postmutate( SwitchStmt * switchStmt ) {
    401434                Entry &e = enclosingControlStructures.back();
    402435                assert ( e == switchStmt );
Note: See TracChangeset for help on using the changeset viewer.