Ignore:
Timestamp:
May 15, 2019, 3:57:26 PM (5 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
3648d98
Parents:
9e1d485 (diff), be567e9 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

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

    r9e1d485 r69bafd2  
    1616#pragma once
    1717// IWYU pragma: private, include "AST/Pass.hpp"
     18
     19#include <type_traits>
     20#include <unordered_map>
    1821
    1922#define VISIT_START( node ) \
     
    2629        __pass::previsit( pass, node, 0 );
    2730
    28 #define VISIT( code ) \
     31#define VISIT( code... ) \
    2932        /* if this node should visit its children */ \
    3033        if ( __visit_children() ) { \
     
    3538#define VISIT_END( type, node ) \
    3639        /* call the implementation of the postvisit of this pass */ \
    37         auto __return = __pass::postvisit< type * >( node ); \
     40        auto __return = __pass::postvisit( pass, node, 0 ); \
    3841        assertf(__return, "post visit should never return null"); \
    3942        return __return;
    4043
    4144#ifdef PEDANTIC_PASS_ASSERT
    42 #define __pedantic_pass_assert (...) assert (__VAR_ARGS__)
    43 #define __pedantic_pass_assertf(...) assertf(__VAR_ARGS__)
     45#define __pedantic_pass_assert(...) assert (__VA_ARGS__)
     46#define __pedantic_pass_assertf(...) assertf(__VA_ARGS__)
    4447#else
    45 #define __pedantic_pass_assert (...)
     48#define __pedantic_pass_assert(...)
    4649#define __pedantic_pass_assertf(...)
    4750#endif
     
    5558                }
    5659
    57                 template<typename it_t, template <class> class container_t>
    58                 static inline void take_all( it_t it, container_t<ast::ptr<ast::Declaration>> * decls, bool * mutated = nullptr ) {
     60                //------------------------------
     61                template<typename it_t, template <class...> class container_t>
     62                static inline void take_all( it_t it, container_t<ast::ptr<ast::Decl>> * decls, bool * mutated = nullptr ) {
    5963                        if(empty(decls)) return;
    6064
    61                         std::transform(decls->begin(), decls->end(), it, [](Declaration * decl) -> auto {
     65                        std::transform(decls->begin(), decls->end(), it, [](const ast::Decl * decl) -> auto {
    6266                                        return new DeclStmt( decl );
    6367                                });
     
    6670                }
    6771
    68                 template<typename it_t, template <class> class container_t>
    69                 static inline void take_all( it_t it, container_t<ast::ptr<ast::Statement>> * decls, bool * mutated = nullptr ) {
     72                template<typename it_t, template <class...> class container_t>
     73                static inline void take_all( it_t it, container_t<ast::ptr<ast::Stmt>> * decls, bool * mutated = nullptr ) {
    7074                        if(empty(decls)) return;
    7175
     
    7579                }
    7680
     81                //------------------------------
     82                /// Check if should be skipped, different for pointers and containers
    7783                template<typename node_t>
    78                 bool differs( const node_t * old_val, const node_t * new_val ) {
     84                bool skip( const ast::ptr<node_t> & val) {
     85                        return !val;
     86                }
     87
     88                template< template <class...> class container_t, typename node_t >
     89                bool skip( const container_t<ast::ptr< node_t >> & val ) {
     90                        return val.empty();
     91                }
     92
     93                //------------------------------
     94                /// Get the value to visit, different for pointers and containers
     95                template<typename node_t>
     96                auto get( const ast::ptr<node_t> & val, int ) -> decltype(val.get()) {
     97                        return val.get();
     98                }
     99
     100                template<typename node_t>
     101                const node_t & get( const node_t & val, long) {
     102                        return val;
     103                }
     104
     105
     106                //------------------------------
     107                /// Check if value was mutated, different for pointers and containers
     108                template<typename lhs_t, typename rhs_t>
     109                bool differs( const lhs_t * old_val, const rhs_t * new_val ) {
    79110                        return old_val != new_val;
    80111                }
    81112
    82                 template< template <class> class container_t >
    83                 bool differs( const container_t<ast::ptr< ast::Statement >> &, const container_t<ast::ptr< ast::Statement >> & new_val ) {
     113                template< template <class...> class container_t, typename node_t >
     114                bool differs( const container_t<ast::ptr< node_t >> &, const container_t<ast::ptr< node_t >> & new_val ) {
    84115                        return !new_val.empty();
    85                 }
    86         }
    87 
    88         template<typename parent_t, typename child_t>
    89         template< typename pass_t >
    90         void Pass< pass_t >::maybe_accept(
    91                 const parent_t * & parent,
    92                 const typename parent_t::child_t * child
    93         ) {
    94                 const auto & old_val = parent->*child;
    95                 if(!old_val) return;
    96 
    97                 auto new_val = call_accept(old_val);
    98 
    99                 if( __pass::differs(old_val, new_val) ) {
    100                         auto new_parent = mutate(parent);
    101                         new_parent->*child = new_val;
    102                         parent = new_parent;
    103116                }
    104117        }
     
    106119        template< typename pass_t >
    107120        template< typename node_t >
    108         auto Pass< pass_t >::call_accept( const node_t * node ) {
     121        auto Pass< pass_t >::call_accept( const node_t * node ) -> decltype( node->accept(*this) ) {
    109122                __pedantic_pass_assert( __visit_children() );
    110123                __pedantic_pass_assert( expr );
    111124
     125                static_assert( !std::is_base_of<ast::Expr, node_t>::value, "ERROR");
     126                static_assert( !std::is_base_of<ast::Stmt, node_t>::value, "ERROR");
     127
    112128                return node->accept( *this );
    113129        }
    114130
    115131        template< typename pass_t >
    116         ast::Expr * Pass< pass_t >::call_accept( const ast::Expr * expr ) {
     132        const ast::Expr * Pass< pass_t >::call_accept( const ast::Expr * expr ) {
    117133                __pedantic_pass_assert( __visit_children() );
    118134                __pedantic_pass_assert( expr );
     
    127143
    128144        template< typename pass_t >
    129         Stmt * Pass< pass_t >::call_accept( const Stmt * stmt ) {
     145        const ast::Stmt * Pass< pass_t >::call_accept( const ast::Stmt * stmt ) {
    130146                __pedantic_pass_assert( __visit_children() );
    131147                __pedantic_pass_assert( stmt );
     
    141157
    142158                // These may be modified by subnode but most be restored once we exit this statemnet.
    143                 ValueGuardPtr< const ast::TypeSubstitution * > __old_env         ( __pass::env( pass, 0); );
    144                 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > __old_decls_before( stmts_before );
    145                 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > __old_decls_after ( stmts_after  );
    146                 ValueGuardPtr< typename std::remove_pointer< decltype(decls_before) > __old_stmts_before( decls_before );
    147                 ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > __old_stmts_after ( decls_after  );
     159                ValueGuardPtr< const ast::TypeSubstitution * > __old_env         ( __pass::env( pass, 0) );
     160                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > > __old_decls_before( stmts_before );
     161                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > > __old_decls_after ( stmts_after  );
     162                ValueGuardPtr< typename std::remove_pointer< decltype(decls_before) > > __old_stmts_before( decls_before );
     163                ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > > __old_stmts_after ( decls_after  );
    148164
    149165                // Now is the time to actually visit the node
    150                 ast::Statement * nstmt = stmt->accept( *this );
     166                const ast::Stmt * nstmt = stmt->accept( *this );
    151167
    152168                // If the pass doesn't want to add anything then we are done
     
    161177
    162178                // Create a new Compound Statement to hold the new decls/stmts
    163                 ast::CompoundStmt * compound = new ast::CompoundStmt( parent->*child.location );
     179                ast::CompoundStmt * compound = new ast::CompoundStmt( stmt->location );
    164180
    165181                // Take all the declarations that go before
     
    168184
    169185                // Insert the original declaration
    170                 compound->kids.push_back( nstmt );
     186                compound->kids.emplace_back( nstmt );
    171187
    172188                // Insert all the declarations that go before
     
    178194
    179195        template< typename pass_t >
    180         template< template <class> class container_t >
     196        template< template <class...> class container_t >
    181197        container_t< ptr<Stmt> > Pass< pass_t >::call_accept( const container_t< ptr<Stmt> > & statements ) {
    182198                __pedantic_pass_assert( __visit_children() );
     
    196212
    197213                // These may be modified by subnode but most be restored once we exit this statemnet.
    198                 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > __old_decls_before( stmts_before );
    199                 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > __old_decls_after ( stmts_after  );
    200                 ValueGuardPtr< typename std::remove_pointer< decltype(decls_before) > __old_stmts_before( decls_before );
    201                 ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > __old_stmts_after ( decls_after  );
     214                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > > __old_decls_before( stmts_before );
     215                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > > __old_decls_after ( stmts_after  );
     216                ValueGuardPtr< typename std::remove_pointer< decltype(decls_before) > > __old_stmts_before( decls_before );
     217                ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > > __old_stmts_after ( decls_after  );
    202218
    203219                // update pass statitistics
     
    211227                        try {
    212228                                __pedantic_pass_assert( stmt );
    213                                 const ast::Statment * new_stmt = stmt->accept( visitor );
     229                                const ast::Stmt * new_stmt = stmt->accept( *this );
    214230                                assert( new_stmt );
    215231                                if(new_stmt != stmt ) mutated = true;
     
    240256                if ( !errors.isEmpty() ) { throw errors; }
    241257
    242                 return mutated ? new_kids : {};
     258                return mutated ? new_kids : container_t< ptr<Stmt> >();
    243259        }
    244260
    245261        template< typename pass_t >
    246         template< template <class> class container_t, typename node_t >
     262        template< template <class...> class container_t, typename node_t >
    247263        container_t< ast::ptr<node_t> > Pass< pass_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) {
    248264                __pedantic_pass_assert( __visit_children() );
     
    259275                        try {
    260276                                __pedantic_pass_assert( node );
    261                                 const node_t * new_node = strict_dynamic_cast< const node_t * >( node->accept( *this ) );
    262                                 if(new_stmt != stmt ) mutated = true;
     277                                const node_t * new_stmt = strict_dynamic_cast< const node_t * >( node->accept( *this ) );
     278                                if(new_stmt != node ) mutated = true;
    263279
    264280                                new_kids.emplace_back( new_stmt );
     
    271287                if ( ! errors.isEmpty() ) { throw errors; }
    272288
    273                 return mutated ? new_kids : {};
    274         }
     289                return mutated ? new_kids : container_t< ast::ptr<node_t> >();
     290        }
     291
     292        template< typename pass_t >
     293        template<typename node_t, typename parent_t, typename child_t>
     294        void Pass< pass_t >::maybe_accept(
     295                const node_t * & parent,
     296                child_t parent_t::*child
     297        ) {
     298                static_assert( std::is_base_of<parent_t, node_t>::value, "Error deductiing member object" );
     299
     300                if(__pass::skip(parent->*child)) return;
     301                const auto & old_val = __pass::get(parent->*child, 0);
     302
     303                static_assert( !std::is_same<const ast::Node * &, decltype(old_val)>::value, "ERROR");
     304
     305                auto new_val = call_accept( old_val );
     306
     307                static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value || std::is_same<int, decltype(old_val)>::value, "ERROR");
     308
     309                if( __pass::differs(old_val, new_val) ) {
     310                        auto new_parent = mutate(parent);
     311                        new_parent->*child = new_val;
     312                        parent = new_parent;
     313                }
     314        }
     315
    275316}
    276317
     
    284325
    285326template< typename pass_t >
    286 inline void ast::acceptAll( std::list< ast::ptr<ast::Decl> > & decls, ast::Pass< pass_t > & visitor ) {
     327inline void ast::accept_all( std::list< ast::ptr<ast::Decl> > & decls, ast::Pass< pass_t > & visitor ) {
    287328        // We are going to aggregate errors for all these statements
    288329        SemanticErrorException errors;
     
    292333
    293334        // get the stmts/decls that will need to be spliced in
    294         auto decls_before = __pass::declsToAddBefore( pass, 0);
    295         auto decls_after  = __pass::declsToAddAfter ( pass, 0);
     335        auto decls_before = __pass::declsToAddBefore( visitor.pass, 0);
     336        auto decls_after  = __pass::declsToAddAfter ( visitor.pass, 0);
    296337
    297338        // update pass statitistics
     
    343384// ObjectDecl
    344385template< typename pass_t >
    345 ast::DeclWithType * ast::Pass< pass_t >::visit( const ast::ObjectDecl * node ) {
     386const ast::DeclWithType * ast::Pass< pass_t >::visit( const ast::ObjectDecl * node ) {
    346387        VISIT_START( node );
    347388
    348389        VISIT(
    349390                {
    350                         indexer_guard guard { *this };
    351                         maybe_accept( node, ObjectDecl::type );
    352                 }
    353                 maybe_accept( node, ObjectDecl::init          );
    354                 maybe_accept( node, ObjectDecl::bitfieldWidth );
    355                 maybe_accept( node, ObjectDecl::attributes    );
     391                        guard_indexer guard { *this };
     392                        maybe_accept( node, &ast::ObjectDecl::type );
     393                }
     394                maybe_accept( node, &ast::ObjectDecl::init          );
     395                maybe_accept( node, &ast::ObjectDecl::bitfieldWidth );
     396                maybe_accept( node, &ast::ObjectDecl::attributes    );
    356397        )
    357398
    358         __pass::indexer::AddId( pass, 0, node );
     399        __pass::indexer::addId( pass, 0, node );
    359400
    360401        VISIT_END( DeclWithType, node );
     402}
     403
     404//--------------------------------------------------------------------------
     405// SingleInit
     406template< typename pass_t >
     407const ast::Init * ast::Pass< pass_t >::visit( const ast::SingleInit * node ) {
     408        VISIT_START( node );
     409
     410        VISIT(
     411                maybe_accept( node, &SingleInit::value );
     412        )
     413
     414        VISIT_END( Init, node );
     415}
     416
     417//--------------------------------------------------------------------------
     418// ListInit
     419template< typename pass_t >
     420const ast::Init * ast::Pass< pass_t >::visit( const ast::ListInit * node ) {
     421        VISIT_START( node );
     422
     423        VISIT(
     424                maybe_accept( node, &ListInit::designations );
     425                maybe_accept( node, &ListInit::initializers );
     426        )
     427
     428        VISIT_END( Init, node );
     429}
     430
     431//--------------------------------------------------------------------------
     432// ConstructorInit
     433template< typename pass_t >
     434const ast::Init * ast::Pass< pass_t >::visit( const ast::ConstructorInit * node ) {
     435        VISIT_START( node );
     436
     437        VISIT(
     438                maybe_accept( node, &ConstructorInit::ctor );
     439                maybe_accept( node, &ConstructorInit::dtor );
     440                maybe_accept( node, &ConstructorInit::init );
     441        )
     442
     443        VISIT_END( Init, node );
    361444}
    362445
    363446//--------------------------------------------------------------------------
    364447// Attribute
    365 template< typename pass_type >
    366 ast::Attribute * ast::Pass< pass_type >::visit( const ast::Attribute * node  )  {
    367         VISIT_START(node);
     448template< typename pass_t >
     449const ast::Attribute * ast::Pass< pass_t >::visit( const ast::Attribute * node  )  {
     450        VISIT_START( node );
    368451
    369452        VISIT(
    370                 maybe_accept( node, ast::Attribute::parameters );
     453                maybe_accept( node, &Attribute::parameters );
    371454        )
    372455
    373         VISIT_END(ast::Attribute *, node );
     456        VISIT_END( Attribute *, node );
    374457}
    375458
    376459//--------------------------------------------------------------------------
    377460// TypeSubstitution
    378 template< typename pass_type >
    379 TypeSubstitution * PassVisitor< pass_type >::mutate( const TypeSubstitution * node ) {
    380         MUTATE_START( node );
    381 
    382         #error this is broken
    383 
    384         for ( auto & p : node->typeEnv ) {
    385                 indexerScopedMutate( p.second, *this );
    386         }
    387         for ( auto & p : node->varEnv ) {
    388                 indexerScopedMutate( p.second, *this );
    389         }
    390 
    391         MUTATE_END( TypeSubstitution, node );
     461template< typename pass_t >
     462const ast::TypeSubstitution * ast::Pass< pass_t >::visit( const ast::TypeSubstitution * node ) {
     463        VISIT_START( node );
     464
     465        VISIT(
     466                {
     467                        bool mutated = false;
     468                        std::unordered_map< std::string, ast::ptr< ast::Type > > new_map;
     469                        for ( const auto & p : node->typeEnv ) {
     470                                guard_indexer guard { *this };
     471                                auto new_node = p.second->accept( *this );
     472                                if (new_node != p.second) mutated = false;
     473                                new_map.insert({ p.first, new_node });
     474                        }
     475                        if (mutated) {
     476                                auto new_node = mutate( node );
     477                                new_node->typeEnv.swap( new_map );
     478                                node = new_node;
     479                        }
     480                }
     481
     482                {
     483                        bool mutated = false;
     484                        std::unordered_map< std::string, ast::ptr< ast::Expr > > new_map;
     485                        for ( const auto & p : node->varEnv ) {
     486                                guard_indexer guard { *this };
     487                                auto new_node = p.second->accept( *this );
     488                                if (new_node != p.second) mutated = false;
     489                                new_map.insert({ p.first, new_node });
     490                        }
     491                        if (mutated) {
     492                                auto new_node = mutate( node );
     493                                new_node->varEnv.swap( new_map );
     494                                node = new_node;
     495                        }
     496                }
     497        )
     498
     499        VISIT_END( TypeSubstitution, node );
    392500}
    393501
Note: See TracChangeset for help on using the changeset viewer.