Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/GenInit.cc

    raec3e6b re3e16bc  
    6262        };
    6363
    64         struct CtorDtor : public WithGuards, public WithShortCircuiting, public WithVisitorRef<CtorDtor>  {
     64        struct CtorDtor : public WithGuards, public WithShortCircuiting  {
    6565                /// create constructor and destructor statements for object declarations.
    6666                /// the actual call statements will be added in after the resolver has run
     
    7575                // that need to be constructed or destructed
    7676                void previsit( StructDecl *aggregateDecl );
    77                 void previsit( AggregateDecl * ) { visit_children = false; }
    78                 void previsit( NamedTypeDecl * ) { visit_children = false; }
    79                 void previsit( FunctionType * ) { visit_children = false; }
     77                void previsit( __attribute__((unused)) UnionDecl    * aggregateDecl ) { visit_children = false; }
     78                void previsit( __attribute__((unused)) EnumDecl     * aggregateDecl ) { visit_children = false; }
     79                void previsit( __attribute__((unused)) TraitDecl    * aggregateDecl ) { visit_children = false; }
     80                void previsit( __attribute__((unused)) TypeDecl     * typeDecl )      { visit_children = false; }
     81                void previsit( __attribute__((unused)) TypedefDecl  * typeDecl )      { visit_children = false; }
     82                void previsit( __attribute__((unused)) FunctionType * funcType )      { visit_children = false; }
    8083
    8184                void previsit( CompoundStmt * compoundStmt );
     
    9396        };
    9497
    95         struct HoistArrayDimension final : public WithDeclsToAdd, public WithShortCircuiting, public WithGuards {
     98        class HoistArrayDimension final : public GenPoly::DeclMutator {
     99          public:
     100                typedef GenPoly::DeclMutator Parent;
     101
    96102                /// hoist dimension from array types in object declaration so that it uses a single
    97103                /// const variable of type size_t, so that side effecting array dimensions are only
     
    99105                static void hoistArrayDimension( std::list< Declaration * > & translationUnit );
    100106
    101                 void premutate( ObjectDecl * objectDecl );
    102                 DeclarationWithType * postmutate( ObjectDecl * objectDecl );
    103                 void premutate( FunctionDecl *functionDecl );
     107          private:
     108                using Parent::mutate;
     109
     110                virtual DeclarationWithType * mutate( ObjectDecl * objectDecl ) override;
     111                virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ) override;
    104112                // should not traverse into any of these declarations to find objects
    105113                // that need to be constructed or destructed
    106                 void premutate( AggregateDecl * ) { visit_children = false; }
    107                 void premutate( NamedTypeDecl * ) { visit_children = false; }
    108                 void premutate( FunctionType * ) { visit_children = false; }
     114                virtual Declaration* mutate( StructDecl *aggregateDecl ) override { return aggregateDecl; }
     115                virtual Declaration* mutate( UnionDecl *aggregateDecl ) override { return aggregateDecl; }
     116                virtual Declaration* mutate( EnumDecl *aggregateDecl ) override { return aggregateDecl; }
     117                virtual Declaration* mutate( TraitDecl *aggregateDecl ) override { return aggregateDecl; }
     118                virtual TypeDecl* mutate( TypeDecl *typeDecl ) override { return typeDecl; }
     119                virtual Declaration* mutate( TypedefDecl *typeDecl ) override { return typeDecl; }
     120
     121                virtual Type* mutate( FunctionType *funcType ) override { return funcType; }
    109122
    110123                void hoist( Type * type );
     
    130143                // hands off if the function returns a reference - we don't want to allocate a temporary if a variable's address
    131144                // is being returned
    132                 if ( returnStmt->get_expr() && returnVals.size() == 1 && isConstructable( returnVals.front()->get_type() ) ) {
     145                if ( returnStmt->get_expr() && returnVals.size() == 1 && ! dynamic_cast< ReferenceType * >( returnVals.front()->get_type() ) ) {
    133146                        // explicitly construct the return value using the return expression and the retVal object
    134147                        assertf( returnVals.front()->get_name() != "", "Function %s has unnamed return value\n", funcName.c_str() );
     
    145158                GuardValue( funcName );
    146159
    147                 ftype = functionDecl->type;
    148                 funcName = functionDecl->name;
     160                ftype = functionDecl->get_functionType();
     161                funcName = functionDecl->get_name();
    149162        }
    150163
     
    152165        // which would be incorrect if it is a side-effecting computation.
    153166        void HoistArrayDimension::hoistArrayDimension( std::list< Declaration * > & translationUnit ) {
    154                 PassVisitor<HoistArrayDimension> hoister;
    155                 mutateAll( translationUnit, hoister );
    156         }
    157 
    158         void HoistArrayDimension::premutate( ObjectDecl * objectDecl ) {
    159                 GuardValue( storageClasses );
     167                HoistArrayDimension hoister;
     168                hoister.mutateDeclarationList( translationUnit );
     169        }
     170
     171        DeclarationWithType * HoistArrayDimension::mutate( ObjectDecl * objectDecl ) {
    160172                storageClasses = objectDecl->get_storageClasses();
    161         }
    162 
    163         DeclarationWithType * HoistArrayDimension::postmutate( ObjectDecl * objectDecl ) {
     173                DeclarationWithType * temp = Parent::mutate( objectDecl );
    164174                hoist( objectDecl->get_type() );
    165                 return objectDecl;
     175                return temp;
    166176        }
    167177
     
    184194
    185195                        arrayType->set_dimension( new VariableExpr( arrayDimension ) );
    186                         declsToAddBefore.push_back( arrayDimension );
     196                        addDeclaration( arrayDimension );
    187197
    188198                        hoist( arrayType->get_base() );
     
    191201        }
    192202
    193         void HoistArrayDimension::premutate( FunctionDecl * ) {
    194                 GuardValue( inFunction );
     203        DeclarationWithType * HoistArrayDimension::mutate( FunctionDecl *functionDecl ) {
     204                ValueGuard< bool > oldInFunc( inFunction );
     205                inFunction = true;
     206                DeclarationWithType * decl = Parent::mutate( functionDecl );
     207                return decl;
    195208        }
    196209
     
    201214
    202215        bool CtorDtor::isManaged( Type * type ) const {
    203                 // references are never constructed
     216                // at least for now, references are never constructed
    204217                if ( dynamic_cast< ReferenceType * >( type ) ) return false;
    205218                // need to clear and reset qualifiers when determining if a type is managed
     
    208221                if ( TupleType * tupleType = dynamic_cast< TupleType * > ( type ) ) {
    209222                        // tuple is also managed if any of its components are managed
    210                         if ( std::any_of( tupleType->types.begin(), tupleType->types.end(), [&](Type * type) { return isManaged( type ); }) ) {
     223                        if ( std::any_of( tupleType->get_types().begin(), tupleType->get_types().end(), [&](Type * type) { return isManaged( type ); }) ) {
    211224                                return true;
    212225                        }
     
    292305
    293306        void CtorDtor::previsit( FunctionDecl *functionDecl ) {
    294                 visit_children = false;  // do not try and construct parameters or forall parameters
    295307                GuardValue( inFunction );
    296308                inFunction = true;
     
    306318                }
    307319
    308                 maybeAccept( functionDecl->get_statements(), *visitor );
     320                PassVisitor<CtorDtor> newCtorDtor;
     321                newCtorDtor.pass = *this;
     322                maybeAccept( functionDecl->get_statements(), newCtorDtor );
     323                visit_children = false;  // do not try and construct parameters or forall parameters - must happen after maybeAccept
    309324        }
    310325
     
    325340        }
    326341
    327         void CtorDtor::previsit( CompoundStmt * ) {
     342        void CtorDtor::previsit( __attribute__((unused)) CompoundStmt * compoundStmt ) {
    328343                GuardScope( managedTypes );
    329344        }
Note: See TracChangeset for help on using the changeset viewer.