Changes in src/AST/Pass.impl.hpp [04124c4:f47f887]
- File:
-
- 1 edited
-
src/AST/Pass.impl.hpp (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Pass.impl.hpp
r04124c4 rf47f887 1 //2 // Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo3 //4 // The contents of this file are covered under the licence agreement in the5 // file "LICENCE" distributed with Cforall.6 //7 // Pass.impl.hpp --8 //9 // Author : Thierry Delisle10 // Created On : Thu May 09 15::37::05 201911 // Last Modified By :12 // Last Modified On :13 // Update Count :14 //15 16 1 #pragma once 17 // IWYU pragma: private, include " AST/Pass.hpp"2 // IWYU pragma: private, include "Pass.hpp" 18 3 19 4 #define VISIT_START( node ) \ 20 using namespace ast; \21 5 /* 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) ); \ 23 7 /* 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) ); \ 25 9 /* call the implementation of the previsit of this pass */ \ 26 __pass::previsit( pass, node, 0 );10 __pass::previsit( m_pass, node, 0 ); 27 11 28 12 #define VISIT( code ) \ … … 114 98 115 99 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 ) { 117 101 __pedantic_pass_assert( __visit_children() ); 118 102 __pedantic_pass_assert( expr ); 119 103 120 const ast::TypeSubstitution ** env_ptr = __pass::env( pass, 0);104 const ast::TypeSubstitution ** env_ptr = __pass::env( m_pass, 0); 121 105 if ( env_ptr && expr->env ) { 122 106 *env_ptr = expr->env; … … 127 111 128 112 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 ) { 130 114 __pedantic_pass_assert( __visit_children() ); 131 115 __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; 132 173 133 174 // add a few useful symbols to the scope … … 141 182 142 183 // 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 184 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > __old_decls_before( stmts_before ); 145 185 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > __old_decls_after ( stmts_after ); … … 147 187 ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > __old_stmts_after ( decls_after ); 148 188 149 // Now is the time to actually visit the node150 ast::Statement * nstmt = stmt->accept( *this );151 152 // If the pass doesn't want to add anything then we are done153 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 both158 // this is because otherwise the order would be awkward to predict159 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/stmts163 ast::CompoundStmt * compound = new ast::CompoundStmt( parent->*child.location );164 165 // Take all the declarations that go before166 __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 declaration170 compound->kids.push_back( nstmt );171 172 // Insert all the declarations that go before173 __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 statements186 SemanticErrorException errors;187 188 // add a few useful symbols to the scope189 using __pass::empty;190 191 // get the stmts/decls that will need to be spliced in192 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 203 189 // update pass statitistics 204 190 pass_visitor_stats.depth++; … … 207 193 208 194 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 ) { 211 197 try { 212 198 __pedantic_pass_assert( stmt ); … … 283 269 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 284 270 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 statements288 SemanticErrorException errors;289 290 // add a few useful symbols to the scope291 using __pass::empty;292 293 // get the stmts/decls that will need to be spliced in294 auto decls_before = __pass::declsToAddBefore( pass, 0);295 auto decls_after = __pass::declsToAddAfter ( pass, 0);296 297 // update pass statitistics298 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 decl304 if ( !empty( decls_after ) ) { decls.splice( i, *decls_after ); }305 306 if ( i == decls.end() ) break;307 308 try {309 // run visitor on declaration310 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 decl319 if ( !empty( decls_before ) ) { decls.splice( i, *decls_before ); }320 }321 pass_visitor_stats.depth--;322 if ( !errors.isEmpty() ) { throw errors; }323 }324 325 271 // A NOTE ON THE ORDER OF TRAVERSAL 326 272 // … … 343 289 // ObjectDecl 344 290 template< typename pass_t > 345 ast::Decl WithType * ast::Pass< pass_t >::visit( constast::ObjectDecl * node ) {291 ast::DeclarationWithType * Pass< pass_t >::mutate( ast::ObjectDecl * node ) { 346 292 VISIT_START( node ); 347 293 348 294 VISIT( 349 295 { 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 ); 356 302 ) 357 303 358 __pass::indexer::AddId( pass, 0, node );359 360 VISIT_END( Decl WithType, node );304 __pass::indexer::AddId( m_pass, 0, node ); 305 306 VISIT_END( DeclarationWithType, node ); 361 307 } 362 308 … … 364 310 // Attribute 365 311 template< typename pass_type > 366 ast::Attribute * ast::Pass< pass_type >::visit( const ast::Attribute *node ) {312 ast::Attribute * ast::Pass< pass_type >::visit( ast::ptr<ast::Attribute> & node ) { 367 313 VISIT_START(node); 368 314 … … 377 323 // TypeSubstitution 378 324 template< typename pass_type > 379 TypeSubstitution * PassVisitor< pass_type >::mutate( constTypeSubstitution * node ) {325 TypeSubstitution * PassVisitor< pass_type >::mutate( TypeSubstitution * node ) { 380 326 MUTATE_START( node ); 381 327
Note:
See TracChangeset
for help on using the changeset viewer.