- Timestamp:
- Nov 5, 2021, 4:18:55 PM (3 years ago)
- Branches:
- ADT, ast-experimental, enum, forall-pointer-decay, master, pthread-emulation, qualifiedEnum
- Children:
- 817bb3c
- Parents:
- b8ab91a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/FixLabels.cpp
rb8ab91a r21fe17f 10 10 // Created On : Mon Nov 1 09:39:00 2021 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Nov 2 10:32:00 202113 // Update Count : 012 // Last Modified On : Mon Nov 5 16:05:00 2021 13 // Update Count : 1 14 14 // 15 15 … … 26 26 namespace { 27 27 28 struct MultiLevelExitCore :29 public ast::WithVisitorRef<MultiLevelExitCore>,30 public ast::WithShortCircuiting, public ast::WithGuards {31 class Entry;32 };33 34 struct Entry {35 ast::Label label;36 const ast::Stmt * def;37 38 Entry() : label( CodeLocation() ), def( nullptr ) {}39 Entry( const ast::Stmt * def ) : label( def->location ), def( def ) {}40 41 bool isDefined() const {42 return nullptr != def;43 }44 45 bool isInsideLoop() {46 return ( dynamic_cast< const ast::ForStmt *>( def ) ||47 dynamic_cast< const ast::WhileStmt *>( def ) );48 }49 };50 51 28 class FixLabelsCore final : public ast::WithGuards { 52 std::map<ast::Label, Entry *>labelTable;29 LabelToStmt labelTable; 53 30 LabelGenerator_new * label_gen; 54 31 public: … … 58 35 {} 59 36 60 std::map<ast::Label, const ast::Stmt *> * resolveJumps();61 62 37 void previsit( const ast::FunctionDecl * ); 63 38 const ast::FunctionDecl * postvisit( const ast::FunctionDecl * ); … … 66 41 void previsit( const ast::LabelAddressExpr * ); 67 42 68 ast::Label setLabelsDef( const std::vector<ast::Label> &, const ast::Stmt * ); 69 template<typename UsageNode> 70 void setLabelsUsage(ast::Label, const UsageNode * usage ); 43 void setLabelsDef( const std::vector<ast::Label> &, const ast::Stmt * ); 44 void setLabelsUsage( const ast::Label & ); 71 45 }; 72 73 std::map<ast::Label, const ast::Stmt *> * FixLabelsCore::resolveJumps() {74 auto ret = new std::map<ast::Label, const ast::Stmt *>();75 for ( auto kvp : labelTable ) {76 if ( !kvp.second->isDefined() ) {77 SemanticError( kvp.first.location,78 "Use of undefined label: " + kvp.first.name );79 }80 (*ret)[ kvp.first ] = kvp.second->def;81 }82 return ret;83 }84 46 85 47 void FixLabelsCore::previsit( const ast::FunctionDecl * ) { … … 90 52 const ast::FunctionDecl * decl ) { 91 53 if ( nullptr == decl->stmts ) return decl; 54 for ( auto kvp : labelTable ) { 55 if ( nullptr == kvp.second ) { 56 SemanticError( kvp.first.location, 57 "Use of undefined label: " + kvp.first.name ); 58 } 59 } 60 LabelToStmt * copy = new LabelToStmt( labelTable ); 92 61 return ast::mutate_field( decl, &ast::FunctionDecl::stmts, 93 multiLevelExitUpdate( decl->stmts.get(), resolveJumps(), label_gen ) );62 multiLevelExitUpdate( decl->stmts.get(), copy, label_gen ) ); 94 63 } 95 64 96 65 void FixLabelsCore::previsit( const ast::Stmt * stmt ) { 97 if ( stmt->labels.empty() ) {98 return;66 if ( !stmt->labels.empty() ) { 67 setLabelsDef( stmt->labels, stmt ); 99 68 } 100 // Only remember one label for each statement.101 // (But we don't do anything with one label. What does it do?)102 ast::Label current = setLabelsDef( stmt->labels, stmt );103 69 } 104 70 105 71 void FixLabelsCore::previsit( const ast::BranchStmt * stmt ) { 106 72 if ( !stmt->labels.empty() ) { 107 ast::Label current =setLabelsDef( stmt->labels, stmt );73 setLabelsDef( stmt->labels, stmt ); 108 74 } 109 75 if ( !stmt->target.empty() ) { 110 setLabelsUsage( stmt->target , stmt);76 setLabelsUsage( stmt->target ); 111 77 } 112 78 } … … 114 80 void FixLabelsCore::previsit( const ast::LabelAddressExpr * expr ) { 115 81 assert( !expr->arg.empty() ); 116 setLabelsUsage( expr->arg , expr);82 setLabelsUsage( expr->arg ); 117 83 } 118 84 119 ast::LabelFixLabelsCore::setLabelsDef(85 void FixLabelsCore::setLabelsDef( 120 86 const std::vector<ast::Label> & labels, const ast::Stmt * stmt ) { 121 87 assert( !labels.empty() ); … … 125 91 if ( labelTable.find( label ) == labelTable.end() ) { 126 92 // Make sure to only create the entry once. 127 labelTable[ label ] = new Entry( stmt );128 } else if ( labelTable[ label ]->isDefined()) {93 labelTable[ label ] = stmt; 94 } else if ( nullptr != labelTable[ label ] ) { 129 95 // Duplicate definition, this is an error. 130 96 SemanticError( label.location, … … 132 98 } else { 133 99 // Perviously used, but not defined until now. 134 // (There was a question about changing objects, is that the Entry?) 135 delete labelTable[ label ]; 136 labelTable[ label ] = new Entry( stmt ); 100 labelTable[ label ] = stmt; 137 101 } 138 102 } 139 140 // Return the labels on this statement to be the tmp. canonical label.141 return labelTable[ labels.front() ]->label;142 103 } 143 104 144 105 // Label was used, if it is new add it to the table. 145 // (Why do we pass in usage? It's only use is in the assertion.) 146 template<typename UsageNode> 147 void FixLabelsCore::setLabelsUsage(ast::Label label, const UsageNode * usage ) { 148 assert( usage ); 149 106 void FixLabelsCore::setLabelsUsage( const ast::Label & label ) { 150 107 if ( labelTable.find( label ) == labelTable.end() ) { 151 labelTable[ label ] = n ew Entry();108 labelTable[ label ] = nullptr; 152 109 } 153 110 }
Note: See TracChangeset
for help on using the changeset viewer.