Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    r698ec72 r33a25f9  
    105105
    106106                /// collects constructed object decls - used as a base class
    107                 struct ObjDeclCollector : public WithGuards, public WithShortCircuiting {
     107                class ObjDeclCollector : public AddStmtVisitor {
     108                  public:
     109                        typedef AddStmtVisitor Parent;
     110                        using Parent::visit;
    108111                        // use ordered data structure to maintain ordering for set_difference and for consistent error messages
    109112                        typedef std::list< ObjectDecl * > ObjectSet;
    110                         void previsit( CompoundStmt *compoundStmt );
    111                         void previsit( DeclStmt *stmt );
     113                        virtual void visit( CompoundStmt *compoundStmt ) override;
     114                        virtual void visit( DeclStmt *stmt ) override;
    112115
    113116                        // don't go into other functions
    114                         void previsit( FunctionDecl * ) { visit_children = false; }
     117                        virtual void visit( FunctionDecl * ) override {}
    115118
    116119                  protected:
     
    136139                }
    137140
    138                 struct LabelFinder final : public ObjDeclCollector {
     141                class LabelFinder final : public ObjDeclCollector {
     142                  public:
     143                        typedef ObjDeclCollector Parent;
    139144                        typedef std::map< Label, ObjectSet > LabelMap;
    140145                        // map of Label -> live variables at that label
    141146                        LabelMap vars;
    142147
    143                         typedef ObjDeclCollector Parent;
    144                         using Parent::previsit;
    145                         void previsit( Statement * stmt );
    146 
    147                         void previsit( CompoundStmt *compoundStmt );
    148                         void previsit( DeclStmt *stmt );
     148                        void handleStmt( Statement * stmt );
     149
     150                        // xxx - This needs to be done better.
     151                        // allow some generalization among different kinds of nodes with with similar parentage (e.g. all
     152                        // expressions, all statements, etc.)  important to have this to provide a single entry point so that as new
     153                        // subclasses are added, there is only one place that the code has to be updated, rather than ensure that
     154                        // every specialized class knows about every new kind of statement that might be added.
     155                        using Parent::visit;
     156                        virtual void visit( CompoundStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
     157                        virtual void visit( ExprStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
     158                        virtual void visit( AsmStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
     159                        virtual void visit( IfStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
     160                        virtual void visit( WhileStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
     161                        virtual void visit( ForStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
     162                        virtual void visit( SwitchStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
     163                        virtual void visit( CaseStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
     164                        virtual void visit( BranchStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
     165                        virtual void visit( ReturnStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
     166                        virtual void visit( TryStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
     167                        virtual void visit( CatchStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
     168                        virtual void visit( FinallyStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
     169                        virtual void visit( NullStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
     170                        virtual void visit( DeclStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
     171                        virtual void visit( ImplicitCtorDtorStmt *stmt ) override { handleStmt( stmt ); return Parent::visit( stmt ); }
    149172                };
    150173
    151                 struct InsertDtors final : public ObjDeclCollector, public WithStmtsToAdd {
     174                class InsertDtors final : public ObjDeclCollector {
     175                public:
    152176                        /// insert destructor calls at the appropriate places.  must happen before CtorInit nodes are removed
    153177                        /// (currently by FixInit)
    154178                        static void insert( std::list< Declaration * > & translationUnit );
    155179
     180                        typedef ObjDeclCollector Parent;
    156181                        typedef std::list< ObjectDecl * > OrderedDecls;
    157182                        typedef std::list< OrderedDecls > OrderedDeclsStack;
    158183
    159                         InsertDtors( PassVisitor<LabelFinder> & finder ) : finder( finder ), labelVars( finder.pass.vars ) {}
    160 
    161                         typedef ObjDeclCollector Parent;
    162                         using Parent::previsit;
    163 
    164                         void previsit( ObjectDecl * objDecl );
    165                         void previsit( FunctionDecl * funcDecl );
    166 
    167                         void previsit( CompoundStmt * compoundStmt );
    168                         void postvisit( CompoundStmt * compoundStmt );
    169                         void previsit( ReturnStmt * returnStmt );
    170                         void previsit( BranchStmt * stmt );
     184                        InsertDtors( LabelFinder & finder ) : finder( finder ), labelVars( finder.vars ) {}
     185
     186                        using Parent::visit;
     187
     188                        virtual void visit( ObjectDecl * objDecl ) override;
     189                        virtual void visit( FunctionDecl * funcDecl ) override;
     190
     191                        virtual void visit( CompoundStmt * compoundStmt ) override;
     192                        virtual void visit( ReturnStmt * returnStmt ) override;
     193                        virtual void visit( BranchStmt * stmt ) override;
    171194                private:
    172195                        void handleGoto( BranchStmt * stmt );
    173196
    174                         PassVisitor<LabelFinder> & finder;
     197                        LabelFinder & finder;
    175198                        LabelFinder::LabelMap & labelVars;
    176199                        OrderedDeclsStack reverseDeclOrder;
     
    310333
    311334                void InsertDtors::insert( std::list< Declaration * > & translationUnit ) {
    312                         PassVisitor<LabelFinder> finder;
    313                         PassVisitor<InsertDtors> inserter( finder );
     335                        LabelFinder finder;
     336                        InsertDtors inserter( finder );
    314337                        acceptAll( translationUnit, inserter );
    315338                }
     
    769792                }
    770793
    771                 void ObjDeclCollector::previsit( CompoundStmt * ) {
    772                         GuardValue( curVars );
    773                 }
    774 
    775                 void ObjDeclCollector::previsit( DeclStmt * stmt ) {
     794                void ObjDeclCollector::visit( CompoundStmt * compoundStmt ) {
     795                        ObjectSet prevVars = curVars;
     796                        Parent::visit( compoundStmt );
     797                        curVars = prevVars;
     798                }
     799
     800                void ObjDeclCollector::visit( DeclStmt * stmt ) {
    776801                        // keep track of all variables currently in scope
    777802                        if ( ObjectDecl * objDecl = dynamic_cast< ObjectDecl * > ( stmt->get_decl() ) ) {
    778803                                curVars.push_back( objDecl );
    779804                        } // if
    780                 }
    781 
    782                 void LabelFinder::previsit( Statement * stmt ) {
     805                        Parent::visit( stmt );
     806                }
     807
     808                void LabelFinder::handleStmt( Statement * stmt ) {
    783809                        // for each label, remember the variables in scope at that label.
    784810                        for ( Label l : stmt->get_labels() ) {
     
    786812                        } // for
    787813                }
    788 
    789                 void LabelFinder::previsit( CompoundStmt * stmt ) {
    790                         previsit( (Statement *)stmt );
    791                         Parent::previsit( stmt );
    792                 }
    793 
    794                 void LabelFinder::previsit( DeclStmt * stmt ) {
    795                         previsit( (Statement *)stmt );
    796                         Parent::previsit( stmt );
    797                 }
    798 
    799814
    800815                template<typename Iterator, typename OutputIterator>
     
    812827                }
    813828
    814                 void InsertDtors::previsit( ObjectDecl * objDecl ) {
     829                void InsertDtors::visit( ObjectDecl * objDecl ) {
    815830                        // remember non-static destructed objects so that their destructors can be inserted later
    816831                        if ( ! objDecl->get_storageClasses().is_static ) {
     
    826841                                } // if
    827842                        } // if
    828                 }
    829 
    830                 void InsertDtors::previsit( FunctionDecl * funcDecl ) {
     843                        Parent::visit( objDecl );
     844                }
     845
     846                template< typename Visitor >
     847                void handleFuncDecl( FunctionDecl * funcDecl, Visitor & visitor ) {
     848                        maybeAccept( funcDecl->get_functionType(), visitor );
     849                        maybeAccept( funcDecl->get_statements(), visitor );
     850                }
     851
     852                void InsertDtors::visit( FunctionDecl * funcDecl ) {
    831853                        // each function needs to have its own set of labels
    832                         GuardValue( labelVars );
     854                        ValueGuard< LabelFinder::LabelMap > oldLabels( labelVars );
    833855                        labelVars.clear();
    834                         maybeAccept( funcDecl->type, finder );
    835                         maybeAccept( funcDecl->statements, finder );
    836 
    837                         // all labels for this function have been collected, insert destructors as appropriate via implicit recursion.
    838                 }
    839 
    840                 void InsertDtors::previsit( CompoundStmt * compoundStmt ) {
     856                        handleFuncDecl( funcDecl, finder );
     857
     858                        // all labels for this function have been collected, insert destructors as appropriate.
     859                        // can't be Parent::mutate, because ObjDeclCollector bottoms out on FunctionDecl
     860                        handleFuncDecl( funcDecl, *this );
     861                }
     862
     863                void InsertDtors::visit( CompoundStmt * compoundStmt ) {
    841864                        // visit statements - this will also populate reverseDeclOrder list.  don't want to dump all destructors
    842865                        // when block is left, just the destructors associated with variables defined in this block, so push a new
    843866                        // list to the top of the stack so that we can differentiate scopes
    844867                        reverseDeclOrder.push_front( OrderedDecls() );
    845                         Parent::previsit( compoundStmt );
    846                 }
    847 
    848                 void InsertDtors::postvisit( CompoundStmt * compoundStmt ) {
     868                        Parent::visit( compoundStmt );
     869
    849870                        // add destructors for the current scope that we're exiting, unless the last statement is a return, which
    850871                        // causes unreachable code warnings
     
    856877                }
    857878
    858                 void InsertDtors::previsit( ReturnStmt * ) {
     879                void InsertDtors::visit( __attribute((unused)) ReturnStmt * returnStmt ) {
    859880                        // return exits all scopes, so dump destructors for all scopes
    860881                        for ( OrderedDecls & od : reverseDeclOrder ) {
    861                                 insertDtors( od.begin(), od.end(), back_inserter( stmtsToAddBefore ) );
     882                                insertDtors( od.begin(), od.end(), back_inserter( stmtsToAdd ) );
    862883                        } // for
    863884                }
     
    907928                                        copy_if( rdo.begin(), rdo.end(), back_inserter( ordered ), [&]( ObjectDecl * objDecl ) { return needsDestructor.count( objDecl ); } );
    908929                                } // for
    909                                 insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAddBefore ) );
     930                                insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAdd ) );
    910931                        } // if
    911932                }
    912933
    913                 void InsertDtors::previsit( BranchStmt * stmt ) {
     934                void InsertDtors::visit( BranchStmt * stmt ) {
    914935                        switch( stmt->get_type() ) {
    915936                          case BranchStmt::Continue:
Note: See TracChangeset for help on using the changeset viewer.