Changeset af68f0a
- Timestamp:
- Apr 5, 2017, 6:07:58 PM (8 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:
- c51b5a3
- Parents:
- fbd7ad6
- Location:
- src/ControlStruct
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/LabelGenerator.cc
rfbd7ad6 raf68f0a 20 20 #include "SynTree/Label.h" 21 21 #include "SynTree/Attribute.h" 22 #include "SynTree/Statement.h" 22 23 23 24 namespace ControlStruct { … … 31 32 } 32 33 33 Label LabelGenerator::newLabel( std::string suffix ) {34 Label LabelGenerator::newLabel( std::string suffix, Statement * stmt ) { 34 35 std::ostringstream os; 35 36 os << "__L" << current++ << "__" << suffix; 37 if ( stmt && ! stmt->get_labels().empty() ) { 38 os << "_" << stmt->get_labels().front() << "__"; 39 } 36 40 std::string ret = os.str(); 37 41 Label l( ret ); -
src/ControlStruct/LabelGenerator.h
rfbd7ad6 raf68f0a 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // LabelGenerator.h -- 7 // LabelGenerator.h -- 8 8 // 9 9 // Author : Rodolfo G. Esteves … … 24 24 public: 25 25 static LabelGenerator *getGenerator(); 26 Label newLabel(std::string suffix = "");26 Label newLabel(std::string suffix, Statement * stmt = nullptr); 27 27 void reset() { current = 0; } 28 28 void rewind() { current--; } -
src/ControlStruct/MLEMutator.cc
rfbd7ad6 raf68f0a 56 56 bool labeledBlock = !(cmpndStmt->get_labels().empty()); 57 57 if ( labeledBlock ) { 58 Label brkLabel = generator->newLabel("blockBreak" );58 Label brkLabel = generator->newLabel("blockBreak", cmpndStmt); 59 59 enclosingControlStructures.push_back( Entry( cmpndStmt, brkLabel ) ); 60 60 } // if … … 80 80 // whether brkLabel and contLabel are used with branch statements and will recursively do the same to nested 81 81 // loops 82 Label brkLabel = generator->newLabel("loopBreak" );83 Label contLabel = generator->newLabel("loopContinue" );82 Label brkLabel = generator->newLabel("loopBreak", loopStmt); 83 Label contLabel = generator->newLabel("loopContinue", loopStmt); 84 84 enclosingControlStructures.push_back( Entry( loopStmt, brkLabel, contLabel ) ); 85 85 loopStmt->set_body ( loopStmt->get_body()->acceptMutator( *this ) ); 86 86 87 assert( ! enclosingControlStructures.empty() ); 87 88 Entry &e = enclosingControlStructures.back(); 88 89 // sanity check that the enclosing loops have been popped correctly … … 108 109 bool labeledBlock = !(ifStmt->get_labels().empty()); 109 110 if ( labeledBlock ) { 110 Label brkLabel = generator->newLabel("blockBreak" );111 Label brkLabel = generator->newLabel("blockBreak", ifStmt); 111 112 enclosingControlStructures.push_back( Entry( ifStmt, brkLabel ) ); 112 113 } // if 113 114 114 115 Parent::mutate( ifStmt ); 115 116 116 117 if ( labeledBlock ) { 117 118 if ( ! enclosingControlStructures.back().useBreakExit().empty() ) { … … 126 127 Statement *MLEMutator::handleSwitchStmt( SwitchClass *switchStmt ) { 127 128 // generate a label for breaking out of a labeled switch 128 Label brkLabel = generator->newLabel("switchBreak" );129 Label brkLabel = generator->newLabel("switchBreak", switchStmt); 129 130 enclosingControlStructures.push_back( Entry(switchStmt, brkLabel) ); 130 131 mutateAll( switchStmt->get_statements(), *this ); … … 158 159 159 160 std::list< Entry >::reverse_iterator targetEntry; 160 if ( branchStmt->get_type() == BranchStmt::Goto ) { 161 return branchStmt; 162 } else if ( branchStmt->get_type() == BranchStmt::Continue) { 163 // continue target must be a loop 164 if ( branchStmt->get_target() == "" ) { 165 targetEntry = std::find_if( enclosingControlStructures.rbegin(), enclosingControlStructures.rend(), [](Entry &e) { return isLoop( e.get_controlStructure() ); } ); 166 } else { 167 // labelled continue - lookup label in table ot find attached control structure 168 targetEntry = std::find( enclosingControlStructures.rbegin(), enclosingControlStructures.rend(), (*targetTable)[branchStmt->get_target()] ); 169 } // if 170 if ( targetEntry == enclosingControlStructures.rend() || ! isLoop( targetEntry->get_controlStructure() ) ) { 171 throw SemanticError( "'continue' target must be an enclosing loop: " + originalTarget ); 172 } // if 173 } else if ( branchStmt->get_type() == BranchStmt::Break ) { 174 if ( enclosingControlStructures.empty() ) throw SemanticError( "'break' outside a loop, switch, or labelled block" ); 175 targetEntry = enclosingControlStructures.rbegin(); 176 } else { 177 assert( false ); 178 } // if 179 180 if ( branchStmt->get_target() != "" && targetTable->find( branchStmt->get_target() ) == targetTable->end() ) { 181 throw SemanticError("The label defined in the exit loop statement does not exist: " + originalTarget ); // shouldn't happen (since that's already checked) 182 } // if 161 switch ( branchStmt->get_type() ) { 162 case BranchStmt::Goto: 163 return branchStmt; 164 case BranchStmt::Continue: 165 case BranchStmt::Break: { 166 bool isContinue = branchStmt->get_type() == BranchStmt::Continue; 167 // unlabeled break/continue 168 if ( branchStmt->get_target() == "" ) { 169 if ( isContinue ) { 170 // continue target is outermost loop 171 targetEntry = std::find_if( enclosingControlStructures.rbegin(), enclosingControlStructures.rend(), [](Entry &e) { return isLoop( e.get_controlStructure() ); } ); 172 } else { 173 // break target is outmost control structure 174 if ( enclosingControlStructures.empty() ) throw SemanticError( "'break' outside a loop, switch, or labelled block" ); 175 targetEntry = enclosingControlStructures.rbegin(); 176 } // if 177 } else { 178 // labeled break/continue - lookup label in table to find attached control structure 179 targetEntry = std::find( enclosingControlStructures.rbegin(), enclosingControlStructures.rend(), (*targetTable)[branchStmt->get_target()] ); 180 } // if 181 // ensure that selected target is valid 182 if ( targetEntry == enclosingControlStructures.rend() || (isContinue && ! isLoop( targetEntry->get_controlStructure() ) ) ) { 183 throw SemanticError( toString( (isContinue ? "'continue'" : "'break'"), " target must be an enclosing ", (isContinue ? "loop: " : "control structure: "), originalTarget ) ); 184 } // if 185 break; 186 } 187 default: 188 assert( false ); 189 } // switch 183 190 184 191 // branch error checks, get the appropriate label name and create a goto … … 197 204 } // switch 198 205 199 if ( branchStmt->get_target() == "" && branchStmt->get_type() != BranchStmt::Continue ) { 200 // unlabelled break/continue - can keep branch as break/continue for extra semantic information, but add 201 // exitLabel as its destination so that label passes can easily determine where the break/continue goes to 202 branchStmt->set_target( exitLabel ); 203 return branchStmt; 204 } else { 205 // labelled break/continue - can't easily emulate this with break and continue, so transform into a goto 206 delete branchStmt; 207 return new BranchStmt( std::list<Label>(), exitLabel, BranchStmt::Goto ); 208 } // if 206 // transform break/continue statements into goto to simplify later handling of branches 207 delete branchStmt; 208 return new BranchStmt( std::list<Label>(), exitLabel, BranchStmt::Goto ); 209 209 } 210 210
Note: See TracChangeset
for help on using the changeset viewer.