Ignore:
Timestamp:
Aug 12, 2015, 2:27:31 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:
f32c7f4
Parents:
e45215c (diff), e869d663 (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' into designate

Conflicts:

src/CodeGen/CodeGenerator.h

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/LabelFixer.cc

    re45215c rd60ccbf  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Jul 08 12:36:46 2015
    13 // Update Count     : 145
     12// Last Modified On : Tue Jul 28 13:32:43 2015
     13// Update Count     : 156
    1414//
    1515
     
    2727
    2828namespace ControlStruct {
    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 
    43 
    4429        bool LabelFixer::Entry::insideLoop() {
    4530                return ( dynamic_cast< ForStmt * > ( definition ) ||
    4631                        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                 }
    5532        }
    5633
     
    7754        // prune to at most one label definition for each statement
    7855        void LabelFixer::visit( Statement *stmt ) {
    79                 currentStatement = stmt;
    8056                std::list< Label > &labels = stmt->get_labels();
    8157
     
    8359                        // only remember one label for each statement
    8460                        Label current = setLabelsDef( labels, stmt );
    85                         labels.clear();
    86                         labels.push_front( current );
    8761                } // if
    8862        }
     
    130104                        }       else {
    131105                                // used previously, but undefined until now -> link with this entry
    132                                 Entry * oldEntry = labelTable[ *i ];
    133                                 e->add_uses( *oldEntry );
     106                                delete labelTable[ *i ];
    134107                                labelTable[ *i ] = e;
    135108                        } // if
     
    141114        }
    142115
    143         // Remember all uses of a label.
     116        // A label was used, add it ot the table if it isn't already there
    144117        template< typename UsageNode >
    145118        void LabelFixer::setLabelsUsg( Label orgValue, UsageNode *use ) {
    146119                assert( use != 0 );
    147120
    148                 if ( labelTable.find( orgValue ) != labelTable.end() ) {
    149                         // the label has been defined or used before
    150                         labelTable[ orgValue ]->add_use( use );
    151                 } else {
    152                         labelTable[ orgValue ] = new Entry( 0, use );
     121                // add label with an unknown origin
     122                if ( labelTable.find( orgValue ) == labelTable.end() ) {
     123                        labelTable[ orgValue ] = new Entry( 0 );
    153124                }
    154125        }
    155126
    156         class LabelGetter : public Visitor {
    157                 public:
    158                 LabelGetter( Label &label ) : label( label ) {}
    159 
    160                 virtual void visit( BranchStmt * branchStmt ) {
    161                         label = branchStmt->get_target();
    162                 }
    163 
    164                 virtual void visit( UntypedExpr * untyped ) {
    165                         NameExpr * name = dynamic_cast< NameExpr * >( untyped->get_function() );
    166                         assert( name );
    167                         assert( name->get_name() == "&&" );
    168                         NameExpr * arg = dynamic_cast< NameExpr * >( untyped->get_args().front() );
    169                         assert( arg );
    170                         label = arg->get_name();
    171                 }               
    172 
    173                 private:
    174                         Label &label;
    175         };
    176 
    177         class LabelSetter : public Visitor {
    178                 public:
    179                 LabelSetter( Label label ) : label( label ) {}
    180 
    181                 virtual void visit( BranchStmt * branchStmt ) {
    182                         branchStmt->set_target( label );
    183                 }
    184 
    185                 virtual void visit( UntypedExpr * untyped ) {
    186                         NameExpr * name = dynamic_cast< NameExpr * >( untyped->get_function() );
    187                         assert( name );
    188                         assert( name->get_name() == "&&" );
    189                         NameExpr * arg = dynamic_cast< NameExpr * >( untyped->get_args().front() );
    190                         assert( arg );
    191                         arg->set_name( label );
    192                 }
    193 
    194         private:
    195                 Label label;
    196         };
    197 
    198         // Ultimately builds a table that maps a label to its defining statement.
    199         // In the process,
     127        // Builds a table that maps a label to its defining statement.
    200128        std::map<Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError ) {
    201                 std::map< Statement *, Entry * > def_us;
    202 
    203                 // combine the entries for all labels that target the same location
    204                 for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); ++i ) {
    205                         Entry *e = i->second;
    206 
    207                         if ( def_us.find ( e->get_definition() ) == def_us.end() ) {
    208                                 def_us[ e->get_definition() ] = e;
    209                         } else if ( e->used() ) {
    210                                 def_us[ e->get_definition() ]->add_uses( *e );
     129                std::map< Label, Statement * > *ret = new std::map< Label, Statement * >();
     130                for ( std::map< Label, Entry * >::iterator i = labelTable.begin(); i != labelTable.end(); ++i ) {
     131                        if ( ! i->second->defined() ) {
     132                                throw SemanticError( "Use of undefined label: " + i->first );
    211133                        }
    212                 }
    213 
    214                 // create a unique label for each target location.
    215                 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); ++i ) {
    216                         Statement *to = (*i).first;
    217                         Entry * entry = (*i).second;
    218                         std::list< Entry::UsageLoc > &from = entry->get_uses();
    219 
    220                         // no label definition found
    221                         if ( to == 0 ) {
    222                                 Label undef;
    223                                 LabelGetter getLabel( undef );
    224                                 from.back().accept( getLabel );
    225                                 // Label undef = getLabel( from.back()->get_target() );
    226                                 throw SemanticError ( "'" + undef + "' label not defined");
    227                         } // if
    228 
    229                         // generate a new label, and attach it to its defining statement as the only label on that statement
    230                         Label finalLabel = generator->newLabel( to->get_labels().back() );
    231                         entry->set_label( finalLabel );
    232 
    233                         to->get_labels().clear();
    234                         to->get_labels().push_back( finalLabel );
    235 
    236                         // redirect each of the source branch statements to the new target label
    237                         for ( std::list< Entry::UsageLoc >::iterator j = from.begin(); j != from.end(); ++j ) {
    238                                 LabelSetter setLabel( finalLabel );
    239                                 (*j).accept( setLabel );
    240                                 // setLabel( *j, finalLabel );
    241 
    242                                 // BranchStmt *jump = *j;
    243                                 // assert( jump != 0 );
    244                                 // jump->set_target( finalLabel );
    245                         } // for
    246                 } // for
    247 
    248                 // create a table where each label maps to its defining statement
    249                 std::map< Label, Statement * > *ret = new std::map< Label, Statement * >();
    250                 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); ++i ) {
    251                         (*ret)[ (*i).second->get_label() ] = (*i).first;
     134                        (*ret)[ i->first ] = i->second->get_definition();
    252135                }
    253136
Note: See TracChangeset for help on using the changeset viewer.