<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto">Thanks, I’ll have a look at that. I was trying to use the marchers and hadn’t thought of other approaches!<br><br><div dir="ltr">Sent from my iPhone</div><div dir="ltr"><br><blockquote type="cite">On 12 Aug 2020, at 20:36, David Rector <davrecthreads@gmail.com> wrote:<br><br></blockquote></div><blockquote type="cite"><div dir="ltr"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">Here is how a RecursiveASTVisitor could do it (not tested):</div><div style="margin: 0px; font-stretch: normal; font-size: 10px; line-height: normal; min-height: 12px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; font-size: 10px; line-height: normal;" class="">```</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">#include "clang/AST/RecursiveASTVisitor.h"</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo; min-height: 11px;" class=""><br class=""></div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">/// Usage: </div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">///   std::map<ForStmt *, std::vector<BreakStmt *>> for2breaks;</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">///   ForBreakMapper(for2breaks).TraverseDecl(</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">///       /*Context.getTranslationUnitDecl(), some function decl, etc…);</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">///</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">class ForBreakMapper : public RecursiveASTVisitor<ForBreakMapper> {</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">  using BaseType = RecursiveASTVisitor<ForBreakMapper>;</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo; min-height: 11px;" class=""><br class=""></div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">  ForStmt *ActiveFor = nullptr;</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">  std::map<ForStmt *, std::vector<BreakStmt *>> &forbreaks_mapref;</div><p style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo; min-height: 11px;" class="">  <br class="webkit-block-placeholder"></p><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">public:</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">  ForBreakMapper(decltype(for2breaks_mapref) forbreaks_mapref)</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">      : for2breaks_mapref(for2breaks_mapref) {}</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo; min-height: 11px;" class=""><br class=""></div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">  // Need this override to disable "data recursion" and thus</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">  // guarantee VisitBreakStmt happens within its parent's </div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">  // Traverse*Stmt call:</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">  bool TraverseStmt(Stmt *S) { return BaseType::TraverseStmt(S); }</div><p style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo; min-height: 11px;" class="">  <br class="webkit-block-placeholder"></p><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">  bool TraverseForStmt(ForStmt *S) {</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">    SaveAndRestore<ForStmt *> RAII(ActiveFor, S);</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">    return BaseType::TraverseForStmt(S);</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">  }</div><p style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo; min-height: 11px;" class="">  <br class="webkit-block-placeholder"></p><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">  // Nullify ActiveFor for SwitchStmts (any others?)</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">  bool TraverseSwitchStmt(SwitchStmt *S) {</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">    SaveAndRestore<ForStmt *> RAII(ActiveFor, nullptr);</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">    return BaseType::TraverseSwitchStmt(S);</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">  }</div><p style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo; min-height: 11px;" class="">  <br class="webkit-block-placeholder"></p><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">  bool VisitBreakStmt(BreakStmt *S) {</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">    if (ActiveFor && S)</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">      forbreaks_mapref[ActiveFor].push_back(S);</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">    return true;</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">  }</div><div style="margin: 0px 0px 0px 17.6px; text-indent: -4.4px; font-stretch: normal; font-size: 10px; line-height: normal; font-family: Menlo;" class="">};</div><div style="margin: 0px; font-stretch: normal; font-size: 10px; line-height: normal;" class="">```</div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">I’m a big fan of this general technique, i.e. using llvm::SaveAndRestore in Traverse* overrides to keep track of traversal state data, which you then use in your Visit* overrides.  </div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">You do need that seemingly-trivial TraverseStmt override whenever you do this sort of thing with Stmts though, otherwise the Visit* statements will not be called within the ancestor’s Traverse* statements (due to the "data recursion" queueing performed by default in the base RecursiveASTVisitor.)</div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">Good luck,</div><div style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class="">- Dave</div><div><br class=""><blockquote type="cite" class=""><div class="">On Aug 12, 2020, at 11:16 AM, Phil King via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Hi,<br class=""><br class="">I am trying to find all of the break statements that can cause termination of for loops. The following gives me all the break statements under a “for” node, but I cannot see how to filter out those that cannot terminate the current loop (e.g., they may terminate a case statement, be enclosed within a nested loop, etc.):<br class=""><br class="">forStmt( forEachDescentant( breakStmt().bind( “myBreaks” ) ) ).bind( “myFors” )<br class=""><br class="">How should I go about filtering out the unwanted breaks?<br class=""><br class="">Sent from my iPhone<br class="">_______________________________________________<br class="">cfe-dev mailing list<br class=""><a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a><br class="">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev<br class=""></div></div></blockquote></div><br class=""></div></blockquote></body></html>