Ignore:
File:
1 edited

Legend:

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

    r7a780ad raf746cc  
    109109                return val;
    110110        }
     111
     112        //------------------------------
     113        /// Check if value was mutated, different for pointers and containers
     114        template<typename lhs_t, typename rhs_t>
     115        bool differs( const lhs_t * old_val, const rhs_t * new_val ) {
     116                return old_val != new_val;
     117        }
     118
     119        template< template <class...> class container_t, typename node_t >
     120        bool differs( const container_t<ast::ptr< node_t >> &, const container_t<ast::ptr< node_t >> & new_val ) {
     121                return !new_val.empty();
     122        }
    111123}
    112124
     
    114126template< typename node_t >
    115127auto ast::Pass< core_t >::call_accept( const node_t * node ) ->
    116                 ast::Pass< core_t >::call_accept_result_t<node_t> {
     128        typename ast::Pass< core_t >::template generic_call_accept_result<node_t>::type
     129{
    117130        __pedantic_pass_assert( __visit_children() );
    118131        __pedantic_pass_assert( node );
    119132
     133        static_assert( !std::is_base_of<ast::Expr, node_t>::value, "ERROR" );
     134        static_assert( !std::is_base_of<ast::Stmt, node_t>::value, "ERROR" );
     135
    120136        auto nval = node->accept( *this );
    121         return { nval != node, nval };
     137        __pass::result1<
     138                typename std::remove_pointer< decltype( node->accept(*this) ) >::type
     139        > res;
     140        res.differs = nval != node;
     141        res.value = nval;
     142        return res;
     143}
     144
     145template< typename core_t >
     146ast::__pass::template result1<ast::Expr> ast::Pass< core_t >::call_accept( const ast::Expr * expr ) {
     147        __pedantic_pass_assert( __visit_children() );
     148        __pedantic_pass_assert( expr );
     149
     150        auto nval = expr->accept( *this );
     151        return { nval != expr, nval };
     152}
     153
     154template< typename core_t >
     155ast::__pass::template result1<ast::Stmt> ast::Pass< core_t >::call_accept( const ast::Stmt * stmt ) {
     156        __pedantic_pass_assert( __visit_children() );
     157        __pedantic_pass_assert( stmt );
     158
     159        const ast::Stmt * nval = stmt->accept( *this );
     160        return { nval != stmt, nval };
    122161}
    123162
     
    191230ast::__pass::template resultNstmt<container_t> ast::Pass< core_t >::call_accept( const container_t< ptr<Stmt> > & statements ) {
    192231        __pedantic_pass_assert( __visit_children() );
    193         __pedantic_pass_assert( !statements.empty() );
     232        if ( statements.empty() ) return {};
    194233
    195234        // We are going to aggregate errors for all these statements
     
    224263                        const ast::Stmt * new_stmt = stmt->accept( *this );
    225264                        assert( new_stmt );
     265                        if ( new_stmt != stmt ) { new_kids.differs = true; }
    226266
    227267                        // Make sure that it is either adding statements or declartions but not both
     
    236276                        // Now add the statement if there is one
    237277                        if ( new_stmt != stmt ) {
    238                                 new_kids.differs = true;
    239                                 new_kids.values.emplace_back( new_stmt );
     278                                new_kids.values.emplace_back( new_stmt, i, false );
    240279                        } else {
    241                                 new_kids.values.emplace_back( i );
     280                                new_kids.values.emplace_back( nullptr, i, true );
    242281                        }
    243282
     
    259298ast::__pass::template resultN<container_t, node_t> ast::Pass< core_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) {
    260299        __pedantic_pass_assert( __visit_children() );
    261         __pedantic_pass_assert( !container.empty() );
    262 
    263         // Collect errors from processing all these nodes.
     300        if ( container.empty() ) return {};
    264301        SemanticErrorException errors;
    265302
     
    305342        static_assert( !std::is_same<const ast::Node * &, decltype(old_val)>::value, "ERROR" );
    306343
    307         auto result = call_accept( old_val );
    308         if ( result.differs ) {
     344        auto new_val = call_accept( old_val );
     345
     346        static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value /* || std::is_same<int, decltype(old_val)>::value */, "ERROR" );
     347
     348        if ( new_val.differs ) {
    309349                auto new_parent = __pass::mutate<core_t>(parent);
    310                 result.apply( new_parent, field );
     350                new_val.apply(new_parent, field);
    311351                parent = new_parent;
    312352        }
     
    326366        static_assert( !std::is_same<const ast::Node * &, decltype(old_val)>::value, "ERROR" );
    327367
    328         auto result = call_accept_top( old_val );
    329         if ( result.differs ) {
     368        auto new_val = call_accept_top( old_val );
     369
     370        static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value /* || std::is_same<int, decltype(old_val)>::value */, "ERROR" );
     371
     372        if ( new_val.differs ) {
    330373                auto new_parent = __pass::mutate<core_t>(parent);
    331                 result.apply( new_parent, field );
     374                new_val.apply(new_parent, field);
    332375                parent = new_parent;
    333376        }
     
    347390        static_assert( !std::is_same<const ast::Node * &, decltype(old_val)>::value, "ERROR" );
    348391
    349         auto result = call_accept_as_compound( old_val );
    350         if ( result.differs ) {
     392        auto new_val = call_accept_as_compound( old_val );
     393
     394        static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value || std::is_same<int, decltype(old_val)>::value, "ERROR" );
     395
     396        if ( new_val.differs ) {
    351397                auto new_parent = __pass::mutate<core_t>(parent);
    352                 result.apply( new_parent, child );
     398                new_val.apply( new_parent, child );
    353399                parent = new_parent;
    354400        }
     
    406452template< typename core_t >
    407453inline void ast::accept_all( ast::TranslationUnit & unit, ast::Pass< core_t > & visitor ) {
    408         if ( auto ptr = __pass::translationUnit( visitor.core, 0 ) ) {
     454        if ( auto ptr = __pass::translation_unit::get_cptr( visitor.core, 0 ) ) {
    409455                ValueGuard<const TranslationUnit *> guard( *ptr );
    410456                *ptr = &unit;
     
    477523                                CodeLocation{}, "__func__",
    478524                                new ast::ArrayType{
    479                                         new ast::BasicType{ ast::BasicKind::Char, ast::CV::Const },
     525                                        new ast::BasicType{ ast::BasicType::Char, ast::CV::Const },
    480526                                        nullptr, VariableLen, DynamicDim
    481527                                },
Note: See TracChangeset for help on using the changeset viewer.