Changeset 51ec1ab
- Timestamp:
- Jan 31, 2022, 10:29:23 PM (3 years ago)
- Branches:
- ADT, ast-experimental, enum, forall-pointer-decay, master, pthread-emulation, qualifiedEnum
- Children:
- ca8c0362
- Parents:
- 45040b61
- Location:
- src/ControlStruct
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/LabelFixer.cc
r45040b61 r51ec1ab 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Tue Jan 21 10:32:00 202013 // Update Count : 16 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jan 31 22:28:31 2022 13 // Update Count : 161 14 14 // 15 15 … … 27 27 28 28 namespace ControlStruct { 29 bool LabelFixer::Entry::insideLoop() { 30 return ( dynamic_cast< ForStmt * > ( definition ) || 31 dynamic_cast< WhileStmt * > ( definition ) ); 29 bool LabelFixer::Entry::insideLoop() { 30 return ( dynamic_cast< ForStmt * > ( definition ) || 31 dynamic_cast< WhileStmt * > ( definition ) ); 32 } 33 34 LabelFixer::LabelFixer( LabelGenerator * gen ) : generator ( gen ) { 35 if ( generator == 0 ) 36 generator = LabelGenerator::getGenerator(); 37 } 38 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 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 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 55 if ( ! labels.empty() ) { 56 // only remember one label for each statement 57 Label current = setLabelsDef( labels, stmt ); 58 } // if 59 } 60 61 void LabelFixer::previsit( BranchStmt * branchStmt ) { 62 previsit( ( Statement *)branchStmt ); 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 ); 68 } 69 } 70 71 void LabelFixer::previsit( LabelAddressExpr * addrExpr ) { 72 Label & target = addrExpr->arg; 73 assert( target != "" ); 74 setLabelsUsg( target, addrExpr ); 75 } 76 77 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 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 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 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(); 32 128 } 33 129 34 LabelFixer::LabelFixer( LabelGenerator * gen ) : generator ( gen ) { 35 if ( generator == 0 ) 36 generator = LabelGenerator::getGenerator(); 37 } 38 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 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 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 55 if ( ! labels.empty() ) { 56 // only remember one label for each statement 57 Label current = setLabelsDef( labels, stmt ); 58 } // if 59 } 60 61 void LabelFixer::previsit( BranchStmt * branchStmt ) { 62 previsit( ( Statement *)branchStmt ); 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 ); 68 } 69 } 70 71 void LabelFixer::previsit( LabelAddressExpr * addrExpr ) { 72 Label & target = addrExpr->arg; 73 assert( target != "" ); 74 setLabelsUsg( target, addrExpr ); 75 } 76 77 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 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 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 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(); 128 } 129 130 return ret; 131 } 130 return ret; 131 } 132 132 } // namespace ControlStruct 133 133 -
src/ControlStruct/LabelFixer.h
r45040b61 r51ec1ab 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:17:24 201713 // Update Count : 3 412 // Last Modified On : Mon Jan 31 22:28:04 2022 13 // Update Count : 35 14 14 // 15 15 … … 26 26 27 27 namespace ControlStruct { 28 /// normalizes label definitions and generates multi-level exit labels29 28 // normalizes label definitions and generates multi-level exit labels 29 class LabelGenerator; 30 30 31 32 33 31 class LabelFixer final : public WithGuards { 32 public: 33 LabelFixer( LabelGenerator *gen = 0 ); 34 34 35 35 std::map < Label, Statement * > *resolveJumps() throw ( SemanticErrorException ); 36 36 37 38 39 37 // Declarations 38 void previsit( FunctionDecl *functionDecl ); 39 void postvisit( FunctionDecl *functionDecl ); 40 40 41 42 43 41 // Statements 42 void previsit( Statement *stmt ); 43 void previsit( BranchStmt *branchStmt ); 44 44 45 46 45 // Expressions 46 void previsit( LabelAddressExpr *addrExpr ); 47 47 48 Label setLabelsDef( std::list< Label > &, Statement *definition ); 49 template< typename UsageNode > 50 void setLabelsUsg( Label, UsageNode *usage = 0 ); 48 Label setLabelsDef( std::list< Label > &, Statement *definition ); 49 template< typename UsageNode > 50 void setLabelsUsg( Label, UsageNode *usage = 0 ); 51 52 private: 53 class Entry { 54 public: 55 Entry( Statement *to ) : definition( to ) {} 56 bool defined() { return ( definition != 0 ); } 57 bool insideLoop(); 58 59 Label get_label() const { return label; } 60 void set_label( Label lab ) { label = lab; } 61 62 Statement *get_definition() const { return definition; } 63 void set_definition( Statement *def ) { definition = def; } 51 64 52 65 private: 53 class Entry { 54 public: 55 Entry( Statement *to ) : definition( to ) {} 56 bool defined() { return ( definition != 0 ); } 57 bool insideLoop(); 66 Label label; 67 Statement *definition; 68 }; 58 69 59 Label get_label() const { return label; } 60 void set_label( Label lab ) { label = lab; } 61 62 Statement *get_definition() const { return definition; } 63 void set_definition( Statement *def ) { definition = def; } 64 65 private: 66 Label label; 67 Statement *definition; 68 }; 69 70 std::map < Label, Entry *> labelTable; 71 LabelGenerator *generator; 72 }; 70 std::map < Label, Entry *> labelTable; 71 LabelGenerator *generator; 72 }; 73 73 } // namespace ControlStruct 74 74 -
src/ControlStruct/LabelGenerator.cc
r45040b61 r51ec1ab 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Mon Nov 8 10:18:00 202113 // Update Count : 1711 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jan 31 18:48:26 2022 13 // Update Count : 27 14 14 // 15 15 … … 17 17 #include <sstream> // for ostringstream 18 18 #include <list> // for list 19 using namespace std; 19 20 20 21 #include "LabelGenerator.h" 21 22 22 #include "AST/Attribute.hpp"23 #include "AST/Label.hpp"24 #include "AST/Stmt.hpp"25 23 #include "SynTree/Attribute.h" // for Attribute 26 24 #include "SynTree/Label.h" // for Label, operator<< … … 32 30 LabelGenerator * LabelGenerator::labelGenerator = nullptr; 33 31 34 35 36 37 38 32 LabelGenerator * LabelGenerator::getGenerator() { 33 if ( LabelGenerator::labelGenerator == 0 ) 34 LabelGenerator::labelGenerator = new LabelGenerator(); 35 return labelGenerator; 36 } 39 37 40 Label LabelGenerator::newLabel( std::string suffix, Statement * stmt ) { 41 std::ostringstream os; 42 os << "__L" << current++ << "__" << suffix; 43 if ( stmt && ! stmt->get_labels().empty() ) { 44 os << "_" << stmt->get_labels().front() << "__"; 45 } // if 46 std::string ret = os.str(); 47 Label l( ret ); 48 l.get_attributes().push_back( new Attribute("unused") ); 49 return l; 50 } 51 52 ast::Label LabelGenerator::newLabel( 53 const std::string & suffix, const ast::Stmt * stmt ) { 54 assert( stmt ); 55 56 std::ostringstream os; 57 os << "__L" << current++ << "__" << suffix; 58 if ( stmt && !stmt->labels.empty() ) { 59 os << "_" << stmt->labels.front() << "__"; 60 } 61 ast::Label ret_label( stmt->location, os.str() ); 62 ret_label.attributes.push_back( new ast::Attribute( "unused" ) ); 63 return ret_label; 38 Label LabelGenerator::newLabel( string suffix, Statement * stmt ) { 39 ostringstream os; 40 os << "__L_OLD" << current++ << "__" << suffix; 41 if ( stmt && ! stmt->get_labels().empty() ) { 42 os << "_" << stmt->get_labels().front() << "__"; 43 } // if 44 string ret = os.str(); 45 Label l( ret ); 46 l.get_attributes().push_back( new Attribute( "unused" ) ); 47 return l; 64 48 } 65 49 … … 67 51 68 52 // Local Variables: // 69 // tab-width: 4 //70 53 // mode: c++ // 71 // compile-command: "make install" //72 54 // End: //
Note: See TracChangeset
for help on using the changeset viewer.