/*******************************************************************************
 * Copyright (c) 2012, 2017 Wind River Systems, Inc. and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Markus Schorn - initial API and implementation
 *     Sergey Prigogin (Google)
 *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;

import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_assign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_binaryAnd;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_binaryAndAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_binaryOr;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_binaryOrAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_binaryXor;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_binaryXorAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_divide;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_divideAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_equals;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_greaterEqual;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_greaterThan;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_lessEqual;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_lessThan;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_logicalAnd;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_logicalOr;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_minus;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_minusAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_modulo;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_moduloAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_multiply;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_multiplyAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_notequals;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_plus;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_plusAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_pmarrow;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_pmdot;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_shiftLeft;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_shiftLeftAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_shiftRight;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_shiftRightAssign;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueTypeWithResolvedTypedefs;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;

import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.DependentValue;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.ValueFactory;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArithmeticConversion;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext;
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUtil.Pair;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;

/**
 * Performs evaluation of an expression.
 */
public class EvalBinary extends CPPDependentEvaluation {
	public final static int op_arrayAccess= Byte.MAX_VALUE;
	private final int fOperator;

	private final ICPPEvaluation fArg1;
	private final ICPPEvaluation fArg2;

	private ICPPFunction fOverload= CPPFunction.UNINITIALIZED_FUNCTION;
	private ICPPEvaluation fOverloadCall;
	private IType fType;
	private boolean fCheckedIsConstantExpression;
	private boolean fIsConstantExpression;

	public EvalBinary(int operator, ICPPEvaluation arg1, ICPPEvaluation arg2, IASTNode pointOfDefinition) {
		this(operator, arg1, arg2, findEnclosingTemplate(pointOfDefinition));
	}

	public EvalBinary(int operator, ICPPEvaluation arg1, ICPPEvaluation arg2, IBinding templateDefinition) {
		super(templateDefinition);
		fOperator= operator;
		fArg1= arg1;
		fArg2= arg2;
	}

	public int getOperator() {
		return fOperator;
	}

	public ICPPEvaluation getArg1() {
		return fArg1;
	}

	public ICPPEvaluation getArg2() {
		return fArg2;
	}

	@Override
	public boolean isInitializerList() {
		return false;
	}

	@Override
	public boolean isFunctionSet() {
		return false;
	}

	@Override
	public IType getType() {
		if (fType == null) {
			if (isTypeDependent()) {
				fType= new TypeOfDependentExpression(this);
			} else {
				ICPPFunction overload = getOverload();
				if (overload != null) {
					fType= ExpressionTypes.restoreTypedefs(
							ExpressionTypes.typeFromFunctionCall(overload), fArg1.getType(), fArg2.getType());
				} else {
					fType= computeType();
				}
			}
		}
		return fType;
	}

	private ICPPEvaluation createOperatorOverloadEvaluation(ICPPFunction overload, ICPPEvaluation arg1, ICPPEvaluation arg2) {
		EvalFunctionCall operatorCall;
		IASTNode point = CPPSemantics.getCurrentLookupPoint();
		if (overload instanceof ICPPMethod) {
			EvalMemberAccess opAccess = new EvalMemberAccess(arg1.getType(), ValueCategory.LVALUE, overload, arg1, false, point);
			ICPPEvaluation[] args = new ICPPEvaluation[]{opAccess, arg2};
			operatorCall = new EvalFunctionCall(args, arg1, point);
		} else {
			EvalBinding op = new EvalBinding(overload, overload.getType(), point);
			ICPPEvaluation[] args = new ICPPEvaluation[]{op, arg1, arg2};
			operatorCall = new EvalFunctionCall(args, null, point);
		}
		return operatorCall;
	}

	private boolean operatorAllowsContextualConversion() {
		return fOperator == op_logicalAnd || fOperator == op_logicalOr;
	}

	@Override
	public IValue getValue() {
		ICPPEvaluation arg1 = fArg1;
		ICPPEvaluation arg2 = fArg2;
		ICPPFunction overload = getOverload();
		if (overload != null) {
			IType[] parameterTypes = SemanticUtil.getParameterTypesIncludingImplicitThis(overload);
			if (parameterTypes.length >= 2) {
				boolean allowContextualConversion = operatorAllowsContextualConversion();
				arg1 = maybeApplyConversion(fArg1, parameterTypes[0], allowContextualConversion);
				arg2 = maybeApplyConversion(fArg2, parameterTypes[1], allowContextualConversion);
			} else {
				CCorePlugin.log(IStatus.ERROR, "Unexpected overload for binary operator " + fOperator //$NON-NLS-1$
						+ ": '" + overload.getName() + "'");  //$NON-NLS-1$//$NON-NLS-2$
			}

			if (!(overload instanceof CPPImplicitFunction)) {
				if (!overload.isConstexpr()) {
					return IntegralValue.ERROR;
				}
				if (fOverloadCall == null) {
					fOverloadCall = createOperatorOverloadEvaluation(overload, arg1, arg2);
				}
				return fOverloadCall.getValue();
			}
		}

		IValue v1 = arg1.getValue();
		if (v1 == null || v1 == IntegralValue.UNKNOWN)
			return IntegralValue.UNKNOWN;
		IValue v2 = arg2.getValue();
		if (v2 == null || v2 == IntegralValue.UNKNOWN)
			return IntegralValue.UNKNOWN;

		switch (fOperator) {
		case op_equals:
			if (v1.equals(v2))
				return IntegralValue.create(true);
			break;
		case op_notequals:
			if (v1.equals(v2))
				return IntegralValue.create(false);
			break;
		case op_assign:
			return v2;
		}

		Number num1 = v1.numberValue();
		if (num1 != null) {
			if (num1 instanceof Long && num1.longValue() == 0) {
				if (fOperator == op_logicalAnd) {
					return v1;
				}
			} else if (fOperator == op_logicalOr) {
				return v1;
			}

			Number num2 = v2.numberValue();
			if (num2 != null) {
				return ValueFactory.evaluateBinaryExpression(fOperator, v1, v2);
			}
		}
		return DependentValue.create(this);
	}

	@Override
	public boolean isTypeDependent() {
		if (fType != null) {
			return fType instanceof TypeOfDependentExpression;
		}
		return fArg1.isTypeDependent() || fArg2.isTypeDependent();
	}

	@Override
	public boolean isValueDependent() {
		return fArg1.isValueDependent() || fArg2.isValueDependent();
	}

	@Override
	public boolean isConstantExpression() {
		if (!fCheckedIsConstantExpression) {
			fCheckedIsConstantExpression = true;
			fIsConstantExpression = computeIsConstantExpression();
		}
		return fIsConstantExpression;
	}
	
	@Override
	public boolean isEquivalentTo(ICPPEvaluation other) {
		if (!(other instanceof EvalBinary)) {
			return false;
		}
		EvalBinary o = (EvalBinary) other;
		return fOperator == o.fOperator
			&& fArg1.isEquivalentTo(o.fArg1)
			&& fArg2.isEquivalentTo(o.fArg2);
	}

	private boolean computeIsConstantExpression() {
		return fArg1.isConstantExpression()
			&& fArg2.isConstantExpression()
			&& isNullOrConstexprFunc(getOverload());
	}

	@Override
	public ValueCategory getValueCategory() {
		if (isTypeDependent())
			return ValueCategory.PRVALUE;

		ICPPFunction overload = getOverload();
		if (overload != null)
			return ExpressionTypes.valueCategoryFromFunctionCall(overload);

		switch (fOperator) {
		case op_arrayAccess:
		case op_assign:
		case op_binaryAndAssign:
		case op_binaryOrAssign:
		case op_binaryXorAssign:
		case op_divideAssign:
		case op_minusAssign:
		case op_moduloAssign:
		case op_multiplyAssign:
		case op_plusAssign:
		case op_shiftLeftAssign:
		case op_shiftRightAssign:
			return LVALUE;

		case op_pmdot:
			if (!(getType() instanceof ICPPFunctionType))
				return fArg1.getValueCategory();
			break;

		case op_pmarrow:
			if (!(getType() instanceof ICPPFunctionType))
				return LVALUE;
			break;
		}

		return ValueCategory.PRVALUE;
	}

	public ICPPFunction getOverload() {
		if (fOverload == CPPFunction.UNINITIALIZED_FUNCTION) {
			fOverload= computeOverload();
		}
		return fOverload;
	}

	private ICPPFunction computeOverload() {
		if (isTypeDependent())
			return null;

		if (fOperator == op_arrayAccess) {
			IType type = fArg1.getType();
			type= SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE);
    		if (type instanceof ICPPClassType) {
    			return CPPSemantics.findOverloadedBinaryOperator(getTemplateDefinitionScope(),
    					OverloadableOperator.BRACKET, fArg1, fArg2);
    		}
		} else {
			final OverloadableOperator op = OverloadableOperator.fromBinaryExpression(fOperator);
			if (op != null) {
				return CPPSemantics.findOverloadedBinaryOperator(getTemplateDefinitionScope(),
						op, fArg1, fArg2);
			}
		}
    	return null;
	}

	public IType computeType() {
		// Check for overloaded operator.
		ICPPFunction o= getOverload();
		if (o != null)
			return typeFromFunctionCall(o);

		final IType originalType1 = fArg1.getType();
		final IType type1 = prvalueTypeWithResolvedTypedefs(originalType1);
		if (type1 instanceof ISemanticProblem) {
			return type1;
		}

    	final IType originalType2 = fArg2.getType();
		final IType type2 = prvalueTypeWithResolvedTypedefs(originalType2);
		if (type2 instanceof ISemanticProblem) {
			return type2;
		}

    	IType type= CPPArithmeticConversion.convertCppOperandTypes(fOperator, type1, type2);
    	if (type != null) {
    		return ExpressionTypes.restoreTypedefs(type, originalType1, originalType2);
    	}

    	switch (fOperator) {
    	case op_arrayAccess:
    		if (type1 instanceof IPointerType) {
    			return glvalueType(((IPointerType) type1).getType());
    		}
    		if (type2 instanceof IPointerType) {
    			return glvalueType(((IPointerType) type2).getType());
    		}
    		return ProblemType.UNKNOWN_FOR_EXPRESSION;

    	case op_lessEqual:
    	case op_lessThan:
    	case op_greaterEqual:
    	case op_greaterThan:
    	case op_logicalAnd:
    	case op_logicalOr:
    	case op_equals:
    	case op_notequals:
    		return CPPBasicType.BOOLEAN;

    	case op_plus:
    		if (type1 instanceof IPointerType) {
        		return ExpressionTypes.restoreTypedefs(type1, originalType1);
    		}
    		if (type2 instanceof IPointerType) {
        		return ExpressionTypes.restoreTypedefs(type2, originalType2);
    		}
    		break;

    	case op_minus:
    		if (type1 instanceof IPointerType) {
    			if (type2 instanceof IPointerType) {
    				return CPPVisitor.getPointerDiffType();
    			}
    			return originalType1;
    		}
    		break;

    	case op_pmarrow:
    	case op_pmdot:
    		if (type2 instanceof ICPPPointerToMemberType) {
    			IType t= ((ICPPPointerToMemberType) type2).getType();
    			if (t instanceof ICPPFunctionType)
    				return t;
    			if (fOperator == op_pmdot && fArg1.getValueCategory() == PRVALUE) {
    				return prvalueType(t);
    			}
    			return glvalueType(t);
    		}
    		return ProblemType.UNKNOWN_FOR_EXPRESSION;
    	}
    	return type1;
	}

	@Override
	public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
		buffer.putShort(ITypeMarshalBuffer.EVAL_BINARY);
		buffer.putByte((byte) fOperator);
		buffer.marshalEvaluation(fArg1, includeValue);
		buffer.marshalEvaluation(fArg2, includeValue);
		marshalTemplateDefinition(buffer);
	}

	public static ICPPEvaluation unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException {
		int op= buffer.getByte();
		ICPPEvaluation arg1= buffer.unmarshalEvaluation();
		ICPPEvaluation arg2= buffer.unmarshalEvaluation();
		IBinding templateDefinition= buffer.unmarshalBinding();
		return new EvalBinary(op, arg1, arg2, templateDefinition);
	}

	@Override
	public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) {
		ICPPEvaluation arg1 = fArg1.instantiate(context, maxDepth);
		ICPPEvaluation arg2 = fArg2.instantiate(context, maxDepth);
		if (arg1 == fArg1 && arg2 == fArg2)
			return this;
		return new EvalBinary(fOperator, arg1, arg2, getTemplateDefinition());
	}

	@Override
	public ICPPEvaluation computeForFunctionCall(ActivationRecord record, ConstexprEvaluationContext context) {
		ICPPFunction overload = getOverload();
		if (overload != null) {
			ICPPEvaluation operatorCall = createOperatorOverloadEvaluation(overload, fArg1, fArg2);
			return operatorCall.computeForFunctionCall(record, context);
		}

		Pair<ICPPEvaluation, ICPPEvaluation> vp1 = EvalUtil.getValuePair(fArg1, record, context);
		final ICPPEvaluation updateable1 = vp1.getFirst();
		final ICPPEvaluation fixed1 = vp1.getSecond();
		Pair<ICPPEvaluation, ICPPEvaluation> vp2 = EvalUtil.getValuePair(fArg2, record, context);
		final ICPPEvaluation fixed2 = vp2.getSecond();
		ICPPEvaluation eval = fixed1 == fArg1 && fixed2 == fArg2 ? this : new EvalBinary(fOperator, fixed1, fixed2, getTemplateDefinition());

		if (isBinaryOperationWithAssignment(fOperator)) {
			if (isPointerToArray(fixed1) && hasIntType(fixed2)) {
				EvalPointer evalPointer = (EvalPointer) fixed1;
				int currentPos = evalPointer.getPosition();
				int rhs = fixed2.getValue().numberValue().intValue();

				if (fOperator == op_plusAssign) {
					evalPointer.setPosition(currentPos + rhs);
				} else if (fOperator == op_minusAssign) {
					evalPointer.setPosition(currentPos - rhs);
				} else {
					return EvalFixed.INCOMPLETE;
				}
			} else {
				if (updateable1 == EvalFixed.INCOMPLETE)
					return EvalFixed.INCOMPLETE;
				int binaryOperator = getBinaryOperatorWithoutAssignment(fOperator);
				EvalBinary binaryOpEval = new EvalBinary(binaryOperator, fixed1, fixed2, getTemplateDefinition());
				EvalBinary assignmentEval = new EvalBinary(op_assign, updateable1, binaryOpEval, getTemplateDefinition());
				return assignmentEval.computeForFunctionCall(record, context);
			}
		} else if (fOperator == op_assign) {
			ICPPEvaluation newValue = null;
			if (fixed2 instanceof EvalPointer) {
				newValue = fixed2;
			} else {
				newValue = new EvalFixed(fixed2.getType(), fixed2.getValueCategory(), fixed2.getValue());
			}

			if (updateable1 instanceof EvalReference && !(updateable1 instanceof EvalPointer)) {
				EvalReference evalRef = (EvalReference) updateable1;
				evalRef.update(newValue);
			} else if (updateable1 instanceof EvalCompositeAccess) {
				EvalCompositeAccess evalCompAccess = (EvalCompositeAccess) updateable1;
				evalCompAccess.update(newValue);
			} else if (updateable1 instanceof EvalBinding) {
				EvalBinding evalBinding = (EvalBinding) updateable1;
				record.update(evalBinding.getBinding(), newValue);
			}
			return updateable1;
		} else if (fOperator == op_arrayAccess) {
			Number numericValue = fixed2.getValue().numberValue();
			if (numericValue == null)
				return EvalFixed.INCOMPLETE;
			ICPPEvaluation composite = fixed1;
			int arrayIndex = numericValue.intValue();
			if (fixed1 instanceof EvalPointer) {
				ICPPEvaluation elementEval = ((EvalPointer) fixed1).getTargetEvaluation();
				if (elementEval instanceof EvalCompositeAccess) {
					// 'composite' will now be the underlying array that the pointer points into.
					// Since the pointer may not point at the beginning of the array, the array
					// index needs to be shifted by the pointer's position.
					composite = ((EvalCompositeAccess) elementEval).getParent();
					arrayIndex += ((EvalPointer) fixed1).getPosition();
				}
			}
			return new EvalCompositeAccess(composite, arrayIndex);
		} else if ((isArray(fixed1) || isArray(fixed2)) && (hasIntType(fixed1) || hasIntType(fixed2))) {
			int offset = hasIntType(fixed1) ? fixed1.getValue().numberValue().intValue() : fixed2.getValue().numberValue().intValue();
			EvalCompositeAccess evalCompositeAccess = new EvalCompositeAccess(isArray(fixed1) ? fixed1 : fixed2, offset);
			return new EvalPointer(record, evalCompositeAccess, evalCompositeAccess.getTemplateDefinition());
		} else if ((isPointerToArray(fixed1) || isPointerToArray(fixed2)) && (hasIntType(fixed1) || hasIntType(fixed2))) {
			final EvalPointer pointer = isPointerToArray(fixed1) ? ((EvalPointer) fixed1).copy() : ((EvalPointer) fixed2).copy();
			pointer.setPosition(eval.getValue().numberValue().intValue());
			return pointer;
		}
		return eval;
	}

	private boolean hasIntType(ICPPEvaluation arg2) {
		IType type = arg2.getType();
		return (type instanceof IBasicType && ((IBasicType) type).getKind() == IBasicType.Kind.eInt);
	}

	private boolean isArray(ICPPEvaluation eval) {
		return eval.getType() instanceof IArrayType;
	}

	private boolean isPointerToArray(ICPPEvaluation argument) {
		if (argument instanceof EvalPointer) {
			EvalPointer evalPointer = (EvalPointer) argument;
			ICPPEvaluation pointerValue = evalPointer.dereference().getTargetEvaluation();
			// TODO(nathanridge): What if the composite being accessed is not an array but a structure?
			return pointerValue instanceof EvalCompositeAccess;
		}
		return false;
	}

	private static boolean isBinaryOperationWithAssignment(int operator) {
		switch (operator) {
			case op_binaryAndAssign:
			case op_binaryOrAssign:
			case op_binaryXorAssign:
			case op_divideAssign:
			case op_plusAssign:
			case op_minusAssign:
			case op_multiplyAssign:
			case op_moduloAssign:
			case op_shiftLeftAssign:
			case op_shiftRightAssign:
				return true;
			default:
				return false;
		}
	}

	private static int getBinaryOperatorWithoutAssignment(int operator) {
		switch (operator) {
			case op_binaryAndAssign:
				return op_binaryAnd;
			case op_binaryOrAssign:
				return op_binaryOr;
			case op_binaryXorAssign:
				return op_binaryXor;
			case op_divideAssign:
				return op_divide;
			case op_plusAssign:
				return op_plus;
			case op_minusAssign:
				return op_minus;
			case op_multiplyAssign:
				return op_multiply;
			case op_moduloAssign:
				return op_modulo;
			case op_shiftLeftAssign:
				return op_shiftLeft;
			case op_shiftRightAssign:
				return op_shiftRight;
			default:
				throw new IllegalArgumentException("Operator must be binary operation with assignment"); //$NON-NLS-1$
		}
	}

	@Override
	public int determinePackSize(ICPPTemplateParameterMap tpMap) {
		return CPPTemplates.combinePackSize(fArg1.determinePackSize(tpMap), fArg2.determinePackSize(tpMap));
	}

	@Override
	public boolean referencesTemplateParameter() {
		return fArg1.referencesTemplateParameter() || fArg2.referencesTemplateParameter();
	}

	@Override
	public String toString() {
		return fArg1.toString() + " <op> " + fArg2.toString(); //$NON-NLS-1$
	}
}
