Changeset 94e025a2
- Timestamp:
- Jan 8, 2018, 2:34:32 PM (6 years ago)
- 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
- Location:
- src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/LabelFixer.cc
r8587878e r94e025a2 44 44 45 45 void LabelFixer::postvisit( FunctionDecl * functionDecl ) { 46 MLEMutatormlemut( resolveJumps(), generator );46 PassVisitor<MLEMutator> mlemut( resolveJumps(), generator ); 47 47 functionDecl->acceptMutator( mlemut ); 48 48 } -
src/ControlStruct/MLEMutator.cc
r8587878e r94e025a2 46 46 void MLEMutator::fixBlock( std::list< Statement * > &kids ) { 47 47 for ( std::list< Statement * >::iterator k = kids.begin(); k != kids.end(); k++ ) { 48 *k = (*k)->acceptMutator(* this);48 *k = (*k)->acceptMutator(*visitor); 49 49 50 50 if ( ! get_breakLabel().empty() ) { … … 57 57 } 58 58 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()); 61 62 if ( labeledBlock ) { 62 63 Label brkLabel = generator->newLabel("blockBreak", cmpndStmt); … … 65 66 66 67 // 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; 68 69 fixBlock( kids ); 69 70 … … 75 76 enclosingControlStructures.pop_back(); 76 77 } // 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 161 80 162 81 void addUnused( Statement * stmt, const Label & originalTarget ) { … … 179 98 180 99 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; 183 102 184 103 std::list< Entry >::reverse_iterator targetEntry; … … 215 134 // branch error checks, get the appropriate label name and create a goto 216 135 Label exitLabel; 217 switch ( branchStmt-> get_type()) {136 switch ( branchStmt->type ) { 218 137 case BranchStmt::Break: 219 138 assert( targetEntry->useBreakExit() != ""); … … 229 148 230 149 // add unused attribute to label to silence warnings 231 addUnused( targetEntry->get_controlStructure(), branchStmt-> get_originalTarget());150 addUnused( targetEntry->get_controlStructure(), branchStmt->originalTarget ); 232 151 233 152 // transform break/continue statements into goto to simplify later handling of branches … … 260 179 } 261 180 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; 276 276 } 277 277 } // namespace ControlStruct -
src/ControlStruct/MLEMutator.h
r8587878e r94e025a2 20 20 #include <string> // for string 21 21 22 #include "Common/PassVisitor.h" 22 23 #include "Common/SemanticError.h" // for SemanticError 23 24 #include "SynTree/Label.h" // for Label … … 26 27 27 28 namespace ControlStruct { 28 class LabelGenerator;29 class LabelGenerator; 29 30 30 class MLEMutator : public Mutator{31 class MLEMutator : public WithVisitorRef<MLEMutator>, public WithShortCircuiting { 31 32 class Entry; 32 33 33 typedef Mutator Parent;34 34 public: 35 35 MLEMutator( std::map<Label, Statement *> *t, LabelGenerator *gen = 0 ) : targetTable( t ), breakLabel(std::string("")), generator( gen ) {} 36 36 ~MLEMutator(); 37 37 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 ); 45 49 46 50 Statement *mutateLoop( Statement *bodyLoop, Entry &e ); … … 54 58 loop( _loop ), breakExit( _breakExit ), contExit( _contExit ), breakUsed(false), contUsed(false) {} 55 59 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; } 58 62 59 bool operator==( const Entry &other ) { return ( loop == other.get_controlStructure()); }63 bool operator==( const Entry &other ) { return loop == other.get_controlStructure(); } 60 64 61 65 Statement *get_controlStructure() const { return loop; } … … 78 82 79 83 template< typename LoopClass > 80 Statement *handleLoopStmt( LoopClass *loopStmt );84 void prehandleLoopStmt( LoopClass * loopStmt ); 81 85 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 ); 87 88 88 89 void fixBlock( std::list< Statement * > &kids ); -
src/SynTree/Label.h
r8587878e r94e025a2 33 33 std::list< Attribute * >& get_attributes() { return attributes; } 34 34 35 operator std::string() { return name; }35 operator std::string() const { return name; } 36 36 bool empty() { return name.empty(); } 37 37 private:
Note: See TracChangeset
for help on using the changeset viewer.