Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/LabelFixer.cc

    r3b0bc16 r9d6317f  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  1 09:12:09 2022
    13 // Update Count     : 162
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tue Jan 21 10:32:00 2020
     13// Update Count     : 160
    1414//
    1515
     
    2727
    2828namespace 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        }
    3333
    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        }
    3838
    39 void LabelFixer::previsit( FunctionDecl * ) {
    40         // need to go into a nested function in a fresh state
    41         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        }
    4444
    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        }
    5050
    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();
     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();
    5454
    55         if ( ! labels.empty() ) {
    56                 // only remember one label for each statement
    57                 Label current = setLabelsDef( labels, stmt );
    58         } // if
    59 }
     55                if ( ! labels.empty() ) {
     56                        // only remember one label for each statement
     57                        Label current = setLabelsDef( labels, stmt );
     58                } // if
     59        }
    6060
    61 void LabelFixer::previsit( BranchStmt * branchStmt ) {
    62         previsit( ( Statement *)branchStmt );
     61        void LabelFixer::previsit( BranchStmt * branchStmt ) {
     62                previsit( ( Statement *)branchStmt );
    6363
    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                }
    6869        }
    69 }
    7070
    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        }
    7676
    7777
    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 );
     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 );
    8383
    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
     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
    103103
    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();
    128107        }
    129108
    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        }
    132132}  // namespace ControlStruct
    133133
Note: See TracChangeset for help on using the changeset viewer.