Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/GenInit.cc

    rce8c12f rd24d4e1  
    1616#include <stack>
    1717#include <list>
     18
     19#include "InitTweak.h"
    1820#include "GenInit.h"
    19 #include "InitTweak.h"
     21
     22#include "Common/PassVisitor.h"
     23
     24#include "GenPoly/DeclMutator.h"
     25#include "GenPoly/PolyMutator.h"
     26#include "GenPoly/ScopedSet.h"
     27
     28#include "ResolvExpr/typeops.h"
     29
    2030#include "SynTree/Declaration.h"
    21 #include "SynTree/Type.h"
    2231#include "SynTree/Expression.h"
    23 #include "SynTree/Statement.h"
    2432#include "SynTree/Initializer.h"
    2533#include "SynTree/Mutator.h"
     34#include "SynTree/Statement.h"
     35#include "SynTree/Type.h"
     36
    2637#include "SymTab/Autogen.h"
    2738#include "SymTab/Mangler.h"
    28 #include "GenPoly/PolyMutator.h"
    29 #include "GenPoly/DeclMutator.h"
    30 #include "GenPoly/ScopedSet.h"
    31 #include "ResolvExpr/typeops.h"
    3239
    3340namespace InitTweak {
     
    3744        }
    3845
    39         class ReturnFixer final : public GenPoly::PolyMutator {
    40           public:
     46        struct ReturnFixer : public WithStmtsToAdd, public WithGuards {
    4147                /// consistently allocates a temporary variable for the return value
    4248                /// of a function so that anything which the resolver decides can be constructed
     
    4450                static void makeReturnTemp( std::list< Declaration * > &translationUnit );
    4551
    46                 ReturnFixer();
    47 
    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         ReturnFixer::ReturnFixer() {}
    138 
    139         Statement *ReturnFixer::mutate( ReturnStmt *returnStmt ) {
     137        void ReturnFixer::premutate( ReturnStmt *returnStmt ) {
    140138                std::list< DeclarationWithType * > & returnVals = ftype->get_returnVals();
    141139                assert( returnVals.size() == 0 || returnVals.size() == 1 );
     
    148146                        construct->get_args().push_back( new AddressExpr( new VariableExpr( returnVals.front() ) ) );
    149147                        construct->get_args().push_back( returnStmt->get_expr() );
    150                         stmtsToAdd.push_back(new ExprStmt(noLabels, construct));
     148                        stmtsToAddBefore.push_back(new ExprStmt(noLabels, construct));
    151149
    152150                        // return the retVal object
    153151                        returnStmt->set_expr( new VariableExpr( returnVals.front() ) );
    154152                } // if
    155                 return returnStmt;
    156         }
    157 
    158         DeclarationWithType* ReturnFixer::mutate( FunctionDecl *functionDecl ) {
    159                 ValueGuard< FunctionType * > oldFtype( ftype );
    160                 ValueGuard< std::string > oldFuncName( funcName );
     153        }
     154
     155        void ReturnFixer::premutate( FunctionDecl *functionDecl ) {
     156                GuardValue( ftype );
     157                GuardValue( funcName );
    161158
    162159                ftype = functionDecl->get_functionType();
    163160                funcName = functionDecl->get_name();
    164                 return Parent::mutate( functionDecl );
    165161        }
    166162
     
    212208
    213209        void CtorDtor::generateCtorDtor( std::list< Declaration * > & translationUnit ) {
    214                 CtorDtor ctordtor;
    215                 mutateAll( translationUnit, ctordtor );
     210                PassVisitor<CtorDtor> ctordtor;
     211                acceptAll( translationUnit, ctordtor );
    216212        }
    217213
     
    243239                        std::list< DeclarationWithType * > & params = GenPoly::getFunctionType( dwt->get_type() )->get_parameters();
    244240                        assert( ! params.empty() );
    245                         Type * type = InitTweak::getPointerBase( params.front()->get_type() );
    246                         assert( type );
    247                         managedTypes.insert( SymTab::Mangler::mangle( type ) );
     241                        PointerType * type = safe_dynamic_cast< PointerType * >( params.front()->get_type() );
     242                        managedTypes.insert( SymTab::Mangler::mangle( type->get_base() ) );
    248243                }
    249244        }
     
    291286        }
    292287
    293         DeclarationWithType * CtorDtor::mutate( ObjectDecl * objDecl ) {
     288        void CtorDtor::previsit( ObjectDecl * objDecl ) {
    294289                handleDWT( objDecl );
    295290                // hands off if @=, extern, builtin, etc.
     
    303298                        objDecl->set_init( genCtorInit( objDecl ) );
    304299                }
    305                 return Parent::mutate( objDecl );
    306         }
    307 
    308         DeclarationWithType * CtorDtor::mutate( FunctionDecl *functionDecl ) {
    309                 ValueGuard< bool > oldInFunc = inFunction;
     300        }
     301
     302        void CtorDtor::previsit( FunctionDecl *functionDecl ) {
     303                GuardValue( inFunction );
    310304                inFunction = true;
    311305
    312306                handleDWT( functionDecl );
    313307
    314                 managedTypes.beginScope();
     308                GuardScope( managedTypes );
    315309                // go through assertions and recursively add seen ctor/dtors
    316310                for ( auto & tyDecl : functionDecl->get_functionType()->get_forall() ) {
    317311                        for ( DeclarationWithType *& assertion : tyDecl->get_assertions() ) {
    318                                 assertion = assertion->acceptMutator( *this );
     312                                handleDWT( assertion );
    319313                        }
    320314                }
    321                 // parameters should not be constructed and destructed, so don't mutate FunctionType
    322                 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
    323 
    324                 managedTypes.endScope();
    325                 return functionDecl;
    326         }
    327 
    328         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
    329325                // don't construct members, but need to take note if there is a managed member,
    330326                // because that means that this type is also managed
     
    338334                        }
    339335                }
    340                 return aggregateDecl;
    341         }
    342 
    343         CompoundStmt * CtorDtor::mutate( CompoundStmt * compoundStmt ) {
    344                 managedTypes.beginScope();
    345                 CompoundStmt * stmt = Parent::mutate( compoundStmt );
    346                 managedTypes.endScope();
    347                 return stmt;
    348         }
    349 
     336        }
     337
     338        void CtorDtor::previsit( CompoundStmt * compoundStmt ) {
     339                GuardScope( managedTypes );
     340        }
    350341} // namespace InitTweak
    351342
Note: See TracChangeset for help on using the changeset viewer.