001: /* StoreInstruction Copyright (C) 1998-2002 Jochen Hoenicke.
002: *
003: * This program is free software; you can redistribute it and/or modify
004: * it under the terms of the GNU Lesser General Public License as published by
005: * the Free Software Foundation; either version 2, or (at your option)
006: * any later version.
007: *
008: * This program is distributed in the hope that it will be useful,
009: * but WITHOUT ANY WARRANTY; without even the implied warranty of
010: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
011: * GNU General Public License for more details.
012: *
013: * You should have received a copy of the GNU Lesser General Public License
014: * along with this program; see the file COPYING.LESSER. If not, write to
015: * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
016: *
017: * $Id: StoreInstruction.java,v 4.21.2.3 2002/05/28 17:34:06 hoenicke Exp $
018: */
019:
020: package jode.expr;
021:
022: import jode.type.Type;
023: import jode.GlobalOptions;
024: import jode.decompiler.TabbedPrintWriter;
025:
026: public class StoreInstruction extends Operator implements
027: CombineableOperator {
028:
029: boolean opAssign = false;
030:
031: public StoreInstruction(LValueExpression lvalue) {
032: super (Type.tVoid, ASSIGN_OP);
033: initOperands(2);
034: setSubExpressions(0, (Operator) lvalue);
035: }
036:
037: public LValueExpression getLValue() {
038: return (LValueExpression) subExpressions[0];
039: }
040:
041: public void makeOpAssign(int operatorIndex) {
042: setOperatorIndex(operatorIndex);
043: if (subExpressions[1] instanceof NopOperator)
044: subExpressions[1].type = Type.tUnknown;
045: opAssign = true;
046: }
047:
048: public boolean isOpAssign() {
049: return opAssign;
050: }
051:
052: /**
053: * Makes a non void expression out of this store instruction.
054: */
055: public void makeNonVoid() {
056: if (type != Type.tVoid)
057: throw new jode.AssertError("already non void");
058: type = subExpressions[0].getType();
059: }
060:
061: public boolean lvalueMatches(Operator loadop) {
062: return getLValue().matches(loadop);
063: }
064:
065: public int getPriority() {
066: return 100;
067: }
068:
069: public void updateSubTypes() {
070: if (!isVoid()) {
071: subExpressions[0].setType(type);
072: subExpressions[1].setType(Type.tSubType(type));
073: }
074: }
075:
076: public void updateType() {
077:
078: Type newType;
079:
080: if (!opAssign) {
081: /* An opassign (+=, -=, etc.) doesn't merge rvalue type. */
082: Type lvalueType = subExpressions[0].getType();
083: Type rvalueType = subExpressions[1].getType();
084: subExpressions[0].setType(Type.tSuperType(rvalueType));
085: subExpressions[1].setType(Type.tSubType(lvalueType));
086: }
087:
088: if (!isVoid())
089: updateParentType(subExpressions[0].getType());
090: }
091:
092: public Expression simplify() {
093: if (subExpressions[1] instanceof ConstOperator) {
094: ConstOperator one = (ConstOperator) subExpressions[1];
095:
096: if ((getOperatorIndex() == OPASSIGN_OP + ADD_OP || getOperatorIndex() == OPASSIGN_OP
097: + SUB_OP)
098: && one.isOne(subExpressions[0].getType())) {
099:
100: int op = (getOperatorIndex() == OPASSIGN_OP + ADD_OP) ? INC_OP
101: : DEC_OP;
102:
103: return new PrePostFixOperator(getType(), op,
104: getLValue(), isVoid()).simplify();
105: }
106: }
107: return super .simplify();
108: }
109:
110: public boolean opEquals(Operator o) {
111: return o instanceof StoreInstruction
112: && o.operatorIndex == operatorIndex
113: && o.isVoid() == isVoid();
114: }
115:
116: public void dumpExpression(TabbedPrintWriter writer)
117: throws java.io.IOException {
118: writer.startOp(writer.NO_PAREN, 2);
119: subExpressions[0].dumpExpression(writer);
120: writer.endOp();
121: writer.breakOp();
122: writer.print(getOperatorString());
123: subExpressions[1].dumpExpression(writer, 100);
124: }
125: }
|