Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/MLEMutator.h

    rd180746 r720a007  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:19:59 2017
    13 // Update Count     : 35
     12// Last Modified On : Thu Mar  8 16:42:32 2018
     13// Update Count     : 41
    1414//
    1515
     
    1919#include <map>                     // for map
    2020#include <string>                  // for string
     21#include <set>                     // for unordered_set
    2122
     23#include "Common/PassVisitor.h"
    2224#include "Common/SemanticError.h"  // for SemanticError
    2325#include "SynTree/Label.h"         // for Label
     
    2628
    2729namespace ControlStruct {
    28 class LabelGenerator;
     30        class LabelGenerator;
    2931
    30         class MLEMutator : public Mutator {
     32        class MLEMutator : public WithVisitorRef<MLEMutator>, public WithShortCircuiting, public WithGuards {
     33          public:
    3134                class Entry;
    32 
    33                 typedef Mutator Parent;
    34           public:
    3535                MLEMutator( std::map<Label, Statement *> *t, LabelGenerator *gen = 0 ) : targetTable( t ), breakLabel(std::string("")), generator( gen ) {}
    3636                ~MLEMutator();
    3737
    38                 virtual CompoundStmt *mutate( CompoundStmt *cmpndStmt ) override;
    39                 virtual Statement *mutate( WhileStmt *whileStmt ) override;
    40                 virtual Statement *mutate( ForStmt *forStmt ) override;
    41                 virtual Statement *mutate( BranchStmt *branchStmt ) throw ( SemanticError ) override;
    42                 virtual Statement *mutate( CaseStmt *caseStmt ) override;
    43                 virtual Statement *mutate( IfStmt *ifStmt ) override;
    44                 virtual Statement *mutate( SwitchStmt *switchStmt ) override;
     38                void premutate( CompoundStmt *cmpndStmt );
     39                Statement * postmutate( BranchStmt *branchStmt ) throw ( SemanticErrorException );
     40                void premutate( WhileStmt *whileStmt );
     41                Statement * postmutate( WhileStmt *whileStmt );
     42                void premutate( ForStmt *forStmt );
     43                Statement * postmutate( ForStmt *forStmt );
     44                void premutate( CaseStmt *caseStmt );
     45                void premutate( IfStmt *ifStmt );
     46                Statement * postmutate( IfStmt *ifStmt );
     47                void premutate( SwitchStmt *switchStmt );
     48                Statement * postmutate( SwitchStmt *switchStmt );
    4549
    4650                Statement *mutateLoop( Statement *bodyLoop, Entry &e );
     
    4852                Label &get_breakLabel() { return breakLabel; }
    4953                void set_breakLabel( Label newValue ) { breakLabel = newValue; }
    50           private:
     54
    5155                class Entry {
    5256                  public:
    53                         explicit Entry( Statement *_loop, Label _breakExit, Label _contExit = Label("") ) :
    54                                 loop( _loop ), breakExit( _breakExit ), contExit( _contExit ), breakUsed(false), contUsed(false) {}
     57                        // specialized constructors for each combination of statement with labelled break/continue/fallthrough that is valid to cleanup the use cases
     58                        explicit Entry( ForStmt *stmt, Label breakExit, Label contExit ) :
     59                                stmt( stmt ), breakExit( breakExit ), contExit( contExit ) {}
    5560
    56                         bool operator==( const Statement *stmt ) { return ( loop == stmt ); }
    57                         bool operator!=( const Statement *stmt ) { return ( loop != stmt ); }
     61                        explicit Entry( WhileStmt *stmt, Label breakExit, Label contExit ) :
     62                                stmt( stmt ), breakExit( breakExit ), contExit( contExit ) {}
    5863
    59                         bool operator==( const Entry &other ) { return ( loop == other.get_controlStructure() ); }
     64                        explicit Entry( CompoundStmt *stmt, Label breakExit ) :
     65                                stmt( stmt ), breakExit( breakExit ) {}
    6066
    61                         Statement *get_controlStructure() const { return loop; }
     67                        explicit Entry( IfStmt *stmt, Label breakExit ) :
     68                                stmt( stmt ), breakExit( breakExit ) {}
     69
     70                        explicit Entry( CaseStmt *stmt, Label fallExit ) :
     71                                stmt( stmt ), fallExit( fallExit ) {}
     72
     73                        explicit Entry( SwitchStmt *stmt, Label breakExit, Label fallDefaultExit ) :
     74                                stmt( stmt ), breakExit( breakExit ), fallDefaultExit( fallDefaultExit ) {}
     75
     76                        bool operator==( const Statement *other ) { return stmt == other; }
     77                        bool operator!=( const Statement *other ) { return stmt != other; }
     78
     79                        bool operator==( const Entry &other ) { return stmt == other.get_controlStructure(); }
     80
     81                        Statement *get_controlStructure() const { return stmt; }
    6282
    6383                        Label useContExit() { contUsed = true; return contExit; }
    6484                        Label useBreakExit() { breakUsed = true; return breakExit; }
     85                        Label useFallExit() { fallUsed = true; return fallExit; }
     86                        Label useFallDefaultExit() { fallDefaultUsed = true; return fallDefaultExit; }
    6587
    6688                        bool isContUsed() const { return contUsed; }
    6789                        bool isBreakUsed() const { return breakUsed; }
     90                        bool isFallUsed() const { return fallUsed; }
     91                        bool isFallDefaultUsed() const { return fallDefaultUsed; }
     92                        void seenDefault() { fallDefaultValid = false; }
     93                        bool isFallDefaultValid() const { return fallDefaultValid; }
    6894                  private:
    69                         Statement *loop;
    70                         Label breakExit, contExit;
    71                         bool breakUsed, contUsed;
     95                        Statement *stmt;
     96                        Label breakExit, contExit, fallExit, fallDefaultExit;
     97                        bool breakUsed = false, contUsed = false, fallUsed = false, fallDefaultUsed = false;
     98                        bool fallDefaultValid = true;
    7299                };
    73100
     101          private:
    74102                std::map< Label, Statement * > *targetTable;
     103                std::set< Label > fallthroughLabels;
    75104                std::list< Entry > enclosingControlStructures;
    76105                Label breakLabel;
     
    78107
    79108                template< typename LoopClass >
    80                 Statement *handleLoopStmt( LoopClass *loopStmt );
     109                void prehandleLoopStmt( LoopClass * loopStmt );
    81110
    82                 template< typename IfClass >
    83                 Statement *handleIfStmt( IfClass *switchStmt );
     111                template< typename LoopClass >
     112                Statement * posthandleLoopStmt( LoopClass * loopStmt );
    84113
    85                 template< typename SwitchClass >
    86                 Statement *handleSwitchStmt( SwitchClass *switchStmt );
    87 
    88                 void fixBlock( std::list< Statement * > &kids );
     114                void fixBlock( std::list< Statement * > &kids, bool caseClause = false );
    89115        };
    90116} // namespace ControlStruct
Note: See TracChangeset for help on using the changeset viewer.