Ignore:
Timestamp:
Jun 24, 2015, 4:33:13 PM (9 years ago)
Author:
Rob Schluntz <rschlunt@…>
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:
721f17a, 937e51d
Parents:
94e0864d
Message:

fix label name in label address expression

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/LabelFixer.cc

    r94e0864d r1869adf  
    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 Jun 23 12:42:23 2015
    13 // Update Count     : 96
     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"
     
    2627
    2728namespace ControlStruct {
    28         LabelFixer::Entry::Entry( Statement *to, BranchStmt *from ) : definition ( to ) {
    29                 if ( from != 0 )
    30                         usage.push_back( from );
    31         }
     29        LabelFixer::Entry::Entry( Statement *to, Statement *from ) : definition ( to ) {
     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
    3243
    3344        bool LabelFixer::Entry::insideLoop() {
     
    3647        }
    3748
     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                }
     55        }
     56
    3857        LabelFixer::LabelFixer( LabelGenerator *gen ) : generator ( gen ) {
    3958                if ( generator == 0 )
     
    5069        // prune to at most one label definition for each statement
    5170        void LabelFixer::visit( Statement *stmt ) {
     71                currentStatement = stmt;
    5272                std::list< Label > &labels = stmt->get_labels();
    5373
     
    6989                }
    7090        }
     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
    71105
    72106        // sets the definition of the labelTable entry to be the provided
     
    89123                                // used previously, but undefined until now -> link with this entry
    90124                                Entry * oldEntry = labelTable[ *i ];
    91                                 e->add_uses( oldEntry->get_uses() );
     125                                e->add_uses( *oldEntry );
    92126                                labelTable[ *i ] = e;
    93127                        } // if
     
    100134
    101135        // Remember all uses of a label.
    102         void LabelFixer::setLabelsUsg( Label orgValue, BranchStmt *use ) {
     136        template< typename UsageNode >
     137        void LabelFixer::setLabelsUsg( Label orgValue, UsageNode *use ) {
    103138                assert( use != 0 );
    104139
     
    111146        }
    112147
     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
    113190        // Ultimately builds a table that maps a label to its defining statement.
    114191        // In the process,
     
    121198
    122199                        if ( def_us.find ( e->get_definition() ) == def_us.end() ) {
    123                                 def_us[ e->get_definition() ] = e;                             
     200                                def_us[ e->get_definition() ] = e;
    124201                        } else if ( e->used() ) {
    125                                 def_us[ e->get_definition() ]->add_uses( e->get_uses() );
     202                                def_us[ e->get_definition() ]->add_uses( *e );
    126203                        }
    127204                }
     
    131208                        Statement *to = (*i).first;
    132209                        Entry * entry = (*i).second;
    133                         std::list< BranchStmt *> &from = entry->get_uses();
     210                        std::list< Entry::UsageLoc > &from = entry->get_uses();
    134211
    135212                        // no label definition found
    136213                        if ( to == 0 ) {
    137                                 Label undef = from.back()->get_target();
     214                                Label undef;
     215                                LabelGetter getLabel( undef );
     216                                from.back().accept( getLabel );
     217                                // Label undef = getLabel( from.back()->get_target() );
    138218                                throw SemanticError ( "'" + undef + "' label not defined");
    139219                        } // if
     
    147227
    148228                        // redirect each of the source branch statements to the new target label
    149                         for ( std::list< BranchStmt *>::iterator j = from.begin(); j != from.end(); ++j ) {
    150                                 BranchStmt *jump = *j;
    151                                 assert( jump != 0 );
    152                                 jump->set_target( finalLabel );
     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 );
    153237                        } // for
    154238                } // for
Note: See TracChangeset for help on using the changeset viewer.