Ignore:
File:
1 edited

Legend:

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

    r954c954 r293dc1c  
    2020#include <unordered_map>
    2121
     22#include "AST/TranslationUnit.hpp"
    2223#include "AST/TypeSubstitution.hpp"
    2324
     
    167168                __pedantic_pass_assert( stmt );
    168169
     170                return stmt->accept( *this );
     171        }
     172
     173        template< typename core_t >
     174        const ast::Stmt * ast::Pass< core_t >::call_accept_as_compound( const ast::Stmt * stmt ) {
     175                __pedantic_pass_assert( __visit_children() );
     176                __pedantic_pass_assert( stmt );
     177
    169178                // add a few useful symbols to the scope
    170179                using __pass::empty;
     
    334343        }
    335344
     345        template< typename core_t >
     346        template<typename node_t, typename parent_t, typename child_t>
     347        void ast::Pass< core_t >::maybe_accept_as_compound(
     348                const node_t * & parent,
     349                child_t parent_t::*child
     350        ) {
     351                static_assert( std::is_base_of<parent_t, node_t>::value, "Error deducing member object" );
     352
     353                if(__pass::skip(parent->*child)) return;
     354                const auto & old_val = __pass::get(parent->*child, 0);
     355
     356                static_assert( !std::is_same<const ast::Node * &, decltype(old_val)>::value, "ERROR");
     357
     358                auto new_val = call_accept_as_compound( old_val );
     359
     360                static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value || std::is_same<int, decltype(old_val)>::value, "ERROR");
     361
     362                if( __pass::differs(old_val, new_val) ) {
     363                        auto new_parent = __pass::mutate<core_t>(parent);
     364                        new_parent->*child = new_val;
     365                        parent = new_parent;
     366                }
     367        }
     368
    336369
    337370        template< typename core_t >
     
    398431        pass_visitor_stats.depth--;
    399432        if ( !errors.isEmpty() ) { throw errors; }
     433}
     434
     435template< typename core_t >
     436inline void ast::accept_all( ast::TranslationUnit & unit, ast::Pass< core_t > & visitor ) {
     437        return ast::accept_all( unit.decls, visitor );
    400438}
    401439
     
    470508                                // foralls are still in function type
    471509                                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
     510                                // First remember that we are now within a function.
    474511                                ValueGuard< bool > oldInFunction( inFunction );
    475512                                inFunction = true;
     513                                // The function body needs to have the same scope as parameters.
     514                                // A CompoundStmt will not enter a new scope if atFunctionTop is true.
     515                                ValueGuard< bool > oldAtFunctionTop( atFunctionTop );
     516                                atFunctionTop = true;
    476517                                maybe_accept( node, &FunctionDecl::stmts );
    477518                                maybe_accept( node, &FunctionDecl::attributes );
     
    639680const ast::CompoundStmt * ast::Pass< core_t >::visit( const ast::CompoundStmt * node ) {
    640681        VISIT_START( node );
    641         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);
     682        VISIT(
     683                // Do not enter (or leave) a new scope if atFunctionTop. Remember to save the result.
     684                auto guard1 = makeFuncGuard( [this, enterScope = !this->atFunctionTop]() {
     685                        if ( enterScope ) __pass::symtab::enter(core, 0);
     686                }, [this, leaveScope = !this->atFunctionTop]() {
     687                        if ( leaveScope ) __pass::symtab::leave(core, 0);
    647688                });
    648                 ValueGuard< bool > guard2( inFunction );
     689                ValueGuard< bool > guard2( atFunctionTop );
     690                atFunctionTop = false;
    649691                guard_scope guard3 { *this };
    650                 inFunction = false;
    651692                maybe_accept( node, &CompoundStmt::kids );
    652         })
     693        )
    653694        VISIT_END( CompoundStmt, node );
    654695}
     
    703744                maybe_accept( node, &IfStmt::inits    );
    704745                maybe_accept( node, &IfStmt::cond     );
    705                 maybe_accept( node, &IfStmt::thenPart );
    706                 maybe_accept( node, &IfStmt::elsePart );
     746                maybe_accept_as_compound( node, &IfStmt::thenPart );
     747                maybe_accept_as_compound( node, &IfStmt::elsePart );
    707748        })
    708749
     
    721762                maybe_accept( node, &WhileStmt::inits );
    722763                maybe_accept( node, &WhileStmt::cond  );
    723                 maybe_accept( node, &WhileStmt::body  );
     764                maybe_accept_as_compound( node, &WhileStmt::body  );
    724765        })
    725766
     
    736777                // for statements introduce a level of scope (for the initialization)
    737778                guard_symtab guard { *this };
     779                // xxx - old ast does not create WithStmtsToAdd scope for loop inits. should revisit this later.
    738780                maybe_accept( node, &ForStmt::inits );
    739781                maybe_accept( node, &ForStmt::cond  );
    740782                maybe_accept( node, &ForStmt::inc   );
    741                 maybe_accept( node, &ForStmt::body  );
     783                maybe_accept_as_compound( node, &ForStmt::body  );
    742784        })
    743785
     
    834876                maybe_accept( node, &CatchStmt::decl );
    835877                maybe_accept( node, &CatchStmt::cond );
    836                 maybe_accept( node, &CatchStmt::body );
     878                maybe_accept_as_compound( node, &CatchStmt::body );
    837879        })
    838880
Note: See TracChangeset for help on using the changeset viewer.