Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Pass.impl.hpp

    ree918356 r3b0bc16  
    7979
    8080                template<typename it_t, template <class...> class container_t>
    81                 static inline void take_all( it_t it, container_t<ast::ptr<ast::Stmt>> * stmts, bool * mutated = nullptr ) {
    82                         if(empty(stmts)) return;
    83 
    84                         std::move(stmts->begin(), stmts->end(), it);
    85                         stmts->clear();
     81                static inline void take_all( it_t it, container_t<ast::ptr<ast::Stmt>> * decls, bool * mutated = nullptr ) {
     82                        if(empty(decls)) return;
     83
     84                        std::move(decls->begin(), decls->end(), it);
     85                        decls->clear();
    8686                        if(mutated) *mutated = true;
    8787                }
     
    123123                        return !new_val.empty();
    124124                }
    125         }
    126 
    127 
    128         template< typename core_t >
    129         template< typename node_t >
    130         template< typename object_t, typename super_t, typename field_t >
    131         void ast::Pass< core_t >::result1< node_t >::apply(object_t * object, field_t super_t::* field) {
    132                 object->*field = value;
    133125        }
    134126
     
    139131                                !std::is_base_of<ast::Expr, node_t>::value &&
    140132                                !std::is_base_of<ast::Stmt, node_t>::value
    141                         , ast::Pass< core_t >::result1<
    142                                 typename std::remove_pointer< decltype( node->accept(*this) ) >::type
    143                         >
     133                        , decltype( node->accept(*this) )
    144134                >::type
    145135        {
     
    150140                static_assert( !std::is_base_of<ast::Stmt, node_t>::value, "ERROR");
    151141
    152                 auto nval = node->accept( *this );
    153                 ast::Pass< core_t >::result1<
    154                         typename std::remove_pointer< decltype( node->accept(*this) ) >::type
    155                 > res;
    156                 res.differs = nval != node;
    157                 res.value = nval;
    158                 return res;
     142                return node->accept( *this );
    159143        }
    160144
    161145        template< typename core_t >
    162         typename ast::Pass< core_t >::template result1<ast::Expr> ast::Pass< core_t >::call_accept( const ast::Expr * expr ) {
     146        const ast::Expr * ast::Pass< core_t >::call_accept( const ast::Expr * expr ) {
    163147                __pedantic_pass_assert( __visit_children() );
    164148                __pedantic_pass_assert( expr );
     
    169153                }
    170154
    171                 auto nval = expr->accept( *this );
    172                 return { nval != expr, nval };
     155                return expr->accept( *this );
    173156        }
    174157
    175158        template< typename core_t >
    176         typename ast::Pass< core_t >::template result1<ast::Stmt> ast::Pass< core_t >::call_accept( const ast::Stmt * stmt ) {
     159        const ast::Stmt * ast::Pass< core_t >::call_accept( const ast::Stmt * stmt ) {
    177160                __pedantic_pass_assert( __visit_children() );
    178161                __pedantic_pass_assert( stmt );
    179162
    180                 const ast::Stmt * nval = stmt->accept( *this );
    181                 return { nval != stmt, nval };
     163                return stmt->accept( *this );
    182164        }
    183165
    184166        template< typename core_t >
    185         typename ast::Pass< core_t >::template result1<ast::Stmt> ast::Pass< core_t >::call_accept_as_compound( const ast::Stmt * stmt ) {
     167        const ast::Stmt * ast::Pass< core_t >::call_accept_as_compound( const ast::Stmt * stmt ) {
    186168                __pedantic_pass_assert( __visit_children() );
    187169                __pedantic_pass_assert( stmt );
     
    208190                // If the pass doesn't want to add anything then we are done
    209191                if( empty(stmts_before) && empty(stmts_after) && empty(decls_before) && empty(decls_after) ) {
    210                         return { nstmt != stmt, nstmt };
     192                        return nstmt;
    211193                }
    212194
     
    230212                __pass::take_all( std::back_inserter( compound->kids ), stmts_after );
    231213
    232                 return {true, compound};
     214                return compound;
    233215        }
    234216
    235217        template< typename core_t >
    236218        template< template <class...> class container_t >
    237         template< typename object_t, typename super_t, typename field_t >
    238         void ast::Pass< core_t >::resultNstmt<container_t>::apply(object_t * object, field_t super_t::* field) {
    239                 auto & container = object->*field;
    240                 __pedantic_pass_assert( container.size() <= values.size() );
    241 
    242                 auto cit = enumerate(container).begin();
    243 
    244                 container_t<ptr<Stmt>> nvals;
    245                 for(delta & d : values) {
    246                         if( d.is_old ) {
    247                                 __pedantic_pass_assert( cit.idx <= d.old_idx );
    248                                 std::advance( cit, d.old_idx - cit.idx );
    249                                 nvals.push_back( std::move( (*cit).val) );
    250                         } else {
    251                                 nvals.push_back( std::move(d.nval) );
    252                         }
    253                 }
    254 
    255                 object->*field = std::move(nvals);
    256         }
    257 
    258         template< typename core_t >
    259         template< template <class...> class container_t >
    260         typename ast::Pass< core_t >::template resultNstmt<container_t> ast::Pass< core_t >::call_accept( const container_t< ptr<Stmt> > & statements ) {
     219        container_t< ptr<Stmt> > ast::Pass< core_t >::call_accept( const container_t< ptr<Stmt> > & statements ) {
    261220                __pedantic_pass_assert( __visit_children() );
    262221                if( statements.empty() ) return {};
     
    285244                pass_visitor_stats.avg->push(pass_visitor_stats.depth);
    286245
    287                 resultNstmt<container_t> new_kids;
    288                 for( auto value : enumerate( statements ) ) {
     246                bool mutated = false;
     247                container_t< ptr<Stmt> > new_kids;
     248                for( const Stmt * stmt : statements ) {
    289249                        try {
    290                                 size_t i = value.idx;
    291                                 const Stmt * stmt = value.val;
    292250                                __pedantic_pass_assert( stmt );
    293251                                const ast::Stmt * new_stmt = stmt->accept( *this );
    294252                                assert( new_stmt );
    295                                 if(new_stmt != stmt ) { new_kids.differs = true; }
     253                                if(new_stmt != stmt ) mutated = true;
    296254
    297255                                // Make sure that it is either adding statements or declartions but not both
     
    303261
    304262                                // Take all the statements which should have gone after, N/A for first iteration
    305                                 new_kids.take_all( decls_before );
    306                                 new_kids.take_all( stmts_before );
     263                                __pass::take_all( std::back_inserter( new_kids ), decls_before, &mutated );
     264                                __pass::take_all( std::back_inserter( new_kids ), stmts_before, &mutated );
    307265
    308266                                // Now add the statement if there is one
    309                                 if(new_stmt != stmt) {
    310                                         new_kids.values.emplace_back( new_stmt, i, false );
    311                                 } else {
    312                                         new_kids.values.emplace_back( nullptr, i, true );
    313                                 }
     267                                new_kids.emplace_back( new_stmt );
    314268
    315269                                // Take all the declarations that go before
    316                                 new_kids.take_all( decls_after );
    317                                 new_kids.take_all( stmts_after );
     270                                __pass::take_all( std::back_inserter( new_kids ), decls_after, &mutated );
     271                                __pass::take_all( std::back_inserter( new_kids ), stmts_after, &mutated );
    318272                        }
    319273                        catch ( SemanticErrorException &e ) {
     
    324278                if ( !errors.isEmpty() ) { throw errors; }
    325279
    326                 return new_kids;
     280                return mutated ? new_kids : container_t< ptr<Stmt> >();
    327281        }
    328282
    329283        template< typename core_t >
    330284        template< template <class...> class container_t, typename node_t >
    331         template< typename object_t, typename super_t, typename field_t >
    332         void ast::Pass< core_t >::resultN<container_t, node_t>::apply(object_t * object, field_t super_t::* field) {
    333                 auto & container = object->*field;
    334                 __pedantic_pass_assert( container.size() == values.size() );
    335 
    336                 for(size_t i = 0; i < container.size(); i++) {
    337                         // Take all the elements that are different in 'values'
    338                         // and swap them into 'container'
    339                         if( values[i] != nullptr ) std::swap(container[i], values[i]);
    340                 }
    341 
    342                 // Now the original containers should still have the unchanged values
    343                 // but also contain the new values
    344         }
    345 
    346         template< typename core_t >
    347         template< template <class...> class container_t, typename node_t >
    348         typename ast::Pass< core_t >::template resultN<container_t, node_t> ast::Pass< core_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) {
     285        container_t< ast::ptr<node_t> > ast::Pass< core_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) {
    349286                __pedantic_pass_assert( __visit_children() );
    350287                if( container.empty() ) return {};
     
    356293
    357294                bool mutated = false;
    358                 container_t<ptr<node_t>> new_kids;
     295                container_t< ast::ptr<node_t> > new_kids;
    359296                for ( const node_t * node : container ) {
    360297                        try {
    361298                                __pedantic_pass_assert( node );
    362299                                const node_t * new_stmt = strict_dynamic_cast< const node_t * >( node->accept( *this ) );
    363                                 if(new_stmt != node ) {
    364                                         mutated = true;
    365                                         new_kids.emplace_back( new_stmt );
    366                                 } else {
    367                                         new_kids.emplace_back( nullptr );
    368                                 }
    369 
     300                                if(new_stmt != node ) mutated = true;
     301
     302                                new_kids.emplace_back( new_stmt );
    370303                        }
    371304                        catch( SemanticErrorException &e ) {
     
    373306                        }
    374307                }
    375 
    376                 __pedantic_pass_assert( new_kids.size() == container.size() );
    377308                pass_visitor_stats.depth--;
    378309                if ( ! errors.isEmpty() ) { throw errors; }
    379310
    380                 return ast::Pass< core_t >::resultN<container_t, node_t>{ mutated,  new_kids };
     311                return mutated ? new_kids : container_t< ast::ptr<node_t> >();
    381312        }
    382313
     
    396327                auto new_val = call_accept( old_val );
    397328
    398                 static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value /* || std::is_same<int, decltype(old_val)>::value */, "ERROR");
    399 
    400                 if( new_val.differs ) {
     329                static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value || std::is_same<int, decltype(old_val)>::value, "ERROR");
     330
     331                if( __pass::differs(old_val, new_val) ) {
    401332                        auto new_parent = __pass::mutate<core_t>(parent);
    402                         new_val.apply(new_parent, child);
     333                        new_parent->*child = new_val;
    403334                        parent = new_parent;
    404335                }
     
    422353                static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value || std::is_same<int, decltype(old_val)>::value, "ERROR");
    423354
    424                 if( new_val.differs ) {
     355                if( __pass::differs(old_val, new_val) ) {
    425356                        auto new_parent = __pass::mutate<core_t>(parent);
    426                         new_val.apply( new_parent, child );
     357                        new_parent->*child = new_val;
    427358                        parent = new_parent;
    428359                }
     
    1010941                        const Expr * func = clause.target.func ? clause.target.func->accept(*this) : nullptr;
    1011942                        if(func != clause.target.func) mutated = true;
    1012                         else func = nullptr;
    1013943
    1014944                        std::vector<ptr<Expr>> new_args;
     
    1016946                        for( const auto & arg : clause.target.args ) {
    1017947                                auto a = arg->accept(*this);
    1018                                 if( a != arg ) {
    1019                                         mutated = true;
    1020                                         new_args.push_back( a );
    1021                                 } else
    1022                                         new_args.push_back( nullptr );
     948                                new_args.push_back( a );
     949                                if( a != arg ) mutated = true;
    1023950                        }
    1024951
    1025952                        const Stmt * stmt = clause.stmt ? clause.stmt->accept(*this) : nullptr;
    1026953                        if(stmt != clause.stmt) mutated = true;
    1027                         else stmt = nullptr;
    1028954
    1029955                        const Expr * cond = clause.cond ? clause.cond->accept(*this) : nullptr;
    1030956                        if(cond != clause.cond) mutated = true;
    1031                         else cond = nullptr;
    1032957
    1033958                        new_clauses.push_back( WaitForStmt::Clause{ {func, std::move(new_args) }, stmt, cond } );
     
    1036961                if(mutated) {
    1037962                        auto n = __pass::mutate<core_t>(node);
    1038                         for(size_t i = 0; i < new_clauses.size(); i++) {
    1039                                 if(new_clauses.at(i).target.func != nullptr) std::swap(n->clauses.at(i).target.func, new_clauses.at(i).target.func);
    1040 
    1041                                 for(size_t j = 0; j < new_clauses.at(i).target.args.size(); j++) {
    1042                                         if(new_clauses.at(i).target.args.at(j) != nullptr) std::swap(n->clauses.at(i).target.args.at(j), new_clauses.at(i).target.args.at(j));
    1043                                 }
    1044 
    1045                                 if(new_clauses.at(i).stmt != nullptr) std::swap(n->clauses.at(i).stmt, new_clauses.at(i).stmt);
    1046                                 if(new_clauses.at(i).cond != nullptr) std::swap(n->clauses.at(i).cond, new_clauses.at(i).cond);
    1047                         }
     963                        n->clauses = std::move( new_clauses );
    1048964                        node = n;
    1049965                }
     
    1053969                if(node->field) { \
    1054970                        auto nval = call_accept( node->field ); \
    1055                         if(nval.differs ) { \
     971                        if(nval != node->field ) { \
    1056972                                auto nparent = __pass::mutate<core_t>(node); \
    1057                                 nparent->field = nval.value; \
     973                                nparent->field = nval; \
    1058974                                node = nparent; \
    1059975                        } \
Note: See TracChangeset for help on using the changeset viewer.