diff options
Diffstat (limited to 'src/ast_utils.h')
-rw-r--r-- | src/ast_utils.h | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/src/ast_utils.h b/src/ast_utils.h index 5deaa6a2c..6b76dd61d 100644 --- a/src/ast_utils.h +++ b/src/ast_utils.h @@ -27,7 +27,7 @@ namespace wasm { struct BreakSeeker : public PostWalker<BreakSeeker, Visitor<BreakSeeker>> { Name target; // look for this one XXX looking by name may fall prey to duplicate names - size_t found; + Index found; BreakSeeker(Name target) : target(target), found(false) {} @@ -47,6 +47,12 @@ struct BreakSeeker : public PostWalker<BreakSeeker, Visitor<BreakSeeker>> { breakSeeker.walk(tree); return breakSeeker.found > 0; } + + static Index count(Expression* tree, Name target) { + BreakSeeker breakSeeker(target); + breakSeeker.walk(tree); + return breakSeeker.found; + } }; // Finds all functions that are reachable via direct calls. @@ -391,6 +397,25 @@ struct ExpressionAnalyzer { return func->result != none; } + // Checks if a break is a simple - no condition, no value, just a plain branching + static bool isSimple(Break* curr) { + return !curr->condition && !curr->value; + } + + // Checks if an expression ends with a simple break, + // and returns a pointer to it if so. + // (It might also have other internal branches.) + static Expression* getEndingSimpleBreak(Expression* curr) { + if (auto* br = curr->dynCast<Break>()) { + if (isSimple(br)) return br; + return nullptr; + } + if (auto* block = curr->dynCast<Block>()) { + if (block->list.size() > 0) return getEndingSimpleBreak(block->list.back()); + } + return nullptr; + } + template<typename T> static bool flexibleEqual(Expression* left, Expression* right, T& comparer) { std::vector<Name> nameStack; |