/******************************************************************************* * Copyright (c) 2005, 2011 IBM Corporation 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: * John Camelon (IBM Rational Software) - Initial API and implementation * Yuan Zhang / Beth Tibbitts (IBM Research) * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.c; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; /** * Unary expression in C. */ public class CASTUnaryExpression extends ASTNode implements IASTUnaryExpression, IASTAmbiguityParent { private int operator; private IASTExpression operand; public CASTUnaryExpression() { } public CASTUnaryExpression(int operator, IASTExpression operand) { this.operator = operator; setOperand(operand); } public CASTUnaryExpression copy() { return copy(CopyStyle.withoutLocations); } public CASTUnaryExpression copy(CopyStyle style) { CASTUnaryExpression copy = new CASTUnaryExpression(operator, operand == null ? null : operand.copy(style)); copy.setOffsetAndLength(this); if (style == CopyStyle.withLocations) { copy.setCopyLocation(this); } return copy; } public int getOperator() { return operator; } public void setOperator(int value) { assertNotFrozen(); this.operator = value; } public IASTExpression getOperand() { return operand; } public void setOperand(IASTExpression expression) { assertNotFrozen(); operand = expression; if (expression != null) { expression.setParent(this); expression.setPropertyInParent(OPERAND); } } @Override public boolean accept( ASTVisitor action ){ if( action.shouldVisitExpressions ){ switch( action.visit( this ) ){ case ASTVisitor.PROCESS_ABORT : return false; case ASTVisitor.PROCESS_SKIP : return true; default : break; } } if( operand != null ) if( !operand.accept( action ) ) return false; if( action.shouldVisitExpressions ){ switch( action.leave( this ) ){ case ASTVisitor.PROCESS_ABORT : return false; case ASTVisitor.PROCESS_SKIP : return true; default : break; } } return true; } public void replace(IASTNode child, IASTNode other) { if( child == operand ) { other.setPropertyInParent( child.getPropertyInParent() ); other.setParent( child.getParent() ); operand = (IASTExpression) other; } } public IType getExpressionType() { int op = getOperator(); if (op == op_sizeof) { return CVisitor.get_SIZE_T(this); } final IType exprType = getOperand().getExpressionType(); IType type = CVisitor.unwrapTypedefs(exprType); switch(op) { case op_star: if (type instanceof IPointerType || type instanceof IArrayType) { return ((ITypeContainer) type).getType(); } break; case op_amper: return new CPointerType(type, 0); case op_minus: case op_plus: case op_tilde: IType t= CArithmeticConversion.promoteCType(type); if (t != null) { return t; } break; } return exprType; // return the original } public boolean isLValue() { switch (getOperator()) { case op_bracketedPrimary: return getOperand().isLValue(); case op_star: case op_prefixDecr: case op_prefixIncr: return true; default: return false; } } public final ValueCategory getValueCategory() { return isLValue() ? ValueCategory.LVALUE : ValueCategory.PRVALUE; } }