Ignore:
Timestamp:
Feb 1, 2022, 12:06:24 PM (2 years ago)
Author:
caparsons <caparson@…>
Branches:
ADT, ast-experimental, enum, forall-pointer-decay, master, pthread-emulation, qualifiedEnum
Children:
ab1a9ea
Parents:
3e5db5b4 (diff), 7b2c8c3c (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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/LabelFixer.cc

    r3e5db5b4 r34c32f0  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Jan 21 10:32:00 2020
    13 // Update Count     : 160
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Mon Jan 31 22:28:31 2022
     13// Update Count     : 161
    1414//
    1515
     
    2727
    2828namespace ControlStruct {
    29         bool LabelFixer::Entry::insideLoop() {
    30                 return ( dynamic_cast< ForStmt * > ( definition ) ||
    31                         dynamic_cast< WhileStmt * > ( definition )  );
     29bool LabelFixer::Entry::insideLoop() {
     30        return ( dynamic_cast< ForStmt * > ( definition ) ||
     31                dynamic_cast< WhileStmt * > ( definition )  );
     32}
     33
     34LabelFixer::LabelFixer( LabelGenerator * gen ) : generator ( gen ) {
     35        if ( generator == 0 )
     36                generator = LabelGenerator::getGenerator();
     37}
     38
     39void LabelFixer::previsit( FunctionDecl * ) {
     40        // need to go into a nested function in a fresh state
     41        GuardValue( labelTable );
     42        labelTable.clear();
     43}
     44
     45void 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
     52void 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
     61void 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
     71void 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.
     80Label 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
     110template< typename UsageNode >
     111void 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.
     121std::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();
    32128        }
    33129
    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}
    132132}  // namespace ControlStruct
    133133
Note: See TracChangeset for help on using the changeset viewer.