| 1 | #include <list>
 | 
|---|
| 2 | #include <cassert>
 | 
|---|
| 3 | 
 | 
|---|
| 4 | #include "LabelFixer.h"
 | 
|---|
| 5 | #include "MLEMutator.h"
 | 
|---|
| 6 | #include "SynTree/Statement.h"
 | 
|---|
| 7 | #include "SynTree/Declaration.h"
 | 
|---|
| 8 | #include "utility.h"
 | 
|---|
| 9 | 
 | 
|---|
| 10 | namespace ControlStruct {
 | 
|---|
| 11 |   LabelFixer::Entry::Entry( Statement *to, Statement *from ) :
 | 
|---|
| 12 |     definition ( to )
 | 
|---|
| 13 |   {
 | 
|---|
| 14 |     if ( from != 0 )
 | 
|---|
| 15 |     usage.push_back( from );
 | 
|---|
| 16 |   }
 | 
|---|
| 17 | 
 | 
|---|
| 18 |   bool LabelFixer::Entry::insideLoop()
 | 
|---|
| 19 |   {
 | 
|---|
| 20 |     return ( dynamic_cast< ForStmt * > ( definition ) ||
 | 
|---|
| 21 |              dynamic_cast< WhileStmt * > ( definition )  );
 | 
|---|
| 22 |   }
 | 
|---|
| 23 | 
 | 
|---|
| 24 |   LabelFixer::LabelFixer( LabelGenerator *gen ) : generator ( gen )
 | 
|---|
| 25 |   {
 | 
|---|
| 26 |     if ( generator == 0 )
 | 
|---|
| 27 |       generator = LabelGenerator::getGenerator();
 | 
|---|
| 28 |   }
 | 
|---|
| 29 | 
 | 
|---|
| 30 |   void LabelFixer::visit(FunctionDecl *functionDecl)
 | 
|---|
| 31 |   {
 | 
|---|
| 32 |     if ( functionDecl->get_statements() != 0 )
 | 
|---|
| 33 |       functionDecl->get_statements()->accept( *this );
 | 
|---|
| 34 | 
 | 
|---|
| 35 |     MLEMutator mlemut( resolveJumps(), generator );
 | 
|---|
| 36 |     functionDecl->acceptMutator( mlemut );
 | 
|---|
| 37 |   }
 | 
|---|
| 38 | 
 | 
|---|
| 39 |   void LabelFixer::visit(Statement *stmt )
 | 
|---|
| 40 |   {
 | 
|---|
| 41 |     std::list< Label > &labels = stmt->get_labels();
 | 
|---|
| 42 | 
 | 
|---|
| 43 |     if ( ! labels.empty() ) {
 | 
|---|
| 44 |       Label current = setLabelsDef( labels, stmt );
 | 
|---|
| 45 |       labels.clear();
 | 
|---|
| 46 |       labels.push_front( current );
 | 
|---|
| 47 |     }
 | 
|---|
| 48 |   }
 | 
|---|
| 49 | 
 | 
|---|
| 50 |   void LabelFixer::visit(BranchStmt *branchStmt)
 | 
|---|
| 51 |   {
 | 
|---|
| 52 |     visit ( ( Statement * )branchStmt );  // the labels this statement might have
 | 
|---|
| 53 | 
 | 
|---|
| 54 |     Label target;
 | 
|---|
| 55 |     if ( (target = branchStmt->get_target()) != "" ) {
 | 
|---|
| 56 |       setLabelsUsg( target, branchStmt );
 | 
|---|
| 57 |     } //else       /* computed goto or normal exit-loop statements */
 | 
|---|
| 58 |   }
 | 
|---|
| 59 | 
 | 
|---|
| 60 | 
 | 
|---|
| 61 |   Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition )
 | 
|---|
| 62 |   {
 | 
|---|
| 63 |     assert( definition != 0 );
 | 
|---|
| 64 |     Entry *entry = new Entry( definition );
 | 
|---|
| 65 |     bool used = false;
 | 
|---|
| 66 | 
 | 
|---|
| 67 |     for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ )
 | 
|---|
| 68 |       if ( labelTable.find( *i ) == labelTable.end() )
 | 
|---|
| 69 |         { used = true; labelTable[ *i ] = entry; } // undefined and unused
 | 
|---|
| 70 |       else
 | 
|---|
| 71 |         if( labelTable[ *i ]->defined() )
 | 
|---|
| 72 |           throw SemanticError("Duplicate definition of label: " + *i );
 | 
|---|
| 73 |         else
 | 
|---|
| 74 |           labelTable[ *i ]->set_definition( definition );
 | 
|---|
| 75 | 
 | 
|---|
| 76 |     if (! used ) delete entry;
 | 
|---|
| 77 | 
 | 
|---|
| 78 |     return labelTable[ llabel.front() ]->get_label();  // this *must* exist
 | 
|---|
| 79 |   }
 | 
|---|
| 80 | 
 | 
|---|
| 81 |   Label LabelFixer::setLabelsUsg( Label orgValue, Statement *use )
 | 
|---|
| 82 |   {
 | 
|---|
| 83 |     assert( use != 0 );
 | 
|---|
| 84 | 
 | 
|---|
| 85 |     if ( labelTable.find( orgValue ) != labelTable.end() )
 | 
|---|
| 86 |       labelTable[ orgValue ]->add_use( use );         // the label has been defined or used before
 | 
|---|
| 87 |     else
 | 
|---|
| 88 |       labelTable[ orgValue ] = new Entry( 0, use );
 | 
|---|
| 89 | 
 | 
|---|
| 90 |     return labelTable[ orgValue ]->get_label();
 | 
|---|
| 91 |   }
 | 
|---|
| 92 | 
 | 
|---|
| 93 |   std::map < Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError )
 | 
|---|
| 94 |   {
 | 
|---|
| 95 |     std::map < Statement *, Entry * > def_us;
 | 
|---|
| 96 | 
 | 
|---|
| 97 |     for( std::map < Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); i++ ) {
 | 
|---|
| 98 |       Entry *e = i->second;
 | 
|---|
| 99 | 
 | 
|---|
| 100 |       if ( def_us.find ( e->get_definition() ) == def_us.end() )
 | 
|---|
| 101 |           def_us[ e->get_definition() ] = e;
 | 
|---|
| 102 |       else
 | 
|---|
| 103 |         if(e->used())
 | 
|---|
| 104 |           def_us[ e->get_definition() ]->add_uses( e->get_uses() );
 | 
|---|
| 105 |     }
 | 
|---|
| 106 | 
 | 
|---|
| 107 |     // get rid of labelTable
 | 
|---|
| 108 |     for( std::map < Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) {
 | 
|---|
| 109 |       Statement *to = (*i).first;
 | 
|---|
| 110 |       std::list < Statement *> &from = (*i).second->get_uses();
 | 
|---|
| 111 |       Label finalLabel = generator->newLabel();
 | 
|---|
| 112 |       (*i).second->set_label( finalLabel );
 | 
|---|
| 113 | 
 | 
|---|
| 114 |       if ( to == 0 ) {
 | 
|---|
| 115 |         BranchStmt *first_use = dynamic_cast<BranchStmt *>(from.back());
 | 
|---|
| 116 |         Label undef("");
 | 
|---|
| 117 |         if ( first_use != 0 )
 | 
|---|
| 118 |           undef = first_use->get_target();
 | 
|---|
| 119 |         throw SemanticError ( "'" + undef + "' label not defined");
 | 
|---|
| 120 |       }
 | 
|---|
| 121 | 
 | 
|---|
| 122 |       to->get_labels().clear();
 | 
|---|
| 123 |       to->get_labels().push_back( finalLabel );
 | 
|---|
| 124 | 
 | 
|---|
| 125 |       for ( std::list< Statement *>::iterator j = from.begin(); j != from.end(); j++ ) {
 | 
|---|
| 126 |         BranchStmt *jumpTo = dynamic_cast < BranchStmt * > ( *j );
 | 
|---|
| 127 |         assert( jumpTo != 0 );
 | 
|---|
| 128 |         jumpTo->set_target( finalLabel );
 | 
|---|
| 129 |       }
 | 
|---|
| 130 |     }
 | 
|---|
| 131 | 
 | 
|---|
| 132 |     // reverse table
 | 
|---|
| 133 |     std::map < Label, Statement * > *ret = new std::map < Label, Statement * >();
 | 
|---|
| 134 |     for(std::map < Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) 
 | 
|---|
| 135 |       (*ret)[ (*i).second->get_label() ] = (*i).first;
 | 
|---|
| 136 | 
 | 
|---|
| 137 |     return ret;
 | 
|---|
| 138 |   }
 | 
|---|
| 139 | 
 | 
|---|
| 140 | }  // namespace ControlStruct
 | 
|---|