Changes in src/AST/Pass.impl.hpp [ee918356:3b0bc16]
- File:
-
- 1 edited
-
src/AST/Pass.impl.hpp (modified) (18 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Pass.impl.hpp
ree918356 r3b0bc16 79 79 80 80 template<typename it_t, template <class...> class container_t> 81 static inline void take_all( it_t it, container_t<ast::ptr<ast::Stmt>> * stmts, bool * mutated = nullptr ) {82 if(empty( stmts)) return;83 84 std::move( stmts->begin(), stmts->end(), it);85 stmts->clear();81 static inline void take_all( it_t it, container_t<ast::ptr<ast::Stmt>> * decls, bool * mutated = nullptr ) { 82 if(empty(decls)) return; 83 84 std::move(decls->begin(), decls->end(), it); 85 decls->clear(); 86 86 if(mutated) *mutated = true; 87 87 } … … 123 123 return !new_val.empty(); 124 124 } 125 }126 127 128 template< typename core_t >129 template< typename node_t >130 template< typename object_t, typename super_t, typename field_t >131 void ast::Pass< core_t >::result1< node_t >::apply(object_t * object, field_t super_t::* field) {132 object->*field = value;133 125 } 134 126 … … 139 131 !std::is_base_of<ast::Expr, node_t>::value && 140 132 !std::is_base_of<ast::Stmt, node_t>::value 141 , ast::Pass< core_t >::result1< 142 typename std::remove_pointer< decltype( node->accept(*this) ) >::type 143 > 133 , decltype( node->accept(*this) ) 144 134 >::type 145 135 { … … 150 140 static_assert( !std::is_base_of<ast::Stmt, node_t>::value, "ERROR"); 151 141 152 auto nval = node->accept( *this ); 153 ast::Pass< core_t >::result1< 154 typename std::remove_pointer< decltype( node->accept(*this) ) >::type 155 > res; 156 res.differs = nval != node; 157 res.value = nval; 158 return res; 142 return node->accept( *this ); 159 143 } 160 144 161 145 template< typename core_t > 162 typename ast::Pass< core_t >::template result1<ast::Expr>ast::Pass< core_t >::call_accept( const ast::Expr * expr ) {146 const ast::Expr * ast::Pass< core_t >::call_accept( const ast::Expr * expr ) { 163 147 __pedantic_pass_assert( __visit_children() ); 164 148 __pedantic_pass_assert( expr ); … … 169 153 } 170 154 171 auto nval = expr->accept( *this ); 172 return { nval != expr, nval }; 155 return expr->accept( *this ); 173 156 } 174 157 175 158 template< typename core_t > 176 typename ast::Pass< core_t >::template result1<ast::Stmt>ast::Pass< core_t >::call_accept( const ast::Stmt * stmt ) {159 const ast::Stmt * ast::Pass< core_t >::call_accept( const ast::Stmt * stmt ) { 177 160 __pedantic_pass_assert( __visit_children() ); 178 161 __pedantic_pass_assert( stmt ); 179 162 180 const ast::Stmt * nval = stmt->accept( *this ); 181 return { nval != stmt, nval }; 163 return stmt->accept( *this ); 182 164 } 183 165 184 166 template< typename core_t > 185 typename ast::Pass< core_t >::template result1<ast::Stmt>ast::Pass< core_t >::call_accept_as_compound( const ast::Stmt * stmt ) {167 const ast::Stmt * ast::Pass< core_t >::call_accept_as_compound( const ast::Stmt * stmt ) { 186 168 __pedantic_pass_assert( __visit_children() ); 187 169 __pedantic_pass_assert( stmt ); … … 208 190 // If the pass doesn't want to add anything then we are done 209 191 if( empty(stmts_before) && empty(stmts_after) && empty(decls_before) && empty(decls_after) ) { 210 return { nstmt != stmt, nstmt };192 return nstmt; 211 193 } 212 194 … … 230 212 __pass::take_all( std::back_inserter( compound->kids ), stmts_after ); 231 213 232 return {true, compound};214 return compound; 233 215 } 234 216 235 217 template< typename core_t > 236 218 template< template <class...> class container_t > 237 template< typename object_t, typename super_t, typename field_t > 238 void ast::Pass< core_t >::resultNstmt<container_t>::apply(object_t * object, field_t super_t::* field) { 239 auto & container = object->*field; 240 __pedantic_pass_assert( container.size() <= values.size() ); 241 242 auto cit = enumerate(container).begin(); 243 244 container_t<ptr<Stmt>> nvals; 245 for(delta & d : values) { 246 if( d.is_old ) { 247 __pedantic_pass_assert( cit.idx <= d.old_idx ); 248 std::advance( cit, d.old_idx - cit.idx ); 249 nvals.push_back( std::move( (*cit).val) ); 250 } else { 251 nvals.push_back( std::move(d.nval) ); 252 } 253 } 254 255 object->*field = std::move(nvals); 256 } 257 258 template< typename core_t > 259 template< template <class...> class container_t > 260 typename ast::Pass< core_t >::template resultNstmt<container_t> ast::Pass< core_t >::call_accept( const container_t< ptr<Stmt> > & statements ) { 219 container_t< ptr<Stmt> > ast::Pass< core_t >::call_accept( const container_t< ptr<Stmt> > & statements ) { 261 220 __pedantic_pass_assert( __visit_children() ); 262 221 if( statements.empty() ) return {}; … … 285 244 pass_visitor_stats.avg->push(pass_visitor_stats.depth); 286 245 287 resultNstmt<container_t> new_kids; 288 for( auto value : enumerate( statements ) ) { 246 bool mutated = false; 247 container_t< ptr<Stmt> > new_kids; 248 for( const Stmt * stmt : statements ) { 289 249 try { 290 size_t i = value.idx;291 const Stmt * stmt = value.val;292 250 __pedantic_pass_assert( stmt ); 293 251 const ast::Stmt * new_stmt = stmt->accept( *this ); 294 252 assert( new_stmt ); 295 if(new_stmt != stmt ) { new_kids.differs = true; }253 if(new_stmt != stmt ) mutated = true; 296 254 297 255 // Make sure that it is either adding statements or declartions but not both … … 303 261 304 262 // Take all the statements which should have gone after, N/A for first iteration 305 new_kids.take_all( decls_before);306 new_kids.take_all( stmts_before);263 __pass::take_all( std::back_inserter( new_kids ), decls_before, &mutated ); 264 __pass::take_all( std::back_inserter( new_kids ), stmts_before, &mutated ); 307 265 308 266 // Now add the statement if there is one 309 if(new_stmt != stmt) { 310 new_kids.values.emplace_back( new_stmt, i, false ); 311 } else { 312 new_kids.values.emplace_back( nullptr, i, true ); 313 } 267 new_kids.emplace_back( new_stmt ); 314 268 315 269 // Take all the declarations that go before 316 new_kids.take_all( decls_after);317 new_kids.take_all( stmts_after);270 __pass::take_all( std::back_inserter( new_kids ), decls_after, &mutated ); 271 __pass::take_all( std::back_inserter( new_kids ), stmts_after, &mutated ); 318 272 } 319 273 catch ( SemanticErrorException &e ) { … … 324 278 if ( !errors.isEmpty() ) { throw errors; } 325 279 326 return new_kids;280 return mutated ? new_kids : container_t< ptr<Stmt> >(); 327 281 } 328 282 329 283 template< typename core_t > 330 284 template< template <class...> class container_t, typename node_t > 331 template< typename object_t, typename super_t, typename field_t > 332 void ast::Pass< core_t >::resultN<container_t, node_t>::apply(object_t * object, field_t super_t::* field) { 333 auto & container = object->*field; 334 __pedantic_pass_assert( container.size() == values.size() ); 335 336 for(size_t i = 0; i < container.size(); i++) { 337 // Take all the elements that are different in 'values' 338 // and swap them into 'container' 339 if( values[i] != nullptr ) std::swap(container[i], values[i]); 340 } 341 342 // Now the original containers should still have the unchanged values 343 // but also contain the new values 344 } 345 346 template< typename core_t > 347 template< template <class...> class container_t, typename node_t > 348 typename ast::Pass< core_t >::template resultN<container_t, node_t> ast::Pass< core_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) { 285 container_t< ast::ptr<node_t> > ast::Pass< core_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) { 349 286 __pedantic_pass_assert( __visit_children() ); 350 287 if( container.empty() ) return {}; … … 356 293 357 294 bool mutated = false; 358 container_t< ptr<node_t>> new_kids;295 container_t< ast::ptr<node_t> > new_kids; 359 296 for ( const node_t * node : container ) { 360 297 try { 361 298 __pedantic_pass_assert( node ); 362 299 const node_t * new_stmt = strict_dynamic_cast< const node_t * >( node->accept( *this ) ); 363 if(new_stmt != node ) { 364 mutated = true; 365 new_kids.emplace_back( new_stmt ); 366 } else { 367 new_kids.emplace_back( nullptr ); 368 } 369 300 if(new_stmt != node ) mutated = true; 301 302 new_kids.emplace_back( new_stmt ); 370 303 } 371 304 catch( SemanticErrorException &e ) { … … 373 306 } 374 307 } 375 376 __pedantic_pass_assert( new_kids.size() == container.size() );377 308 pass_visitor_stats.depth--; 378 309 if ( ! errors.isEmpty() ) { throw errors; } 379 310 380 return ast::Pass< core_t >::resultN<container_t, node_t>{ mutated, new_kids };311 return mutated ? new_kids : container_t< ast::ptr<node_t> >(); 381 312 } 382 313 … … 396 327 auto new_val = call_accept( old_val ); 397 328 398 static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value /* || std::is_same<int, decltype(old_val)>::value */, "ERROR");399 400 if( new_val.differs) {329 static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value || std::is_same<int, decltype(old_val)>::value, "ERROR"); 330 331 if( __pass::differs(old_val, new_val) ) { 401 332 auto new_parent = __pass::mutate<core_t>(parent); 402 new_ val.apply(new_parent, child);333 new_parent->*child = new_val; 403 334 parent = new_parent; 404 335 } … … 422 353 static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value || std::is_same<int, decltype(old_val)>::value, "ERROR"); 423 354 424 if( new_val.differs) {355 if( __pass::differs(old_val, new_val) ) { 425 356 auto new_parent = __pass::mutate<core_t>(parent); 426 new_ val.apply( new_parent, child );357 new_parent->*child = new_val; 427 358 parent = new_parent; 428 359 } … … 1010 941 const Expr * func = clause.target.func ? clause.target.func->accept(*this) : nullptr; 1011 942 if(func != clause.target.func) mutated = true; 1012 else func = nullptr;1013 943 1014 944 std::vector<ptr<Expr>> new_args; … … 1016 946 for( const auto & arg : clause.target.args ) { 1017 947 auto a = arg->accept(*this); 1018 if( a != arg ) { 1019 mutated = true; 1020 new_args.push_back( a ); 1021 } else 1022 new_args.push_back( nullptr ); 948 new_args.push_back( a ); 949 if( a != arg ) mutated = true; 1023 950 } 1024 951 1025 952 const Stmt * stmt = clause.stmt ? clause.stmt->accept(*this) : nullptr; 1026 953 if(stmt != clause.stmt) mutated = true; 1027 else stmt = nullptr;1028 954 1029 955 const Expr * cond = clause.cond ? clause.cond->accept(*this) : nullptr; 1030 956 if(cond != clause.cond) mutated = true; 1031 else cond = nullptr;1032 957 1033 958 new_clauses.push_back( WaitForStmt::Clause{ {func, std::move(new_args) }, stmt, cond } ); … … 1036 961 if(mutated) { 1037 962 auto n = __pass::mutate<core_t>(node); 1038 for(size_t i = 0; i < new_clauses.size(); i++) { 1039 if(new_clauses.at(i).target.func != nullptr) std::swap(n->clauses.at(i).target.func, new_clauses.at(i).target.func); 1040 1041 for(size_t j = 0; j < new_clauses.at(i).target.args.size(); j++) { 1042 if(new_clauses.at(i).target.args.at(j) != nullptr) std::swap(n->clauses.at(i).target.args.at(j), new_clauses.at(i).target.args.at(j)); 1043 } 1044 1045 if(new_clauses.at(i).stmt != nullptr) std::swap(n->clauses.at(i).stmt, new_clauses.at(i).stmt); 1046 if(new_clauses.at(i).cond != nullptr) std::swap(n->clauses.at(i).cond, new_clauses.at(i).cond); 1047 } 963 n->clauses = std::move( new_clauses ); 1048 964 node = n; 1049 965 } … … 1053 969 if(node->field) { \ 1054 970 auto nval = call_accept( node->field ); \ 1055 if(nval .differs) { \971 if(nval != node->field ) { \ 1056 972 auto nparent = __pass::mutate<core_t>(node); \ 1057 nparent->field = nval .value; \973 nparent->field = nval; \ 1058 974 node = nparent; \ 1059 975 } \
Note:
See TracChangeset
for help on using the changeset viewer.