| 57 | */ |
| 58 | template<class T, class TFunc, REQUIRES("T must be a Token class", std::is_convertible<T*, const Token*> )> |
| 59 | void visitAstNodes(T *ast, const TFunc &visitor) |
| 60 | { |
| 61 | if (!ast) |
| 62 | return; |
| 63 | |
| 64 | // the size of 8 was determined in tests to be sufficient to avoid excess allocations. also add 1 as a buffer. |
| 65 | // we might need to increase that value in the future. |
| 66 | SmallVector<T *, 8 + 1> tokens; |
| 67 | T *tok = ast; |
| 68 | do { |
| 69 | const ChildrenToVisit c = visitor(tok); |
| 70 | if (c == ChildrenToVisit::done) |
| 71 | break; |
| 72 | |
| 73 | if (c == ChildrenToVisit::op2 || c == ChildrenToVisit::op1_and_op2) { |
| 74 | T *t2 = tok->astOperand2(); |
| 75 | if (t2) |
| 76 | tokens.push_back(t2); |
| 77 | } |
| 78 | if (c == ChildrenToVisit::op1 || c == ChildrenToVisit::op1_and_op2) { |
| 79 | T *t1 = tok->astOperand1(); |
| 80 | if (t1) |
| 81 | tokens.push_back(t1); |
| 82 | } |
| 83 | |
| 84 | if (tokens.empty()) |
| 85 | break; |
| 86 | |
| 87 | tok = tokens.back(); |
| 88 | tokens.pop_back(); |
| 89 | } while (true); |
| 90 | } |
| 91 | |
| 92 | template<class TFunc> |
| 93 | const Token* findAstNode(const Token* ast, const TFunc& pred) |
no test coverage detected