Changeset 2e9b59b for src/ControlStruct/MultiLevelExit.cpp
- Timestamp:
- Apr 19, 2022, 3:00:04 PM (3 years ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
- Children:
- 5b84a321
- Parents:
- ba897d21 (diff), bb7c77d (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/MultiLevelExit.cpp
rba897d21 r2e9b59b 9 9 // Author : Andrew Beach 10 10 // Created On : Mon Nov 1 13:48:00 2021 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Feb 2 23:07:54202213 // Update Count : 3 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Mar 28 9:42:00 2022 13 // Update Count : 34 14 14 // 15 15 … … 40 40 41 41 enum Kind { 42 ForStmtK, WhileDoStmtK, CompoundStmtK, IfStmtK, Case StmtK, SwitchStmtK, TryStmtK42 ForStmtK, WhileDoStmtK, CompoundStmtK, IfStmtK, CaseClauseK, SwitchStmtK, TryStmtK 43 43 } kind; 44 44 … … 58 58 Entry( const IfStmt *stmt, Label breakExit ) : 59 59 stmt( stmt ), firstTarget( breakExit ), secondTarget(), kind( IfStmtK ) {} 60 Entry( const Case Stmt *stmt, Label fallExit ) :61 stmt( stmt ), firstTarget( fallExit ), secondTarget(), kind( Case StmtK ) {}60 Entry( const CaseClause *, const CompoundStmt *stmt, Label fallExit ) : 61 stmt( stmt ), firstTarget( fallExit ), secondTarget(), kind( CaseClauseK ) {} 62 62 Entry( const SwitchStmt *stmt, Label breakExit, Label fallDefaultExit ) : 63 63 stmt( stmt ), firstTarget( breakExit ), secondTarget( fallDefaultExit ), kind( SwitchStmtK ) {} … … 66 66 67 67 bool isContTarget() const { return kind <= WhileDoStmtK; } 68 bool isBreakTarget() const { return kind != Case StmtK; }69 bool isFallTarget() const { return kind == Case StmtK; }68 bool isBreakTarget() const { return kind != CaseClauseK; } 69 bool isFallTarget() const { return kind == CaseClauseK; } 70 70 bool isFallDefaultTarget() const { return kind == SwitchStmtK; } 71 71 72 72 // These routines set a target as being "used" by a BranchStmt 73 73 Label useContExit() { assert( kind <= WhileDoStmtK ); return useTarget(secondTarget); } 74 Label useBreakExit() { assert( kind != Case StmtK ); return useTarget(firstTarget); }75 Label useFallExit() { assert( kind == Case StmtK ); return useTarget(firstTarget); }74 Label useBreakExit() { assert( kind != CaseClauseK ); return useTarget(firstTarget); } 75 Label useFallExit() { assert( kind == CaseClauseK ); return useTarget(firstTarget); } 76 76 Label useFallDefaultExit() { assert( kind == SwitchStmtK ); return useTarget(secondTarget); } 77 77 78 78 // These routines check if a specific label for a statement is used by a BranchStmt 79 79 bool isContUsed() const { assert( kind <= WhileDoStmtK ); return secondTarget.used; } 80 bool isBreakUsed() const { assert( kind != Case StmtK ); return firstTarget.used; }81 bool isFallUsed() const { assert( kind == Case StmtK ); return firstTarget.used; }80 bool isBreakUsed() const { assert( kind != CaseClauseK ); return firstTarget.used; } 81 bool isFallUsed() const { assert( kind == CaseClauseK ); return firstTarget.used; } 82 82 bool isFallDefaultUsed() const { assert( kind == SwitchStmtK ); return secondTarget.used; } 83 83 void seenDefault() { fallDefaultValid = false; } … … 115 115 void previsit( const ForStmt * ); 116 116 const ForStmt * postvisit( const ForStmt * ); 117 const Case Stmt * previsit( const CaseStmt* );117 const CaseClause * previsit( const CaseClause * ); 118 118 void previsit( const IfStmt * ); 119 119 const IfStmt * postvisit( const IfStmt * ); … … 123 123 void previsit( const TryStmt * ); 124 124 void postvisit( const TryStmt * ); 125 void previsit( const Finally Stmt* );125 void previsit( const FinallyClause * ); 126 126 127 127 const Stmt * mutateLoop( const Stmt * body, Entry& ); … … 288 288 auto switchStmt = strict_dynamic_cast< const SwitchStmt * >( targetEntry->stmt ); 289 289 bool foundDefault = false; 290 for ( auto subStmt : switchStmt->stmts ) { 291 const CaseStmt * caseStmt = subStmt.strict_as<CaseStmt>(); 290 for ( auto caseStmt : switchStmt->cases ) { 292 291 if ( caseStmt->isDefault() ) { 293 292 foundDefault = true; … … 365 364 } 366 365 367 const Case Stmt * MultiLevelExitCore::previsit( const CaseStmt* stmt ) {366 const CaseClause * MultiLevelExitCore::previsit( const CaseClause * stmt ) { 368 367 visit_children = false; 369 368 … … 375 374 376 375 // The cond may not exist, but if it does update it now. 377 visitor->maybe_accept( stmt, &Case Stmt::cond );376 visitor->maybe_accept( stmt, &CaseClause::cond ); 378 377 379 378 // Just save the mutated node for simplicity. 380 Case Stmt* mutStmt = mutate( stmt );381 382 Label fallLabel = newLabel( "fallThrough", stmt );379 CaseClause * mutStmt = mutate( stmt ); 380 381 Label fallLabel = newLabel( "fallThrough", stmt->location ); 383 382 if ( ! mutStmt->stmts.empty() ) { 383 // These should already be in a block. 384 auto first = mutStmt->stmts.front().get_and_mutate(); 385 auto block = strict_dynamic_cast<CompoundStmt *>( first ); 386 384 387 // Ensure that the stack isn't corrupted by exceptions in fixBlock. 385 388 auto guard = makeFuncGuard( 386 [&](){ enclosing_control_structures.emplace_back( mutStmt, fallLabel ); },389 [&](){ enclosing_control_structures.emplace_back( mutStmt, block, fallLabel ); }, 387 390 [this](){ enclosing_control_structures.pop_back(); } 388 391 ); 389 392 390 // These should already be in a block.391 auto block = mutate( mutStmt->stmts.front().strict_as<CompoundStmt>() );392 393 block->kids = fixBlock( block->kids, true ); 393 394 … … 396 397 Entry & entry = enclosing_control_structures.back(); 397 398 if ( entry.isFallUsed() ) { 398 mutStmt->stmts.push_back( labelledNullStmt( mutStmt->location, entry.useFallExit() ) );399 mutStmt->stmts.push_back( labelledNullStmt( block->location, entry.useFallExit() ) ); 399 400 } 400 401 } … … 433 434 } 434 435 435 bool isDefaultCase( const ptr<Stmt> & stmt ) { 436 const CaseStmt * caseStmt = stmt.strict_as<CaseStmt>(); 437 return caseStmt->isDefault(); 436 static bool isDefaultCase( const ptr<CaseClause> & caseClause ) { 437 return caseClause->isDefault(); 438 438 } 439 439 440 440 void MultiLevelExitCore::previsit( const SwitchStmt * stmt ) { 441 441 Label label = newLabel( "switchBreak", stmt ); 442 auto it = find_if( stmt-> stmts.rbegin(), stmt->stmts.rend(), isDefaultCase );443 444 const Case Stmt * defaultCase = it != stmt->stmts.rend() ? (it)->strict_as<CaseStmt>() : nullptr;445 Label defaultLabel = defaultCase ? newLabel( "fallThroughDefault", defaultCase ) : Label( stmt->location, "" );442 auto it = find_if( stmt->cases.rbegin(), stmt->cases.rend(), isDefaultCase ); 443 444 const CaseClause * defaultCase = it != stmt->cases.rend() ? (*it) : nullptr; 445 Label defaultLabel = defaultCase ? newLabel( "fallThroughDefault", defaultCase->location ) : Label( stmt->location, "" ); 446 446 enclosing_control_structures.emplace_back( stmt, label, defaultLabel ); 447 447 GuardAction( [this]() { enclosing_control_structures.pop_back(); } ); … … 449 449 // Collect valid labels for fallthrough. It starts with all labels at this level, then remove as each is seen during 450 450 // traversal. 451 for ( const Stmt * stmt : stmt->stmts ) { 452 auto * caseStmt = strict_dynamic_cast< const CaseStmt * >( stmt ); 451 for ( const CaseClause * caseStmt : stmt->cases ) { 453 452 if ( caseStmt->stmts.empty() ) continue; 454 453 auto block = caseStmt->stmts.front().strict_as<CompoundStmt>(); … … 471 470 // exit label and break to the last case, create a default case if no cases. 472 471 SwitchStmt * mutStmt = mutate( stmt ); 473 if ( mutStmt-> stmts.empty() ) {474 mutStmt-> stmts.push_back( new CaseStmt( mutStmt->location, nullptr, {} ) );475 } 476 477 auto caseStmt = mutStmt-> stmts.back().strict_as<CaseStmt>();472 if ( mutStmt->cases.empty() ) { 473 mutStmt->cases.push_back( new CaseClause( mutStmt->location, nullptr, {} ) ); 474 } 475 476 auto caseStmt = mutStmt->cases.back().get(); 478 477 auto mutCase = mutate( caseStmt ); 479 mutStmt-> stmts.back() = mutCase;478 mutStmt->cases.back() = mutCase; 480 479 481 480 Label label( mutCase->location, "breakLabel" ); … … 514 513 } 515 514 516 void MultiLevelExitCore::previsit( const Finally Stmt* ) {515 void MultiLevelExitCore::previsit( const FinallyClause * ) { 517 516 GuardAction([this, old = move( enclosing_control_structures)](){ enclosing_control_structures = move(old); }); 518 517 enclosing_control_structures = vector<Entry>();
Note:
See TracChangeset
for help on using the changeset viewer.