Changes in / [b1b3df5:3e1cd17]


Ignore:
Location:
src/AST
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Pass.hpp

    rb1b3df5 r3e1cd17  
    252252private:
    253253
    254         /// The return type of the general call_accept function.
     254        __pass::result1<ast::Stmt> call_accept( const ast::Stmt * );
     255        __pass::result1<ast::Expr> call_accept( const ast::Expr * );
     256
     257        /// This has a `type` member that is the return type for the
     258        /// generic call_accept if the generic call_accept is defined.
    255259        template< typename node_t >
    256         using call_accept_result_t = __pass::result1<
    257                 typename std::remove_pointer< typename std::result_of<
    258                         decltype(&node_t::accept)(node_t*, type&) >::type >::type
     260        using generic_call_accept_result =
     261                std::enable_if<
     262                                !std::is_base_of<ast::Expr, node_t>::value &&
     263                                !std::is_base_of<ast::Stmt, node_t>::value
     264                        , __pass::result1<
     265                                typename std::remove_pointer< typename std::result_of<
     266                                        decltype(&node_t::accept)(node_t*, type&) >::type >::type
     267                        >
    259268                >;
    260269
    261270        template< typename node_t >
    262         auto call_accept( const node_t * node ) -> call_accept_result_t<node_t>;
     271        auto call_accept( const node_t * node )
     272                -> typename generic_call_accept_result<node_t>::type;
    263273
    264274        // requests WithStmtsToAdd directly add to this statement, as if it is a compound.
  • src/AST/Pass.impl.hpp

    rb1b3df5 r3e1cd17  
    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;
  • src/AST/Pass.proto.hpp

    rb1b3df5 r3e1cd17  
    154154                bool is_old;
    155155
    156                 explicit delta(const Stmt * s) : new_val(s), old_idx(-1), is_old(false) {}
    157                 explicit delta(ssize_t i) : new_val(nullptr), old_idx(i), is_old(true) {}
     156                delta(const Stmt * s, ssize_t i, bool old) :
     157                        new_val(s), old_idx(i), is_old(old) {}
    158158        };
    159159
     
    188188                std::transform( stmts->begin(), stmts->end(), std::back_inserter( values ),
    189189                        [](ast::ptr<ast::Stmt>& stmt) -> delta {
    190                                 return delta( stmt.release() );
     190                                return delta( stmt.release(), -1, false );
    191191                        });
    192192                stmts->clear();
     
    201201                        [](ast::ptr<ast::Decl>& decl) -> delta {
    202202                                ast::Decl const * d = decl.release();
    203                                 return delta( new DeclStmt( d->location, d ) );
     203                                return delta( new DeclStmt( d->location, d ), -1, false );
    204204                        });
    205205                decls->clear();
     
    257257        } else {
    258258                node = core.previsit( node );
    259                 assertf( node, "Previsit must not return nullptr." );
     259                assertf(node, "Previsit must not return NULL");
    260260        }
    261261}
     
    310310FIELD_PTR( at_cleanup, __pass::at_cleanup_t )
    311311FIELD_PTR( visitor, ast::Pass<core_t> * const )
    312 FIELD_PTR( translationUnit, const TranslationUnit * )
    313312
    314313// Remove the macro to make sure we don't clash
     
    507506} // namespace forall
    508507
     508// For passes that need access to the global context. Searches `translationUnit`
     509namespace translation_unit {
     510        template<typename core_t>
     511        static inline auto get_cptr( core_t & core, int )
     512                        -> decltype( &core.translationUnit ) {
     513                return &core.translationUnit;
     514        }
     515
     516        template<typename core_t>
     517        static inline const TranslationUnit ** get_cptr( core_t &, long ) {
     518                return nullptr;
     519        }
     520}
     521
    509522// For passes, usually utility passes, that have a result.
    510523namespace result {
Note: See TracChangeset for help on using the changeset viewer.