Changeset 698ec72


Ignore:
Timestamp:
Sep 18, 2017, 3:05:47 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
80ac42d
Parents:
9857e8d
Message:

Convert InsertDtors? to PassVisitor?

Location:
src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    r9857e8d r698ec72  
    105105
    106106                /// collects constructed object decls - used as a base class
    107                 class ObjDeclCollector : public AddStmtVisitor {
    108                   public:
    109                         typedef AddStmtVisitor Parent;
    110                         using Parent::visit;
     107                struct ObjDeclCollector : public WithGuards, public WithShortCircuiting {
    111108                        // use ordered data structure to maintain ordering for set_difference and for consistent error messages
    112109                        typedef std::list< ObjectDecl * > ObjectSet;
    113                         virtual void visit( CompoundStmt *compoundStmt ) override;
    114                         virtual void visit( DeclStmt *stmt ) override;
     110                        void previsit( CompoundStmt *compoundStmt );
     111                        void previsit( DeclStmt *stmt );
    115112
    116113                        // don't go into other functions
    117                         virtual void visit( FunctionDecl * ) override {}
     114                        void previsit( FunctionDecl * ) { visit_children = false; }
    118115
    119116                  protected:
     
    139136                }
    140137
    141                 class LabelFinder final : public ObjDeclCollector {
    142                   public:
    143                         typedef ObjDeclCollector Parent;
     138                struct LabelFinder final : public ObjDeclCollector {
    144139                        typedef std::map< Label, ObjectSet > LabelMap;
    145140                        // map of Label -> live variables at that label
    146141                        LabelMap vars;
    147142
    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 ); }
     143                        typedef ObjDeclCollector Parent;
     144                        using Parent::previsit;
     145                        void previsit( Statement * stmt );
     146
     147                        void previsit( CompoundStmt *compoundStmt );
     148                        void previsit( DeclStmt *stmt );
    172149                };
    173150
    174                 class InsertDtors final : public ObjDeclCollector {
    175                 public:
     151                struct InsertDtors final : public ObjDeclCollector, public WithStmtsToAdd {
    176152                        /// insert destructor calls at the appropriate places.  must happen before CtorInit nodes are removed
    177153                        /// (currently by FixInit)
    178154                        static void insert( std::list< Declaration * > & translationUnit );
    179155
    180                         typedef ObjDeclCollector Parent;
    181156                        typedef std::list< ObjectDecl * > OrderedDecls;
    182157                        typedef std::list< OrderedDecls > OrderedDeclsStack;
    183158
    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;
     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 );
    194171                private:
    195172                        void handleGoto( BranchStmt * stmt );
    196173
    197                         LabelFinder & finder;
     174                        PassVisitor<LabelFinder> & finder;
    198175                        LabelFinder::LabelMap & labelVars;
    199176                        OrderedDeclsStack reverseDeclOrder;
     
    333310
    334311                void InsertDtors::insert( std::list< Declaration * > & translationUnit ) {
    335                         LabelFinder finder;
    336                         InsertDtors inserter( finder );
     312                        PassVisitor<LabelFinder> finder;
     313                        PassVisitor<InsertDtors> inserter( finder );
    337314                        acceptAll( translationUnit, inserter );
    338315                }
     
    792769                }
    793770
    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 ) {
     771                void ObjDeclCollector::previsit( CompoundStmt * ) {
     772                        GuardValue( curVars );
     773                }
     774
     775                void ObjDeclCollector::previsit( DeclStmt * stmt ) {
    801776                        // keep track of all variables currently in scope
    802777                        if ( ObjectDecl * objDecl = dynamic_cast< ObjectDecl * > ( stmt->get_decl() ) ) {
    803778                                curVars.push_back( objDecl );
    804779                        } // if
    805                         Parent::visit( stmt );
    806                 }
    807 
    808                 void LabelFinder::handleStmt( Statement * stmt ) {
     780                }
     781
     782                void LabelFinder::previsit( Statement * stmt ) {
    809783                        // for each label, remember the variables in scope at that label.
    810784                        for ( Label l : stmt->get_labels() ) {
     
    812786                        } // for
    813787                }
     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
    814799
    815800                template<typename Iterator, typename OutputIterator>
     
    827812                }
    828813
    829                 void InsertDtors::visit( ObjectDecl * objDecl ) {
     814                void InsertDtors::previsit( ObjectDecl * objDecl ) {
    830815                        // remember non-static destructed objects so that their destructors can be inserted later
    831816                        if ( ! objDecl->get_storageClasses().is_static ) {
     
    841826                                } // if
    842827                        } // if
    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 ) {
     828                }
     829
     830                void InsertDtors::previsit( FunctionDecl * funcDecl ) {
    853831                        // each function needs to have its own set of labels
    854                         ValueGuard< LabelFinder::LabelMap > oldLabels( labelVars );
     832                        GuardValue( labelVars );
    855833                        labelVars.clear();
    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 ) {
     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 ) {
    864841                        // visit statements - this will also populate reverseDeclOrder list.  don't want to dump all destructors
    865842                        // when block is left, just the destructors associated with variables defined in this block, so push a new
    866843                        // list to the top of the stack so that we can differentiate scopes
    867844                        reverseDeclOrder.push_front( OrderedDecls() );
    868                         Parent::visit( compoundStmt );
    869 
     845                        Parent::previsit( compoundStmt );
     846                }
     847
     848                void InsertDtors::postvisit( CompoundStmt * compoundStmt ) {
    870849                        // add destructors for the current scope that we're exiting, unless the last statement is a return, which
    871850                        // causes unreachable code warnings
     
    877856                }
    878857
    879                 void InsertDtors::visit( __attribute((unused)) ReturnStmt * returnStmt ) {
     858                void InsertDtors::previsit( ReturnStmt * ) {
    880859                        // return exits all scopes, so dump destructors for all scopes
    881860                        for ( OrderedDecls & od : reverseDeclOrder ) {
    882                                 insertDtors( od.begin(), od.end(), back_inserter( stmtsToAdd ) );
     861                                insertDtors( od.begin(), od.end(), back_inserter( stmtsToAddBefore ) );
    883862                        } // for
    884863                }
     
    928907                                        copy_if( rdo.begin(), rdo.end(), back_inserter( ordered ), [&]( ObjectDecl * objDecl ) { return needsDestructor.count( objDecl ); } );
    929908                                } // for
    930                                 insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAdd ) );
     909                                insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAddBefore ) );
    931910                        } // if
    932911                }
    933912
    934                 void InsertDtors::visit( BranchStmt * stmt ) {
     913                void InsertDtors::previsit( BranchStmt * stmt ) {
    935914                        switch( stmt->get_type() ) {
    936915                          case BranchStmt::Continue:
  • src/tests/.expect/dtor-early-exit-ERR1.txt

    r9857e8d r698ec72  
    1 dtor-early-exit.c:142:1 error: jump to label 'L1' crosses initialization of y Branch (Goto)
     1dtor-early-exit.c:153:1 error: jump to label 'L1' crosses initialization of y Branch (Goto)
    22  with target: L1
    33  with original target: L1
  • src/tests/.expect/dtor-early-exit-ERR2.txt

    r9857e8d r698ec72  
    1 dtor-early-exit.c:142:1 error: jump to label 'L2' crosses initialization of y Branch (Goto)
     1dtor-early-exit.c:220:1 error: jump to label 'L2' crosses initialization of y Branch (Goto)
    22  with target: L2
    33  with original target: L2
Note: See TracChangeset for help on using the changeset viewer.