/* This file is part of the db4o object database http://www.db4o.com Copyright (C) 2004 - 2011 Versant Corporation http://www.versant.com db4o is free software; you can redistribute it and/or modify it under the terms of version 3 of the GNU General Public License as published by the Free Software Foundation. db4o is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. */ package EDU.purdue.cs.bloat.tree; import java.util.*; import EDU.purdue.cs.bloat.util.*; /** * A PhiCatchStmt is used to handle variables that are used inside an exception * handler. Inside a try block a variable may be used several times. It may be * updated, may be invovled in a phi-function, etc. A PhiCatchStmt is placed at * the beginning of each expection handling (catch) block to factor together the * variables that are live within the protected region. */ public class PhiCatchStmt extends PhiStmt { ArrayList operands; /** * Constructor. * * @param target * Local variable to which the result of this phi-function is to * be assigned. */ public PhiCatchStmt(final LocalExpr target) { super(target); this.operands = new ArrayList(); } public void visitForceChildren(final TreeVisitor visitor) { if (visitor.reverse()) { target.visit(visitor); } for (int i = 0; i < operands.size(); i++) { final LocalExpr expr = (LocalExpr) operands.get(i); expr.visit(visitor); } if (!visitor.reverse()) { target.visit(visitor); } } public void visit(final TreeVisitor visitor) { visitor.visitPhiCatchStmt(this); } /** * Searches the list of operands for a local variable. * * @param def * The local variable definition to search for. * @return True, if def is found, otherwise, false. */ public boolean hasOperandDef(final LocalExpr def) { for (int i = 0; i < operands.size(); i++) { final LocalExpr expr = (LocalExpr) operands.get(i); if (expr.def() == def) { return true; } } return false; } /** * Add a local variable to the operand list for this phi-function. * * @param operand * An operand of this phi-function. */ public void addOperand(final LocalExpr operand) { for (int i = 0; i < operands.size(); i++) { final LocalExpr expr = (LocalExpr) operands.get(i); Assert.isTrue(expr.def() != operand.def()); } operands.add(operand); operand.setParent(this); } /** * Returns the operands to this phi-function. */ public Collection operands() { if (operands == null) { return new ArrayList(); } for (int i = 0; i < operands.size(); i++) { final LocalExpr ei = (LocalExpr) operands.get(i); for (int j = operands.size() - 1; j > i; j--) { final LocalExpr ej = (LocalExpr) operands.get(j); if (ei.def() == ej.def()) { ej.cleanup(); operands.remove(j); } } } return operands; } /** * Returns the number of operands to this phi-function. */ public int numOperands() { return operands.size(); } /** * Sets the value of one of this phi-function's operands. * * @param i * The number parameter to set. * @param expr * The new value of the parameter. */ public void setOperandAt(final int i, final Expr expr) { final Expr old = (Expr) operands.get(i); old.cleanup(); operands.set(i, expr); expr.setParent(this); } /** * Returns the operand at a given index. */ public Expr operandAt(final int i) { return (Expr) operands.get(i); } }