Changeset adcc065 for src/ControlStruct/MLEMutator.cc
- Timestamp:
- Jul 6, 2016, 6:06:27 PM (9 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 3f869f0
- Parents:
- e04c5ff
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/MLEMutator.cc
re04c5ff radcc065 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Mon Jul 20 13:58:35 2015 13 // Update Count : 176 14 // 15 16 // NOTE: There are two known subtle differences from the code that uC++ 17 // generates for the same input 18 // -CFA puts the break label inside at the end of a switch, uC++ puts it after 19 // -CFA puts the break label after a block, uC++ puts it inside at the end 20 // we don't yet know if these differences are important, but if they are then 21 // the fix would go in this file, since this is where these labels are generated. 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jul 6 17:40:02 2016 13 // Update Count : 196 14 // 15 16 // NOTE: There are two known subtle differences from the code that uC++ generates for the same input 17 // -CFA puts the break label inside at the end of a switch, uC++ puts it after 18 // -CFA puts the break label after a block, uC++ puts it inside at the end 19 // It is unclear if these differences are important, but if they are, then the fix would go in this file, since this is 20 // where these labels are generated. 22 21 23 22 #include <cassert> … … 38 37 } 39 38 40 // break labels have to come after the statement they break out of, 41 // so mutate a statement, then if they inform us through the breakLabel field 42 // tha they need a place to jump to on a break statement, add the break label 43 // to the body of statements 39 // break labels have to come after the statement they break out of, so mutate a statement, then if they inform us 40 // through the breakLabel field tha they need a place to jump to on a break statement, add the break label to the 41 // body of statements 44 42 void MLEMutator::fixBlock( std::list< Statement * > &kids ) { 45 43 for ( std::list< Statement * >::iterator k = kids.begin(); k != kids.end(); k++ ) { … … 62 60 } // if 63 61 64 // a child statement may set the break label 65 // - if they do, attach it to the next statement 62 // a child statement may set the break label - if they do, attach it to the next statement 66 63 std::list< Statement * > &kids = cmpndStmt->get_kids(); 67 64 fixBlock( kids ); … … 71 68 if ( ! enclosingControlStructures.back().useBreakExit().empty() ) { 72 69 set_breakLabel( enclosingControlStructures.back().useBreakExit() ); 73 } 70 } // if 74 71 enclosingControlStructures.pop_back(); 75 72 } // if … … 80 77 template< typename LoopClass > 81 78 Statement *MLEMutator::handleLoopStmt( LoopClass *loopStmt ) { 82 // remember this as the most recent enclosing loop, then mutate 83 // the body of the loop -- this will determine whether brkLabel 84 // and contLabel are used with branch statements 85 // and will recursively do the same to nested loops 79 // remember this as the most recent enclosing loop, then mutate the body of the loop -- this will determine 80 // whether brkLabel and contLabel are used with branch statements and will recursively do the same to nested 81 // loops 86 82 Label brkLabel = generator->newLabel("loopBreak"); 87 83 Label contLabel = generator->newLabel("loopContinue"); … … 89 85 loopStmt->set_body ( loopStmt->get_body()->acceptMutator( *this ) ); 90 86 87 Entry &e = enclosingControlStructures.back(); 91 88 // sanity check that the enclosing loops have been popped correctly 92 Entry &e = enclosingControlStructures.back();93 89 assert ( e == loopStmt ); 94 90 95 // this will take the necessary steps to add definitions of the previous 96 // two labels, if they are used. 91 // this will take the necessary steps to add definitions of the previous two labels, if they are used. 97 92 loopStmt->set_body( mutateLoop( loopStmt->get_body(), e ) ); 98 93 enclosingControlStructures.pop_back(); … … 106 101 107 102 return caseStmt; 103 } 104 105 template< typename IfClass > 106 Statement *MLEMutator::handleIfStmt( IfClass *ifStmt ) { 107 // generate a label for breaking out of a labeled if 108 bool labeledBlock = !(ifStmt->get_labels().empty()); 109 if ( labeledBlock ) { 110 Label brkLabel = generator->newLabel("blockBreak"); 111 enclosingControlStructures.push_back( Entry( ifStmt, brkLabel ) ); 112 } // if 113 114 Parent::mutate( ifStmt ); 115 116 if ( labeledBlock ) { 117 if ( ! enclosingControlStructures.back().useBreakExit().empty() ) { 118 set_breakLabel( enclosingControlStructures.back().useBreakExit() ); 119 } // if 120 enclosingControlStructures.pop_back(); 121 } // if 122 return ifStmt; 108 123 } 109 124 … … 119 134 120 135 // only generate break label if labeled break is used 121 if ( e.isBreakUsed()) {122 // for the purposes of keeping switch statements uniform (i.e. all statements that are 123 // direct children of a switch should be CastStmts), append the exit label + break to the124 // last case statement; create a defaultcase if there are no cases136 if ( e.isBreakUsed() ) { 137 // for the purposes of keeping switch statements uniform (i.e. all statements that are direct children of a 138 // switch should be CastStmts), append the exit label + break to the last case statement; create a default 139 // case if there are no cases 125 140 std::list< Statement * > &branches = switchStmt->get_branches(); 126 141 if ( branches.empty() ) { 127 142 branches.push_back( CaseStmt::makeDefault() ); 128 } 143 } // if 129 144 130 145 if ( CaseStmt * c = dynamic_cast< CaseStmt * >( branches.back() ) ) { … … 132 147 c->get_statements().push_back( new BranchStmt( temp, Label("brkLabel"), BranchStmt::Break ) ); 133 148 } else assert(0); // as of this point, all branches of a switch are still CaseStmts 134 } 149 } // if 135 150 136 151 assert ( enclosingControlStructures.back() == switchStmt ); … … 152 167 // labelled continue - lookup label in table ot find attached control structure 153 168 targetEntry = std::find( enclosingControlStructures.rbegin(), enclosingControlStructures.rend(), (*targetTable)[branchStmt->get_target()] ); 154 } 169 } // if 155 170 if ( targetEntry == enclosingControlStructures.rend() || ! isLoop( targetEntry->get_controlStructure() ) ) { 156 171 throw SemanticError( "'continue' target must be an enclosing loop: " + originalTarget ); 157 } 172 } // if 158 173 } else if ( branchStmt->get_type() == BranchStmt::Break ) { 159 174 if ( enclosingControlStructures.empty() ) throw SemanticError( "'break' outside a loop, switch, or labelled block" ); … … 161 176 } else { 162 177 assert( false ); 163 } 178 } // if 164 179 165 180 if ( branchStmt->get_target() != "" && targetTable->find( branchStmt->get_target() ) == targetTable->end() ) { 166 181 throw SemanticError("The label defined in the exit loop statement does not exist: " + originalTarget ); // shouldn't happen (since that's already checked) 167 } 182 } // if 168 183 169 184 // branch error checks, get the appropriate label name and create a goto … … 191 206 delete branchStmt; 192 207 return new BranchStmt( std::list<Label>(), exitLabel, BranchStmt::Goto ); 193 } 208 } // if 194 209 } 195 210 … … 208 223 std::list< Label > labels; labels.push_back( e.useContExit() ); 209 224 newBody->get_kids().push_back( new NullStmt( labels ) ); 210 } 225 } // if 211 226 212 227 if ( e.isBreakUsed() ) { 213 // break label goes after the loop -- it'll get set by the 214 // outer mutator if we do this 228 // break label goes after the loop -- it'll get set by the outer mutator if we do this 215 229 set_breakLabel( e.useBreakExit() ); 216 } 230 } // if 217 231 218 232 return newBody; … … 227 241 } 228 242 243 Statement *MLEMutator::mutate( IfStmt *ifStmt ) { 244 return handleIfStmt( ifStmt ); 245 } 246 229 247 Statement *MLEMutator::mutate( SwitchStmt *switchStmt ) { 230 248 return handleSwitchStmt( switchStmt ); … … 234 252 return handleSwitchStmt( switchStmt ); 235 253 } 236 237 254 } // namespace ControlStruct 238 255
Note: See TracChangeset
for help on using the changeset viewer.