Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/GenInit.cc

    r8ca3a72 rd24d4e1  
    3939
    4040namespace InitTweak {
    41         class ReturnFixer final : public GenPoly::PolyMutator {
    42           public:
     41        namespace {
     42                const std::list<Label> noLabels;
     43                const std::list<Expression *> noDesignators;
     44        }
     45
     46        struct ReturnFixer : public WithStmtsToAdd, public WithGuards {
    4347                /// consistently allocates a temporary variable for the return value
    4448                /// of a function so that anything which the resolver decides can be constructed
     
    4650                static void makeReturnTemp( std::list< Declaration * > &translationUnit );
    4751
    48                 typedef GenPoly::PolyMutator Parent;
    49                 using Parent::mutate;
    50                 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ) override;
    51                 virtual Statement * mutate( ReturnStmt * returnStmt ) override;
     52                void premutate( FunctionDecl *functionDecl );
     53                void premutate( ReturnStmt * returnStmt );
    5254
    5355          protected:
     
    5658        };
    5759
    58         class CtorDtor final : public GenPoly::PolyMutator {
    59           public:
    60                 typedef GenPoly::PolyMutator Parent;
    61                 using Parent::mutate;
     60        struct CtorDtor : public WithGuards, public WithShortCircuiting  {
    6261                /// create constructor and destructor statements for object declarations.
    6362                /// the actual call statements will be added in after the resolver has run
     
    6665                static void generateCtorDtor( std::list< Declaration * > &translationUnit );
    6766
    68                 virtual DeclarationWithType * mutate( ObjectDecl * ) override;
    69                 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ) override;
     67                void previsit( ObjectDecl * );
     68                void previsit( FunctionDecl *functionDecl );
     69
    7070                // should not traverse into any of these declarations to find objects
    7171                // that need to be constructed or destructed
    72                 virtual Declaration* mutate( StructDecl *aggregateDecl ) override;
    73                 virtual Declaration* mutate( UnionDecl *aggregateDecl ) override { return aggregateDecl; }
    74                 virtual Declaration* mutate( EnumDecl *aggregateDecl ) override { return aggregateDecl; }
    75                 virtual Declaration* mutate( TraitDecl *aggregateDecl ) override { return aggregateDecl; }
    76                 virtual TypeDecl* mutate( TypeDecl *typeDecl ) override { return typeDecl; }
    77                 virtual Declaration* mutate( TypedefDecl *typeDecl ) override { return typeDecl; }
    78 
    79                 virtual Type * mutate( FunctionType *funcType ) override { return funcType; }
    80 
    81                 virtual CompoundStmt * mutate( CompoundStmt * compoundStmt ) override;
     72                void previsit( StructDecl *aggregateDecl );
     73                void previsit( UnionDecl *aggregateDecl ) { visit_children = false; }
     74                void previsit( EnumDecl *aggregateDecl ) { visit_children = false; }
     75                void previsit( TraitDecl *aggregateDecl ) { visit_children = false; }
     76                void previsit( TypeDecl *typeDecl ) { visit_children = false; }
     77                void previsit( TypedefDecl *typeDecl ) { visit_children = false; }
     78
     79                void previsit( FunctionType *funcType ) { visit_children = false; }
     80
     81                void previsit( CompoundStmt * compoundStmt );
    8282
    8383          private:
     
    131131
    132132        void ReturnFixer::makeReturnTemp( std::list< Declaration * > & translationUnit ) {
    133                 ReturnFixer fixer;
     133                PassVisitor<ReturnFixer> fixer;
    134134                mutateAll( translationUnit, fixer );
    135135        }
    136136
    137         Statement *ReturnFixer::mutate( ReturnStmt *returnStmt ) {
     137        void ReturnFixer::premutate( ReturnStmt *returnStmt ) {
    138138                std::list< DeclarationWithType * > & returnVals = ftype->get_returnVals();
    139139                assert( returnVals.size() == 0 || returnVals.size() == 1 );
     
    146146                        construct->get_args().push_back( new AddressExpr( new VariableExpr( returnVals.front() ) ) );
    147147                        construct->get_args().push_back( returnStmt->get_expr() );
    148                         stmtsToAdd.push_back(new ExprStmt(noLabels, construct));
     148                        stmtsToAddBefore.push_back(new ExprStmt(noLabels, construct));
    149149
    150150                        // return the retVal object
    151151                        returnStmt->set_expr( new VariableExpr( returnVals.front() ) );
    152152                } // if
    153                 return returnStmt;
    154         }
    155 
    156         DeclarationWithType* ReturnFixer::mutate( FunctionDecl *functionDecl ) {
    157                 ValueGuard< FunctionType * > oldFtype( ftype );
    158                 ValueGuard< std::string > oldFuncName( funcName );
     153        }
     154
     155        void ReturnFixer::premutate( FunctionDecl *functionDecl ) {
     156                GuardValue( ftype );
     157                GuardValue( funcName );
    159158
    160159                ftype = functionDecl->get_functionType();
    161160                funcName = functionDecl->get_name();
    162                 return Parent::mutate( functionDecl );
    163161        }
    164162
     
    210208
    211209        void CtorDtor::generateCtorDtor( std::list< Declaration * > & translationUnit ) {
    212                 CtorDtor ctordtor;
    213                 mutateAll( translationUnit, ctordtor );
     210                PassVisitor<CtorDtor> ctordtor;
     211                acceptAll( translationUnit, ctordtor );
    214212        }
    215213
     
    288286        }
    289287
    290         DeclarationWithType * CtorDtor::mutate( ObjectDecl * objDecl ) {
     288        void CtorDtor::previsit( ObjectDecl * objDecl ) {
    291289                handleDWT( objDecl );
    292290                // hands off if @=, extern, builtin, etc.
     
    300298                        objDecl->set_init( genCtorInit( objDecl ) );
    301299                }
    302                 return Parent::mutate( objDecl );
    303         }
    304 
    305         DeclarationWithType * CtorDtor::mutate( FunctionDecl *functionDecl ) {
    306                 ValueGuard< bool > oldInFunc = inFunction;
     300        }
     301
     302        void CtorDtor::previsit( FunctionDecl *functionDecl ) {
     303                GuardValue( inFunction );
    307304                inFunction = true;
    308305
    309306                handleDWT( functionDecl );
    310307
    311                 managedTypes.beginScope();
     308                GuardScope( managedTypes );
    312309                // go through assertions and recursively add seen ctor/dtors
    313310                for ( auto & tyDecl : functionDecl->get_functionType()->get_forall() ) {
     
    316313                        }
    317314                }
    318                 // parameters should not be constructed and destructed, so don't mutate FunctionType
    319                 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
    320 
    321                 managedTypes.endScope();
    322                 return functionDecl;
    323         }
    324 
    325         Declaration* CtorDtor::mutate( StructDecl *aggregateDecl ) {
     315
     316                PassVisitor<CtorDtor> newCtorDtor;
     317                newCtorDtor.pass = *this;
     318                maybeAccept( functionDecl->get_statements(), newCtorDtor );
     319                visit_children = false;  // do not try and construct parameters or forall parameters - must happen after maybeAccept
     320        }
     321
     322        void CtorDtor::previsit( StructDecl *aggregateDecl ) {
     323                visit_children = false; // do not try to construct and destruct aggregate members
     324
    326325                // don't construct members, but need to take note if there is a managed member,
    327326                // because that means that this type is also managed
     
    335334                        }
    336335                }
    337                 return aggregateDecl;
    338         }
    339 
    340         CompoundStmt * CtorDtor::mutate( CompoundStmt * compoundStmt ) {
    341                 managedTypes.beginScope();
    342                 CompoundStmt * stmt = Parent::mutate( compoundStmt );
    343                 managedTypes.endScope();
    344                 return stmt;
    345         }
    346 
     336        }
     337
     338        void CtorDtor::previsit( CompoundStmt * compoundStmt ) {
     339                GuardScope( managedTypes );
     340        }
    347341} // namespace InitTweak
    348342
Note: See TracChangeset for help on using the changeset viewer.