| 291 | } // namespace |
| 292 | |
| 293 | void Expr::FlattenedErase() { |
| 294 | // High level idea is to build a topological ordering of the AST, then erase |
| 295 | // leaf to root. |
| 296 | this->u_.next = nullptr; |
| 297 | Expr* prev_tail = nullptr; |
| 298 | Expr* tail = this; |
| 299 | |
| 300 | while (tail != prev_tail) { |
| 301 | Expr* next_prev_tail = tail; |
| 302 | Expr* expand_ptr = tail; |
| 303 | while (expand_ptr != prev_tail) { |
| 304 | ABSL_DCHECK(expand_ptr != nullptr); // Linked list is broken or changed. |
| 305 | Expr* next_expand_ptr = expand_ptr->u_.next; |
| 306 | Expand(&tail, expand_ptr); |
| 307 | expand_ptr = next_expand_ptr; |
| 308 | } |
| 309 | prev_tail = next_prev_tail; |
| 310 | } |
| 311 | |
| 312 | Expr* node = tail; |
| 313 | while (node != nullptr) { |
| 314 | Expr* next = node->u_.next; |
| 315 | node->Clear(); |
| 316 | node = next; |
| 317 | } |
| 318 | } |
| 319 | |
| 320 | } // namespace cel |