Changes in / [b1b3df5:3e1cd17]
- Location:
- src/AST
- Files:
-
- 3 edited
-
Pass.hpp (modified) (1 diff)
-
Pass.impl.hpp (modified) (10 diffs)
-
Pass.proto.hpp (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Pass.hpp
rb1b3df5 r3e1cd17 252 252 private: 253 253 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. 255 259 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 > 259 268 >; 260 269 261 270 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; 263 273 264 274 // requests WithStmtsToAdd directly add to this statement, as if it is a compound. -
src/AST/Pass.impl.hpp
rb1b3df5 r3e1cd17 109 109 return val; 110 110 } 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 } 111 123 } 112 124 … … 114 126 template< typename node_t > 115 127 auto 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 { 117 130 __pedantic_pass_assert( __visit_children() ); 118 131 __pedantic_pass_assert( node ); 119 132 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 120 136 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 145 template< typename core_t > 146 ast::__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 154 template< typename core_t > 155 ast::__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 }; 122 161 } 123 162 … … 191 230 ast::__pass::template resultNstmt<container_t> ast::Pass< core_t >::call_accept( const container_t< ptr<Stmt> > & statements ) { 192 231 __pedantic_pass_assert( __visit_children() ); 193 __pedantic_pass_assert( !statements.empty() );232 if ( statements.empty() ) return {}; 194 233 195 234 // We are going to aggregate errors for all these statements … … 224 263 const ast::Stmt * new_stmt = stmt->accept( *this ); 225 264 assert( new_stmt ); 265 if ( new_stmt != stmt ) { new_kids.differs = true; } 226 266 227 267 // Make sure that it is either adding statements or declartions but not both … … 236 276 // Now add the statement if there is one 237 277 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 ); 240 279 } else { 241 new_kids.values.emplace_back( i);280 new_kids.values.emplace_back( nullptr, i, true ); 242 281 } 243 282 … … 259 298 ast::__pass::template resultN<container_t, node_t> ast::Pass< core_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) { 260 299 __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 {}; 264 301 SemanticErrorException errors; 265 302 … … 305 342 static_assert( !std::is_same<const ast::Node * &, decltype(old_val)>::value, "ERROR" ); 306 343 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 ) { 309 349 auto new_parent = __pass::mutate<core_t>(parent); 310 result.apply( new_parent, field);350 new_val.apply(new_parent, field); 311 351 parent = new_parent; 312 352 } … … 326 366 static_assert( !std::is_same<const ast::Node * &, decltype(old_val)>::value, "ERROR" ); 327 367 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 ) { 330 373 auto new_parent = __pass::mutate<core_t>(parent); 331 result.apply( new_parent, field);374 new_val.apply(new_parent, field); 332 375 parent = new_parent; 333 376 } … … 347 390 static_assert( !std::is_same<const ast::Node * &, decltype(old_val)>::value, "ERROR" ); 348 391 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 ) { 351 397 auto new_parent = __pass::mutate<core_t>(parent); 352 result.apply( new_parent, child );398 new_val.apply( new_parent, child ); 353 399 parent = new_parent; 354 400 } … … 406 452 template< typename core_t > 407 453 inline void ast::accept_all( ast::TranslationUnit & unit, ast::Pass< core_t > & visitor ) { 408 if ( auto ptr = __pass::translation Unit( visitor.core, 0 ) ) {454 if ( auto ptr = __pass::translation_unit::get_cptr( visitor.core, 0 ) ) { 409 455 ValueGuard<const TranslationUnit *> guard( *ptr ); 410 456 *ptr = &unit; -
src/AST/Pass.proto.hpp
rb1b3df5 r3e1cd17 154 154 bool is_old; 155 155 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) {} 158 158 }; 159 159 … … 188 188 std::transform( stmts->begin(), stmts->end(), std::back_inserter( values ), 189 189 [](ast::ptr<ast::Stmt>& stmt) -> delta { 190 return delta( stmt.release() );190 return delta( stmt.release(), -1, false ); 191 191 }); 192 192 stmts->clear(); … … 201 201 [](ast::ptr<ast::Decl>& decl) -> delta { 202 202 ast::Decl const * d = decl.release(); 203 return delta( new DeclStmt( d->location, d ) );203 return delta( new DeclStmt( d->location, d ), -1, false ); 204 204 }); 205 205 decls->clear(); … … 257 257 } else { 258 258 node = core.previsit( node ); 259 assertf( node, "Previsit must not return nullptr.");259 assertf(node, "Previsit must not return NULL"); 260 260 } 261 261 } … … 310 310 FIELD_PTR( at_cleanup, __pass::at_cleanup_t ) 311 311 FIELD_PTR( visitor, ast::Pass<core_t> * const ) 312 FIELD_PTR( translationUnit, const TranslationUnit * )313 312 314 313 // Remove the macro to make sure we don't clash … … 507 506 } // namespace forall 508 507 508 // For passes that need access to the global context. Searches `translationUnit` 509 namespace 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 509 522 // For passes, usually utility passes, that have a result. 510 523 namespace result {
Note:
See TracChangeset
for help on using the changeset viewer.