Changeset 88bc876 for src/ControlStruct
- Timestamp:
- Jul 16, 2024, 5:28:10 PM (5 months ago)
- Branches:
- master
- Children:
- 97f9619
- Parents:
- 2363147
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/MultiLevelExit.cpp
r2363147 r88bc876 78 78 stmt( stmt ), firstTarget( breakExit ), secondTarget(), kind( TryStmtK ) {} 79 79 80 // Check if this entry can be the target of the given type of control flow. 80 81 bool isContTarget() const { return kind <= WhileDoStmtK; } 81 82 bool isBreakTarget() const { return kind != CaseClauseK; } … … 207 208 208 209 // If the label is empty, do not add unused attribute. 209 210 if ( originalTarget.empty() ) return size; 210 211 211 212 // Search for a label that matches the originalTarget. … … 343 344 assert(0); 344 345 } 346 assert( !exitLabel.empty() ); 345 347 346 348 // Add unused attribute to silence warnings. … … 486 488 } 487 489 488 auto caseStmt = mutStmt->cases.back().get(); 489 auto mutCase = mutate( caseStmt ); 490 mutStmt->cases.back() = mutCase; 490 auto mutCase = mutStmt->cases.back().get_and_mutate(); 491 491 492 492 Label label( mutCase->location, "breakLabel" ); … … 597 597 template<typename LoopNode> 598 598 void MultiLevelExitCore::prehandleLoopStmt( const LoopNode * loopStmt ) { 599 // Remember is loop before going onto mutate the body.599 // Create temporary labels and mark the enclosing loop before traversal. 600 600 // The labels will be folded in if they are used. 601 601 Label breakLabel = newLabel( "loopBreak", loopStmt ); 602 602 Label contLabel = newLabel( "loopContinue", loopStmt ); 603 603 enclosing_control_structures.emplace_back( loopStmt, breakLabel, contLabel ); 604 // labels are added temporarily to see if they are used and then added permanently in postvisit if ther are used 605 // children will tag labels as being used during their traversal which occurs before postvisit 606 607 // GuardAction calls the lambda after the node is done being visited 604 608 605 GuardAction( [this](){ enclosing_control_structures.pop_back(); } ); 606 607 // Because of fixBlock, this should be empty now (and must be). 608 assert( nullptr == loopStmt->else_ ); 609 609 } 610 610 … … 617 617 // Now check if the labels are used and add them if so. 618 618 return mutate_field( loopStmt, &LoopNode::body, mutateLoop( loopStmt->body, entry ) ); 619 // this call to mutate_field compares loopStmt->body and the result of mutateLoop620 // if they are the same the node isn't mutated, if they differ then the new mutated node is returned621 // the stmts will only differ if a label is used622 619 } 623 620 … … 639 636 640 637 ptr<Stmt> else_stmt = nullptr; 641 const Stmt * loop_kid = nullptr;638 const Stmt * to_visit; 642 639 // check if loop node and if so add else clause if it exists 643 const WhileDoStmt * whilePtr = kid.as<WhileDoStmt>();644 if ( whilePtr && whilePtr->else_ ) {645 else_stmt = whilePtr->else_;646 loop_kid = mutate_field( whilePtr, &WhileDoStmt::else_, nullptr );647 }648 const ForStmt * forPtr = kid.as<ForStmt>();649 if ( forPtr && forPtr->else_ ){650 else_stmt = forPtr->else_;651 loop_kid = mutate_field( forPtr, &ForStmt::else_, nullptr );652 } 653 640 if ( auto ptr = kid.as<WhileDoStmt>() ; ptr && ptr->else_ ) { 641 else_stmt = ptr->else_; 642 to_visit = mutate_field( ptr, &WhileDoStmt::else_, nullptr ); 643 } else if ( auto ptr = kid.as<ForStmt>() ; ptr && ptr->else_ ) { 644 else_stmt = ptr->else_; 645 to_visit = mutate_field( ptr, &ForStmt::else_, nullptr ); 646 } else { 647 to_visit = kid.get(); 648 } 649 650 // This is the main (safe) visit of the child node. 654 651 try { 655 if (else_stmt) ret.push_back( loop_kid->accept( *visitor ) ); 656 else ret.push_back( kid->accept( *visitor ) ); 652 ret.push_back( to_visit->accept( *visitor ) ); 657 653 } catch ( SemanticErrorException & e ) { 658 654 errors.append( e ); 659 655 } 660 656 661 if (else_stmt) ret.push_back(else_stmt); 662 663 if ( ! break_label.empty() ) { 657 // The following sections handle visiting loop else clause and makes 658 // sure breaking from a loop body does not execute that clause. 659 Label local_break_label = std::move( break_label ); 660 break_label = Label( CodeLocation(), "" ); 661 662 if ( else_stmt ) try { 663 ret.push_back( else_stmt->accept( *visitor ) ); 664 } catch ( SemanticErrorException & e ) { 665 errors.append( e ); 666 } 667 668 if ( !break_label.empty() ) { 664 669 ret.push_back( labelledNullStmt( ret.back()->location, break_label ) ); 665 670 break_label = Label( CodeLocation(), "" ); 666 671 } 667 } 668 669 if ( ! errors.isEmpty() ) { 672 673 // This handles a break from the body or non-loop statement. 674 if ( !local_break_label.empty() ) { 675 ret.push_back( labelledNullStmt( ret.back()->location, local_break_label ) ); 676 } 677 } 678 679 if ( !errors.isEmpty() ) { 670 680 throw errors; 671 681 }
Note: See TracChangeset
for help on using the changeset viewer.