Changeset 94e025a2


Ignore:
Timestamp:
Jan 8, 2018, 2:34:32 PM (6 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
b3fc977
Parents:
8587878e
Message:

Convert MLEMutator to PassVisitor?

Location:
src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/LabelFixer.cc

    r8587878e r94e025a2  
    4444
    4545        void LabelFixer::postvisit( FunctionDecl * functionDecl ) {
    46                 MLEMutator mlemut( resolveJumps(), generator );
     46                PassVisitor<MLEMutator> mlemut( resolveJumps(), generator );
    4747                functionDecl->acceptMutator( mlemut );
    4848        }
  • src/ControlStruct/MLEMutator.cc

    r8587878e r94e025a2  
    4646        void MLEMutator::fixBlock( std::list< Statement * > &kids ) {
    4747                for ( std::list< Statement * >::iterator k = kids.begin(); k != kids.end(); k++ ) {
    48                         *k = (*k)->acceptMutator(*this);
     48                        *k = (*k)->acceptMutator(*visitor);
    4949
    5050                        if ( ! get_breakLabel().empty() ) {
     
    5757        }
    5858
    59         CompoundStmt* MLEMutator::mutate( CompoundStmt *cmpndStmt ) {
    60                 bool labeledBlock = !(cmpndStmt->get_labels().empty());
     59        void MLEMutator::premutate( CompoundStmt *cmpndStmt ) {
     60                visit_children = false;
     61                bool labeledBlock = !(cmpndStmt->labels.empty());
    6162                if ( labeledBlock ) {
    6263                        Label brkLabel = generator->newLabel("blockBreak", cmpndStmt);
     
    6566
    6667                // a child statement may set the break label - if they do, attach it to the next statement
    67                 std::list< Statement * > &kids = cmpndStmt->get_kids();
     68                std::list< Statement * > &kids = cmpndStmt->kids;
    6869                fixBlock( kids );
    6970
     
    7576                        enclosingControlStructures.pop_back();
    7677                } // if
    77 
    78                 return cmpndStmt;
    79         }
    80 
    81         template< typename LoopClass >
    82         Statement *MLEMutator::handleLoopStmt( LoopClass *loopStmt ) {
    83                 // remember this as the most recent enclosing loop, then mutate the body of the loop -- this will determine
    84                 // whether brkLabel and contLabel are used with branch statements and will recursively do the same to nested
    85                 // loops
    86                 Label brkLabel = generator->newLabel("loopBreak", loopStmt);
    87                 Label contLabel = generator->newLabel("loopContinue", loopStmt);
    88                 enclosingControlStructures.push_back( Entry( loopStmt, brkLabel, contLabel ) );
    89                 loopStmt->set_body ( loopStmt->get_body()->acceptMutator( *this ) );
    90 
    91                 assert( ! enclosingControlStructures.empty() );
    92                 Entry &e = enclosingControlStructures.back();
    93                 // sanity check that the enclosing loops have been popped correctly
    94                 assert ( e == loopStmt );
    95 
    96                 // this will take the necessary steps to add definitions of the previous two labels, if they are used.
    97                 loopStmt->set_body( mutateLoop( loopStmt->get_body(), e ) );
    98                 enclosingControlStructures.pop_back();
    99 
    100                 return loopStmt;
    101         }
    102 
    103         Statement *MLEMutator::mutate( CaseStmt *caseStmt ) {
    104                 caseStmt->set_condition( maybeMutate( caseStmt->get_condition(), *this ) );
    105                 fixBlock( caseStmt->get_statements() );
    106 
    107                 return caseStmt;
    108         }
    109 
    110         template< typename IfClass >
    111         Statement *MLEMutator::handleIfStmt( IfClass *ifStmt ) {
    112                 // generate a label for breaking out of a labeled if
    113                 bool labeledBlock = !(ifStmt->get_labels().empty());
    114                 if ( labeledBlock ) {
    115                         Label brkLabel = generator->newLabel("blockBreak", ifStmt);
    116                         enclosingControlStructures.push_back( Entry( ifStmt, brkLabel ) );
    117                 } // if
    118 
    119                 Parent::mutate( ifStmt );
    120 
    121                 if ( labeledBlock ) {
    122                         if ( ! enclosingControlStructures.back().useBreakExit().empty() ) {
    123                                 set_breakLabel( enclosingControlStructures.back().useBreakExit() );
    124                         } // if
    125                         enclosingControlStructures.pop_back();
    126                 } // if
    127                 return ifStmt;
    128         }
    129 
    130         template< typename SwitchClass >
    131         Statement *MLEMutator::handleSwitchStmt( SwitchClass *switchStmt ) {
    132                 // generate a label for breaking out of a labeled switch
    133                 Label brkLabel = generator->newLabel("switchBreak", switchStmt);
    134                 enclosingControlStructures.push_back( Entry(switchStmt, brkLabel) );
    135                 mutateAll( switchStmt->get_statements(), *this );
    136 
    137                 Entry &e = enclosingControlStructures.back();
    138                 assert ( e == switchStmt );
    139 
    140                 // only generate break label if labeled break is used
    141                 if ( e.isBreakUsed() ) {
    142                         // for the purposes of keeping switch statements uniform (i.e. all statements that are direct children of a
    143                         // switch should be CastStmts), append the exit label + break to the last case statement; create a default
    144                         // case if there are no cases
    145                         std::list< Statement * > &statements = switchStmt->get_statements();
    146                         if ( statements.empty() ) {
    147                                 statements.push_back( CaseStmt::makeDefault() );
    148                         } // if
    149 
    150                         if ( CaseStmt * c = dynamic_cast< CaseStmt * >( statements.back() ) ) {
    151                                 Statement * stmt = new BranchStmt( Label("brkLabel"), BranchStmt::Break );
    152                                 stmt->labels.push_back( brkLabel );
    153                                 c->get_statements().push_back( stmt );
    154                         } else assert(0); // as of this point, all statements of a switch are still CaseStmts
    155                 } // if
    156 
    157                 assert ( enclosingControlStructures.back() == switchStmt );
    158                 enclosingControlStructures.pop_back();
    159                 return switchStmt;
    160         }
     78        }
     79
    16180
    16281        void addUnused( Statement * stmt, const Label & originalTarget ) {
     
    17998
    18099
    181         Statement *MLEMutator::mutate( BranchStmt *branchStmt ) throw ( SemanticError ) {
    182                 std::string originalTarget = branchStmt->get_originalTarget();
     100        Statement *MLEMutator::postmutate( BranchStmt *branchStmt ) throw ( SemanticError ) {
     101                std::string originalTarget = branchStmt->originalTarget;
    183102
    184103                std::list< Entry >::reverse_iterator targetEntry;
     
    215134                // branch error checks, get the appropriate label name and create a goto
    216135                Label exitLabel;
    217                 switch ( branchStmt->get_type() ) {
     136                switch ( branchStmt->type ) {
    218137                  case BranchStmt::Break:
    219138                                assert( targetEntry->useBreakExit() != "");
     
    229148
    230149                // add unused attribute to label to silence warnings
    231                 addUnused( targetEntry->get_controlStructure(), branchStmt->get_originalTarget() );
     150                addUnused( targetEntry->get_controlStructure(), branchStmt->originalTarget );
    232151
    233152                // transform break/continue statements into goto to simplify later handling of branches
     
    260179        }
    261180
    262         Statement *MLEMutator::mutate( WhileStmt *whileStmt ) {
    263                 return handleLoopStmt( whileStmt );
    264         }
    265 
    266         Statement *MLEMutator::mutate( ForStmt *forStmt ) {
    267                 return handleLoopStmt( forStmt );
    268         }
    269 
    270         Statement *MLEMutator::mutate( IfStmt *ifStmt ) {
    271                 return handleIfStmt( ifStmt );
    272         }
    273 
    274         Statement *MLEMutator::mutate( SwitchStmt *switchStmt ) {
    275                 return handleSwitchStmt( switchStmt );
     181        template< typename LoopClass >
     182        void MLEMutator::prehandleLoopStmt( LoopClass * loopStmt ) {
     183                // remember this as the most recent enclosing loop, then mutate the body of the loop -- this will determine
     184                // whether brkLabel and contLabel are used with branch statements and will recursively do the same to nested
     185                // loops
     186                Label brkLabel = generator->newLabel("loopBreak", loopStmt);
     187                Label contLabel = generator->newLabel("loopContinue", loopStmt);
     188                enclosingControlStructures.push_back( Entry( loopStmt, brkLabel, contLabel ) );
     189        }
     190
     191        template< typename LoopClass >
     192        Statement * MLEMutator::posthandleLoopStmt( LoopClass * loopStmt ) {
     193                assert( ! enclosingControlStructures.empty() );
     194                Entry &e = enclosingControlStructures.back();
     195                // sanity check that the enclosing loops have been popped correctly
     196                assert ( e == loopStmt );
     197
     198                // this will take the necessary steps to add definitions of the previous two labels, if they are used.
     199                loopStmt->set_body( mutateLoop( loopStmt->get_body(), e ) );
     200                enclosingControlStructures.pop_back();
     201                return loopStmt;
     202        }
     203
     204        void MLEMutator::premutate( WhileStmt * whileStmt ) {
     205                return prehandleLoopStmt( whileStmt );
     206        }
     207
     208        void MLEMutator::premutate( ForStmt * forStmt ) {
     209                return prehandleLoopStmt( forStmt );
     210        }
     211
     212        Statement * MLEMutator::postmutate( WhileStmt * whileStmt ) {
     213                return posthandleLoopStmt( whileStmt );
     214        }
     215
     216        Statement * MLEMutator::postmutate( ForStmt * forStmt ) {
     217                return posthandleLoopStmt( forStmt );
     218        }
     219
     220        void MLEMutator::premutate( IfStmt * ifStmt ) {
     221                // generate a label for breaking out of a labeled if
     222                bool labeledBlock = !(ifStmt->get_labels().empty());
     223                if ( labeledBlock ) {
     224                        Label brkLabel = generator->newLabel("blockBreak", ifStmt);
     225                        enclosingControlStructures.push_back( Entry( ifStmt, brkLabel ) );
     226                } // if
     227        }
     228
     229        Statement * MLEMutator::postmutate( IfStmt * ifStmt ) {
     230                bool labeledBlock = !(ifStmt->get_labels().empty());
     231                if ( labeledBlock ) {
     232                        if ( ! enclosingControlStructures.back().useBreakExit().empty() ) {
     233                                set_breakLabel( enclosingControlStructures.back().useBreakExit() );
     234                        } // if
     235                        enclosingControlStructures.pop_back();
     236                } // if
     237                return ifStmt;
     238        }
     239
     240        void MLEMutator::premutate( CaseStmt *caseStmt ) {
     241                visit_children = false;
     242                caseStmt->condition = maybeMutate( caseStmt->condition, *visitor );
     243                fixBlock( caseStmt->stmts );
     244        }
     245
     246        void MLEMutator::premutate( SwitchStmt *switchStmt ) {
     247                // generate a label for breaking out of a labeled switch
     248                Label brkLabel = generator->newLabel("switchBreak", switchStmt);
     249                enclosingControlStructures.push_back( Entry(switchStmt, brkLabel) );
     250        }
     251
     252        Statement * MLEMutator::postmutate( SwitchStmt * switchStmt ) {
     253                Entry &e = enclosingControlStructures.back();
     254                assert ( e == switchStmt );
     255
     256                // only generate break label if labeled break is used
     257                if ( e.isBreakUsed() ) {
     258                        // for the purposes of keeping switch statements uniform (i.e. all statements that are direct children of a
     259                        // switch should be CastStmts), append the exit label + break to the last case statement; create a default
     260                        // case if there are no cases
     261                        std::list< Statement * > &statements = switchStmt->statements;
     262                        if ( statements.empty() ) {
     263                                statements.push_back( CaseStmt::makeDefault() );
     264                        } // if
     265
     266                        if ( CaseStmt * c = dynamic_cast< CaseStmt * >( statements.back() ) ) {
     267                                Statement * stmt = new BranchStmt( Label("brkLabel"), BranchStmt::Break );
     268                                stmt->labels.push_back( e.useBreakExit() );
     269                                c->stmts.push_back( stmt );
     270                        } else assert(0); // as of this point, all statements of a switch are still CaseStmts
     271                } // if
     272
     273                assert ( enclosingControlStructures.back() == switchStmt );
     274                enclosingControlStructures.pop_back();
     275                return switchStmt;
    276276        }
    277277} // namespace ControlStruct
  • src/ControlStruct/MLEMutator.h

    r8587878e r94e025a2  
    2020#include <string>                  // for string
    2121
     22#include "Common/PassVisitor.h"
    2223#include "Common/SemanticError.h"  // for SemanticError
    2324#include "SynTree/Label.h"         // for Label
     
    2627
    2728namespace ControlStruct {
    28 class LabelGenerator;
     29        class LabelGenerator;
    2930
    30         class MLEMutator : public Mutator {
     31        class MLEMutator : public WithVisitorRef<MLEMutator>, public WithShortCircuiting {
    3132                class Entry;
    3233
    33                 typedef Mutator Parent;
    3434          public:
    3535                MLEMutator( std::map<Label, Statement *> *t, LabelGenerator *gen = 0 ) : targetTable( t ), breakLabel(std::string("")), generator( gen ) {}
    3636                ~MLEMutator();
    3737
    38                 virtual CompoundStmt *mutate( CompoundStmt *cmpndStmt ) override;
    39                 virtual Statement *mutate( WhileStmt *whileStmt ) override;
    40                 virtual Statement *mutate( ForStmt *forStmt ) override;
    41                 virtual Statement *mutate( BranchStmt *branchStmt ) throw ( SemanticError ) override;
    42                 virtual Statement *mutate( CaseStmt *caseStmt ) override;
    43                 virtual Statement *mutate( IfStmt *ifStmt ) override;
    44                 virtual Statement *mutate( SwitchStmt *switchStmt ) override;
     38                void premutate( CompoundStmt *cmpndStmt );
     39                Statement * postmutate( BranchStmt *branchStmt ) throw ( SemanticError );
     40                void premutate( WhileStmt *whileStmt );
     41                Statement * postmutate( WhileStmt *whileStmt );
     42                void premutate( ForStmt *forStmt );
     43                Statement * postmutate( ForStmt *forStmt );
     44                void premutate( CaseStmt *caseStmt );
     45                void premutate( IfStmt *ifStmt );
     46                Statement * postmutate( IfStmt *ifStmt );
     47                void premutate( SwitchStmt *switchStmt );
     48                Statement * postmutate( SwitchStmt *switchStmt );
    4549
    4650                Statement *mutateLoop( Statement *bodyLoop, Entry &e );
     
    5458                                loop( _loop ), breakExit( _breakExit ), contExit( _contExit ), breakUsed(false), contUsed(false) {}
    5559
    56                         bool operator==( const Statement *stmt ) { return ( loop == stmt ); }
    57                         bool operator!=( const Statement *stmt ) { return ( loop != stmt ); }
     60                        bool operator==( const Statement *stmt ) { return loop == stmt; }
     61                        bool operator!=( const Statement *stmt ) { return loop != stmt; }
    5862
    59                         bool operator==( const Entry &other ) { return ( loop == other.get_controlStructure() ); }
     63                        bool operator==( const Entry &other ) { return loop == other.get_controlStructure(); }
    6064
    6165                        Statement *get_controlStructure() const { return loop; }
     
    7882
    7983                template< typename LoopClass >
    80                 Statement *handleLoopStmt( LoopClass *loopStmt );
     84                void prehandleLoopStmt( LoopClass * loopStmt );
    8185
    82                 template< typename IfClass >
    83                 Statement *handleIfStmt( IfClass *switchStmt );
    84 
    85                 template< typename SwitchClass >
    86                 Statement *handleSwitchStmt( SwitchClass *switchStmt );
     86                template< typename LoopClass >
     87                Statement * posthandleLoopStmt( LoopClass * loopStmt );
    8788
    8889                void fixBlock( std::list< Statement * > &kids );
  • src/SynTree/Label.h

    r8587878e r94e025a2  
    3333        std::list< Attribute * >& get_attributes() { return attributes; }
    3434
    35         operator std::string() { return name; }
     35        operator std::string() const { return name; }
    3636        bool empty() { return name.empty(); }
    3737  private:
Note: See TracChangeset for help on using the changeset viewer.