Changeset 3d5701e for src/ControlStruct
- Timestamp:
- Feb 25, 2020, 1:17:33 PM (6 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum, stuck-waitfor-destruct
- Children:
- 7dc2e015
- Parents:
- 9fb8f01 (diff), dd9e1ca (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. - Location:
- src/ControlStruct
- Files:
-
- 5 edited
-
ExceptTranslate.cc (modified) (2 diffs)
-
LabelFixer.cc (modified) (5 diffs)
-
MLEMutator.cc (modified) (12 diffs)
-
MLEMutator.h (modified) (5 diffs)
-
Mutate.cc (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/ExceptTranslate.cc
r9fb8f01 r3d5701e 10 10 // Created On : Wed Jun 14 16:49:00 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Feb 13 18:15:29201913 // Update Count : 1 112 // Last Modified On : Fri Dec 13 23:40:15 2019 13 // Update Count : 12 14 14 // 15 15 … … 24 24 #include "Common/SemanticError.h" // for SemanticError 25 25 #include "Common/utility.h" // for CodeLocation 26 #include " Parser/LinkageSpec.h"// for Cforall26 #include "SynTree/LinkageSpec.h" // for Cforall 27 27 #include "SynTree/Attribute.h" // for Attribute 28 28 #include "SynTree/Constant.h" // for Constant -
src/ControlStruct/LabelFixer.cc
r9fb8f01 r3d5701e 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Mar 11 22:26:02 201913 // Update Count : 1 5911 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Jan 21 10:32:00 2020 13 // Update Count : 160 14 14 // 15 15 … … 21 21 #include "ControlStruct/LabelGenerator.h" // for LabelGenerator 22 22 #include "LabelFixer.h" 23 #include "MLEMutator.h" // for M LEMutator23 #include "MLEMutator.h" // for MultiLevelExitMutator 24 24 #include "SynTree/Declaration.h" // for FunctionDecl 25 25 #include "SynTree/Expression.h" // for NameExpr, Expression, Unty... … … 44 44 45 45 void LabelFixer::postvisit( FunctionDecl * functionDecl ) { 46 PassVisitor<MLEMutator> mlemut( resolveJumps(), generator ); 47 functionDecl->acceptMutator( mlemut ); 46 PassVisitor<MultiLevelExitMutator> mlem( resolveJumps(), generator ); 47 // We start in the body so we can stop when we hit another FunctionDecl. 48 maybeMutate( functionDecl->statements, mlem ); 48 49 } 49 50 … … 75 76 76 77 77 // sets the definition of the labelTable entry to be the provided statement for every label in the list78 // parameter. Happens for every kind of statement78 // Sets the definition of the labelTable entry to be the provided statement for every label in 79 // the list parameter. Happens for every kind of statement. 79 80 Label LabelFixer::setLabelsDef( std::list< Label > & llabel, Statement * definition ) { 80 81 assert( definition != 0 ); 81 82 assert( llabel.size() > 0 ); 82 83 Entry * e = new Entry( definition );84 83 85 84 for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ ) { … … 87 86 l.set_statement( definition ); // attach statement to the label to be used later 88 87 if ( labelTable.find( l ) == labelTable.end() ) { 89 // all labels on this statement need to use the same entry, so this should only be created once 88 // All labels on this statement need to use the same entry, 89 // so this should only be created once. 90 90 // undefined and unused until now, add an entry 91 labelTable[ l ] = e;91 labelTable[ l ] = new Entry( definition ); 92 92 } else if ( labelTable[ l ]->defined() ) { 93 93 // defined twice, error 94 SemanticError( l.get_statement()->location, "Duplicate definition of label: " + l.get_name() ); 95 } else { 94 SemanticError( l.get_statement()->location, 95 "Duplicate definition of label: " + l.get_name() ); 96 } else { 96 97 // used previously, but undefined until now -> link with this entry 98 // Question: Is changing objects important? 97 99 delete labelTable[ l ]; 98 labelTable[ l ] = e;100 labelTable[ l ] = new Entry( definition ); 99 101 } // if 100 102 } // for 101 103 102 // produce one of the labels attached to this statement to be temporarily used as the canonical label 104 // Produce one of the labels attached to this statement to be temporarily used as the 105 // canonical label. 103 106 return labelTable[ llabel.front() ]->get_label(); 104 107 } -
src/ControlStruct/MLEMutator.cc
r9fb8f01 r3d5701e 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Mar 8 17:08:25 201813 // Update Count : 2 1911 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Jan 22 11:50:00 2020 13 // Update Count : 223 14 14 // 15 15 … … 33 33 34 34 namespace ControlStruct { 35 M LEMutator::~MLEMutator() {35 MultiLevelExitMutator::~MultiLevelExitMutator() { 36 36 delete targetTable; 37 37 targetTable = 0; 38 38 } 39 39 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 } 47 61 } // namespace 62 63 void MultiLevelExitMutator::premutate( FunctionDecl * ) { 64 visit_children = false; 65 } 48 66 49 67 // break labels have to come after the statement they break out of, so mutate a statement, then if they inform us 50 68 // through the breakLabel field tha they need a place to jump to on a break statement, add the break label to the 51 69 // body of statements 52 void M LEMutator::fixBlock( std::list< Statement * > &kids, bool caseClause ) {70 void MultiLevelExitMutator::fixBlock( std::list< Statement * > &kids, bool caseClause ) { 53 71 SemanticErrorException errors; 54 72 … … 81 99 } 82 100 83 void M LEMutator::premutate( CompoundStmt *cmpndStmt ) {101 void MultiLevelExitMutator::premutate( CompoundStmt *cmpndStmt ) { 84 102 visit_children = false; 85 103 bool labeledBlock = !(cmpndStmt->labels.empty()); … … 118 136 } 119 137 } 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 ) { 125 145 std::string originalTarget = branchStmt->originalTarget; 126 146 … … 230 250 } 231 251 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 233 256 // 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 ); 241 259 242 260 if ( e.isContUsed() ) { … … 255 273 256 274 template< typename LoopClass > 257 void M LEMutator::prehandleLoopStmt( LoopClass * loopStmt ) {275 void MultiLevelExitMutator::prehandleLoopStmt( LoopClass * loopStmt ) { 258 276 // remember this as the most recent enclosing loop, then mutate the body of the loop -- this will determine 259 277 // whether brkLabel and contLabel are used with branch statements and will recursively do the same to nested … … 266 284 267 285 template< typename LoopClass > 268 Statement * M LEMutator::posthandleLoopStmt( LoopClass * loopStmt ) {286 Statement * MultiLevelExitMutator::posthandleLoopStmt( LoopClass * loopStmt ) { 269 287 assert( ! enclosingControlStructures.empty() ); 270 288 Entry &e = enclosingControlStructures.back(); … … 277 295 } 278 296 279 void M LEMutator::premutate( WhileStmt * whileStmt ) {297 void MultiLevelExitMutator::premutate( WhileStmt * whileStmt ) { 280 298 return prehandleLoopStmt( whileStmt ); 281 299 } 282 300 283 void M LEMutator::premutate( ForStmt * forStmt ) {301 void MultiLevelExitMutator::premutate( ForStmt * forStmt ) { 284 302 return prehandleLoopStmt( forStmt ); 285 303 } 286 304 287 Statement * M LEMutator::postmutate( WhileStmt * whileStmt ) {305 Statement * MultiLevelExitMutator::postmutate( WhileStmt * whileStmt ) { 288 306 return posthandleLoopStmt( whileStmt ); 289 307 } 290 308 291 Statement * M LEMutator::postmutate( ForStmt * forStmt ) {309 Statement * MultiLevelExitMutator::postmutate( ForStmt * forStmt ) { 292 310 return posthandleLoopStmt( forStmt ); 293 311 } 294 312 295 void M LEMutator::premutate( IfStmt * ifStmt ) {313 void MultiLevelExitMutator::premutate( IfStmt * ifStmt ) { 296 314 // generate a label for breaking out of a labeled if 297 315 bool labeledBlock = !(ifStmt->get_labels().empty()); … … 303 321 } 304 322 305 Statement * M LEMutator::postmutate( IfStmt * ifStmt ) {323 Statement * MultiLevelExitMutator::postmutate( IfStmt * ifStmt ) { 306 324 bool labeledBlock = !(ifStmt->get_labels().empty()); 307 325 if ( labeledBlock ) { … … 313 331 } 314 332 315 void MLEMutator::premutate( CaseStmt *caseStmt ) { 333 void MultiLevelExitMutator::premutate( TryStmt * tryStmt ) { 334 // generate a label for breaking out of a labeled if 335 bool labeledBlock = !(tryStmt->get_labels().empty()); 336 if ( labeledBlock ) { 337 Label brkLabel = generator->newLabel("blockBreak", tryStmt); 338 enclosingControlStructures.push_back( Entry( tryStmt, brkLabel ) ); 339 GuardAction( [this]() { enclosingControlStructures.pop_back(); } ); 340 } // if 341 } 342 343 Statement * MultiLevelExitMutator::postmutate( TryStmt * tryStmt ) { 344 bool labeledBlock = !(tryStmt->get_labels().empty()); 345 if ( labeledBlock ) { 346 if ( ! enclosingControlStructures.back().useBreakExit().empty() ) { 347 set_breakLabel( enclosingControlStructures.back().useBreakExit() ); 348 } // if 349 } // if 350 return tryStmt; 351 } 352 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 ) { 316 369 visit_children = false; 317 370 … … 352 405 } 353 406 354 void M LEMutator::premutate( SwitchStmt *switchStmt ) {407 void MultiLevelExitMutator::premutate( SwitchStmt *switchStmt ) { 355 408 // generate a label for breaking out of a labeled switch 356 409 Label brkLabel = generator->newLabel("switchBreak", switchStmt); … … 378 431 } 379 432 380 Statement * M LEMutator::postmutate( SwitchStmt * switchStmt ) {433 Statement * MultiLevelExitMutator::postmutate( SwitchStmt * switchStmt ) { 381 434 Entry &e = enclosingControlStructures.back(); 382 435 assert ( e == switchStmt ); -
src/ControlStruct/MLEMutator.h
r9fb8f01 r3d5701e 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Mar 8 16:42:32 201813 // Update Count : 4 111 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Jan 22 11:50:00 2020 13 // Update Count : 48 14 14 // 15 15 … … 30 30 class LabelGenerator; 31 31 32 class MLEMutator : public WithVisitorRef<MLEMutator>, public WithShortCircuiting, public WithGuards { 32 class MultiLevelExitMutator : public WithVisitorRef<MultiLevelExitMutator>, 33 public WithShortCircuiting, public WithGuards { 33 34 public: 34 35 class Entry; 35 MLEMutator( std::map<Label, Statement *> *t, LabelGenerator *gen = 0 ) : targetTable( t ), breakLabel(std::string("")), generator( gen ) {} 36 ~MLEMutator(); 36 MultiLevelExitMutator( std::map<Label, Statement *> *t, LabelGenerator *gen = 0 ) : 37 targetTable( t ), breakLabel(std::string("")), generator( gen ) {} 38 ~MultiLevelExitMutator(); 39 40 void premutate( FunctionDecl * ); 37 41 38 42 void premutate( CompoundStmt *cmpndStmt ); … … 47 51 void premutate( SwitchStmt *switchStmt ); 48 52 Statement * postmutate( SwitchStmt *switchStmt ); 53 void premutate( ReturnStmt *returnStmt ); 54 void premutate( TryStmt *tryStmt ); 55 Statement * postmutate( TryStmt *tryStmt ); 56 void premutate( FinallyStmt *finallyStmt ); 49 57 50 58 Statement *mutateLoop( Statement *bodyLoop, Entry &e ); … … 73 81 explicit Entry( SwitchStmt *stmt, Label breakExit, Label fallDefaultExit ) : 74 82 stmt( stmt ), breakExit( breakExit ), fallDefaultExit( fallDefaultExit ) {} 83 84 explicit Entry( TryStmt *stmt, Label breakExit ) : 85 stmt( stmt ), breakExit( breakExit ) {} 75 86 76 87 bool operator==( const Statement *other ) { return stmt == other; } … … 105 116 Label breakLabel; 106 117 LabelGenerator *generator; 118 bool inFinally = false; 107 119 108 120 template< typename LoopClass > -
src/ControlStruct/Mutate.cc
r9fb8f01 r3d5701e 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Aug 4 11:39:08 201613 // Update Count : 912 // Last Modified On : Sun Feb 16 03:22:07 2020 13 // Update Count : 10 14 14 // 15 15 … … 37 37 mutateAll( translationUnit, formut ); 38 38 } 39 } // namespace Co deGen39 } // namespace ControlStruct 40 40 41 41 // Local Variables: //
Note:
See TracChangeset
for help on using the changeset viewer.