// // Returns true if 'ast' is directly under 'fi'. // BTW in this case fi's enclosing BlockStmt is ast's parentExpr. // BTW we could use AST_CALL_STDVEC/AST_CALL_CHILD for a "directly or // indirectly under fi" check, although we'd need extra effort // to make them return a bool and abort early if the answer is known. // bool astUnderFI(const Expr* ast, ForallIntents* fi) { if (!fi) return false; #define CHECK(arg) { if (((Expr*)(arg)) == ast) return true; } for_vector(Expr, var, fi->fiVars) CHECK(var); for_riSpecs_vector(ri, fi) CHECK(ri); CHECK(fi->iterRec); CHECK(fi->leadIdx); CHECK(fi->leadIdxCopy); #undef CHECK // none found return false; }
// This is intended to mimick Expr::remove(), without 'this' being an Expr. void ForallIntents::removeFI(Expr* parentB) { // If this fails need to use trace_remove() instead of remove_help() // - see Expr::remove(). INT_ASSERT(parentB->parentSymbol); // "Remove" all ASTs that 'this' contains. #define REMOVE(dest) if (dest) remove_help(dest, 'r') for_vector(Expr, var, fiVars) REMOVE(var); for_riSpecs_vector(ri, this) REMOVE(ri); REMOVE(iterRec); REMOVE(leadIdx); REMOVE(leadIdxCopy); #undef REMOVE }
ExpandVisitor::~ExpandVisitor() { for_vector(Expr, expr, delayedRemoval) expr->remove(); }