Ignore:
File:
1 edited

Legend:

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

    r954c954 rc6c682cf  
    167167                __pedantic_pass_assert( stmt );
    168168
     169                return stmt->accept( *this );
     170        }
     171
     172        template< typename core_t >
     173        const ast::Stmt * ast::Pass< core_t >::call_accept_as_compound( const ast::Stmt * stmt ) {
     174                __pedantic_pass_assert( __visit_children() );
     175                __pedantic_pass_assert( stmt );
     176
    169177                // add a few useful symbols to the scope
    170178                using __pass::empty;
     
    324332
    325333                auto new_val = call_accept( old_val );
     334
     335                static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value || std::is_same<int, decltype(old_val)>::value, "ERROR");
     336
     337                if( __pass::differs(old_val, new_val) ) {
     338                        auto new_parent = __pass::mutate<core_t>(parent);
     339                        new_parent->*child = new_val;
     340                        parent = new_parent;
     341                }
     342        }
     343
     344        template< typename core_t >
     345        template<typename node_t, typename parent_t, typename child_t>
     346        void ast::Pass< core_t >::maybe_accept_as_compound(
     347                const node_t * & parent,
     348                child_t parent_t::*child
     349        ) {
     350                static_assert( std::is_base_of<parent_t, node_t>::value, "Error deducing member object" );
     351
     352                if(__pass::skip(parent->*child)) return;
     353                const auto & old_val = __pass::get(parent->*child, 0);
     354
     355                static_assert( !std::is_same<const ast::Node * &, decltype(old_val)>::value, "ERROR");
     356
     357                auto new_val = call_accept_as_compound( old_val );
    326358
    327359                static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value || std::is_same<int, decltype(old_val)>::value, "ERROR");
     
    470502                                // foralls are still in function type
    471503                                maybe_accept( node, &FunctionDecl::type );
    472                                 // function body needs to have the same scope as parameters - CompoundStmt will not enter
    473                                 // a new scope if inFunction is true
     504                                // First remember that we are now within a function.
    474505                                ValueGuard< bool > oldInFunction( inFunction );
    475506                                inFunction = true;
     507                                // The function body needs to have the same scope as parameters.
     508                                // A CompoundStmt will not enter a new scope if atFunctionTop is true.
     509                                ValueGuard< bool > oldAtFunctionTop( atFunctionTop );
     510                                atFunctionTop = true;
    476511                                maybe_accept( node, &FunctionDecl::stmts );
    477512                                maybe_accept( node, &FunctionDecl::attributes );
     
    640675        VISIT_START( node );
    641676        VISIT({
    642                 // do not enter a new scope if inFunction is true - needs to check old state before the assignment
    643                 auto guard1 = makeFuncGuard( [this, inFunctionCpy = this->inFunction]() {
    644                         if ( ! inFunctionCpy ) __pass::symtab::enter(core, 0);
    645                 }, [this, inFunctionCpy = this->inFunction]() {
    646                         if ( ! inFunctionCpy ) __pass::symtab::leave(core, 0);
     677                // Do not enter (or leave) a new scope if atFunctionTop. Remember to save the result.
     678                auto guard1 = makeFuncGuard( [this, enterScope = !this->atFunctionTop]() {
     679                        if ( enterScope ) __pass::symtab::enter(core, 0);
     680                }, [this, leaveScope = !this->atFunctionTop]() {
     681                        if ( leaveScope ) __pass::symtab::leave(core, 0);
    647682                });
    648683                ValueGuard< bool > guard2( inFunction );
     
    703738                maybe_accept( node, &IfStmt::inits    );
    704739                maybe_accept( node, &IfStmt::cond     );
    705                 maybe_accept( node, &IfStmt::thenPart );
    706                 maybe_accept( node, &IfStmt::elsePart );
     740                maybe_accept_as_compound( node, &IfStmt::thenPart );
     741                maybe_accept_as_compound( node, &IfStmt::elsePart );
    707742        })
    708743
     
    721756                maybe_accept( node, &WhileStmt::inits );
    722757                maybe_accept( node, &WhileStmt::cond  );
    723                 maybe_accept( node, &WhileStmt::body  );
     758                maybe_accept_as_compound( node, &WhileStmt::body  );
    724759        })
    725760
     
    736771                // for statements introduce a level of scope (for the initialization)
    737772                guard_symtab guard { *this };
     773                // xxx - old ast does not create WithStmtsToAdd scope for loop inits. should revisit this later.
    738774                maybe_accept( node, &ForStmt::inits );
    739775                maybe_accept( node, &ForStmt::cond  );
    740776                maybe_accept( node, &ForStmt::inc   );
    741                 maybe_accept( node, &ForStmt::body  );
     777                maybe_accept_as_compound( node, &ForStmt::body  );
    742778        })
    743779
     
    834870                maybe_accept( node, &CatchStmt::decl );
    835871                maybe_accept( node, &CatchStmt::cond );
    836                 maybe_accept( node, &CatchStmt::body );
     872                maybe_accept_as_compound( node, &CatchStmt::body );
    837873        })
    838874
Note: See TracChangeset for help on using the changeset viewer.