Ignore:
File:
1 edited

Legend:

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

    r04124c4 rf47f887  
    1 //
    2 // Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
    3 //
    4 // The contents of this file are covered under the licence agreement in the
    5 // file "LICENCE" distributed with Cforall.
    6 //
    7 // Pass.impl.hpp --
    8 //
    9 // Author           : Thierry Delisle
    10 // Created On       : Thu May 09 15::37::05 2019
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     :
    14 //
    15 
    161#pragma once
    17 // IWYU pragma: private, include "AST/Pass.hpp"
     2// IWYU pragma: private, include "Pass.hpp"
    183
    194#define VISIT_START( node ) \
    20         using namespace ast; \
    215        /* back-up the visit children */ \
    22         __attribute__((unused)) ast::__pass::visit_children_guard guard1( ast::__pass::visit_children(pass, 0) ); \
     6        __attribute__((unused)) ast::__pass::visit_children_guard guard1( ast::__pass::visit_children(m_pass, 0) ); \
    237        /* setup the scope for passes that want to run code at exit */ \
    24         __attribute__((unused)) ast::__pass::guard_value          guard2( ast::__pass::at_cleanup    (pass, 0) ); \
     8        __attribute__((unused)) ast::__pass::guard_value          guard2( ast::__pass::at_cleanup    (m_pass, 0) ); \
    259        /* call the implementation of the previsit of this pass */ \
    26         __pass::previsit( pass, node, 0 );
     10        __pass::previsit( m_pass, node, 0 );
    2711
    2812#define VISIT( code ) \
     
    11498
    11599        template< typename pass_t >
    116         ast::Expr * Pass< pass_t >::call_accept( const ast::Expr * expr ) {
     100        ast::Expression * Pass< pass_t >::call_accept( const ast::Expression * expr ) {
    117101                __pedantic_pass_assert( __visit_children() );
    118102                __pedantic_pass_assert( expr );
    119103
    120                 const ast::TypeSubstitution ** env_ptr = __pass::env( pass, 0);
     104                const ast::TypeSubstitution ** env_ptr = __pass::env( m_pass, 0);
    121105                if ( env_ptr && expr->env ) {
    122106                        *env_ptr = expr->env;
     
    127111
    128112        template< typename pass_t >
    129         Stmt * Pass< pass_t >::call_accept( const Stmt * stmt ) {
     113        ast::Statement * Pass< pass_t >::call_accept( const ast::Statement * stmt ) {
    130114                __pedantic_pass_assert( __visit_children() );
    131115                __pedantic_pass_assert( stmt );
     116
     117                // add a few useful symbols to the scope
     118                using __pass::empty;
     119                using decls_t = typename std::remove_pointer< decltype(__decls_before()) >::type;
     120                using stmts_t = typename std::remove_pointer< decltype(__stmts_before()) >::type;
     121
     122                // get the stmts/decls that will need to be spliced in
     123                auto stmts_before = __pass::stmtsToAddBefore( m_pass, 0);
     124                auto stmts_after  = __pass::stmtsToAddAfter ( m_pass, 0);
     125                auto decls_before = __pass::declsToAddBefore( m_pass, 0);
     126                auto decls_after  = __pass::declsToAddAfter ( m_pass, 0);
     127
     128                // These may be modified by subnode but most be restored once we exit this statemnet.
     129                ValueGuardPtr< const ast::TypeSubstitution * > __old_env         ( __pass::env( m_pass, 0);  );
     130                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > __old_decls_before( stmts_before );
     131                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > __old_decls_after ( stmts_after  );
     132                ValueGuardPtr< typename std::remove_pointer< decltype(decls_before) > __old_stmts_before( decls_before );
     133                ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > __old_stmts_after ( decls_after  );
     134
     135                // Now is the time to actually visit the node
     136                ast::Statement * nstmt = stmt->accept( *this );
     137
     138                // If the pass doesn't want to add anything then we are done
     139                if( empty(stmts_before) && empty(stmts_after) && empty(decls_before) && empty(decls_after) ) {
     140                        return nstmt;
     141                }
     142
     143                // Make sure that it is either adding statements or declartions but not both
     144                // this is because otherwise the order would be awkward to predict
     145                assert(( empty( stmts_before ) && empty( stmts_after ))
     146                    || ( empty( decls_before ) && empty( decls_after )) );
     147
     148                // Create a new Compound Statement to hold the new decls/stmts
     149                ast::CompoundStmt * compound = new ast::CompoundStmt( parent->*child.location );
     150
     151                // Take all the declarations that go before
     152                __pass::take_all( std::back_inserter( compound->kids ), decls_before );
     153                __pass::take_all( std::back_inserter( compound->kids ), stmts_before );
     154
     155                // Insert the original declaration
     156                compound->kids.push_back( nstmt );
     157
     158                // Insert all the declarations that go before
     159                __pass::take_all( std::back_inserter( compound->kids ), decls_after );
     160                __pass::take_all( std::back_inserter( compound->kids ), stmts_after );
     161
     162                return compound;
     163        }
     164
     165        template< typename pass_t >
     166        template< template <class> class container_t >
     167        container_t< ast::ptr<ast::Statement> > Pass< pass_t >::call_accept( const container_t< ast::ptr<ast::Statement> > & statements ) {
     168                __pedantic_pass_assert( __visit_children() );
     169                if( statements.empty() ) return {};
     170
     171                // We are going to aggregate errors for all these statements
     172                SemanticErrorException errors;
    132173
    133174                // add a few useful symbols to the scope
     
    141182
    142183                // 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);  );
    144184                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > __old_decls_before( stmts_before );
    145185                ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > __old_decls_after ( stmts_after  );
     
    147187                ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > __old_stmts_after ( decls_after  );
    148188
    149                 // Now is the time to actually visit the node
    150                 ast::Statement * nstmt = stmt->accept( *this );
    151 
    152                 // If the pass doesn't want to add anything then we are done
    153                 if( empty(stmts_before) && empty(stmts_after) && empty(decls_before) && empty(decls_after) ) {
    154                         return nstmt;
    155                 }
    156 
    157                 // Make sure that it is either adding statements or declartions but not both
    158                 // this is because otherwise the order would be awkward to predict
    159                 assert(( empty( stmts_before ) && empty( stmts_after ))
    160                     || ( empty( decls_before ) && empty( decls_after )) );
    161 
    162                 // Create a new Compound Statement to hold the new decls/stmts
    163                 ast::CompoundStmt * compound = new ast::CompoundStmt( parent->*child.location );
    164 
    165                 // Take all the declarations that go before
    166                 __pass::take_all( std::back_inserter( compound->kids ), decls_before );
    167                 __pass::take_all( std::back_inserter( compound->kids ), stmts_before );
    168 
    169                 // Insert the original declaration
    170                 compound->kids.push_back( nstmt );
    171 
    172                 // Insert all the declarations that go before
    173                 __pass::take_all( std::back_inserter( compound->kids ), decls_after );
    174                 __pass::take_all( std::back_inserter( compound->kids ), stmts_after );
    175 
    176                 return compound;
    177         }
    178 
    179         template< typename pass_t >
    180         template< template <class> class container_t >
    181         container_t< ptr<Stmt> > Pass< pass_t >::call_accept( const container_t< ptr<Stmt> > & statements ) {
    182                 __pedantic_pass_assert( __visit_children() );
    183                 if( statements.empty() ) return {};
    184 
    185                 // We are going to aggregate errors for all these statements
    186                 SemanticErrorException errors;
    187 
    188                 // add a few useful symbols to the scope
    189                 using __pass::empty;
    190 
    191                 // get the stmts/decls that will need to be spliced in
    192                 auto stmts_before = __pass::stmtsToAddBefore( pass, 0);
    193                 auto stmts_after  = __pass::stmtsToAddAfter ( pass, 0);
    194                 auto decls_before = __pass::declsToAddBefore( pass, 0);
    195                 auto decls_after  = __pass::declsToAddAfter ( pass, 0);
    196 
    197                 // 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  );
    202 
    203189                // update pass statitistics
    204190                pass_visitor_stats.depth++;
     
    207193
    208194                bool mutated = false;
    209                 container_t< ptr<Stmt> > new_kids;
    210                 for( const Stmt * stmt : statements ) {
     195                container_t<ast::ptr< ast::Statement >> new_kids;
     196                for( const ast::Statement * stmt : statements ) {
    211197                        try {
    212198                                __pedantic_pass_assert( stmt );
     
    283269//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    284270
    285 template< typename pass_t >
    286 inline void ast::acceptAll( std::list< ast::ptr<ast::Decl> > & decls, ast::Pass< pass_t > & visitor ) {
    287         // We are going to aggregate errors for all these statements
    288         SemanticErrorException errors;
    289 
    290         // add a few useful symbols to the scope
    291         using __pass::empty;
    292 
    293         // 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);
    296 
    297         // update pass statitistics
    298         pass_visitor_stats.depth++;
    299         pass_visitor_stats.max->push(pass_visitor_stats.depth);
    300         pass_visitor_stats.avg->push(pass_visitor_stats.depth);
    301 
    302         for ( std::list< ast::ptr<ast::Decl> >::iterator i = decls.begin(); ; ++i ) {
    303                 // splice in new declarations after previous decl
    304                 if ( !empty( decls_after ) ) { decls.splice( i, *decls_after ); }
    305 
    306                 if ( i == decls.end() ) break;
    307 
    308                 try {
    309                         // run visitor on declaration
    310                         ast::ptr<ast::Decl> & node = *i;
    311                         assert( node );
    312                         node = node->accept( visitor );
    313                 }
    314                 catch( SemanticErrorException &e ) {
    315                         errors.append( e );
    316                 }
    317 
    318                 // splice in new declarations before current decl
    319                 if ( !empty( decls_before ) ) { decls.splice( i, *decls_before ); }
    320         }
    321         pass_visitor_stats.depth--;
    322         if ( !errors.isEmpty() ) { throw errors; }
    323 }
    324 
    325271// A NOTE ON THE ORDER OF TRAVERSAL
    326272//
     
    343289// ObjectDecl
    344290template< typename pass_t >
    345 ast::DeclWithType * ast::Pass< pass_t >::visit( const ast::ObjectDecl * node ) {
     291ast::DeclarationWithType * Pass< pass_t >::mutate( ast::ObjectDecl * node ) {
    346292        VISIT_START( node );
    347293
    348294        VISIT(
    349295                {
    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    );
     296                        auto guard = make_indexer_guard();
     297                        maybe_accept( node, ast::ObjectDecl::type );
     298                }
     299                maybe_accept( node, ast::ObjectDecl::init          );
     300                maybe_accept( node, ast::ObjectDecl::bitfieldWidth );
     301                maybe_accept( node, ast::ObjectDecl::attributes    );
    356302        )
    357303
    358         __pass::indexer::AddId( pass, 0, node );
    359 
    360         VISIT_END( DeclWithType, node );
     304        __pass::indexer::AddId( m_pass, 0, node );
     305
     306        VISIT_END( DeclarationWithType, node );
    361307}
    362308
     
    364310// Attribute
    365311template< typename pass_type >
    366 ast::Attribute * ast::Pass< pass_type >::visit( const ast::Attribute * node  )  {
     312ast::Attribute * ast::Pass< pass_type >::visit( ast::ptr<ast::Attribute> & node  )  {
    367313        VISIT_START(node);
    368314
     
    377323// TypeSubstitution
    378324template< typename pass_type >
    379 TypeSubstitution * PassVisitor< pass_type >::mutate( const TypeSubstitution * node ) {
     325TypeSubstitution * PassVisitor< pass_type >::mutate( TypeSubstitution * node ) {
    380326        MUTATE_START( node );
    381327
Note: See TracChangeset for help on using the changeset viewer.