Ignore:
Timestamp:
Jun 26, 2015, 4:00:26 PM (10 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
Children:
0df292b, e0ff3e6
Parents:
eb50842 (diff), 1869adf (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 pointer to pointer to qualified fix into master

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/LabelFixer.cc

    reb50842 r937e51d  
    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 May 19 15:25:59 2015
    13 // Update Count     : 1
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Jun 24 16:24:34 2015
     13// Update Count     : 141
    1414//
    1515
     
    1919#include "LabelFixer.h"
    2020#include "MLEMutator.h"
     21#include "SynTree/Expression.h"
    2122#include "SynTree/Statement.h"
    2223#include "SynTree/Declaration.h"
    2324#include "utility.h"
    2425
     26#include <iostream>
     27
    2528namespace ControlStruct {
    2629        LabelFixer::Entry::Entry( Statement *to, Statement *from ) : definition ( to ) {
    27                 if ( from != 0 )
    28                         usage.push_back( from );
    29         }
     30                if ( from != 0 ) {
     31                        UsageLoc loc; loc.stmt = from;
     32                        usage.push_back( loc );
     33                }
     34        }
     35
     36        LabelFixer::Entry::Entry( Statement *to, Expression *from ) : definition ( to ) {
     37                if ( from != 0 ) {
     38                        UsageLoc loc; loc.expr = from;
     39                        usage.push_back( loc );
     40                }
     41        }
     42
    3043
    3144        bool LabelFixer::Entry::insideLoop() {
    3245                return ( dynamic_cast< ForStmt * > ( definition ) ||
    33                                  dynamic_cast< WhileStmt * > ( definition )  );
     46                        dynamic_cast< WhileStmt * > ( definition )  );
     47        }
     48
     49        void LabelFixer::Entry::UsageLoc::accept( Visitor & visitor ) {
     50                if ( dynamic_cast< Statement * >( stmt ) ) {
     51                        stmt->accept( visitor );
     52                } else {
     53                        expr->accept( visitor );
     54                }
    3455        }
    3556
     
    4061
    4162        void LabelFixer::visit( FunctionDecl *functionDecl ) {
    42                 if ( functionDecl->get_statements() != 0 )
    43                         functionDecl->get_statements()->accept( *this );
     63                maybeAccept( functionDecl->get_statements(), *this );
    4464
    4565                MLEMutator mlemut( resolveJumps(), generator );
     
    4767        }
    4868
     69        // prune to at most one label definition for each statement
    4970        void LabelFixer::visit( Statement *stmt ) {
     71                currentStatement = stmt;
    5072                std::list< Label > &labels = stmt->get_labels();
    5173
    5274                if ( ! labels.empty() ) {
     75                        // only remember one label for each statement
    5376                        Label current = setLabelsDef( labels, stmt );
    5477                        labels.clear();
     
    5881
    5982        void LabelFixer::visit( BranchStmt *branchStmt ) {
    60                 visit ( ( Statement * )branchStmt );  // the labels this statement might have
    61 
    62                 Label target;
    63                 if ( (target = branchStmt->get_target()) != "" ) {
     83                visit ( ( Statement * )branchStmt );
     84
     85                // for labeled branches, add an entry to the label table
     86                Label target = branchStmt->get_target();
     87                if ( target != "" ) {
    6488                        setLabelsUsg( target, branchStmt );
    65                 } //else       /* computed goto or normal exit-loop statements */
    66         }
    67 
     89                }
     90        }
     91
     92        void LabelFixer::visit( UntypedExpr *untyped ) {
     93                if ( NameExpr * func = dynamic_cast< NameExpr * >( untyped->get_function() ) ) {
     94                        if ( func->get_name() == "&&" ) {
     95                                NameExpr * arg = dynamic_cast< NameExpr * >( untyped->get_args().front() );
     96                                Label target = arg->get_name();
     97                                assert( target != "" );
     98                                setLabelsUsg( target, untyped );
     99                        } else {
     100                                Visitor::visit( untyped );
     101                        }
     102                }
     103        }
     104
     105
     106        // sets the definition of the labelTable entry to be the provided
     107        // statement for every label in the list parameter. Happens for every kind of statement
    68108        Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition ) {
    69109                assert( definition != 0 );
    70                 Entry *entry = new Entry( definition );
    71                 bool used = false;
    72 
    73                 for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ )
    74                         if ( labelTable.find( *i ) == labelTable.end() )
    75                                 { used = true; labelTable[ *i ] = entry; } // undefined and unused
    76                         else
    77                                 if ( labelTable[ *i ]->defined() )
    78                                         throw SemanticError( "Duplicate definition of label: " + *i );
    79                                 else
    80                                         labelTable[ *i ]->set_definition( definition );
    81 
    82                 if ( ! used ) delete entry;
    83 
    84                 return labelTable[ llabel.front() ]->get_label();  // this *must* exist
    85         }
    86 
    87         Label LabelFixer::setLabelsUsg( Label orgValue, Statement *use ) {
     110                assert( llabel.size() > 0 );
     111
     112                Entry * e = new Entry( definition );
     113
     114                for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ ) {
     115                        if ( labelTable.find( *i ) == labelTable.end() ) {
     116                                // all labels on this statement need to use the same entry, so this should only be created once
     117                                // undefined and unused until now, add an entry
     118                                labelTable[ *i ] =  e;
     119                        } else if ( labelTable[ *i ]->defined() ) {
     120                                // defined twice, error
     121                                throw SemanticError( "Duplicate definition of label: " + *i );
     122                        }       else {
     123                                // used previously, but undefined until now -> link with this entry
     124                                Entry * oldEntry = labelTable[ *i ];
     125                                e->add_uses( *oldEntry );
     126                                labelTable[ *i ] = e;
     127                        } // if
     128                } // for
     129
     130                // produce one of the labels attached to this statement to be
     131                // temporarily used as the canonical label
     132                return labelTable[ llabel.front() ]->get_label();
     133        }
     134
     135        // Remember all uses of a label.
     136        template< typename UsageNode >
     137        void LabelFixer::setLabelsUsg( Label orgValue, UsageNode *use ) {
    88138                assert( use != 0 );
    89139
    90                 if ( labelTable.find( orgValue ) != labelTable.end() )
    91                         labelTable[ orgValue ]->add_use( use );         // the label has been defined or used before
    92                 else
     140                if ( labelTable.find( orgValue ) != labelTable.end() ) {
     141                        // the label has been defined or used before
     142                        labelTable[ orgValue ]->add_use( use );
     143                } else {
    93144                        labelTable[ orgValue ] = new Entry( 0, use );
    94 
    95                 return labelTable[ orgValue ]->get_label();
    96         }
    97 
     145                }
     146        }
     147
     148        class LabelGetter : public Visitor {
     149                public:
     150                LabelGetter( Label &label ) : label( label ) {}
     151
     152                virtual void visit( BranchStmt * branchStmt ) {
     153                        label = branchStmt->get_target();
     154                }
     155
     156                virtual void visit( UntypedExpr * untyped ) {
     157                        NameExpr * name = dynamic_cast< NameExpr * >( untyped->get_function() );
     158                        assert( name );
     159                        assert( name->get_name() == "&&" );
     160                        NameExpr * arg = dynamic_cast< NameExpr * >( untyped->get_args().front() );
     161                        assert( arg );
     162                        label = arg->get_name();
     163                }               
     164
     165                private:
     166                        Label &label;
     167        };
     168
     169        class LabelSetter : public Visitor {
     170                public:
     171                LabelSetter( Label label ) : label( label ) {}
     172
     173                virtual void visit( BranchStmt * branchStmt ) {
     174                        branchStmt->set_target( label );
     175                }
     176
     177                virtual void visit( UntypedExpr * untyped ) {
     178                        NameExpr * name = dynamic_cast< NameExpr * >( untyped->get_function() );
     179                        assert( name );
     180                        assert( name->get_name() == "&&" );
     181                        NameExpr * arg = dynamic_cast< NameExpr * >( untyped->get_args().front() );
     182                        assert( arg );
     183                        arg->set_name( label );
     184                }
     185
     186        private:
     187                Label label;
     188        };
     189
     190        // Ultimately builds a table that maps a label to its defining statement.
     191        // In the process,
    98192        std::map<Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError ) {
    99193                std::map< Statement *, Entry * > def_us;
    100194
    101                 for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); i++ ) {
     195                // combine the entries for all labels that target the same location
     196                for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); ++i ) {
    102197                        Entry *e = i->second;
    103198
    104                         if ( def_us.find ( e->get_definition() ) == def_us.end() )
     199                        if ( def_us.find ( e->get_definition() ) == def_us.end() ) {
    105200                                def_us[ e->get_definition() ] = e;
    106                         else
    107                                 if ( e->used() )
    108                                         def_us[ e->get_definition() ]->add_uses( e->get_uses() );
    109                 }
    110 
    111                 // get rid of labelTable
    112                 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) {
     201                        } else if ( e->used() ) {
     202                                def_us[ e->get_definition() ]->add_uses( *e );
     203                        }
     204                }
     205
     206                // create a unique label for each target location.
     207                for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); ++i ) {
    113208                        Statement *to = (*i).first;
    114                         std::list< Statement *> &from = (*i).second->get_uses();
    115                         Label finalLabel = generator->newLabel();
    116                         (*i).second->set_label( finalLabel );
    117 
     209                        Entry * entry = (*i).second;
     210                        std::list< Entry::UsageLoc > &from = entry->get_uses();
     211
     212                        // no label definition found
    118213                        if ( to == 0 ) {
    119                                 BranchStmt *first_use = dynamic_cast<BranchStmt *>(from.back());
    120                                 Label undef("");
    121                                 if ( first_use != 0 )
    122                                         undef = first_use->get_target();
     214                                Label undef;
     215                                LabelGetter getLabel( undef );
     216                                from.back().accept( getLabel );
     217                                // Label undef = getLabel( from.back()->get_target() );
    123218                                throw SemanticError ( "'" + undef + "' label not defined");
    124                         }
     219                        } // if
     220
     221                        // generate a new label, and attach it to its defining statement as the only label on that statement
     222                        Label finalLabel = generator->newLabel( to->get_labels().back() );
     223                        entry->set_label( finalLabel );
    125224
    126225                        to->get_labels().clear();
    127226                        to->get_labels().push_back( finalLabel );
    128227
    129                         for ( std::list< Statement *>::iterator j = from.begin(); j != from.end(); j++ ) {
    130                                 BranchStmt *jumpTo = dynamic_cast< BranchStmt * > ( *j );
    131                                 assert( jumpTo != 0 );
    132                                 jumpTo->set_target( finalLabel );
     228                        // redirect each of the source branch statements to the new target label
     229                        for ( std::list< Entry::UsageLoc >::iterator j = from.begin(); j != from.end(); ++j ) {
     230                                LabelSetter setLabel( finalLabel );
     231                                (*j).accept( setLabel );
     232                                // setLabel( *j, finalLabel );
     233
     234                                // BranchStmt *jump = *j;
     235                                // assert( jump != 0 );
     236                                // jump->set_target( finalLabel );
    133237                        } // for
    134238                } // for
    135239
    136                 // reverse table
     240                // create a table where each label maps to its defining statement
    137241                std::map< Label, Statement * > *ret = new std::map< Label, Statement * >();
    138                 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ )
     242                for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); ++i ) {
    139243                        (*ret)[ (*i).second->get_label() ] = (*i).first;
     244                }
    140245
    141246                return ret;
Note: See TracChangeset for help on using the changeset viewer.