Changeset b7d6a36 for src/ControlStruct
- Timestamp:
- Feb 20, 2020, 4:15:51 PM (6 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum, stuck-waitfor-destruct
- Children:
- 6a490b2
- Parents:
- dca5802 (diff), 2cbfe92 (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) (14 diffs)
-
MLEMutator.h (modified) (4 diffs)
-
Mutate.cc (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/ExceptTranslate.cc
rdca5802 rb7d6a36 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
rdca5802 rb7d6a36 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
rdca5802 rb7d6a36 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 : Tue Oct 22 17:22:44 201913 // Update Count : 22 011 // 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 *M LEMutator::mutateLoop( Statement *bodyLoop, Entry &e ) {252 Statement *MultiLevelExitMutator::mutateLoop( Statement *bodyLoop, Entry &e ) { 233 253 // only generate these when needed 234 254 if( !e.isContUsed() && !e.isBreakUsed() ) return bodyLoop; … … 253 273 254 274 template< typename LoopClass > 255 void M LEMutator::prehandleLoopStmt( LoopClass * loopStmt ) {275 void MultiLevelExitMutator::prehandleLoopStmt( LoopClass * loopStmt ) { 256 276 // remember this as the most recent enclosing loop, then mutate the body of the loop -- this will determine 257 277 // whether brkLabel and contLabel are used with branch statements and will recursively do the same to nested … … 264 284 265 285 template< typename LoopClass > 266 Statement * M LEMutator::posthandleLoopStmt( LoopClass * loopStmt ) {286 Statement * MultiLevelExitMutator::posthandleLoopStmt( LoopClass * loopStmt ) { 267 287 assert( ! enclosingControlStructures.empty() ); 268 288 Entry &e = enclosingControlStructures.back(); … … 275 295 } 276 296 277 void M LEMutator::premutate( WhileStmt * whileStmt ) {297 void MultiLevelExitMutator::premutate( WhileStmt * whileStmt ) { 278 298 return prehandleLoopStmt( whileStmt ); 279 299 } 280 300 281 void M LEMutator::premutate( ForStmt * forStmt ) {301 void MultiLevelExitMutator::premutate( ForStmt * forStmt ) { 282 302 return prehandleLoopStmt( forStmt ); 283 303 } 284 304 285 Statement * M LEMutator::postmutate( WhileStmt * whileStmt ) {305 Statement * MultiLevelExitMutator::postmutate( WhileStmt * whileStmt ) { 286 306 return posthandleLoopStmt( whileStmt ); 287 307 } 288 308 289 Statement * M LEMutator::postmutate( ForStmt * forStmt ) {309 Statement * MultiLevelExitMutator::postmutate( ForStmt * forStmt ) { 290 310 return posthandleLoopStmt( forStmt ); 291 311 } 292 312 293 void M LEMutator::premutate( IfStmt * ifStmt ) {313 void MultiLevelExitMutator::premutate( IfStmt * ifStmt ) { 294 314 // generate a label for breaking out of a labeled if 295 315 bool labeledBlock = !(ifStmt->get_labels().empty()); … … 301 321 } 302 322 303 Statement * M LEMutator::postmutate( IfStmt * ifStmt ) {323 Statement * MultiLevelExitMutator::postmutate( IfStmt * ifStmt ) { 304 324 bool labeledBlock = !(ifStmt->get_labels().empty()); 305 325 if ( labeledBlock ) { … … 311 331 } 312 332 313 void M LEMutator::premutate( TryStmt * tryStmt ) {333 void MultiLevelExitMutator::premutate( TryStmt * tryStmt ) { 314 334 // generate a label for breaking out of a labeled if 315 335 bool labeledBlock = !(tryStmt->get_labels().empty()); … … 321 341 } 322 342 323 Statement * M LEMutator::postmutate( TryStmt * tryStmt ) {343 Statement * MultiLevelExitMutator::postmutate( TryStmt * tryStmt ) { 324 344 bool labeledBlock = !(tryStmt->get_labels().empty()); 325 345 if ( labeledBlock ) { … … 331 351 } 332 352 333 void MLEMutator::premutate( CaseStmt *caseStmt ) { 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 ) { 334 369 visit_children = false; 335 370 … … 370 405 } 371 406 372 void M LEMutator::premutate( SwitchStmt *switchStmt ) {407 void MultiLevelExitMutator::premutate( SwitchStmt *switchStmt ) { 373 408 // generate a label for breaking out of a labeled switch 374 409 Label brkLabel = generator->newLabel("switchBreak", switchStmt); … … 396 431 } 397 432 398 Statement * M LEMutator::postmutate( SwitchStmt * switchStmt ) {433 Statement * MultiLevelExitMutator::postmutate( SwitchStmt * switchStmt ) { 399 434 Entry &e = enclosingControlStructures.back(); 400 435 assert ( e == switchStmt ); -
src/ControlStruct/MLEMutator.h
rdca5802 rb7d6a36 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 : Tue Oct 22 17:22:47 201913 // Update Count : 4 511 // 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 ); 49 54 void premutate( TryStmt *tryStmt ); 50 55 Statement * postmutate( TryStmt *tryStmt ); 56 void premutate( FinallyStmt *finallyStmt ); 51 57 52 58 Statement *mutateLoop( Statement *bodyLoop, Entry &e ); … … 110 116 Label breakLabel; 111 117 LabelGenerator *generator; 118 bool inFinally = false; 112 119 113 120 template< typename LoopClass > -
src/ControlStruct/Mutate.cc
rdca5802 rb7d6a36 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.