Changes in src/ControlStruct/LabelFixer.cc [3b0bc16:9d6317f]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/LabelFixer.cc
r3b0bc16 r9d6317f 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 Feb 1 09:12:09 202213 // Update Count : 16 211 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Jan 21 10:32:00 2020 13 // Update Count : 160 14 14 // 15 15 … … 27 27 28 28 namespace ControlStruct { 29 bool LabelFixer::Entry::insideLoop() {30 return ( dynamic_cast< ForStmt * > ( definition ) ||31 dynamic_cast< WhileDoStmt * > ( definition ) );32 }29 bool LabelFixer::Entry::insideLoop() { 30 return ( dynamic_cast< ForStmt * > ( definition ) || 31 dynamic_cast< WhileStmt * > ( definition ) ); 32 } 33 33 34 LabelFixer::LabelFixer( LabelGenerator * gen ) : generator ( gen ) {35 if ( generator == 0 )36 generator = LabelGenerator::getGenerator();37 }34 LabelFixer::LabelFixer( LabelGenerator * gen ) : generator ( gen ) { 35 if ( generator == 0 ) 36 generator = LabelGenerator::getGenerator(); 37 } 38 38 39 void LabelFixer::previsit( FunctionDecl * ) {40 // need to go into a nested function in a fresh state41 GuardValue( labelTable );42 labelTable.clear();43 }39 void LabelFixer::previsit( FunctionDecl * ) { 40 // need to go into a nested function in a fresh state 41 GuardValue( labelTable ); 42 labelTable.clear(); 43 } 44 44 45 void LabelFixer::postvisit( FunctionDecl * functionDecl ) {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 );49 }45 void LabelFixer::postvisit( FunctionDecl * functionDecl ) { 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 ); 49 } 50 50 51 // prune to at most one label definition for each statement52 void LabelFixer::previsit( Statement * stmt ) {53 std::list< Label > &labels = stmt->get_labels();51 // prune to at most one label definition for each statement 52 void LabelFixer::previsit( Statement * stmt ) { 53 std::list< Label > &labels = stmt->get_labels(); 54 54 55 if ( ! labels.empty() ) {56 // only remember one label for each statement57 Label current = setLabelsDef( labels, stmt );58 } // if59 }55 if ( ! labels.empty() ) { 56 // only remember one label for each statement 57 Label current = setLabelsDef( labels, stmt ); 58 } // if 59 } 60 60 61 void LabelFixer::previsit( BranchStmt * branchStmt ) {62 previsit( ( Statement *)branchStmt );61 void LabelFixer::previsit( BranchStmt * branchStmt ) { 62 previsit( ( Statement *)branchStmt ); 63 63 64 // for labeled branches, add an entry to the label table 65 Label target = branchStmt->get_target(); 66 if ( target != "" ) { 67 setLabelsUsg( target, branchStmt ); 64 // for labeled branches, add an entry to the label table 65 Label target = branchStmt->get_target(); 66 if ( target != "" ) { 67 setLabelsUsg( target, branchStmt ); 68 } 68 69 } 69 }70 70 71 void LabelFixer::previsit( LabelAddressExpr * addrExpr ) {72 Label & target = addrExpr->arg;73 assert( target != "" );74 setLabelsUsg( target, addrExpr );75 }71 void LabelFixer::previsit( LabelAddressExpr * addrExpr ) { 72 Label & target = addrExpr->arg; 73 assert( target != "" ); 74 setLabelsUsg( target, addrExpr ); 75 } 76 76 77 77 78 // Sets the definition of the labelTable entry to be the provided statement for every label in79 // the list parameter. Happens for every kind of statement.80 Label LabelFixer::setLabelsDef( std::list< Label > & llabel, Statement * definition ) {81 assert( definition != 0 );82 assert( llabel.size() > 0 );78 // 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. 80 Label LabelFixer::setLabelsDef( std::list< Label > & llabel, Statement * definition ) { 81 assert( definition != 0 ); 82 assert( llabel.size() > 0 ); 83 83 84 for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ ) {85 Label & l = *i;86 l.set_statement( definition ); // attach statement to the label to be used later87 if ( labelTable.find( l ) == labelTable.end() ) {88 // All labels on this statement need to use the same entry,89 // so this should only be created once.90 // undefined and unused until now, add an entry91 labelTable[ l ] = new Entry( definition );92 } else if ( labelTable[ l ]->defined() ) {93 // defined twice, error94 SemanticError( l.get_statement()->location,95 "Duplicate definition of label: " + l.get_name() );96 } else {97 // used previously, but undefined until now -> link with this entry98 // Question: Is changing objects important?99 delete labelTable[ l ];100 labelTable[ l ] = new Entry( definition );101 } // if102 } // for84 for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ ) { 85 Label & l = *i; 86 l.set_statement( definition ); // attach statement to the label to be used later 87 if ( labelTable.find( l ) == labelTable.end() ) { 88 // All labels on this statement need to use the same entry, 89 // so this should only be created once. 90 // undefined and unused until now, add an entry 91 labelTable[ l ] = new Entry( definition ); 92 } else if ( labelTable[ l ]->defined() ) { 93 // defined twice, error 94 SemanticError( l.get_statement()->location, 95 "Duplicate definition of label: " + l.get_name() ); 96 } else { 97 // used previously, but undefined until now -> link with this entry 98 // Question: Is changing objects important? 99 delete labelTable[ l ]; 100 labelTable[ l ] = new Entry( definition ); 101 } // if 102 } // for 103 103 104 // Produce one of the labels attached to this statement to be temporarily used as the 105 // canonical label. 106 return labelTable[ llabel.front() ]->get_label(); 107 } 108 109 // A label was used, add it to the table if it isn't already there 110 template< typename UsageNode > 111 void LabelFixer::setLabelsUsg( Label orgValue, UsageNode *use ) { 112 assert( use != 0 ); 113 114 // add label with an unknown origin 115 if ( labelTable.find( orgValue ) == labelTable.end() ) { 116 labelTable[ orgValue ] = new Entry( 0 ); 117 } 118 } 119 120 // Builds a table that maps a label to its defining statement. 121 std::map<Label, Statement * > * LabelFixer::resolveJumps() throw ( SemanticErrorException ) { 122 std::map< Label, Statement * > *ret = new std::map< Label, Statement * >(); 123 for ( std::map< Label, Entry * >::iterator i = labelTable.begin(); i != labelTable.end(); ++i ) { 124 if ( ! i->second->defined() ) { 125 SemanticError( i->first.get_statement()->location, "Use of undefined label: " + i->first.get_name() ); 126 } 127 (*ret)[ i->first ] = i->second->get_definition(); 104 // Produce one of the labels attached to this statement to be temporarily used as the 105 // canonical label. 106 return labelTable[ llabel.front() ]->get_label(); 128 107 } 129 108 130 return ret; 131 } 109 // A label was used, add it to the table if it isn't already there 110 template< typename UsageNode > 111 void LabelFixer::setLabelsUsg( Label orgValue, UsageNode *use ) { 112 assert( use != 0 ); 113 114 // add label with an unknown origin 115 if ( labelTable.find( orgValue ) == labelTable.end() ) { 116 labelTable[ orgValue ] = new Entry( 0 ); 117 } 118 } 119 120 // Builds a table that maps a label to its defining statement. 121 std::map<Label, Statement * > * LabelFixer::resolveJumps() throw ( SemanticErrorException ) { 122 std::map< Label, Statement * > *ret = new std::map< Label, Statement * >(); 123 for ( std::map< Label, Entry * >::iterator i = labelTable.begin(); i != labelTable.end(); ++i ) { 124 if ( ! i->second->defined() ) { 125 SemanticError( i->first.get_statement()->location, "Use of undefined label: " + i->first.get_name() ); 126 } 127 (*ret)[ i->first ] = i->second->get_definition(); 128 } 129 130 return ret; 131 } 132 132 } // namespace ControlStruct 133 133
Note:
See TracChangeset
for help on using the changeset viewer.