- Timestamp:
- Feb 8, 2022, 11:53:13 AM (4 years ago)
- Branches:
- ADT, ast-experimental, enum, master, pthread-emulation, qualifiedEnum, stuck-waitfor-destruct
- Children:
- cc7bbe6
- Parents:
- 97c215f (diff), 1cf8a9f (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. - Location:
- src/AST
- Files:
-
- 11 edited
-
Convert.cpp (modified) (7 diffs)
-
Copy.hpp (modified) (2 diffs)
-
Fwd.hpp (modified) (2 diffs)
-
Node.cpp (modified) (2 diffs)
-
Node.hpp (modified) (1 diff)
-
Pass.hpp (modified) (2 diffs)
-
Pass.impl.hpp (modified) (133 diffs)
-
Print.cpp (modified) (3 diffs)
-
Stmt.cpp (modified) (2 diffs)
-
Stmt.hpp (modified) (9 diffs)
-
Visitor.hpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
r97c215f rf5a51db 9 9 // Author : Thierry Delisle 10 10 // Created On : Thu May 09 15::37::05 2019 11 // Last Modified By : Andrew Beach12 // Last Modified On : Wed Jul 14 16:15:00 202113 // Update Count : 3711 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Feb 2 13:19:22 2022 13 // Update Count : 41 14 14 // 15 15 … … 393 393 auto stmt = new IfStmt( 394 394 get<Expression>().accept1( node->cond ), 395 get<Statement>().accept1( node->then Part),396 get<Statement>().accept1( node->else Part),395 get<Statement>().accept1( node->then ), 396 get<Statement>().accept1( node->else_ ), 397 397 get<Statement>().acceptL( node->inits ) 398 398 ); … … 419 419 } 420 420 421 const ast::Stmt * visit( const ast::While Stmt * node ) override final {421 const ast::Stmt * visit( const ast::WhileDoStmt * node ) override final { 422 422 if ( inCache( node ) ) return nullptr; 423 423 auto inits = get<Statement>().acceptL( node->inits ); 424 auto stmt = new While Stmt(424 auto stmt = new WhileDoStmt( 425 425 get<Expression>().accept1( node->cond ), 426 426 get<Statement>().accept1( node->body ), 427 get<Statement>().accept1( node->else_ ), 427 428 inits, 428 429 node->isDoWhile … … 437 438 get<Expression>().accept1( node->cond ), 438 439 get<Expression>().accept1( node->inc ), 439 get<Statement>().accept1( node->body ) 440 get<Statement>().accept1( node->body ), 441 get<Statement>().accept1( node->else_ ) 440 442 ); 441 443 return stmtPostamble( stmt, node ); … … 1872 1874 old->location, 1873 1875 GET_ACCEPT_1(condition, Expr), 1874 GET_ACCEPT_1(then Part, Stmt),1875 GET_ACCEPT_1(else Part, Stmt),1876 GET_ACCEPT_1(then, Stmt), 1877 GET_ACCEPT_1(else_, Stmt), 1876 1878 GET_ACCEPT_V(initialization, Stmt), 1877 1879 GET_LABELS_V(old->labels) … … 1902 1904 } 1903 1905 1904 virtual void visit( const While Stmt * old ) override final {1906 virtual void visit( const WhileDoStmt * old ) override final { 1905 1907 if ( inCache( old ) ) return; 1906 this->node = new ast::While Stmt(1908 this->node = new ast::WhileDoStmt( 1907 1909 old->location, 1908 1910 GET_ACCEPT_1(condition, Expr), 1909 1911 GET_ACCEPT_1(body, Stmt), 1912 GET_ACCEPT_1(else_, Stmt), 1910 1913 GET_ACCEPT_V(initialization, Stmt), 1911 1914 old->isDoWhile, … … 1923 1926 GET_ACCEPT_1(increment, Expr), 1924 1927 GET_ACCEPT_1(body, Stmt), 1928 GET_ACCEPT_1(else_, Stmt), 1925 1929 GET_LABELS_V(old->labels) 1926 1930 ); -
src/AST/Copy.hpp
r97c215f rf5a51db 10 10 // Created On : Wed Jul 10 16:13:00 2019 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Nov 11 9:22:00 202113 // Update Count : 212 // Last Modified On : Wed Dec 15 11:07:00 2021 13 // Update Count : 3 14 14 // 15 15 … … 52 52 Node * deepCopy<Node>( const Node * localRoot ); 53 53 54 template<typename node_t, enum Node::ref_type ref_t> 55 node_t * shallowCopy( const ptr_base<node_t, ref_t> & localRoot ) { 56 return shallowCopy( localRoot.get() ); 57 } 58 59 template<typename node_t, enum Node::ref_type ref_t> 60 node_t * deepCopy( const ptr_base<node_t, ref_t> & localRoot ) { 61 return deepCopy( localRoot.get() ); 62 } 63 54 64 } 55 65 -
src/AST/Fwd.hpp
r97c215f rf5a51db 10 10 // Created On : Wed May 8 16:05:00 2019 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 12 18:37:39 202113 // Update Count : 412 // Last Modified On : Tue Feb 1 09:08:33 2022 13 // Update Count : 5 14 14 // 15 15 … … 44 44 class DirectiveStmt; 45 45 class IfStmt; 46 class While Stmt;46 class WhileDoStmt; 47 47 class ForStmt; 48 48 class SwitchStmt; -
src/AST/Node.cpp
r97c215f rf5a51db 10 10 // Created On : Thu May 16 14:16:00 2019 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 12 18:25:06 202113 // Update Count : 212 // Last Modified On : Tue Feb 1 09:09:39 2022 13 // Update Count : 3 14 14 // 15 15 … … 146 146 template class ast::ptr_base< ast::IfStmt, ast::Node::ref_type::weak >; 147 147 template class ast::ptr_base< ast::IfStmt, ast::Node::ref_type::strong >; 148 template class ast::ptr_base< ast::While Stmt, ast::Node::ref_type::weak >;149 template class ast::ptr_base< ast::While Stmt, ast::Node::ref_type::strong >;148 template class ast::ptr_base< ast::WhileDoStmt, ast::Node::ref_type::weak >; 149 template class ast::ptr_base< ast::WhileDoStmt, ast::Node::ref_type::strong >; 150 150 template class ast::ptr_base< ast::ForStmt, ast::Node::ref_type::weak >; 151 151 template class ast::ptr_base< ast::ForStmt, ast::Node::ref_type::strong >; -
src/AST/Node.hpp
r97c215f rf5a51db 188 188 } 189 189 190 ptr_base & operator=( const node_t * node ) { 191 assign( node ); 192 return *this; 193 } 194 190 195 template<typename o_node_t> 191 196 ptr_base & operator=( const o_node_t * node ) { -
src/AST/Pass.hpp
r97c215f rf5a51db 146 146 const ast::Stmt * visit( const ast::DirectiveStmt * ) override final; 147 147 const ast::Stmt * visit( const ast::IfStmt * ) override final; 148 const ast::Stmt * visit( const ast::While Stmt* ) override final;148 const ast::Stmt * visit( const ast::WhileDoStmt * ) override final; 149 149 const ast::Stmt * visit( const ast::ForStmt * ) override final; 150 150 const ast::Stmt * visit( const ast::SwitchStmt * ) override final; … … 238 238 239 239 private: 240 const ast::Stmt * call_accept( const ast::Stmt * ); 241 const ast::Expr * call_accept( const ast::Expr * ); 242 243 // requests WithStmtsToAdd directly add to this statement, as if it is a compound. 244 245 const ast::Stmt * call_accept_as_compound(const ast::Stmt *); 246 240 241 // Regular nodes 247 242 template< typename node_t > 248 auto call_accept( const node_t * node ) -> typename std::enable_if< 243 struct result1 { 244 bool differs; 245 const node_t * value; 246 247 template< typename object_t, typename super_t, typename field_t > 248 void apply(object_t *, field_t super_t::* field); 249 }; 250 251 result1<ast::Stmt> call_accept( const ast::Stmt * ); 252 result1<ast::Expr> call_accept( const ast::Expr * ); 253 254 template< typename node_t > 255 auto call_accept( const node_t * node ) 256 -> typename std::enable_if< 249 257 !std::is_base_of<ast::Expr, node_t>::value && 250 258 !std::is_base_of<ast::Stmt, node_t>::value 251 , decltype( node->accept(*this) ) 259 , result1< 260 typename std::remove_pointer< decltype( node->accept(*this) ) >::type 261 > 252 262 >::type; 253 263 264 // requests WithStmtsToAdd directly add to this statement, as if it is a compound. 265 result1<ast::Stmt> call_accept_as_compound(const ast::Stmt *); 266 267 template<typename it_t, template <class...> class container_t> 268 static inline void take_all_delta( it_t it, container_t<ast::ptr<ast::Decl>> * decls, bool * mutated = nullptr ) { 269 if(empty(decls)) return; 270 271 std::transform(decls->begin(), decls->end(), it, [](ast::ptr<ast::Decl>&& decl) -> auto { 272 auto loc = decl->location; 273 auto stmt = new DeclStmt( loc, decl.release() ); 274 return { {stmt}, -1, false }; 275 }); 276 decls->clear(); 277 if(mutated) *mutated = true; 278 } 279 280 // Container of statements 254 281 template< template <class...> class container_t > 255 container_t< ptr<Stmt> > call_accept( const container_t< ptr<Stmt> > & ); 256 282 struct resultNstmt { 283 struct delta { 284 ptr<Stmt> nval; 285 ssize_t old_idx; 286 bool is_old; 287 288 delta(const Stmt * s, ssize_t i, bool old) : nval{s}, old_idx{i}, is_old{old} {} 289 }; 290 291 bool differs; 292 container_t< delta > values; 293 294 resultNstmt() : differs(false), values{} {} 295 resultNstmt(bool diff, container_t< delta > && vals) : differs(diff), values(vals) {} 296 297 template< typename object_t, typename super_t, typename field_t > 298 void apply(object_t *, field_t super_t::* field); 299 300 template< template <class...> class incontainer_t > 301 void take_all( incontainer_t<ast::ptr<ast::Stmt>> * stmts ) { 302 if(!stmts || stmts->empty()) return; 303 304 std::transform(stmts->begin(), stmts->end(), std::back_inserter( values ), [](ast::ptr<ast::Stmt>& decl) -> delta { 305 return delta( decl.release(), -1, false ); 306 }); 307 stmts->clear(); 308 differs = true; 309 } 310 311 template< template <class...> class incontainer_t > 312 void take_all( incontainer_t<ast::ptr<ast::Decl>> * decls ) { 313 if(!decls || decls->empty()) return; 314 315 std::transform(decls->begin(), decls->end(), std::back_inserter( values ), [](ast::ptr<ast::Decl>& decl) -> auto { 316 auto loc = decl->location; 317 auto stmt = new DeclStmt( loc, decl.release() ); 318 return delta( stmt, -1, false ); 319 }); 320 decls->clear(); 321 differs = true; 322 } 323 }; 324 325 template< template <class...> class container_t > 326 resultNstmt<container_t> call_accept( const container_t< ptr<Stmt> > & ); 327 328 // Container of something 257 329 template< template <class...> class container_t, typename node_t > 258 container_t< ptr<node_t> > call_accept( const container_t< ptr<node_t> > & container ); 330 struct resultN { 331 bool differs; 332 container_t<ptr<node_t>> values; 333 334 template< typename object_t, typename super_t, typename field_t > 335 void apply(object_t *, field_t super_t::* field); 336 }; 337 338 template< template <class...> class container_t, typename node_t > 339 resultN< container_t, node_t > call_accept( const container_t< ptr<node_t> > & container ); 259 340 260 341 public: 261 342 /// Logic to call the accept and mutate the parent if needed, delegates call to accept 262 template<typename node_t, typename parent_t, typename child_t>263 void maybe_accept(const node_t * &, child_t parent_t::* child);264 265 template<typename node_t, typename parent_t, typename child_t>266 void maybe_accept_as_compound(const node_t * &, child_t parent_t::* child);343 template<typename node_t, typename parent_t, typename field_t> 344 void maybe_accept(const node_t * &, field_t parent_t::* field); 345 346 template<typename node_t, typename parent_t, typename field_t> 347 void maybe_accept_as_compound(const node_t * &, field_t parent_t::* field); 267 348 268 349 private: -
src/AST/Pass.impl.hpp
r97c215f rf5a51db 34 34 __pass::previsit( core, node, 0 ); 35 35 36 #define VISIT( code... ) \37 /* if this node should visit its children */ \38 if ( __visit_children() ) { \39 /* visit the children */ \40 code \41 }42 43 36 #define VISIT_END( type, node ) \ 44 37 /* call the implementation of the postvisit of this pass */ \ … … 86 79 87 80 template<typename it_t, template <class...> class container_t> 88 static inline void take_all( it_t it, container_t<ast::ptr<ast::Stmt>> * decls, bool * mutated = nullptr ) {89 if(empty( decls)) return;90 91 std::move( decls->begin(), decls->end(), it);92 decls->clear();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(); 93 86 if(mutated) *mutated = true; 94 87 } … … 130 123 return !new_val.empty(); 131 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; 132 133 } 133 134 … … 138 139 !std::is_base_of<ast::Expr, node_t>::value && 139 140 !std::is_base_of<ast::Stmt, node_t>::value 140 , decltype( node->accept(*this) ) 141 , ast::Pass< core_t >::result1< 142 typename std::remove_pointer< decltype( node->accept(*this) ) >::type 143 > 141 144 >::type 142 145 { … … 147 150 static_assert( !std::is_base_of<ast::Stmt, node_t>::value, "ERROR"); 148 151 149 return node->accept( *this ); 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; 150 159 } 151 160 152 161 template< typename core_t > 153 const ast::Expr *ast::Pass< core_t >::call_accept( const ast::Expr * expr ) {162 ast::Pass< core_t >::result1<ast::Expr> ast::Pass< core_t >::call_accept( const ast::Expr * expr ) { 154 163 __pedantic_pass_assert( __visit_children() ); 155 164 __pedantic_pass_assert( expr ); … … 160 169 } 161 170 162 return expr->accept( *this ); 171 auto nval = expr->accept( *this ); 172 return { nval != expr, nval }; 163 173 } 164 174 165 175 template< typename core_t > 166 const ast::Stmt *ast::Pass< core_t >::call_accept( const ast::Stmt * stmt ) {176 ast::Pass< core_t >::result1<ast::Stmt> ast::Pass< core_t >::call_accept( const ast::Stmt * stmt ) { 167 177 __pedantic_pass_assert( __visit_children() ); 168 178 __pedantic_pass_assert( stmt ); 169 179 170 return stmt->accept( *this ); 180 const ast::Stmt * nval = stmt->accept( *this ); 181 return { nval != stmt, nval }; 171 182 } 172 183 173 184 template< typename core_t > 174 const ast::Stmt *ast::Pass< core_t >::call_accept_as_compound( const ast::Stmt * stmt ) {185 ast::Pass< core_t >::result1<ast::Stmt> ast::Pass< core_t >::call_accept_as_compound( const ast::Stmt * stmt ) { 175 186 __pedantic_pass_assert( __visit_children() ); 176 187 __pedantic_pass_assert( stmt ); … … 197 208 // If the pass doesn't want to add anything then we are done 198 209 if( empty(stmts_before) && empty(stmts_after) && empty(decls_before) && empty(decls_after) ) { 199 return nstmt;210 return { nstmt != stmt, nstmt }; 200 211 } 201 212 … … 219 230 __pass::take_all( std::back_inserter( compound->kids ), stmts_after ); 220 231 221 return compound;232 return {true, compound}; 222 233 } 223 234 224 235 template< typename core_t > 225 236 template< template <class...> class container_t > 226 container_t< ptr<Stmt> > ast::Pass< core_t >::call_accept( const container_t< ptr<Stmt> > & statements ) { 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 ast::Pass< core_t >::resultNstmt<container_t> ast::Pass< core_t >::call_accept( const container_t< ptr<Stmt> > & statements ) { 227 261 __pedantic_pass_assert( __visit_children() ); 228 262 if( statements.empty() ) return {}; … … 251 285 pass_visitor_stats.avg->push(pass_visitor_stats.depth); 252 286 253 bool mutated = false; 254 container_t< ptr<Stmt> > new_kids; 255 for( const Stmt * stmt : statements ) { 287 resultNstmt<container_t> new_kids; 288 for( auto value : enumerate( statements ) ) { 256 289 try { 290 size_t i = value.idx; 291 const Stmt * stmt = value.val; 257 292 __pedantic_pass_assert( stmt ); 258 293 const ast::Stmt * new_stmt = stmt->accept( *this ); 259 294 assert( new_stmt ); 260 if(new_stmt != stmt ) mutated = true;295 if(new_stmt != stmt ) { new_kids.differs = true; } 261 296 262 297 // Make sure that it is either adding statements or declartions but not both … … 268 303 269 304 // Take all the statements which should have gone after, N/A for first iteration 270 __pass::take_all( std::back_inserter( new_kids ), decls_before, &mutated);271 __pass::take_all( std::back_inserter( new_kids ), stmts_before, &mutated);305 new_kids.take_all( decls_before ); 306 new_kids.take_all( stmts_before ); 272 307 273 308 // Now add the statement if there is one 274 new_kids.emplace_back( new_stmt ); 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 } 275 314 276 315 // Take all the declarations that go before 277 __pass::take_all( std::back_inserter( new_kids ), decls_after, &mutated);278 __pass::take_all( std::back_inserter( new_kids ), stmts_after, &mutated);316 new_kids.take_all( decls_after ); 317 new_kids.take_all( stmts_after ); 279 318 } 280 319 catch ( SemanticErrorException &e ) { … … 285 324 if ( !errors.isEmpty() ) { throw errors; } 286 325 287 return mutated ? new_kids : container_t< ptr<Stmt> >();326 return new_kids; 288 327 } 289 328 290 329 template< typename core_t > 291 330 template< template <class...> class container_t, typename node_t > 292 container_t< ast::ptr<node_t> > ast::Pass< core_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) { 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 ast::Pass< core_t >::resultN<container_t, node_t> ast::Pass< core_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) { 293 349 __pedantic_pass_assert( __visit_children() ); 294 350 if( container.empty() ) return {}; … … 300 356 301 357 bool mutated = false; 302 container_t< ast::ptr<node_t>> new_kids;358 container_t<ptr<node_t>> new_kids; 303 359 for ( const node_t * node : container ) { 304 360 try { 305 361 __pedantic_pass_assert( node ); 306 362 const node_t * new_stmt = strict_dynamic_cast< const node_t * >( node->accept( *this ) ); 307 if(new_stmt != node ) mutated = true; 308 309 new_kids.emplace_back( new_stmt ); 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 310 370 } 311 371 catch( SemanticErrorException &e ) { … … 313 373 } 314 374 } 375 376 __pedantic_pass_assert( new_kids.size() == container.size() ); 315 377 pass_visitor_stats.depth--; 316 378 if ( ! errors.isEmpty() ) { throw errors; } 317 379 318 return mutated ? new_kids : container_t< ast::ptr<node_t> >();380 return ast::Pass< core_t >::resultN<container_t, node_t>{ mutated, new_kids }; 319 381 } 320 382 … … 334 396 auto new_val = call_accept( old_val ); 335 397 336 static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value || std::is_same<int, decltype(old_val)>::value, "ERROR");337 338 if( __pass::differs(old_val, new_val)) {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 ) { 339 401 auto new_parent = __pass::mutate<core_t>(parent); 340 new_ parent->*child = new_val;402 new_val.apply(new_parent, child); 341 403 parent = new_parent; 342 404 } … … 360 422 static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value || std::is_same<int, decltype(old_val)>::value, "ERROR"); 361 423 362 if( __pass::differs(old_val, new_val)) {424 if( new_val.differs ) { 363 425 auto new_parent = __pass::mutate<core_t>(parent); 364 new_ parent->*child = new_val;426 new_val.apply( new_parent, child ); 365 427 parent = new_parent; 366 428 } … … 452 514 VISIT_START( node ); 453 515 454 VISIT(516 if ( __visit_children() ) { 455 517 { 456 518 guard_symtab guard { *this }; … … 460 522 maybe_accept( node, &ObjectDecl::bitfieldWidth ); 461 523 maybe_accept( node, &ObjectDecl::attributes ); 462 )524 } 463 525 464 526 __pass::symtab::addId( core, 0, node ); … … 475 537 __pass::symtab::addId( core, 0, node ); 476 538 477 VISIT(maybe_accept( node, &FunctionDecl::withExprs );) 539 if ( __visit_children() ) { 540 maybe_accept( node, &FunctionDecl::withExprs ); 541 } 478 542 { 479 543 // with clause introduces a level of scope (for the with expression members). … … 493 557 } }; 494 558 __pass::symtab::addId( core, 0, func ); 495 VISIT(559 if ( __visit_children() ) { 496 560 // parameter declarations 497 561 maybe_accept( node, &FunctionDecl::params ); … … 509 573 maybe_accept( node, &FunctionDecl::stmts ); 510 574 maybe_accept( node, &FunctionDecl::attributes ); 511 )575 } 512 576 } 513 577 } … … 526 590 __pass::symtab::addStructFwd( core, 0, node ); 527 591 528 VISIT({592 if ( __visit_children() ) { 529 593 guard_symtab guard { * this }; 530 594 maybe_accept( node, &StructDecl::params ); 531 595 maybe_accept( node, &StructDecl::members ); 532 596 maybe_accept( node, &StructDecl::attributes ); 533 } )597 } 534 598 535 599 // this addition replaces the forward declaration … … 548 612 __pass::symtab::addUnionFwd( core, 0, node ); 549 613 550 VISIT({614 if ( __visit_children() ) { 551 615 guard_symtab guard { * this }; 552 616 maybe_accept( node, &UnionDecl::params ); 553 617 maybe_accept( node, &UnionDecl::members ); 554 618 maybe_accept( node, &UnionDecl::attributes ); 555 } )619 } 556 620 557 621 __pass::symtab::addUnion( core, 0, node ); … … 568 632 __pass::symtab::addEnum( core, 0, node ); 569 633 570 VISIT(634 if ( __visit_children() ) { 571 635 // unlike structs, traits, and unions, enums inject their members into the global scope 572 636 maybe_accept( node, &EnumDecl::params ); 573 637 maybe_accept( node, &EnumDecl::members ); 574 638 maybe_accept( node, &EnumDecl::attributes ); 575 )639 } 576 640 577 641 VISIT_END( Decl, node ); … … 584 648 VISIT_START( node ); 585 649 586 VISIT({650 if ( __visit_children() ) { 587 651 guard_symtab guard { *this }; 588 652 maybe_accept( node, &TraitDecl::params ); 589 653 maybe_accept( node, &TraitDecl::members ); 590 654 maybe_accept( node, &TraitDecl::attributes ); 591 } )655 } 592 656 593 657 __pass::symtab::addTrait( core, 0, node ); … … 602 666 VISIT_START( node ); 603 667 604 VISIT({668 if ( __visit_children() ) { 605 669 guard_symtab guard { *this }; 606 670 maybe_accept( node, &TypeDecl::base ); 607 } )671 } 608 672 609 673 // see A NOTE ON THE ORDER OF TRAVERSAL, above … … 612 676 __pass::symtab::addType( core, 0, node ); 613 677 614 VISIT(678 if ( __visit_children() ) { 615 679 maybe_accept( node, &TypeDecl::assertions ); 616 680 … … 619 683 maybe_accept( node, &TypeDecl::init ); 620 684 } 621 )685 } 622 686 623 687 VISIT_END( Decl, node ); … … 630 694 VISIT_START( node ); 631 695 632 VISIT({696 if ( __visit_children() ) { 633 697 guard_symtab guard { *this }; 634 698 maybe_accept( node, &TypedefDecl::base ); 635 } )699 } 636 700 637 701 __pass::symtab::addType( core, 0, node ); 638 702 639 VISIT( maybe_accept( node, &TypedefDecl::assertions ); ) 703 if ( __visit_children() ) { 704 maybe_accept( node, &TypedefDecl::assertions ); 705 } 640 706 641 707 VISIT_END( Decl, node ); … … 648 714 VISIT_START( node ); 649 715 650 VISIT(716 if ( __visit_children() ) { 651 717 maybe_accept( node, &AsmDecl::stmt ); 652 )718 } 653 719 654 720 VISIT_END( AsmDecl, node ); … … 661 727 VISIT_START( node ); 662 728 663 VISIT(729 if ( __visit_children() ) { 664 730 maybe_accept( node, &DirectiveDecl::stmt ); 665 )731 } 666 732 667 733 VISIT_END( DirectiveDecl, node ); … … 674 740 VISIT_START( node ); 675 741 676 VISIT(742 if ( __visit_children() ) { 677 743 maybe_accept( node, &StaticAssertDecl::cond ); 678 744 maybe_accept( node, &StaticAssertDecl::msg ); 679 )745 } 680 746 681 747 VISIT_END( StaticAssertDecl, node ); … … 687 753 const ast::CompoundStmt * ast::Pass< core_t >::visit( const ast::CompoundStmt * node ) { 688 754 VISIT_START( node ); 689 VISIT( 755 756 if ( __visit_children() ) { 690 757 // Do not enter (or leave) a new scope if atFunctionTop. Remember to save the result. 691 758 auto guard1 = makeFuncGuard( [this, enterScope = !this->atFunctionTop]() { … … 704 771 guard_scope guard3 { *this }; 705 772 maybe_accept( node, &CompoundStmt::kids ); 706 ) 773 } 774 707 775 VISIT_END( CompoundStmt, node ); 708 776 } … … 714 782 VISIT_START( node ); 715 783 716 VISIT(784 if ( __visit_children() ) { 717 785 maybe_accept( node, &ExprStmt::expr ); 718 )786 } 719 787 720 788 VISIT_END( Stmt, node ); … … 727 795 VISIT_START( node ) 728 796 729 VISIT(797 if ( __visit_children() ) { 730 798 maybe_accept( node, &AsmStmt::instruction ); 731 799 maybe_accept( node, &AsmStmt::output ); 732 800 maybe_accept( node, &AsmStmt::input ); 733 801 maybe_accept( node, &AsmStmt::clobber ); 734 )802 } 735 803 736 804 VISIT_END( Stmt, node ); … … 752 820 VISIT_START( node ); 753 821 754 VISIT({822 if ( __visit_children() ) { 755 823 // if statements introduce a level of scope (for the initialization) 756 824 guard_symtab guard { *this }; 757 825 maybe_accept( node, &IfStmt::inits ); 758 826 maybe_accept( node, &IfStmt::cond ); 759 maybe_accept_as_compound( node, &IfStmt::then Part);760 maybe_accept_as_compound( node, &IfStmt::else Part);761 } )827 maybe_accept_as_compound( node, &IfStmt::then ); 828 maybe_accept_as_compound( node, &IfStmt::else_ ); 829 } 762 830 763 831 VISIT_END( Stmt, node ); … … 765 833 766 834 //-------------------------------------------------------------------------- 767 // While Stmt768 template< typename core_t > 769 const ast::Stmt * ast::Pass< core_t >::visit( const ast::While Stmt * node ) {770 VISIT_START( node ); 771 772 VISIT({835 // WhileDoStmt 836 template< typename core_t > 837 const ast::Stmt * ast::Pass< core_t >::visit( const ast::WhileDoStmt * node ) { 838 VISIT_START( node ); 839 840 if ( __visit_children() ) { 773 841 // while statements introduce a level of scope (for the initialization) 774 842 guard_symtab guard { *this }; 775 maybe_accept( node, &While Stmt::inits );776 maybe_accept( node, &While Stmt::cond );777 maybe_accept_as_compound( node, &While Stmt::body );778 } )843 maybe_accept( node, &WhileDoStmt::inits ); 844 maybe_accept( node, &WhileDoStmt::cond ); 845 maybe_accept_as_compound( node, &WhileDoStmt::body ); 846 } 779 847 780 848 VISIT_END( Stmt, node ); … … 787 855 VISIT_START( node ); 788 856 789 VISIT({857 if ( __visit_children() ) { 790 858 // for statements introduce a level of scope (for the initialization) 791 859 guard_symtab guard { *this }; … … 795 863 maybe_accept( node, &ForStmt::inc ); 796 864 maybe_accept_as_compound( node, &ForStmt::body ); 797 } )865 } 798 866 799 867 VISIT_END( Stmt, node ); … … 806 874 VISIT_START( node ); 807 875 808 VISIT(876 if ( __visit_children() ) { 809 877 maybe_accept( node, &SwitchStmt::cond ); 810 878 maybe_accept( node, &SwitchStmt::stmts ); 811 )879 } 812 880 813 881 VISIT_END( Stmt, node ); … … 820 888 VISIT_START( node ); 821 889 822 VISIT(890 if ( __visit_children() ) { 823 891 maybe_accept( node, &CaseStmt::cond ); 824 892 maybe_accept( node, &CaseStmt::stmts ); 825 )893 } 826 894 827 895 VISIT_END( Stmt, node ); … … 842 910 VISIT_START( node ); 843 911 844 VISIT(912 if ( __visit_children() ) { 845 913 maybe_accept( node, &ReturnStmt::expr ); 846 )914 } 847 915 848 916 VISIT_END( Stmt, node ); … … 855 923 VISIT_START( node ); 856 924 857 VISIT(925 if ( __visit_children() ) { 858 926 maybe_accept( node, &ThrowStmt::expr ); 859 927 maybe_accept( node, &ThrowStmt::target ); 860 )928 } 861 929 862 930 VISIT_END( Stmt, node ); … … 869 937 VISIT_START( node ); 870 938 871 VISIT(939 if ( __visit_children() ) { 872 940 maybe_accept( node, &TryStmt::body ); 873 941 maybe_accept( node, &TryStmt::handlers ); 874 942 maybe_accept( node, &TryStmt::finally ); 875 )943 } 876 944 877 945 VISIT_END( Stmt, node ); … … 884 952 VISIT_START( node ); 885 953 886 VISIT({954 if ( __visit_children() ) { 887 955 // catch statements introduce a level of scope (for the caught exception) 888 956 guard_symtab guard { *this }; … … 890 958 maybe_accept( node, &CatchStmt::cond ); 891 959 maybe_accept_as_compound( node, &CatchStmt::body ); 892 } )960 } 893 961 894 962 VISIT_END( Stmt, node ); … … 901 969 VISIT_START( node ); 902 970 903 VISIT(971 if ( __visit_children() ) { 904 972 maybe_accept( node, &FinallyStmt::body ); 905 )973 } 906 974 907 975 VISIT_END( Stmt, node ); … … 914 982 VISIT_START( node ); 915 983 916 VISIT(984 if ( __visit_children() ) { 917 985 maybe_accept( node, &SuspendStmt::then ); 918 )986 } 919 987 920 988 VISIT_END( Stmt, node ); … … 934 1002 // } 935 1003 936 VISIT({1004 if ( __visit_children() ) { 937 1005 std::vector<WaitForStmt::Clause> new_clauses; 938 1006 new_clauses.reserve( node->clauses.size() ); … … 942 1010 const Expr * func = clause.target.func ? clause.target.func->accept(*this) : nullptr; 943 1011 if(func != clause.target.func) mutated = true; 1012 else func = nullptr; 944 1013 945 1014 std::vector<ptr<Expr>> new_args; … … 947 1016 for( const auto & arg : clause.target.args ) { 948 1017 auto a = arg->accept(*this); 949 new_args.push_back( a ); 950 if( a != arg ) mutated = true; 1018 if( a != arg ) { 1019 mutated = true; 1020 new_args.push_back( a ); 1021 } else 1022 new_args.push_back( nullptr ); 951 1023 } 952 1024 953 1025 const Stmt * stmt = clause.stmt ? clause.stmt->accept(*this) : nullptr; 954 1026 if(stmt != clause.stmt) mutated = true; 1027 else stmt = nullptr; 955 1028 956 1029 const Expr * cond = clause.cond ? clause.cond->accept(*this) : nullptr; 957 1030 if(cond != clause.cond) mutated = true; 1031 else cond = nullptr; 958 1032 959 1033 new_clauses.push_back( WaitForStmt::Clause{ {func, std::move(new_args) }, stmt, cond } ); … … 962 1036 if(mutated) { 963 1037 auto n = __pass::mutate<core_t>(node); 964 n->clauses = std::move( new_clauses ); 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 } 965 1048 node = n; 966 1049 } 967 } )1050 } 968 1051 969 1052 #define maybe_accept(field) \ 970 1053 if(node->field) { \ 971 1054 auto nval = call_accept( node->field ); \ 972 if(nval != node->field) { \1055 if(nval.differs ) { \ 973 1056 auto nparent = __pass::mutate<core_t>(node); \ 974 nparent->field = nval ; \1057 nparent->field = nval.value; \ 975 1058 node = nparent; \ 976 1059 } \ 977 1060 } 978 1061 979 VISIT(1062 if ( __visit_children() ) { 980 1063 maybe_accept( timeout.time ); 981 1064 maybe_accept( timeout.stmt ); … … 983 1066 maybe_accept( orElse.stmt ); 984 1067 maybe_accept( orElse.cond ); 985 )1068 } 986 1069 987 1070 #undef maybe_accept … … 996 1079 VISIT_START( node ); 997 1080 998 VISIT(1081 if ( __visit_children() ) { 999 1082 maybe_accept( node, &WithStmt::exprs ); 1000 1083 { … … 1004 1087 maybe_accept( node, &WithStmt::stmt ); 1005 1088 } 1006 ) 1089 } 1090 1007 1091 VISIT_END( Stmt, node ); 1008 1092 } … … 1022 1106 VISIT_START( node ); 1023 1107 1024 VISIT(1108 if ( __visit_children() ) { 1025 1109 maybe_accept( node, &DeclStmt::decl ); 1026 )1110 } 1027 1111 1028 1112 VISIT_END( Stmt, node ); … … 1037 1121 // For now this isn't visited, it is unclear if this causes problem 1038 1122 // if all tests are known to pass, remove this code 1039 VISIT(1123 if ( __visit_children() ) { 1040 1124 maybe_accept( node, &ImplicitCtorDtorStmt::callStmt ); 1041 )1125 } 1042 1126 1043 1127 VISIT_END( Stmt, node ); … … 1050 1134 VISIT_START( node ); 1051 1135 1052 VISIT({1136 if ( __visit_children() ) { 1053 1137 // mutex statements introduce a level of scope (for the initialization) 1054 1138 guard_symtab guard { *this }; 1055 1139 maybe_accept( node, &MutexStmt::stmt ); 1056 1140 maybe_accept( node, &MutexStmt::mutexObjs ); 1057 } )1141 } 1058 1142 1059 1143 VISIT_END( Stmt, node ); … … 1066 1150 VISIT_START( node ); 1067 1151 1068 VISIT(1152 if ( __visit_children() ) { 1069 1153 { 1070 1154 guard_symtab guard { *this }; … … 1073 1157 maybe_accept( node, &ApplicationExpr::func ); 1074 1158 maybe_accept( node, &ApplicationExpr::args ); 1075 )1159 } 1076 1160 1077 1161 VISIT_END( Expr, node ); … … 1084 1168 VISIT_START( node ); 1085 1169 1086 VISIT(1170 if ( __visit_children() ) { 1087 1171 { 1088 1172 guard_symtab guard { *this }; … … 1091 1175 1092 1176 maybe_accept( node, &UntypedExpr::args ); 1093 )1177 } 1094 1178 1095 1179 VISIT_END( Expr, node ); … … 1102 1186 VISIT_START( node ); 1103 1187 1104 VISIT({1188 if ( __visit_children() ) { 1105 1189 guard_symtab guard { *this }; 1106 1190 maybe_accept( node, &NameExpr::result ); 1107 } )1191 } 1108 1192 1109 1193 VISIT_END( Expr, node ); … … 1116 1200 VISIT_START( node ); 1117 1201 1118 VISIT({ 1202 if ( __visit_children() ) { 1203 { 1119 1204 guard_symtab guard { *this }; 1120 1205 maybe_accept( node, &CastExpr::result ); 1121 1206 } 1122 1207 maybe_accept( node, &CastExpr::arg ); 1123 )1208 } 1124 1209 1125 1210 VISIT_END( Expr, node ); … … 1132 1217 VISIT_START( node ); 1133 1218 1134 VISIT({ 1219 if ( __visit_children() ) { 1220 { 1135 1221 guard_symtab guard { *this }; 1136 1222 maybe_accept( node, &KeywordCastExpr::result ); 1137 1223 } 1138 1224 maybe_accept( node, &KeywordCastExpr::arg ); 1139 )1225 } 1140 1226 1141 1227 VISIT_END( Expr, node ); … … 1148 1234 VISIT_START( node ); 1149 1235 1150 VISIT({ 1236 if ( __visit_children() ) { 1237 { 1151 1238 guard_symtab guard { *this }; 1152 1239 maybe_accept( node, &VirtualCastExpr::result ); 1153 1240 } 1154 1241 maybe_accept( node, &VirtualCastExpr::arg ); 1155 )1242 } 1156 1243 1157 1244 VISIT_END( Expr, node ); … … 1164 1251 VISIT_START( node ); 1165 1252 1166 VISIT({ 1253 if ( __visit_children() ) { 1254 { 1167 1255 guard_symtab guard { *this }; 1168 1256 maybe_accept( node, &AddressExpr::result ); 1169 1257 } 1170 1258 maybe_accept( node, &AddressExpr::arg ); 1171 )1259 } 1172 1260 1173 1261 VISIT_END( Expr, node ); … … 1180 1268 VISIT_START( node ); 1181 1269 1182 VISIT({1270 if ( __visit_children() ) { 1183 1271 guard_symtab guard { *this }; 1184 1272 maybe_accept( node, &LabelAddressExpr::result ); 1185 } )1273 } 1186 1274 1187 1275 VISIT_END( Expr, node ); … … 1194 1282 VISIT_START( node ); 1195 1283 1196 VISIT({ 1284 if ( __visit_children() ) { 1285 { 1197 1286 guard_symtab guard { *this }; 1198 1287 maybe_accept( node, &UntypedMemberExpr::result ); … … 1200 1289 maybe_accept( node, &UntypedMemberExpr::aggregate ); 1201 1290 maybe_accept( node, &UntypedMemberExpr::member ); 1202 )1291 } 1203 1292 1204 1293 VISIT_END( Expr, node ); … … 1211 1300 VISIT_START( node ); 1212 1301 1213 VISIT({ 1302 if ( __visit_children() ) { 1303 { 1214 1304 guard_symtab guard { *this }; 1215 1305 maybe_accept( node, &MemberExpr::result ); 1216 1306 } 1217 1307 maybe_accept( node, &MemberExpr::aggregate ); 1218 )1308 } 1219 1309 1220 1310 VISIT_END( Expr, node ); … … 1227 1317 VISIT_START( node ); 1228 1318 1229 VISIT({1319 if ( __visit_children() ) { 1230 1320 guard_symtab guard { *this }; 1231 1321 maybe_accept( node, &VariableExpr::result ); 1232 } )1322 } 1233 1323 1234 1324 VISIT_END( Expr, node ); … … 1241 1331 VISIT_START( node ); 1242 1332 1243 VISIT({1333 if ( __visit_children() ) { 1244 1334 guard_symtab guard { *this }; 1245 1335 maybe_accept( node, &ConstantExpr::result ); 1246 } )1336 } 1247 1337 1248 1338 VISIT_END( Expr, node ); … … 1255 1345 VISIT_START( node ); 1256 1346 1257 VISIT({ 1347 if ( __visit_children() ) { 1348 { 1258 1349 guard_symtab guard { *this }; 1259 1350 maybe_accept( node, &SizeofExpr::result ); … … 1264 1355 maybe_accept( node, &SizeofExpr::expr ); 1265 1356 } 1266 )1357 } 1267 1358 1268 1359 VISIT_END( Expr, node ); … … 1275 1366 VISIT_START( node ); 1276 1367 1277 VISIT({ 1368 if ( __visit_children() ) { 1369 { 1278 1370 guard_symtab guard { *this }; 1279 1371 maybe_accept( node, &AlignofExpr::result ); … … 1284 1376 maybe_accept( node, &AlignofExpr::expr ); 1285 1377 } 1286 )1378 } 1287 1379 1288 1380 VISIT_END( Expr, node ); … … 1295 1387 VISIT_START( node ); 1296 1388 1297 VISIT({ 1389 if ( __visit_children() ) { 1390 { 1298 1391 guard_symtab guard { *this }; 1299 1392 maybe_accept( node, &UntypedOffsetofExpr::result ); 1300 1393 } 1301 1394 maybe_accept( node, &UntypedOffsetofExpr::type ); 1302 )1395 } 1303 1396 1304 1397 VISIT_END( Expr, node ); … … 1311 1404 VISIT_START( node ); 1312 1405 1313 VISIT({ 1406 if ( __visit_children() ) { 1407 { 1314 1408 guard_symtab guard { *this }; 1315 1409 maybe_accept( node, &OffsetofExpr::result ); 1316 1410 } 1317 1411 maybe_accept( node, &OffsetofExpr::type ); 1318 )1412 } 1319 1413 1320 1414 VISIT_END( Expr, node ); … … 1327 1421 VISIT_START( node ); 1328 1422 1329 VISIT({ 1423 if ( __visit_children() ) { 1424 { 1330 1425 guard_symtab guard { *this }; 1331 1426 maybe_accept( node, &OffsetPackExpr::result ); 1332 1427 } 1333 1428 maybe_accept( node, &OffsetPackExpr::type ); 1334 )1429 } 1335 1430 1336 1431 VISIT_END( Expr, node ); … … 1343 1438 VISIT_START( node ); 1344 1439 1345 VISIT({ 1440 if ( __visit_children() ) { 1441 { 1346 1442 guard_symtab guard { *this }; 1347 1443 maybe_accept( node, &LogicalExpr::result ); … … 1349 1445 maybe_accept( node, &LogicalExpr::arg1 ); 1350 1446 maybe_accept( node, &LogicalExpr::arg2 ); 1351 )1447 } 1352 1448 1353 1449 VISIT_END( Expr, node ); … … 1360 1456 VISIT_START( node ); 1361 1457 1362 VISIT({ 1458 if ( __visit_children() ) { 1459 { 1363 1460 guard_symtab guard { *this }; 1364 1461 maybe_accept( node, &ConditionalExpr::result ); … … 1367 1464 maybe_accept( node, &ConditionalExpr::arg2 ); 1368 1465 maybe_accept( node, &ConditionalExpr::arg3 ); 1369 )1466 } 1370 1467 1371 1468 VISIT_END( Expr, node ); … … 1378 1475 VISIT_START( node ); 1379 1476 1380 VISIT({ 1477 if ( __visit_children() ) { 1478 { 1381 1479 guard_symtab guard { *this }; 1382 1480 maybe_accept( node, &CommaExpr::result ); … … 1384 1482 maybe_accept( node, &CommaExpr::arg1 ); 1385 1483 maybe_accept( node, &CommaExpr::arg2 ); 1386 )1484 } 1387 1485 1388 1486 VISIT_END( Expr, node ); … … 1395 1493 VISIT_START( node ); 1396 1494 1397 VISIT({ 1495 if ( __visit_children() ) { 1496 { 1398 1497 guard_symtab guard { *this }; 1399 1498 maybe_accept( node, &TypeExpr::result ); 1400 1499 } 1401 1500 maybe_accept( node, &TypeExpr::type ); 1402 )1501 } 1403 1502 1404 1503 VISIT_END( Expr, node ); … … 1411 1510 VISIT_START( node ); 1412 1511 1413 VISIT({ 1512 if ( __visit_children() ) { 1513 { 1414 1514 guard_symtab guard { *this }; 1415 1515 maybe_accept( node, &AsmExpr::result ); … … 1417 1517 maybe_accept( node, &AsmExpr::constraint ); 1418 1518 maybe_accept( node, &AsmExpr::operand ); 1419 )1519 } 1420 1520 1421 1521 VISIT_END( Expr, node ); … … 1428 1528 VISIT_START( node ); 1429 1529 1430 VISIT({ 1530 if ( __visit_children() ) { 1531 { 1431 1532 guard_symtab guard { *this }; 1432 1533 maybe_accept( node, &ImplicitCopyCtorExpr::result ); 1433 1534 } 1434 1535 maybe_accept( node, &ImplicitCopyCtorExpr::callExpr ); 1435 )1536 } 1436 1537 1437 1538 VISIT_END( Expr, node ); … … 1444 1545 VISIT_START( node ); 1445 1546 1446 VISIT({ 1547 if ( __visit_children() ) { 1548 { 1447 1549 guard_symtab guard { *this }; 1448 1550 maybe_accept( node, &ConstructorExpr::result ); 1449 1551 } 1450 1552 maybe_accept( node, &ConstructorExpr::callExpr ); 1451 )1553 } 1452 1554 1453 1555 VISIT_END( Expr, node ); … … 1460 1562 VISIT_START( node ); 1461 1563 1462 VISIT({ 1564 if ( __visit_children() ) { 1565 { 1463 1566 guard_symtab guard { *this }; 1464 1567 maybe_accept( node, &CompoundLiteralExpr::result ); 1465 1568 } 1466 1569 maybe_accept( node, &CompoundLiteralExpr::init ); 1467 )1570 } 1468 1571 1469 1572 VISIT_END( Expr, node ); … … 1476 1579 VISIT_START( node ); 1477 1580 1478 VISIT({ 1581 if ( __visit_children() ) { 1582 { 1479 1583 guard_symtab guard { *this }; 1480 1584 maybe_accept( node, &RangeExpr::result ); … … 1482 1586 maybe_accept( node, &RangeExpr::low ); 1483 1587 maybe_accept( node, &RangeExpr::high ); 1484 )1588 } 1485 1589 1486 1590 VISIT_END( Expr, node ); … … 1493 1597 VISIT_START( node ); 1494 1598 1495 VISIT({ 1599 if ( __visit_children() ) { 1600 { 1496 1601 guard_symtab guard { *this }; 1497 1602 maybe_accept( node, &UntypedTupleExpr::result ); 1498 1603 } 1499 1604 maybe_accept( node, &UntypedTupleExpr::exprs ); 1500 )1605 } 1501 1606 1502 1607 VISIT_END( Expr, node ); … … 1509 1614 VISIT_START( node ); 1510 1615 1511 VISIT({ 1616 if ( __visit_children() ) { 1617 { 1512 1618 guard_symtab guard { *this }; 1513 1619 maybe_accept( node, &TupleExpr::result ); 1514 1620 } 1515 1621 maybe_accept( node, &TupleExpr::exprs ); 1516 )1622 } 1517 1623 1518 1624 VISIT_END( Expr, node ); … … 1525 1631 VISIT_START( node ); 1526 1632 1527 VISIT({ 1633 if ( __visit_children() ) { 1634 { 1528 1635 guard_symtab guard { *this }; 1529 1636 maybe_accept( node, &TupleIndexExpr::result ); 1530 1637 } 1531 1638 maybe_accept( node, &TupleIndexExpr::tuple ); 1532 )1639 } 1533 1640 1534 1641 VISIT_END( Expr, node ); … … 1541 1648 VISIT_START( node ); 1542 1649 1543 VISIT({ 1650 if ( __visit_children() ) { 1651 { 1544 1652 guard_symtab guard { *this }; 1545 1653 maybe_accept( node, &TupleAssignExpr::result ); 1546 1654 } 1547 1655 maybe_accept( node, &TupleAssignExpr::stmtExpr ); 1548 )1656 } 1549 1657 1550 1658 VISIT_END( Expr, node ); … … 1557 1665 VISIT_START( node ); 1558 1666 1559 VISIT(// don't want statements from outer CompoundStmts to be added to this StmtExpr 1667 if ( __visit_children() ) { 1668 // don't want statements from outer CompoundStmts to be added to this StmtExpr 1560 1669 // get the stmts that will need to be spliced in 1561 1670 auto stmts_before = __pass::stmtsToAddBefore( core, 0); … … 1574 1683 maybe_accept( node, &StmtExpr::returnDecls ); 1575 1684 maybe_accept( node, &StmtExpr::dtors ); 1576 )1685 } 1577 1686 1578 1687 VISIT_END( Expr, node ); … … 1585 1694 VISIT_START( node ); 1586 1695 1587 VISIT({ 1696 if ( __visit_children() ) { 1697 { 1588 1698 guard_symtab guard { *this }; 1589 1699 maybe_accept( node, &UniqueExpr::result ); 1590 1700 } 1591 1701 maybe_accept( node, &UniqueExpr::expr ); 1592 )1702 } 1593 1703 1594 1704 VISIT_END( Expr, node ); … … 1601 1711 VISIT_START( node ); 1602 1712 1603 VISIT({ 1713 if ( __visit_children() ) { 1714 { 1604 1715 guard_symtab guard { *this }; 1605 1716 maybe_accept( node, &UntypedInitExpr::result ); … … 1607 1718 maybe_accept( node, &UntypedInitExpr::expr ); 1608 1719 // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver. 1609 )1720 } 1610 1721 1611 1722 VISIT_END( Expr, node ); … … 1618 1729 VISIT_START( node ); 1619 1730 1620 VISIT({ 1731 if ( __visit_children() ) { 1732 { 1621 1733 guard_symtab guard { *this }; 1622 1734 maybe_accept( node, &InitExpr::result ); … … 1624 1736 maybe_accept( node, &InitExpr::expr ); 1625 1737 maybe_accept( node, &InitExpr::designation ); 1626 )1738 } 1627 1739 1628 1740 VISIT_END( Expr, node ); … … 1635 1747 VISIT_START( node ); 1636 1748 1637 VISIT({ 1749 if ( __visit_children() ) { 1750 { 1638 1751 guard_symtab guard { *this }; 1639 1752 maybe_accept( node, &DeletedExpr::result ); … … 1641 1754 maybe_accept( node, &DeletedExpr::expr ); 1642 1755 // don't visit deleteStmt, because it is a pointer to somewhere else in the tree. 1643 )1756 } 1644 1757 1645 1758 VISIT_END( Expr, node ); … … 1652 1765 VISIT_START( node ); 1653 1766 1654 VISIT({ 1767 if ( __visit_children() ) { 1768 { 1655 1769 guard_symtab guard { *this }; 1656 1770 maybe_accept( node, &DefaultArgExpr::result ); 1657 1771 } 1658 1772 maybe_accept( node, &DefaultArgExpr::expr ); 1659 )1773 } 1660 1774 1661 1775 VISIT_END( Expr, node ); … … 1668 1782 VISIT_START( node ); 1669 1783 1670 VISIT({ 1784 if ( __visit_children() ) { 1785 { 1671 1786 guard_symtab guard { *this }; 1672 1787 maybe_accept( node, &GenericExpr::result ); … … 1697 1812 node = n; 1698 1813 } 1699 )1814 } 1700 1815 1701 1816 VISIT_END( Expr, node ); … … 1726 1841 VISIT_START( node ); 1727 1842 1728 VISIT(1843 if ( __visit_children() ) { 1729 1844 // xxx - should PointerType visit/mutate dimension? 1730 1845 maybe_accept( node, &PointerType::base ); 1731 )1846 } 1732 1847 1733 1848 VISIT_END( Type, node ); … … 1740 1855 VISIT_START( node ); 1741 1856 1742 VISIT(1857 if ( __visit_children() ) { 1743 1858 maybe_accept( node, &ArrayType::dimension ); 1744 1859 maybe_accept( node, &ArrayType::base ); 1745 )1860 } 1746 1861 1747 1862 VISIT_END( Type, node ); … … 1754 1869 VISIT_START( node ); 1755 1870 1756 VISIT(1871 if ( __visit_children() ) { 1757 1872 maybe_accept( node, &ReferenceType::base ); 1758 )1873 } 1759 1874 1760 1875 VISIT_END( Type, node ); … … 1767 1882 VISIT_START( node ); 1768 1883 1769 VISIT(1884 if ( __visit_children() ) { 1770 1885 maybe_accept( node, &QualifiedType::parent ); 1771 1886 maybe_accept( node, &QualifiedType::child ); 1772 )1887 } 1773 1888 1774 1889 VISIT_END( Type, node ); … … 1781 1896 VISIT_START( node ); 1782 1897 1783 VISIT({1898 if ( __visit_children() ) { 1784 1899 // guard_forall_subs forall_guard { *this, node }; 1785 1900 // mutate_forall( node ); … … 1787 1902 maybe_accept( node, &FunctionType::returns ); 1788 1903 maybe_accept( node, &FunctionType::params ); 1789 } )1904 } 1790 1905 1791 1906 VISIT_END( Type, node ); … … 1800 1915 __pass::symtab::addStruct( core, 0, node->name ); 1801 1916 1802 VISIT({1917 if ( __visit_children() ) { 1803 1918 guard_symtab guard { *this }; 1804 1919 maybe_accept( node, &StructInstType::params ); 1805 } )1920 } 1806 1921 1807 1922 VISIT_END( Type, node ); … … 1816 1931 __pass::symtab::addUnion( core, 0, node->name ); 1817 1932 1818 VISIT({1933 if ( __visit_children() ) { 1819 1934 guard_symtab guard { *this }; 1820 1935 maybe_accept( node, &UnionInstType::params ); 1821 } )1936 } 1822 1937 1823 1938 VISIT_END( Type, node ); … … 1830 1945 VISIT_START( node ); 1831 1946 1832 VISIT({1947 if ( __visit_children() ) { 1833 1948 maybe_accept( node, &EnumInstType::params ); 1834 } )1949 } 1835 1950 1836 1951 VISIT_END( Type, node ); … … 1843 1958 VISIT_START( node ); 1844 1959 1845 VISIT({1960 if ( __visit_children() ) { 1846 1961 maybe_accept( node, &TraitInstType::params ); 1847 } )1962 } 1848 1963 1849 1964 VISIT_END( Type, node ); … … 1856 1971 VISIT_START( node ); 1857 1972 1858 VISIT(1973 if ( __visit_children() ) { 1859 1974 { 1860 1975 maybe_accept( node, &TypeInstType::params ); … … 1862 1977 // ensure that base re-bound if doing substitution 1863 1978 __pass::forall::replace( core, 0, node ); 1864 )1979 } 1865 1980 1866 1981 VISIT_END( Type, node ); … … 1873 1988 VISIT_START( node ); 1874 1989 1875 VISIT(1990 if ( __visit_children() ) { 1876 1991 maybe_accept( node, &TupleType::types ); 1877 1992 maybe_accept( node, &TupleType::members ); 1878 )1993 } 1879 1994 1880 1995 VISIT_END( Type, node ); … … 1887 2002 VISIT_START( node ); 1888 2003 1889 VISIT(2004 if ( __visit_children() ) { 1890 2005 maybe_accept( node, &TypeofType::expr ); 1891 )2006 } 1892 2007 1893 2008 VISIT_END( Type, node ); … … 1900 2015 VISIT_START( node ); 1901 2016 1902 VISIT(2017 if ( __visit_children() ) { 1903 2018 maybe_accept( node, &VTableType::base ); 1904 )2019 } 1905 2020 1906 2021 VISIT_END( Type, node ); … … 1950 2065 VISIT_START( node ); 1951 2066 1952 VISIT( maybe_accept( node, &Designation::designators ); ) 2067 if ( __visit_children() ) { 2068 maybe_accept( node, &Designation::designators ); 2069 } 1953 2070 1954 2071 VISIT_END( Designation, node ); … … 1961 2078 VISIT_START( node ); 1962 2079 1963 VISIT(2080 if ( __visit_children() ) { 1964 2081 maybe_accept( node, &SingleInit::value ); 1965 )2082 } 1966 2083 1967 2084 VISIT_END( Init, node ); … … 1974 2091 VISIT_START( node ); 1975 2092 1976 VISIT(2093 if ( __visit_children() ) { 1977 2094 maybe_accept( node, &ListInit::designations ); 1978 2095 maybe_accept( node, &ListInit::initializers ); 1979 )2096 } 1980 2097 1981 2098 VISIT_END( Init, node ); … … 1988 2105 VISIT_START( node ); 1989 2106 1990 VISIT(2107 if ( __visit_children() ) { 1991 2108 maybe_accept( node, &ConstructorInit::ctor ); 1992 2109 maybe_accept( node, &ConstructorInit::dtor ); 1993 2110 maybe_accept( node, &ConstructorInit::init ); 1994 )2111 } 1995 2112 1996 2113 VISIT_END( Init, node ); … … 2003 2120 VISIT_START( node ); 2004 2121 2005 VISIT(2122 if ( __visit_children() ) { 2006 2123 maybe_accept( node, &Attribute::params ); 2007 )2124 } 2008 2125 2009 2126 VISIT_END( Attribute, node ); … … 2016 2133 VISIT_START( node ); 2017 2134 2018 VISIT(2135 if ( __visit_children() ) { 2019 2136 { 2020 2137 bool mutated = false; … … 2032 2149 } 2033 2150 } 2034 )2151 } 2035 2152 2036 2153 VISIT_END( TypeSubstitution, node ); … … 2038 2155 2039 2156 #undef VISIT_START 2040 #undef VISIT2041 2157 #undef VISIT_END -
src/AST/Print.cpp
r97c215f rf5a51db 333 333 print( node->funcSpec ); 334 334 335 if ( node->type ) { 335 336 337 if ( node->type && node->isTypeFixed ) { 336 338 node->type->accept( *this ); 337 339 } else { 338 os << "untyped entity"; 340 if (!node->type_params.empty()) { 341 os << "forall" << endl; 342 ++indent; 343 printAll(node->type_params); 344 os << indent; 345 --indent; 346 347 if (!node->assertions.empty()) { 348 os << "with assertions" << endl; 349 ++indent; 350 printAll(node->assertions); 351 os << indent; 352 --indent; 353 } 354 } 355 356 os << "function" << endl; 357 if ( ! node->params.empty() ) { 358 os << indent << "... with parameters" << endl; 359 ++indent; 360 printAll( node->params ); 361 if ( node->type->isVarArgs ) { 362 os << indent << "and a variable number of other arguments" << endl; 363 } 364 --indent; 365 } else if ( node->type->isVarArgs ) { 366 os << indent+1 << "accepting unspecified arguments" << endl; 367 } 368 369 os << indent << "... returning"; 370 if ( node->returns.empty() ) { 371 os << " nothing" << endl; 372 } else { 373 os << endl; 374 ++indent; 375 printAll( node->returns ); 376 --indent; 377 } 339 378 } 340 379 … … 472 511 ++indent; 473 512 os << indent; 474 safe_print( node->then Part);475 --indent; 476 477 if ( node->else Part!= 0 ) {513 safe_print( node->then ); 514 --indent; 515 516 if ( node->else_ != 0 ) { 478 517 os << indent << "... else:" << endl; 479 518 ++indent; 480 519 os << indent; 481 node->else Part->accept( *this );520 node->else_->accept( *this ); 482 521 --indent; 483 522 } // if … … 485 524 } 486 525 487 virtual const ast::Stmt * visit( const ast::While Stmt * node ) override final {526 virtual const ast::Stmt * visit( const ast::WhileDoStmt * node ) override final { 488 527 if ( node->isDoWhile ) { os << "Do-"; } 489 528 os << "While on condition:" << endl; -
src/AST/Stmt.cpp
r97c215f rf5a51db 9 9 // Author : Aaron B. Moss 10 10 // Created On : Wed May 8 13:00:00 2019 11 // Last Modified By : Andrew Beach12 // Last Modified On : Wed May 15 15:53:00 201913 // Update Count : 211 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Feb 2 19:01:20 2022 13 // Update Count : 3 14 14 // 15 15 … … 56 56 57 57 // --- BranchStmt 58 BranchStmt::BranchStmt( const CodeLocation& loc, Kind kind, Label target, std::vector<Label>&& labels )59 : Stmt(loc, std::move(labels)), originalTarget(target), target(target), kind(kind) {58 BranchStmt::BranchStmt( const CodeLocation& loc, Kind kind, Label target, const std::vector<Label>&& labels ) 59 : Stmt(loc, std::move(labels)), originalTarget(target), target(target), kind(kind) { 60 60 // Make sure a syntax error hasn't slipped through. 61 61 assert( Goto != kind || !target.empty() ); -
src/AST/Stmt.hpp
r97c215f rf5a51db 9 9 // Author : Aaron B. Moss 10 10 // Created On : Wed May 8 13:00:00 2019 11 // Last Modified By : Andrew Beach12 // Last Modified On : Fri May 17 12:45:00 201913 // Update Count : 511 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Feb 2 20:06:41 2022 13 // Update Count : 34 14 14 // 15 15 … … 17 17 18 18 #include <list> 19 #include <utility> // for move19 #include <utility> // for move 20 20 #include <vector> 21 21 22 22 #include "Label.hpp" 23 #include "Node.hpp" // for node, ptr23 #include "Node.hpp" // for node, ptr 24 24 #include "ParseNode.hpp" 25 25 #include "Visitor.hpp" … … 27 27 28 28 // Must be included in *all* AST classes; should be #undef'd at the end of the file 29 #define MUTATE_FRIEND \29 #define MUTATE_FRIEND \ 30 30 template<typename node_t> friend node_t * mutate(const node_t * node); \ 31 31 template<typename node_t> friend node_t * shallowCopy(const node_t * node); 32 32 33 33 namespace ast { 34 35 34 class Expr; 36 35 37 // /Base statement node36 // Base statement node 38 37 class Stmt : public ParseNode { 39 public:38 public: 40 39 std::vector<Label> labels; 41 40 42 Stmt( const CodeLocation & loc, std::vector<Label> && labels = {} )43 : ParseNode(loc), labels(std::move(labels)) {}44 45 Stmt(const Stmt & o) : ParseNode(o), labels(o.labels) {}41 Stmt( const CodeLocation & loc, const std::vector<Label> && labels = {} ) 42 : ParseNode(loc), labels(std::move(labels)) {} 43 44 Stmt(const Stmt & o) : ParseNode(o), labels(o.labels) {} 46 45 47 46 const Stmt * accept( Visitor & v ) const override = 0; 48 private:47 private: 49 48 Stmt * clone() const override = 0; 50 49 MUTATE_FRIEND 51 50 }; 52 51 53 // / Compound statement `{ ... }`52 // Compound statement: { ... } 54 53 class CompoundStmt final : public Stmt { 55 public:54 public: 56 55 std::list<ptr<Stmt>> kids; 57 56 58 CompoundStmt(const CodeLocation & loc, std::list<ptr<Stmt>> && ks = {}, 59 std::vector<Label>&& labels = {} ) 60 : Stmt(loc, std::move(labels)), kids(std::move(ks)) {} 61 62 CompoundStmt( const CompoundStmt& o ); 63 CompoundStmt( CompoundStmt&& o ) = default; 57 CompoundStmt(const CodeLocation & loc, const std::list<ptr<Stmt>> && ks = {}, const std::vector<Label> && labels = {} ) 58 : Stmt(loc, std::move(labels)), kids(std::move(ks)) {} 59 60 CompoundStmt( const CompoundStmt & o ); 61 CompoundStmt( CompoundStmt && o ) = default; 64 62 65 63 void push_back( const Stmt * s ) { kids.emplace_back( s ); } … … 67 65 68 66 const CompoundStmt * accept( Visitor & v ) const override { return v.visit( this ); } 69 private:67 private: 70 68 CompoundStmt * clone() const override { return new CompoundStmt{ *this }; } 71 69 MUTATE_FRIEND 72 70 }; 73 71 74 // / Empty statment `;`72 // Empty statment: ; 75 73 class NullStmt final : public Stmt { 76 public:77 NullStmt( const CodeLocation & loc, std::vector<Label> && labels = {} )78 : Stmt(loc, std::move(labels)) {}74 public: 75 NullStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} ) 76 : Stmt(loc, std::move(labels)) {} 79 77 80 78 const NullStmt * accept( Visitor & v ) const override { return v.visit( this ); } 81 private:79 private: 82 80 NullStmt * clone() const override { return new NullStmt{ *this }; } 83 81 MUTATE_FRIEND 84 82 }; 85 83 86 // /Expression wrapped by statement84 // Expression wrapped by statement 87 85 class ExprStmt final : public Stmt { 88 public:86 public: 89 87 ptr<Expr> expr; 90 88 91 ExprStmt( const CodeLocation & loc, const Expr* e, std::vector<Label>&& labels = {} )92 : Stmt(loc, std::move(labels)), expr(e) {}93 94 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 95 private:89 ExprStmt( const CodeLocation & loc, const Expr* e, const std::vector<Label> && labels = {} ) 90 : Stmt(loc, std::move(labels)), expr(e) {} 91 92 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 93 private: 96 94 ExprStmt * clone() const override { return new ExprStmt{ *this }; } 97 95 MUTATE_FRIEND 98 96 }; 99 97 100 // / Assembly statement `asm ... ( "..." : ... )`98 // Assembly statement: asm ... ( "..." : ... ) 101 99 class AsmStmt final : public Stmt { 102 public:100 public: 103 101 bool isVolatile; 104 102 ptr<Expr> instruction; … … 108 106 109 107 AsmStmt( const CodeLocation & loc, bool isVolatile, const Expr * instruction, 110 std::vector<ptr<Expr>> && output,std::vector<ptr<Expr>> && input,111 std::vector<ptr<ConstantExpr>> && clobber,std::vector<Label> && gotoLabels,112 std::vector<Label> && labels = {})113 : Stmt(loc, std::move(labels)), isVolatile(isVolatile), instruction(instruction),114 output(std::move(output)), input(std::move(input)), clobber(std::move(clobber)),115 gotoLabels(std::move(gotoLabels)) {}116 117 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 118 private:108 const std::vector<ptr<Expr>> && output, const std::vector<ptr<Expr>> && input, 109 const std::vector<ptr<ConstantExpr>> && clobber, const std::vector<Label> && gotoLabels, 110 const std::vector<Label> && labels = {}) 111 : Stmt(loc, std::move(labels)), isVolatile(isVolatile), instruction(instruction), 112 output(std::move(output)), input(std::move(input)), clobber(std::move(clobber)), 113 gotoLabels(std::move(gotoLabels)) {} 114 115 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 116 private: 119 117 AsmStmt * clone() const override { return new AsmStmt{ *this }; } 120 118 MUTATE_FRIEND 121 119 }; 122 120 123 // / C-preprocessor directive `#...`121 // C-preprocessor directive: #... 124 122 class DirectiveStmt final : public Stmt { 125 public:123 public: 126 124 std::string directive; 127 125 128 126 DirectiveStmt( const CodeLocation & loc, const std::string & directive, 129 std::vector<Label> && labels = {} )130 : Stmt(loc, std::move(labels)), directive(directive) {}131 132 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 133 private:127 std::vector<Label> && labels = {} ) 128 : Stmt(loc, std::move(labels)), directive(directive) {} 129 130 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 131 private: 134 132 DirectiveStmt * clone() const override { return new DirectiveStmt{ *this }; } 135 133 MUTATE_FRIEND 136 134 }; 137 135 138 // / If conditional statement `if (...) ... else ...`136 // If statement: if (...) ... else ... 139 137 class IfStmt final : public Stmt { 140 public:141 ptr<Expr> cond; 142 ptr<Stmt> then Part;143 ptr<Stmt> else Part;138 public: 139 ptr<Expr> cond; 140 ptr<Stmt> then; 141 ptr<Stmt> else_; 144 142 std::vector<ptr<Stmt>> inits; 145 143 146 IfStmt( const CodeLocation & loc, const Expr * cond, const Stmt * then Part,147 const Stmt * elsePart = nullptr,std::vector<ptr<Stmt>> && inits = {},148 std::vector<Label> && labels = {} )149 : Stmt(loc, std::move(labels)), cond(cond), thenPart(thenPart), elsePart(elsePart),150 inits(std::move(inits)) {}151 152 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 153 private:144 IfStmt( const CodeLocation & loc, const Expr * cond, const Stmt * then, 145 const Stmt * else_ = nullptr, const std::vector<ptr<Stmt>> && inits = {}, 146 const std::vector<Label> && labels = {} ) 147 : Stmt(loc, std::move(labels)), cond(cond), then(then), else_(else_), 148 inits(std::move(inits)) {} 149 150 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 151 private: 154 152 IfStmt * clone() const override { return new IfStmt{ *this }; } 155 153 MUTATE_FRIEND 156 154 }; 157 155 158 // / Switch or choose conditional statement `switch (...) { ... }`156 // Switch or choose statement: switch (...) { ... } 159 157 class SwitchStmt final : public Stmt { 160 public:158 public: 161 159 ptr<Expr> cond; 162 160 std::vector<ptr<Stmt>> stmts; 163 161 164 SwitchStmt( const CodeLocation & loc, const Expr * cond, std::vector<ptr<Stmt>> && stmts,165 std::vector<Label> && labels = {} )166 : Stmt(loc, std::move(labels)), cond(cond), stmts(std::move(stmts)) {}167 168 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 169 private:162 SwitchStmt( const CodeLocation & loc, const Expr * cond, const std::vector<ptr<Stmt>> && stmts, 163 const std::vector<Label> && labels = {} ) 164 : Stmt(loc, std::move(labels)), cond(cond), stmts(std::move(stmts)) {} 165 166 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 167 private: 170 168 SwitchStmt * clone() const override { return new SwitchStmt{ *this }; } 171 169 MUTATE_FRIEND 172 170 }; 173 171 174 // / Case label `case ...:` `default:`172 // Case label: case ...: or default: 175 173 class CaseStmt final : public Stmt { 176 public:177 // /Null for the default label.174 public: 175 // Null for the default label. 178 176 ptr<Expr> cond; 179 177 std::vector<ptr<Stmt>> stmts; 180 178 181 CaseStmt( const CodeLocation & loc, const Expr * cond, std::vector<ptr<Stmt>> && stmts,182 std::vector<Label> && labels = {} )183 : Stmt(loc, std::move(labels)), cond(cond), stmts(std::move(stmts)) {}179 CaseStmt( const CodeLocation & loc, const Expr * cond, const std::vector<ptr<Stmt>> && stmts, 180 const std::vector<Label> && labels = {} ) 181 : Stmt(loc, std::move(labels)), cond(cond), stmts(std::move(stmts)) {} 184 182 185 183 bool isDefault() const { return !cond; } 186 184 187 185 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 188 private:186 private: 189 187 CaseStmt * clone() const override { return new CaseStmt{ *this }; } 190 188 MUTATE_FRIEND 191 189 }; 192 190 193 // / While loop `while (...) ...` `do ... while (...);194 class While Stmt final : public Stmt {195 public:191 // While loop: while (...) ... else ... or do ... while (...) else ...; 192 class WhileDoStmt final : public Stmt { 193 public: 196 194 ptr<Expr> cond; 197 195 ptr<Stmt> body; 196 ptr<Stmt> else_; 198 197 std::vector<ptr<Stmt>> inits; 199 198 bool isDoWhile; 200 199 201 WhileStmt( const CodeLocation & loc, const Expr * cond, const Stmt * body, 202 std::vector<ptr<Stmt>> && inits, bool isDoWhile = false, std::vector<Label> && labels = {} ) 203 : Stmt(loc, std::move(labels)), cond(cond), body(body), inits(std::move(inits)), 204 isDoWhile(isDoWhile) {} 205 206 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 207 private: 208 WhileStmt * clone() const override { return new WhileStmt{ *this }; } 209 MUTATE_FRIEND 210 }; 211 212 /// For loop `for (... ; ... ; ...) ...` 200 WhileDoStmt( const CodeLocation & loc, const Expr * cond, const Stmt * body, 201 const std::vector<ptr<Stmt>> && inits, bool isDoWhile = false, const std::vector<Label> && labels = {} ) 202 : Stmt(loc, std::move(labels)), cond(cond), body(body), else_(nullptr), inits(std::move(inits)), isDoWhile(isDoWhile) {} 203 204 WhileDoStmt( const CodeLocation & loc, const Expr * cond, const Stmt * body, const Stmt * else_, 205 const std::vector<ptr<Stmt>> && inits, bool isDoWhile = false, const std::vector<Label> && labels = {} ) 206 : Stmt(loc, std::move(labels)), cond(cond), body(body), else_(else_), inits(std::move(inits)), isDoWhile(isDoWhile) {} 207 208 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 209 private: 210 WhileDoStmt * clone() const override { return new WhileDoStmt{ *this }; } 211 MUTATE_FRIEND 212 }; 213 214 // For loop: for (... ; ... ; ...) ... else ... 213 215 class ForStmt final : public Stmt { 214 public:216 public: 215 217 std::vector<ptr<Stmt>> inits; 216 218 ptr<Expr> cond; 217 219 ptr<Expr> inc; 218 220 ptr<Stmt> body; 219 220 ForStmt( const CodeLocation & loc, std::vector<ptr<Stmt>> && inits, const Expr * cond, 221 const Expr * inc, const Stmt * body, std::vector<Label> && labels = {} ) 222 : Stmt(loc, std::move(labels)), inits(std::move(inits)), cond(cond), inc(inc), 223 body(body) {} 224 225 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 226 private: 221 ptr<Stmt> else_; 222 223 ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * cond, 224 const Expr * inc, const Stmt * body, const std::vector<Label> && label = {} ) 225 : Stmt(loc, std::move(label)), inits(std::move(inits)), cond(cond), inc(inc), body(body), else_(nullptr) {} 226 227 ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * cond, 228 const Expr * inc, const Stmt * body, const Stmt * else_, const std::vector<Label> && labels = {} ) 229 : Stmt(loc, std::move(labels)), inits(std::move(inits)), cond(cond), inc(inc), body(body), else_(else_) {} 230 231 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 232 private: 227 233 ForStmt * clone() const override { return new ForStmt{ *this }; } 228 234 MUTATE_FRIEND 229 235 }; 230 236 231 // / Branch control flow statement `goto ...` `break` `continue` `fallthru`237 // Branch control flow statement: goto ... or break or continue or fallthru 232 238 class BranchStmt final : public Stmt { 233 public:239 public: 234 240 enum Kind { Goto, Break, Continue, FallThrough, FallThroughDefault }; 235 241 static constexpr size_t kindEnd = 1 + (size_t)FallThroughDefault; … … 240 246 Kind kind; 241 247 242 BranchStmt( const CodeLocation & loc, Kind kind, Label target, 243 std::vector<Label> && labels = {} ); 244 BranchStmt( const CodeLocation & loc, const Expr * computedTarget, 245 std::vector<Label> && labels = {} ) 246 : Stmt(loc, std::move(labels)), originalTarget(loc), target(loc), 247 computedTarget(computedTarget), kind(Goto) {} 248 BranchStmt( const CodeLocation & loc, Kind kind, Label target, const std::vector<Label> && labels = {} ); 249 BranchStmt( const CodeLocation & loc, const Expr * computedTarget, const std::vector<Label> && labels = {} ) 250 : Stmt(loc, std::move(labels)), originalTarget(loc), target(loc), computedTarget(computedTarget), kind(Goto) {} 248 251 249 252 const char * kindName() const { return kindNames[kind]; } 250 253 251 254 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 252 private:255 private: 253 256 BranchStmt * clone() const override { return new BranchStmt{ *this }; } 254 257 MUTATE_FRIEND … … 257 260 }; 258 261 259 // / Return statement `return ...`262 // Return statement: return ... 260 263 class ReturnStmt final : public Stmt { 261 public:264 public: 262 265 ptr<Expr> expr; 263 266 264 ReturnStmt( const CodeLocation & loc, const Expr * expr, std::vector<Label> && labels = {} )265 : Stmt(loc, std::move(labels)), expr(expr) {}266 267 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 268 private:267 ReturnStmt( const CodeLocation & loc, const Expr * expr, const std::vector<Label> && labels = {} ) 268 : Stmt(loc, std::move(labels)), expr(expr) {} 269 270 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 271 private: 269 272 ReturnStmt * clone() const override { return new ReturnStmt{ *this }; } 270 273 MUTATE_FRIEND 271 274 }; 272 275 273 // /Kind of exception276 // Kind of exception 274 277 enum ExceptionKind { Terminate, Resume }; 275 278 276 // / Throw statement `throw ...`279 // Throw statement: throw ... 277 280 class ThrowStmt final : public Stmt { 278 public:281 public: 279 282 ptr<Expr> expr; 280 283 ptr<Expr> target; 281 284 ExceptionKind kind; 282 285 283 ThrowStmt( 284 const CodeLocation & loc, ExceptionKind kind, const Expr * expr, const Expr * target, 285 std::vector<Label> && labels = {} ) 286 : Stmt(loc, std::move(labels)), expr(expr), target(target), kind(kind) {} 287 288 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 289 private: 286 ThrowStmt( const CodeLocation & loc, ExceptionKind kind, const Expr * expr, 287 const Expr * target, const std::vector<Label> && labels = {} ) 288 : Stmt(loc, std::move(labels)), expr(expr), target(target), kind(kind) {} 289 290 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 291 private: 290 292 ThrowStmt * clone() const override { return new ThrowStmt{ *this }; } 291 293 MUTATE_FRIEND 292 294 }; 293 295 294 // / Try statement `try { ... } ...`296 // Try statement: try { ... } ... 295 297 class TryStmt final : public Stmt { 296 public:298 public: 297 299 ptr<CompoundStmt> body; 298 300 std::vector<ptr<CatchStmt>> handlers; 299 301 ptr<FinallyStmt> finally; 300 302 301 TryStmt( 302 const CodeLocation & loc, const CompoundStmt * body, 303 std::vector<ptr<CatchStmt>> && handlers, const FinallyStmt * finally, 304 std::vector<Label> && labels = {} ) 305 : Stmt(loc, std::move(labels)), body(body), handlers(std::move(handlers)), finally(finally) {} 306 307 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 308 private: 303 TryStmt( const CodeLocation & loc, const CompoundStmt * body, 304 const std::vector<ptr<CatchStmt>> && handlers, const FinallyStmt * finally, 305 const std::vector<Label> && labels = {} ) 306 : Stmt(loc, std::move(labels)), body(body), handlers(std::move(handlers)), finally(finally) {} 307 308 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 309 private: 309 310 TryStmt * clone() const override { return new TryStmt{ *this }; } 310 311 MUTATE_FRIEND 311 312 }; 312 313 313 // /Catch clause of try statement314 // Catch clause of try statement 314 315 class CatchStmt final : public Stmt { 315 public:316 public: 316 317 ptr<Decl> decl; 317 318 ptr<Expr> cond; … … 319 320 ExceptionKind kind; 320 321 321 CatchStmt( 322 const CodeLocation & loc, ExceptionKind kind, const Decl * decl, const Expr * cond, 323 const Stmt * body, std::vector<Label> && labels = {} ) 324 : Stmt(loc, std::move(labels)), decl(decl), cond(cond), body(body), kind(kind) {} 325 326 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 327 private: 322 CatchStmt( const CodeLocation & loc, ExceptionKind kind, const Decl * decl, const Expr * cond, 323 const Stmt * body, const std::vector<Label> && labels = {} ) 324 : Stmt(loc, std::move(labels)), decl(decl), cond(cond), body(body), kind(kind) {} 325 326 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 327 private: 328 328 CatchStmt * clone() const override { return new CatchStmt{ *this }; } 329 329 MUTATE_FRIEND 330 330 }; 331 331 332 // /Finally clause of try statement332 // Finally clause of try statement 333 333 class FinallyStmt final : public Stmt { 334 public:334 public: 335 335 ptr<CompoundStmt> body; 336 336 337 337 FinallyStmt( const CodeLocation & loc, const CompoundStmt * body, 338 std::vector<Label> && labels = {} )339 : Stmt(loc, std::move(labels)), body(body) {}340 341 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 342 private:338 std::vector<Label> && labels = {} ) 339 : Stmt(loc, std::move(labels)), body(body) {} 340 341 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 342 private: 343 343 FinallyStmt * clone() const override { return new FinallyStmt{ *this }; } 344 344 MUTATE_FRIEND 345 345 }; 346 346 347 // /Suspend statement347 // Suspend statement 348 348 class SuspendStmt final : public Stmt { 349 public:349 public: 350 350 ptr<CompoundStmt> then; 351 351 enum Type { None, Coroutine, Generator } type = None; 352 352 353 SuspendStmt( const CodeLocation & loc, const CompoundStmt * then, Type type, std::vector<Label> && labels = {} )354 : Stmt(loc, std::move(labels)), then(then), type(type) {}355 356 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 357 private:353 SuspendStmt( const CodeLocation & loc, const CompoundStmt * then, Type type, const std::vector<Label> && labels = {} ) 354 : Stmt(loc, std::move(labels)), then(then), type(type) {} 355 356 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 357 private: 358 358 SuspendStmt * clone() const override { return new SuspendStmt{ *this }; } 359 359 MUTATE_FRIEND 360 360 }; 361 361 362 // / Wait for concurrency statement `when (...) waitfor (... , ...) ... timeout(...) ... else ...`362 // Waitfor statement: when (...) waitfor (... , ...) ... timeout(...) ... else ... 363 363 class WaitForStmt final : public Stmt { 364 public:364 public: 365 365 struct Target { 366 366 ptr<Expr> func; … … 389 389 OrElse orElse; 390 390 391 WaitForStmt( const CodeLocation & loc, std::vector<Label> && labels = {} )392 : Stmt(loc, std::move(labels)) {}393 394 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 395 private:391 WaitForStmt( const CodeLocation & loc, const std::vector<Label> && labels = {} ) 392 : Stmt(loc, std::move(labels)) {} 393 394 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 395 private: 396 396 WaitForStmt * clone() const override { return new WaitForStmt{ *this }; } 397 397 MUTATE_FRIEND 398 398 }; 399 399 400 // /Any declaration in a (compound) statement.400 // Any declaration in a (compound) statement. 401 401 class DeclStmt final : public Stmt { 402 public:402 public: 403 403 ptr<Decl> decl; 404 404 405 DeclStmt( const CodeLocation & loc, const Decl * decl, std::vector<Label> && labels = {} )406 : Stmt(loc, std::move(labels)), decl(decl) {}407 408 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 409 private:405 DeclStmt( const CodeLocation & loc, const Decl * decl, const std::vector<Label> && labels = {} ) 406 : Stmt(loc, std::move(labels)), decl(decl) {} 407 408 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 409 private: 410 410 DeclStmt * clone() const override { return new DeclStmt{ *this }; } 411 411 MUTATE_FRIEND 412 412 }; 413 413 414 // /Represents an implicit application of a constructor or destructor.414 // Represents an implicit application of a constructor or destructor. 415 415 class ImplicitCtorDtorStmt final : public Stmt { 416 public:416 public: 417 417 ptr<Stmt> callStmt; 418 418 419 419 ImplicitCtorDtorStmt( const CodeLocation & loc, const Stmt * callStmt, 420 std::vector<Label> && labels = {} )421 : Stmt(loc, std::move(labels)), callStmt(callStmt) {}422 423 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 424 private:420 std::vector<Label> && labels = {} ) 421 : Stmt(loc, std::move(labels)), callStmt(callStmt) {} 422 423 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 424 private: 425 425 ImplicitCtorDtorStmt * clone() const override { return new ImplicitCtorDtorStmt{ *this }; } 426 426 MUTATE_FRIEND 427 427 }; 428 428 429 // /Mutex Statement429 // Mutex Statement 430 430 class MutexStmt final : public Stmt { 431 public:431 public: 432 432 ptr<Stmt> stmt; 433 433 std::vector<ptr<Expr>> mutexObjs; 434 434 435 435 MutexStmt( const CodeLocation & loc, const Stmt * stmt, 436 std::vector<ptr<Expr>> && mutexes,std::vector<Label> && labels = {} )437 : Stmt(loc, std::move(labels)), stmt(stmt), mutexObjs(std::move(mutexes)) {}438 439 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 440 private:436 const std::vector<ptr<Expr>> && mutexes, const std::vector<Label> && labels = {} ) 437 : Stmt(loc, std::move(labels)), stmt(stmt), mutexObjs(std::move(mutexes)) {} 438 439 const Stmt * accept( Visitor & v ) const override { return v.visit( this ); } 440 private: 441 441 MutexStmt * clone() const override { return new MutexStmt{ *this }; } 442 442 MUTATE_FRIEND 443 443 }; 444 445 } 444 } // namespace ast 446 445 447 446 #undef MUTATE_FRIEND 448 447 449 448 // Local Variables: // 450 // tab-width: 4 //451 449 // mode: c++ // 452 // compile-command: "make install" //453 450 // End: // -
src/AST/Visitor.hpp
r97c215f rf5a51db 10 10 // Created On : Thr May 9 15:28:00 2019 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 12 18:25:07 202113 // Update Count : 112 // Last Modified On : Tue Feb 1 09:09:34 2022 13 // Update Count : 2 14 14 // 15 15 … … 38 38 virtual const ast::Stmt * visit( const ast::DirectiveStmt * ) = 0; 39 39 virtual const ast::Stmt * visit( const ast::IfStmt * ) = 0; 40 virtual const ast::Stmt * visit( const ast::While Stmt* ) = 0;40 virtual const ast::Stmt * visit( const ast::WhileDoStmt * ) = 0; 41 41 virtual const ast::Stmt * visit( const ast::ForStmt * ) = 0; 42 42 virtual const ast::Stmt * visit( const ast::SwitchStmt * ) = 0;
Note:
See TracChangeset
for help on using the changeset viewer.