@@ -1619,78 +1619,96 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
16191619// / this statement is not executed normally, it not containing a label means
16201620// / that we can just remove the code.
16211621bool CodeGenFunction::ContainsLabel (const Stmt *S, bool IgnoreCaseStmts) {
1622- // Null statement, not a label!
1623- if (!S) return false ;
1622+ llvm::SmallVector<std::pair< const Stmt *, bool >, 32 > WorkList;
1623+ WorkList. emplace_back (S, IgnoreCaseStmts) ;
16241624
1625- // If this is a label, we have to emit the code, consider something like:
1626- // if (0) { ... foo: bar(); } goto foo;
1627- //
1628- // TODO: If anyone cared, we could track __label__'s, since we know that you
1629- // can't jump to one from outside their declared region.
1630- if (isa<LabelStmt>(S))
1631- return true ;
1625+ while (!WorkList.empty ()) {
1626+ auto [CurStmt, CurIgnoreCaseStmts] = WorkList.pop_back_val ();
16321627
1633- // If this is a case/default statement, and we haven't seen a switch, we have
1634- // to emit the code.
1635- if (isa<SwitchCase>(S) && !IgnoreCaseStmts)
1636- return true ;
1628+ // Null statement, not a label!
1629+ if (!CurStmt)
1630+ continue ;
16371631
1638- // If this is a switch statement, we want to ignore cases below it.
1639- if (isa<SwitchStmt>(S))
1640- IgnoreCaseStmts = true ;
1632+ // If this is a label, we have to emit the code, consider something like:
1633+ // if (0) { ... foo: bar(); } goto foo;
1634+ //
1635+ // TODO: If anyone cared, we could track __label__'s, since we know that you
1636+ // can't jump to one from outside their declared region.
1637+ if (isa<LabelStmt>(CurStmt))
1638+ return true ;
16411639
1642- // Scan subexpressions for verboten labels.
1643- for ( const Stmt *SubStmt : S-> children ())
1644- if (ContainsLabel (SubStmt, IgnoreCaseStmts) )
1640+ // If this is a case/default statement, and we haven't seen a switch, we
1641+ // have to emit the code.
1642+ if (isa<SwitchCase>(CurStmt) && !CurIgnoreCaseStmts )
16451643 return true ;
16461644
1645+ // If this is a switch statement, we want to ignore cases below it.
1646+ if (isa<SwitchStmt>(CurStmt))
1647+ CurIgnoreCaseStmts = true ;
1648+
1649+ // Scan subexpressions for verboten labels.
1650+ for (const Stmt *SubStmt : CurStmt->children ())
1651+ WorkList.emplace_back (SubStmt, CurIgnoreCaseStmts);
1652+ }
1653+
16471654 return false ;
16481655}
16491656
16501657// / containsBreak - Return true if the statement contains a break out of it.
16511658// / If the statement (recursively) contains a switch or loop with a break
16521659// / inside of it, this is fine.
16531660bool CodeGenFunction::containsBreak (const Stmt *S) {
1654- // Null statement, not a label!
1655- if (!S) return false ;
1661+ llvm::SmallVector<const Stmt *, 32 > WorkList;
1662+ WorkList.push_back (S);
1663+ while (!WorkList.empty ()) {
1664+ const Stmt *CurStmt = WorkList.pop_back_val ();
16561665
1657- // If this is a switch or loop that defines its own break scope, then we can
1658- // include it and anything inside of it.
1659- if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || isa<DoStmt>(S) ||
1660- isa<ForStmt>(S))
1661- return false ;
1666+ // Null statement, not a label!
1667+ if (!CurStmt)
1668+ continue ;
16621669
1663- if (isa<BreakStmt>(S))
1664- return true ;
1670+ // If this is a switch or loop that defines its own break scope, then we can
1671+ // include it and anything inside of it.
1672+ if (isa<SwitchStmt>(CurStmt) || isa<WhileStmt>(CurStmt) ||
1673+ isa<DoStmt>(CurStmt) || isa<ForStmt>(CurStmt))
1674+ continue ;
16651675
1666- // Scan subexpressions for verboten breaks.
1667- for (const Stmt *SubStmt : S->children ())
1668- if (containsBreak (SubStmt))
1676+ if (isa<BreakStmt>(CurStmt))
16691677 return true ;
16701678
1679+ // Scan subexpressions for verboten breaks.
1680+ for (const Stmt *SubStmt : CurStmt->children ())
1681+ WorkList.push_back (SubStmt);
1682+ }
16711683 return false ;
16721684}
16731685
16741686bool CodeGenFunction::mightAddDeclToScope (const Stmt *S) {
1675- if (!S) return false ;
1676-
1677- // Some statement kinds add a scope and thus never add a decl to the current
1678- // scope. Note, this list is longer than the list of statements that might
1679- // have an unscoped decl nested within them, but this way is conservatively
1680- // correct even if more statement kinds are added.
1681- if (isa<IfStmt>(S) || isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
1682- isa<DoStmt>(S) || isa<ForStmt>(S) || isa<CompoundStmt>(S) ||
1683- isa<CXXForRangeStmt>(S) || isa<CXXTryStmt>(S) ||
1684- isa<ObjCForCollectionStmt>(S) || isa<ObjCAtTryStmt>(S))
1685- return false ;
1687+ llvm::SmallVector<const Stmt *, 32 > WorkList;
1688+ WorkList.push_back (S);
1689+ while (!WorkList.empty ()) {
1690+ const Stmt *CurStmt = WorkList.pop_back_val ();
16861691
1687- if (isa<DeclStmt>(S) )
1688- return true ;
1692+ if (!CurStmt )
1693+ continue ;
16891694
1690- for (const Stmt *SubStmt : S->children ())
1691- if (mightAddDeclToScope (SubStmt))
1695+ // Some statement kinds add a scope and thus never add a decl to the current
1696+ // scope. Note, this list is longer than the list of statements that might
1697+ // have an unscoped decl nested within them, but this way is conservatively
1698+ // correct even if more statement kinds are added.
1699+ if (isa<IfStmt>(CurStmt) || isa<SwitchStmt>(CurStmt) ||
1700+ isa<WhileStmt>(CurStmt) || isa<DoStmt>(CurStmt) ||
1701+ isa<ForStmt>(CurStmt) || isa<CompoundStmt>(CurStmt) ||
1702+ isa<CXXForRangeStmt>(CurStmt) || isa<CXXTryStmt>(CurStmt) ||
1703+ isa<ObjCForCollectionStmt>(CurStmt) || isa<ObjCAtTryStmt>(CurStmt))
1704+ continue ;
1705+
1706+ if (isa<DeclStmt>(CurStmt))
16921707 return true ;
16931708
1709+ for (const Stmt *SubStmt : CurStmt->children ())
1710+ WorkList.push_back (SubStmt);
1711+ }
16941712 return false ;
16951713}
16961714
0 commit comments