Changes in / [30651b0:1136d96]


Ignore:
Location:
src
Files:
2 added
2 deleted
18 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/GenType.cc

    r30651b0 r1136d96  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 18 23:38:22 2015
    13 // Update Count     : 2
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Tue Jun 02 11:07:25 2015
     13// Update Count     : 3
    1414//
    1515
     
    1818
    1919#include "GenType.h"
    20 #include "CodeGenerator2.h"
     20#include "CodeGenerator.h"
    2121#include "SynTree/Visitor.h"
    2222#include "SynTree/Type.h"
     
    9797                } // if
    9898                if ( dimension != 0 ) {
    99                         CodeGenerator2 cg( os );
     99                        CodeGenerator cg( os );
    100100                        dimension->accept( cg );
    101101                } // if
     
    148148                        } // if
    149149                } else {
    150                         CodeGenerator2 cg( os );
     150                        CodeGenerator cg( os );
    151151                        os << "(" ;
    152152
  • src/CodeGen/Generate.cc

    r30651b0 r1136d96  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 18 23:39:24 2015
    13 // Update Count     : 1
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Tue Jun 02 11:08:44 2015
     13// Update Count     : 4
    1414//
    1515
     
    2222#include "SynTree/Declaration.h"
    2323
    24 #include "CodeGenerator2.h"
     24#include "CodeGenerator.h"
    2525
    2626using namespace std;
     
    2828namespace CodeGen {
    2929        void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics ) {
    30                 CodeGen::CodeGenerator2 cgv( os );
     30                CodeGen::CodeGenerator cgv( os );
    3131
    3232                for ( std::list<Declaration *>::iterator i = translationUnit.begin(); i != translationUnit.end();  i++ ) {
    3333                        if ( LinkageSpec::isGeneratable( (*i)->get_linkage() ) && (doIntrinsics || ! LinkageSpec::isBuiltin( (*i)->get_linkage() ) ) ) {
    3434                                (*i)->accept(cgv);
    35                                 cgv.shift_left();
    3635                                if ( doSemicolon( *i ) ) {
    3736                                        os << ";";
  • src/CodeGen/module.mk

    r30651b0 r1136d96  
    1919
    2020SRC +=  CodeGen/Generate.cc \
    21         CodeGen/CodeGenerator2.cc \
     21        CodeGen/CodeGenerator.cc \
    2222        CodeGen/GenType.cc \
    2323        CodeGen/FixNames.cc \
  • src/Common/utility.h

    r30651b0 r1136d96  
    99// Author           : Richard C. Bilson
    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:34:57 2015
    13 // Update Count     : 3
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Fri May 29 16:17:02 2015
     13// Update Count     : 7
    1414//
    1515
     
    198198}
    199199
     200// it's nice to actually be able to increment iterators by an arbitrary amount
     201template< typename Iterator >
     202Iterator operator+(Iterator i, int inc) {
     203        while ( inc > 0 ) {
     204                ++i;
     205                --inc;
     206        }
     207        return i;
     208}
     209
    200210#endif // _UTILITY_H
    201211
  • src/ControlStruct/ChooseMutator.cc

    r30651b0 r1136d96  
    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:31:39 2015
    13 // Update Count     : 2
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Jun 03 15:30:20 2015
     13// Update Count     : 5
    1414//
    1515
     
    4444                std::list< Statement * > &stmts = caseStmt->get_statements();
    4545
     46                // the difference between switch and choose is that switch has an implicit fallthrough
     47                // to the next case, whereas choose has an implicit break at the end of the current case.
     48                // thus to transform a choose statement into a switch, we only need to insert breaks at the
     49                // end of any case that doesn't already end in a break and that doesn't end in a fallthru
     50
    4651                if ( insideChoose ) {
    4752                        BranchStmt *posBrk;
  • src/ControlStruct/LabelFixer.cc

    r30651b0 r1136d96  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed May 27 16:16:14 2015
    13 // Update Count     : 4
     12// Last Modified On : Tue Jun 02 15:30:32 2015
     13// Update Count     : 93
    1414//
    1515
     
    2323#include "utility.h"
    2424
     25#include <iostream>
     26
    2527namespace ControlStruct {
    26         LabelFixer::Entry::Entry( Statement *to, Statement *from ) : definition ( to ) {
     28        LabelFixer::Entry::Entry( Statement *to, BranchStmt *from ) : definition ( to ) {
    2729                if ( from != 0 )
    2830                        usage.push_back( from );
     
    3133        bool LabelFixer::Entry::insideLoop() {
    3234                return ( dynamic_cast< ForStmt * > ( definition ) ||
    33                                  dynamic_cast< WhileStmt * > ( definition )  );
     35                        dynamic_cast< WhileStmt * > ( definition )  );
    3436        }
    3537
     
    4648        }
    4749
     50        // prune to at most one label definition for each statement
    4851        void LabelFixer::visit( Statement *stmt ) {
    4952                std::list< Label > &labels = stmt->get_labels();
    5053
    5154                if ( ! labels.empty() ) {
     55                        // only remember one label for each statement
    5256                        Label current = setLabelsDef( labels, stmt );
    5357                        labels.clear();
     
    5761
    5862        void LabelFixer::visit( BranchStmt *branchStmt ) {
    59                 visit ( ( Statement * )branchStmt );  // the labels this statement might have
     63                visit ( ( Statement * )branchStmt );
    6064
    61                 Label target;
    62                 if ( (target = branchStmt->get_target()) != "" ) {
     65                // for labeled branches, add an entry to the label table
     66                Label target = branchStmt->get_target();
     67                if ( target != "" ) {
    6368                        setLabelsUsg( target, branchStmt );
    64                 } //else       /* computed goto or normal exit-loop statements */
     69                }
    6570        }
    6671
     72        // sets the definition of the labelTable entry to be the provided
     73        // statement for every label in the list parameter. Happens for every kind of statement
    6774        Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition ) {
    6875                assert( definition != 0 );
    69                 Entry *entry = new Entry( definition );
    70                 bool used = false;
     76                assert( llabel.size() > 0 );
    7177
    72                 for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ )
    73                         if ( labelTable.find( *i ) == labelTable.end() )
    74                                 { used = true; labelTable[ *i ] = entry; } // undefined and unused
    75                         else
    76                                 if ( labelTable[ *i ]->defined() )
    77                                         throw SemanticError( "Duplicate definition of label: " + *i );
    78                                 else
    79                                         labelTable[ *i ]->set_definition( definition );
     78                Entry * e = new Entry( definition );
    8079
    81                 if ( ! used ) delete entry;
     80                for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ ) {
     81                        if ( labelTable.find( *i ) == labelTable.end() ) {
     82                                // all labels on this statement need to use the same entry, so this should only be created once
     83                                // undefined and unused until now, add an entry
     84                                labelTable[ *i ] =  e;
     85                        } else if ( labelTable[ *i ]->defined() ) {
     86                                // defined twice, error
     87                                throw SemanticError( "Duplicate definition of label: " + *i );
     88                        }       else {
     89                                // used previously, but undefined until now -> link with this entry
     90                                Entry * oldEntry = labelTable[ *i ];
     91                                e->add_uses( oldEntry->get_uses() );
     92                                labelTable[ *i ] = e;
     93                        } // if
     94                } // for
    8295
    83                 return labelTable[ llabel.front() ]->get_label();  // this *must* exist
     96                // produce one of the labels attached to this statement to be
     97                // temporarily used as the canonical label
     98                return labelTable[ llabel.front() ]->get_label();
    8499        }
    85100
    86         Label LabelFixer::setLabelsUsg( Label orgValue, Statement *use ) {
     101        // Remember all uses of a label.
     102        void LabelFixer::setLabelsUsg( Label orgValue, BranchStmt *use ) {
    87103                assert( use != 0 );
    88104
    89                 if ( labelTable.find( orgValue ) != labelTable.end() )
    90                         labelTable[ orgValue ]->add_use( use );         // the label has been defined or used before
    91                 else
     105                if ( labelTable.find( orgValue ) != labelTable.end() ) {
     106                        // the label has been defined or used before
     107                        labelTable[ orgValue ]->add_use( use );
     108                } else {
    92109                        labelTable[ orgValue ] = new Entry( 0, use );
    93 
    94                 return labelTable[ orgValue ]->get_label();
     110                }
    95111        }
    96112
     113        // Ultimately builds a table that maps a label to its defining statement.
     114        // In the process,
    97115        std::map<Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError ) {
    98116                std::map< Statement *, Entry * > def_us;
    99117
    100                 for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); i++ ) {
     118                // combine the entries for all labels that target the same location
     119                for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); ++i ) {
    101120                        Entry *e = i->second;
    102121
    103122                        if ( def_us.find ( e->get_definition() ) == def_us.end() ) {
    104123                                def_us[ e->get_definition() ] = e;                             
    105                         } else {
    106                                 if ( e->used() )
    107                                         def_us[ e->get_definition() ]->add_uses( e->get_uses() );
     124                        } else if ( e->used() ) {
     125                                def_us[ e->get_definition() ]->add_uses( e->get_uses() );
    108126                        }
    109127                }
    110128
    111                 // get rid of labelTable
    112                 for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) {
     129                // create a unique label for each target location.
     130                for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); ++i ) {
    113131                        Statement *to = (*i).first;
    114                         std::list< Statement *> &from = (*i).second->get_uses();
    115                         Label finalLabel = generator->newLabel();
    116                         (*i).second->set_label( finalLabel );
     132                        Entry * entry = (*i).second;
     133                        std::list< BranchStmt *> &from = entry->get_uses();
    117134
     135                        // no label definition found
    118136                        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();
     137                                Label undef = from.back()->get_target();
    123138                                throw SemanticError ( "'" + undef + "' label not defined");
    124139                        }
     140
     141                        // generate a new label, and attach it to its defining statement
     142                        // as the only label on that statement
     143                        Label finalLabel = generator->newLabel();
     144                        entry->set_label( finalLabel );
    125145
    126146                        to->get_labels().clear();
    127147                        to->get_labels().push_back( finalLabel );
    128148
    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 );
     149                        // redirect each of the source branch statements to the new target label
     150                        for ( std::list< BranchStmt *>::iterator j = from.begin(); j != from.end(); ++j ) {
     151                                BranchStmt *jump = *j;
     152                                assert( jump != 0 );
     153                                jump->set_target( finalLabel );
    133154                        } // for
    134155                } // for
    135156
    136                 // reverse table
     157                // create a table where each label maps to its defining statement
    137158                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++ )
     159                for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); ++i ) {
    139160                        (*ret)[ (*i).second->get_label() ] = (*i).first;
     161                }
    140162
    141163                return ret;
  • src/ControlStruct/LabelFixer.h

    r30651b0 r1136d96  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue May 26 12:55:10 2015
    13 // Update Count     : 4
     12// Last Modified On : Fri May 29 15:25:55 2015
     13// Update Count     : 11
    1414//
    1515
     
    5555
    5656                Label setLabelsDef( std::list< Label > &, Statement *definition );
    57                 Label setLabelsUsg( Label, Statement *usage = 0 );
     57                void setLabelsUsg( Label, BranchStmt *usage = 0 );
    5858
    5959          private:
    6060                class Entry {
    6161                  public:
    62                         Entry( Statement *to = 0, Statement *from = 0 );
     62                        Entry( Statement *to = 0, BranchStmt *from = 0 );
    6363                        bool used() { return ( usage.empty() ); }
    6464                        bool defined() { return ( definition != 0 ); }
     
    7171                        void set_definition( Statement *def ) { definition = def; }
    7272
    73                         std::list< Statement *> &get_uses() { return usage; }
    74                         void add_use ( Statement *use ) { usage.push_back( use ); }
    75                         void add_uses ( std::list<Statement *> uses ) { usage.insert( usage.end(), uses.begin(), uses.end() ); }
     73                        std::list< BranchStmt *> &get_uses() { return usage; }
     74                        void add_use ( BranchStmt *use ) { usage.push_back( use ); }
     75                        void add_uses ( std::list<BranchStmt *> uses ) { usage.insert( usage.end(), uses.begin(), uses.end() ); }
    7676                  private:
    7777                        Label label; 
    7878                        Statement *definition;
    79                         std::list<Statement *> usage;
     79                        std::list<BranchStmt *> usage;
    8080                };
    8181                 
  • src/ControlStruct/LabelGenerator.cc

    r30651b0 r1136d96  
    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:32:04 2015
    13 // Update Count     : 2
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Jun 03 14:23:26 2015
     13// Update Count     : 9
    1414//
    1515
     
    2929        }
    3030
    31         Label LabelGenerator::newLabel() {
     31        Label LabelGenerator::newLabel(std::string suffix) {
    3232                std::ostrstream os;
    33                 os << "__L" << current++ << "__";// << std::ends;
     33                os << "__L" << current++ << "__" << suffix;
    3434                os.freeze( false );
    3535                std::string ret = std::string (os.str(), os.pcount());
  • src/ControlStruct/LabelGenerator.h

    r30651b0 r1136d96  
    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:33:20 2015
    13 // Update Count     : 3
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Jun 03 14:16:26 2015
     13// Update Count     : 5
    1414//
    1515
     
    1818
    1919#include "SynTree/SynTree.h"
     20#include <string>
    2021
    2122namespace ControlStruct {
     
    2324          public:
    2425                static LabelGenerator *getGenerator();
    25                 Label newLabel();
     26                Label newLabel(std::string suffix = "");
    2627                void reset() { current = 0; }
    2728                void rewind() { current--; }
  • src/ControlStruct/MLEMutator.cc

    r30651b0 r1136d96  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed May 27 16:19:32 2015
    13 // Update Count     : 44
     12// Last Modified On : Wed Jun 03 15:09:27 2015
     13// Update Count     : 170
    1414//
    1515
     
    1919#include "MLEMutator.h"
    2020#include "SynTree/Statement.h"
     21#include "SynTree/Expression.h"
    2122
    2223namespace ControlStruct {
     
    2627        }
    2728
    28         CompoundStmt* MLEMutator::mutate( CompoundStmt *cmpndStmt ) {
    29                 bool labeledBlock = false;
    30                 if ( !(cmpndStmt->get_labels().empty()) ) {
    31                         labeledBlock = true;
    32                         enclosingBlocks.push_back( Entry( cmpndStmt ) );
    33                 } // if
    34 
    35                 std::list< Statement * > &kids = cmpndStmt->get_kids();
     29        // break labels have to come after the statement they break out of,
     30        // so mutate a statement, then if they inform us through the breakLabel field
     31        // tha they need a place to jump to on a break statement, add the break label
     32        // to the body of statements
     33        void MLEMutator::fixBlock( std::list< Statement * > &kids ) {
    3634                for ( std::list< Statement * >::iterator k = kids.begin(); k != kids.end(); k++ ) {
    3735                        *k = (*k)->acceptMutator(*this);
    3836
    3937                        if ( ! get_breakLabel().empty() ) {
    40                                 std::list< Statement * >::iterator next = k; next++;
     38                                std::list< Statement * >::iterator next = k+1;
    4139                                if ( next == kids.end() ) {
    4240                                        std::list<Label> ls; ls.push_back( get_breakLabel() );
     
    4947                        } // if
    5048                } // for
     49        }
     50
     51        CompoundStmt* MLEMutator::mutate( CompoundStmt *cmpndStmt ) {
     52                bool labeledBlock = !(cmpndStmt->get_labels().empty());
     53                if ( labeledBlock ) {
     54                        Label brkLabel = generator->newLabel();
     55                        enclosingBlocks.push_back( Entry( cmpndStmt, brkLabel ) );
     56                } // if
     57
     58                // a child statement may set the break label
     59                // - if they do, attach it to the next statement
     60                std::list< Statement * > &kids = cmpndStmt->get_kids();
     61                fixBlock( kids );
    5162
    5263                if ( labeledBlock ) {
    5364                        assert( ! enclosingBlocks.empty() );
    54                         if ( ! enclosingBlocks.back().get_breakExit().empty() ) {
    55                                 set_breakLabel( enclosingBlocks.back().get_breakExit() );
     65                        if ( ! enclosingBlocks.back().useBreakExit().empty() ) {
     66                                set_breakLabel( enclosingBlocks.back().useBreakExit() );
    5667                        }
    5768                        enclosingBlocks.pop_back();
    5869                } // if
    5970
    60                 //mutateAll( cmpndStmt->get_kids(), *this );
    6171                return cmpndStmt;
    6272        }
    6373
    64         Statement *MLEMutator::mutate( WhileStmt *whileStmt ) {
    65                 enclosingLoops.push_back( Entry( whileStmt ) );
    66                 whileStmt->set_body ( whileStmt->get_body()->acceptMutator( *this ) );
    67 
     74        template< typename LoopClass >
     75        Statement *MLEMutator::handleLoopStmt( LoopClass *loopStmt ) {
     76                // remember this as the most recent enclosing loop, then mutate
     77                // the body of the loop -- this will do SOMETHING with branch statements
     78                // and will recursively do the same to nested loops
     79                Label brkLabel = generator->newLabel("loopBreak");
     80                Label contLabel = generator->newLabel("loopContinue");
     81                enclosingLoops.push_back( Entry( loopStmt, brkLabel, contLabel ) );
     82                loopStmt->set_body ( loopStmt->get_body()->acceptMutator( *this ) );
     83
     84                // sanity check that the enclosing loops have been popped correctly
    6885                Entry &e = enclosingLoops.back();
    69                 assert ( e == whileStmt );
    70                 whileStmt->set_body( mutateLoop( whileStmt->get_body(), e ) );
     86                assert ( e == loopStmt );
     87
     88                // generate labels as needed
     89                loopStmt->set_body( mutateLoop( loopStmt->get_body(), e ) );
    7190                enclosingLoops.pop_back();
    7291
    73                 return whileStmt;
    74         }
    75 
    76         Statement *MLEMutator::mutate( ForStmt *forStmt ) {
    77                 enclosingLoops.push_back( Entry( forStmt ) );
    78                 maybeMutate( forStmt->get_body(), *this );
    79 
    80                 Entry &e = enclosingLoops.back();
    81                 assert ( e == forStmt );
    82                 forStmt->set_body( mutateLoop( forStmt->get_body(), e ) );
    83                 enclosingLoops.pop_back();
    84 
    85                 return forStmt;
     92                return loopStmt;
     93        }
     94
     95        Statement *MLEMutator::mutate( CaseStmt *caseStmt ) {
     96                caseStmt->set_condition( maybeMutate( caseStmt->get_condition(), *this ) );
     97                fixBlock( caseStmt->get_statements() );
     98
     99                return caseStmt;
     100        }
     101
     102        template< typename SwitchClass >
     103        Statement *MLEMutator::handleSwitchStmt( SwitchClass *switchStmt ) {
     104                // generate a label for breaking out of a labeled switch
     105                Label brkLabel = generator->newLabel("switchBreak");
     106                enclosingSwitches.push_back( Entry(switchStmt, brkLabel) );
     107                mutateAll( switchStmt->get_branches(), *this );
     108
     109                Entry &e = enclosingSwitches.back();
     110                assert ( e == switchStmt );
     111
     112                // only generate break label if labeled break is used
     113                if (e.isBreakUsed()) {
     114                        // for the purposes of keeping switch statements uniform (i.e. all statements that are
     115                        // direct children of a switch should be CastStmts), append the exit label + break to the
     116                        // last case statement; create a default case if there are no cases
     117                        std::list< Statement * > &branches = switchStmt->get_branches();
     118                        if ( branches.empty() ) {
     119                                branches.push_back( CaseStmt::makeDefault() );
     120                        }
     121
     122                        if ( CaseStmt * c = dynamic_cast< CaseStmt * >( branches.back() ) ) {
     123                                std::list<Label> temp; temp.push_back( brkLabel );
     124                                c->get_statements().push_back( new BranchStmt( temp, Label(""), BranchStmt::Break ) );
     125                        } else assert(0); // as of this point, all branches of a switch are still CaseStmts
     126                }
     127
     128                assert ( enclosingSwitches.back() == switchStmt );
     129                enclosingSwitches.pop_back();
     130                return switchStmt;
    86131        }
    87132
     
    117162                                        throw SemanticError("The target specified in the exit loop statement does not correspond to an enclosing control structure: " + originalTarget );
    118163
     164                // what about exiting innermost block or switch???
    119165                if ( enclosingLoops.back() == (*check) )
    120166                        return branchStmt;                              // exit the innermost loop (labels unnecessary)
    121167
    122                 Label newLabel;
     168                // branch error checks, get the appropriate label name and create a goto
     169                Label exitLabel;
    123170                switch ( branchStmt->get_type() ) {
    124171                  case BranchStmt::Break:
    125                                 if ( check->get_breakExit() != "" ) {
    126                                         newLabel = check->get_breakExit();
    127                                 } else {
    128                                         newLabel = generator->newLabel();
    129                                         check->set_breakExit( newLabel );
    130                                 } // if
     172                                assert( check->useBreakExit() != "");
     173                                exitLabel = check->useBreakExit();
    131174                                break;
    132175                  case BranchStmt::Continue:
    133                                 if ( check->get_contExit() != "" ) {
    134                                         newLabel = check->get_contExit();
    135                                 } else {
    136                                         newLabel = generator->newLabel();
    137                                         check->set_contExit( newLabel );
    138                                 } // if
     176                                assert( check->useContExit() != "");
     177                                exitLabel = check->useContExit();
    139178                                break;
    140179                  default:
    141                                 return 0;                                       // shouldn't be here
     180                                assert(0);                                      // shouldn't be here
    142181                } // switch
    143182
    144                 return new BranchStmt( std::list<Label>(), newLabel, BranchStmt::Goto );
    145         }
    146 
    147         template< typename SwitchClass >
    148         Statement *handleSwitchStmt( SwitchClass *switchStmt, MLEMutator &mutator ) {
    149                 // set up some aliases so that the rest of the code isn't messy
    150                 typedef MLEMutator::Entry Entry;
    151                 LabelGenerator *generator = mutator.generator;
    152                 std::list< Entry > &enclosingSwitches = mutator.enclosingSwitches;
    153 
    154                 Label brkLabel = generator->newLabel();
    155                 enclosingSwitches.push_back( Entry(switchStmt, "", brkLabel) );
    156                 mutateAll( switchStmt->get_branches(), mutator ); {
    157                         // check if this is necessary (if there is a break to this point, otherwise do not generate
    158                         std::list<Label> temp; temp.push_back( brkLabel );
    159                         switchStmt->get_branches().push_back( new BranchStmt( temp, Label(""), BranchStmt::Break ) );
    160                 }
    161                 assert ( enclosingSwitches.back() == switchStmt );
    162                 enclosingSwitches.pop_back();
    163                 return switchStmt;
    164         }
    165 
    166         Statement *MLEMutator::mutate( SwitchStmt *switchStmt ) {
    167                 return handleSwitchStmt( switchStmt, *this );
    168         }
    169 
    170         Statement *MLEMutator::mutate( ChooseStmt *switchStmt ) {
    171                 return handleSwitchStmt( switchStmt, *this );           
     183                return new BranchStmt( std::list<Label>(), exitLabel, BranchStmt::Goto );
    172184        }
    173185
    174186        Statement *MLEMutator::mutateLoop( Statement *bodyLoop, Entry &e ) {
     187                // ensure loop body is a block
    175188                CompoundStmt *newBody;
    176189                if ( ! (newBody = dynamic_cast<CompoundStmt *>( bodyLoop )) ) {
     
    179192                } // if
    180193
    181                 Label endLabel = e.get_contExit();
    182 
    183                 if ( e.get_breakExit() != "" ) {
    184                         if ( endLabel == "" ) endLabel = generator->newLabel();
    185                         // check for whether this label is used or not, so as to not generate extraneous gotos
    186                         if (e.breakExitUsed)
    187                                 newBody->get_kids().push_back( new BranchStmt( std::list< Label >(), endLabel, BranchStmt::Goto ) );
    188                         // xxx
    189                         //std::list< Label > ls; ls.push_back( e.get_breakExit() );
    190                         set_breakLabel( e.get_breakExit() );
    191                         //newBody->get_kids().push_back( new BranchStmt( ls, "", BranchStmt::Break ) );
    192                 } // if
    193 
    194                 if ( e.get_breakExit() != "" || e.get_contExit() != "" ) {
    195                         if (dynamic_cast< NullStmt *>( newBody->get_kids().back() ))
    196                                 newBody->get_kids().back()->get_labels().push_back( endLabel );
    197                         else {
    198                                 std::list < Label > ls; ls.push_back( endLabel );
    199                                 newBody->get_kids().push_back( new NullStmt( ls ) );
    200                         } // if
    201                 } // if
     194                // only generate these when needed
     195
     196                if ( e.isContUsed() ) {
     197                        // continue label goes in the body as the last statement
     198                        std::list< Label > labels; labels.push_back( e.useContExit() );
     199                        newBody->get_kids().push_back( new NullStmt( labels ) );                       
     200                }
     201
     202                if ( e.isBreakUsed() ) {
     203                        // break label goes after the loop -- it'll get set by the
     204                        // outer mutator if we do this
     205                        set_breakLabel( e.useBreakExit() );                     
     206                }
    202207
    203208                return newBody;
    204209        }
    205210
    206         //*** Entry's methods
    207         void MLEMutator::Entry::set_contExit( Label l ) {
    208                 assert ( contExit == "" || contExit == l );
    209                 contExit = l;
    210         }
    211 
    212         void MLEMutator::Entry::set_breakExit( Label l ) {
    213                 assert ( breakExit == "" || breakExit == l );
    214                 breakExit = l;
    215         }
     211        Statement *MLEMutator::mutate( WhileStmt *whileStmt ) {
     212                return handleLoopStmt( whileStmt );
     213        }
     214
     215        Statement *MLEMutator::mutate( ForStmt *forStmt ) {
     216                return handleLoopStmt( forStmt );
     217        }
     218
     219        Statement *MLEMutator::mutate( SwitchStmt *switchStmt ) {
     220                return handleSwitchStmt( switchStmt );
     221        }
     222
     223        Statement *MLEMutator::mutate( ChooseStmt *switchStmt ) {
     224                return handleSwitchStmt( switchStmt );         
     225        }
     226
    216227} // namespace ControlStruct
    217228
  • src/ControlStruct/MLEMutator.h

    r30651b0 r1136d96  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue May 26 15:04:21 2015
    13 // Update Count     : 7
     12// Last Modified On : Wed Jun 03 15:06:36 2015
     13// Update Count     : 25
    1414//
    1515
     
    3838                Statement *mutate( BranchStmt *branchStmt ) throw ( SemanticError );
    3939
     40                Statement *mutate( CaseStmt *caseStmt );
    4041                Statement *mutate( SwitchStmt *switchStmt );
    4142                Statement *mutate( ChooseStmt *switchStmt );
     
    4849                class Entry {
    4950                  public:
    50                         explicit Entry( Statement *_loop = 0, Label _contExit = Label(""), Label _breakExit = Label("") ) :
    51                                 loop( _loop ), contExit( _contExit ), breakExit( _breakExit ), contExitUsed( false ), breakExitUsed( false ) {}
     51                        explicit Entry( Statement *_loop, Label _breakExit, Label _contExit = Label("") ) :
     52                                loop( _loop ), breakExit( _breakExit ), contExit( _contExit ), breakUsed(false), contUsed(false) {}
    5253
    5354                        bool operator==( const Statement *stmt ) { return ( loop == stmt ); }
     
    5859                        Statement *get_loop() const { return loop; }
    5960
    60                         Label get_contExit() const { return contExit; }
    61                         void set_contExit( Label );
     61                        Label useContExit() { contUsed = true; return contExit; }
     62                        Label useBreakExit() { breakUsed = true; return breakExit; }
    6263
    63                         Label get_breakExit() const { return breakExit; }
    64                         void set_breakExit( Label );
     64                        bool isContUsed() const { return contUsed; }
     65                        bool isBreakUsed() const { return breakUsed; }
    6566
    6667                  private:
    6768                        Statement *loop;
    68                         Label contExit, breakExit;
    69                   public: // hack, provide proper [sg]etters
    70                         bool contExitUsed, breakExitUsed;
     69                        Label breakExit, contExit;
     70                        bool breakUsed, contUsed;
    7171                };
    7272
     
    7676                LabelGenerator *generator;
    7777
     78                template< typename LoopClass >
     79                Statement *handleLoopStmt( LoopClass *loopStmt );
     80
    7881                template< typename SwitchClass >
    79                 friend Statement *handleSwitchStmt( SwitchClass *switchStmt, MLEMutator &mutator );
     82                Statement *handleSwitchStmt( SwitchClass *switchStmt );
     83
     84                void fixBlock( std::list< Statement * > &kids );
    8085        };
    8186} // namespace ControlStruct
  • src/ControlStruct/Mutate.cc

    r30651b0 r1136d96  
    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:32:52 2015
    13 // Update Count     : 2
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Jun 03 23:08:43 2015
     13// Update Count     : 5
    1414//
    1515
     
    3737        void mutate( std::list< Declaration * > translationUnit ) {
    3838                // ForExprMutator formut;
     39
     40                // normalizes label definitions and generates multi-level
     41                // exit labels
    3942                LabelFixer lfix;
     43
     44                // transform choose statements into switch statements
    4045                ChooseMutator chmut;
     46
     47                // expand case ranges and turn fallthru into a null statement
    4148                CaseRangeMutator ranges;  // has to run after ChooseMutator
     49
    4250                //ExceptMutator exc;
    4351                // LabelTypeChecker lbl;
  • src/Makefile.in

    r30651b0 r1136d96  
    9898am__objects_1 = cfa_cpp-main.$(OBJEXT) cfa_cpp-MakeLibCfa.$(OBJEXT) \
    9999        CodeGen/cfa_cpp-Generate.$(OBJEXT) \
    100         CodeGen/cfa_cpp-CodeGenerator2.$(OBJEXT) \
     100        CodeGen/cfa_cpp-CodeGenerator.$(OBJEXT) \
    101101        CodeGen/cfa_cpp-GenType.$(OBJEXT) \
    102102        CodeGen/cfa_cpp-FixNames.$(OBJEXT) \
     
    335335AUTOMAKE_OPTIONS = subdir-objects
    336336SRC = main.cc MakeLibCfa.cc CodeGen/Generate.cc \
    337         CodeGen/CodeGenerator2.cc CodeGen/GenType.cc \
     337        CodeGen/CodeGenerator.cc CodeGen/GenType.cc \
    338338        CodeGen/FixNames.cc CodeGen/OperatorTable.cc \
    339339        Common/SemanticError.cc Common/UniqueName.cc \
     
    475475CodeGen/cfa_cpp-Generate.$(OBJEXT): CodeGen/$(am__dirstamp) \
    476476        CodeGen/$(DEPDIR)/$(am__dirstamp)
    477 CodeGen/cfa_cpp-CodeGenerator2.$(OBJEXT): CodeGen/$(am__dirstamp) \
     477CodeGen/cfa_cpp-CodeGenerator.$(OBJEXT): CodeGen/$(am__dirstamp) \
    478478        CodeGen/$(DEPDIR)/$(am__dirstamp)
    479479CodeGen/cfa_cpp-GenType.$(OBJEXT): CodeGen/$(am__dirstamp) \
     
    760760mostlyclean-compile:
    761761        -rm -f *.$(OBJEXT)
    762         -rm -f CodeGen/cfa_cpp-CodeGenerator2.$(OBJEXT)
     762        -rm -f CodeGen/cfa_cpp-CodeGenerator.$(OBJEXT)
    763763        -rm -f CodeGen/cfa_cpp-FixNames.$(OBJEXT)
    764764        -rm -f CodeGen/cfa_cpp-GenType.$(OBJEXT)
     
    868868@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cfa_cpp-MakeLibCfa.Po@am__quote@
    869869@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cfa_cpp-main.Po@am__quote@
    870 @AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/cfa_cpp-CodeGenerator2.Po@am__quote@
     870@AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/cfa_cpp-CodeGenerator.Po@am__quote@
    871871@AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/cfa_cpp-FixNames.Po@am__quote@
    872872@AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/cfa_cpp-GenType.Po@am__quote@
     
    10291029@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/cfa_cpp-Generate.obj `if test -f 'CodeGen/Generate.cc'; then $(CYGPATH_W) 'CodeGen/Generate.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/Generate.cc'; fi`
    10301030
    1031 CodeGen/cfa_cpp-CodeGenerator2.o: CodeGen/CodeGenerator2.cc
    1032 @am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/cfa_cpp-CodeGenerator2.o -MD -MP -MF CodeGen/$(DEPDIR)/cfa_cpp-CodeGenerator2.Tpo -c -o CodeGen/cfa_cpp-CodeGenerator2.o `test -f 'CodeGen/CodeGenerator2.cc' || echo '$(srcdir)/'`CodeGen/CodeGenerator2.cc
    1033 @am__fastdepCXX_TRUE@   $(am__mv) CodeGen/$(DEPDIR)/cfa_cpp-CodeGenerator2.Tpo CodeGen/$(DEPDIR)/cfa_cpp-CodeGenerator2.Po
    1034 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='CodeGen/CodeGenerator2.cc' object='CodeGen/cfa_cpp-CodeGenerator2.o' libtool=no @AMDEPBACKSLASH@
    1035 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1036 @am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/cfa_cpp-CodeGenerator2.o `test -f 'CodeGen/CodeGenerator2.cc' || echo '$(srcdir)/'`CodeGen/CodeGenerator2.cc
    1037 
    1038 CodeGen/cfa_cpp-CodeGenerator2.obj: CodeGen/CodeGenerator2.cc
    1039 @am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/cfa_cpp-CodeGenerator2.obj -MD -MP -MF CodeGen/$(DEPDIR)/cfa_cpp-CodeGenerator2.Tpo -c -o CodeGen/cfa_cpp-CodeGenerator2.obj `if test -f 'CodeGen/CodeGenerator2.cc'; then $(CYGPATH_W) 'CodeGen/CodeGenerator2.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/CodeGenerator2.cc'; fi`
    1040 @am__fastdepCXX_TRUE@   $(am__mv) CodeGen/$(DEPDIR)/cfa_cpp-CodeGenerator2.Tpo CodeGen/$(DEPDIR)/cfa_cpp-CodeGenerator2.Po
    1041 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='CodeGen/CodeGenerator2.cc' object='CodeGen/cfa_cpp-CodeGenerator2.obj' libtool=no @AMDEPBACKSLASH@
    1042 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1043 @am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/cfa_cpp-CodeGenerator2.obj `if test -f 'CodeGen/CodeGenerator2.cc'; then $(CYGPATH_W) 'CodeGen/CodeGenerator2.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/CodeGenerator2.cc'; fi`
     1031CodeGen/cfa_cpp-CodeGenerator.o: CodeGen/CodeGenerator.cc
     1032@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/cfa_cpp-CodeGenerator.o -MD -MP -MF CodeGen/$(DEPDIR)/cfa_cpp-CodeGenerator.Tpo -c -o CodeGen/cfa_cpp-CodeGenerator.o `test -f 'CodeGen/CodeGenerator.cc' || echo '$(srcdir)/'`CodeGen/CodeGenerator.cc
     1033@am__fastdepCXX_TRUE@   $(am__mv) CodeGen/$(DEPDIR)/cfa_cpp-CodeGenerator.Tpo CodeGen/$(DEPDIR)/cfa_cpp-CodeGenerator.Po
     1034@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='CodeGen/CodeGenerator.cc' object='CodeGen/cfa_cpp-CodeGenerator.o' libtool=no @AMDEPBACKSLASH@
     1035@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1036@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/cfa_cpp-CodeGenerator.o `test -f 'CodeGen/CodeGenerator.cc' || echo '$(srcdir)/'`CodeGen/CodeGenerator.cc
     1037
     1038CodeGen/cfa_cpp-CodeGenerator.obj: CodeGen/CodeGenerator.cc
     1039@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/cfa_cpp-CodeGenerator.obj -MD -MP -MF CodeGen/$(DEPDIR)/cfa_cpp-CodeGenerator.Tpo -c -o CodeGen/cfa_cpp-CodeGenerator.obj `if test -f 'CodeGen/CodeGenerator.cc'; then $(CYGPATH_W) 'CodeGen/CodeGenerator.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/CodeGenerator.cc'; fi`
     1040@am__fastdepCXX_TRUE@   $(am__mv) CodeGen/$(DEPDIR)/cfa_cpp-CodeGenerator.Tpo CodeGen/$(DEPDIR)/cfa_cpp-CodeGenerator.Po
     1041@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='CodeGen/CodeGenerator.cc' object='CodeGen/cfa_cpp-CodeGenerator.obj' libtool=no @AMDEPBACKSLASH@
     1042@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1043@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/cfa_cpp-CodeGenerator.obj `if test -f 'CodeGen/CodeGenerator.cc'; then $(CYGPATH_W) 'CodeGen/CodeGenerator.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/CodeGenerator.cc'; fi`
    10441044
    10451045CodeGen/cfa_cpp-GenType.o: CodeGen/GenType.cc
  • src/SynTree/Mutator.h

    r30651b0 r1136d96  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 18 10:12:28 2015
    13 // Update Count     : 3
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Fri May 29 16:34:08 2015
     13// Update Count     : 4
    1414//
    1515#include <cassert>
     
    104104                assert( newnode );
    105105                return newnode;
    106 ///         return tree->acceptMutator( mutator );
    107106        } else {
    108107                return 0;
  • src/SynTree/ObjectDecl.cc

    r30651b0 r1136d96  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 18 10:14:18 2015
    13 // Update Count     : 2
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu May 28 14:10:02 2015
     13// Update Count     : 8
    1414//
    1515
     
    6565
    6666void ObjectDecl::printShort( std::ostream &os, int indent ) const {
     67#if 0
     68        if ( get_mangleName() != "") {
     69                os << get_mangleName() << ": a ";
     70        } else
     71#endif
    6772        if ( get_name() != "" ) {
    6873                os << get_name() << ": a ";
  • src/SynTree/Statement.cc

    r30651b0 r1136d96  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed May 27 15:41:13 2015
    13 // Update Count     : 8
     12// Last Modified On : Tue Jun 02 13:07:09 2015
     13// Update Count     : 14
    1414//
    1515
     
    124124CaseStmt::~CaseStmt() {
    125125        delete condition;
     126}
     127
     128CaseStmt * CaseStmt::makeDefault( std::list<Label> labels, std::list<Statement *> branches ) {
     129        return new CaseStmt( labels, 0, branches, true );
    126130}
    127131
  • src/SynTree/Statement.h

    r30651b0 r1136d96  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed May 27 15:40:43 2015
    13 // Update Count     : 5
     12// Last Modified On : Tue Jun 02 13:07:25 2015
     13// Update Count     : 13
    1414//
    1515
     
    149149              std::list<Statement *> &stmts, bool isdef = false ) throw(SemanticError);
    150150        virtual ~CaseStmt();
     151
     152        static CaseStmt * makeDefault( std::list<Label> labels = std::list<Label>(),
     153                std::list<Statement *> stmts = std::list<Statement *>() );
    151154
    152155        bool isDefault() { return _isDefault; }
  • src/examples/control_structures.c

    r30651b0 r1136d96  
    1818                L2: switch ( 3_333_333 ) {                                              // underscores in constant
    1919                        case 1,2,3:                                                                     // 4~8, 4...8 not working
     20                        case 4~8:
    2021                                L3: for ( ;; ) {
    2122                                        L4: for ( ;; ) {
Note: See TracChangeset for help on using the changeset viewer.