/*******************************************************************************
* Copyright (c) 2004, 2010 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:
* Devin Steffler (IBM Corporation) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.c.ICASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.c.ICArrayType;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableType;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.core.runtime.CoreException;
public class CArrayType implements ICArrayType, ITypeContainer, ISerializableType {
IType type;
private IASTExpression sizeExpression;
private IValue value= Value.NOT_INITIALIZED;
private boolean isConst;
private boolean isVolatile;
private boolean isRestrict;
private boolean isStatic;
private boolean isVariableSized;
public CArrayType(IType type) {
this.type = type;
}
public CArrayType(IType type, boolean isConst, boolean isVolatile, boolean isRestrict, IValue size) {
this.type= type;
this.isConst= isConst;
this.isVolatile= isVolatile;
this.isRestrict= isRestrict;
this.value= size;
}
public void setIsStatic(boolean val) {
isStatic= val;
}
public void setIsVariableLength(boolean val) {
isVariableSized= val;
}
public boolean isSameType(IType obj) {
if (obj == this)
return true;
if (obj instanceof ITypedef)
return obj.isSameType(this);
if (obj instanceof ICArrayType) {
ICArrayType at = (ICArrayType) obj;
if (isConst() != at.isConst()) return false;
if (isRestrict() != at.isRestrict()) return false;
if (isStatic() != at.isStatic()) return false;
if (isVolatile() != at.isVolatile()) return false;
if (isVariableLength() != at.isVariableLength()) return false;
return at.getType().isSameType(type) && hasSameSize(at);
}
return false;
}
private boolean hasSameSize(IArrayType rhs) {
IValue s1 = getSize();
IValue s2 = rhs.getSize();
if (s1 == s2)
return true;
if (s1 == null || s2 == null)
return false;
return CharArrayUtils.equals(s1.getSignature(), s2.getSignature());
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IArrayType#getType()
*/
public IType getType() {
return type;
}
public void setType(IType t) {
this.type = t;
}
public void setModifier(ICASTArrayModifier mod) {
isConst= mod.isConst();
isVolatile= mod.isVolatile();
isRestrict= mod.isRestrict();
isStatic= mod.isStatic();
isVariableSized= mod.isVariableSized();
sizeExpression= mod.getConstantExpression();
}
public boolean isConst() {
return isConst;
}
public boolean isRestrict() {
return isRestrict;
}
public boolean isVolatile() {
return isVolatile;
}
public boolean isStatic() {
return isStatic;
}
public boolean isVariableLength() {
return isVariableSized;
}
public IValue getSize() {
if (value != Value.NOT_INITIALIZED)
return value;
if (sizeExpression == null)
return value= null;
return value= Value.create(sizeExpression, Value.MAX_RECURSION_DEPTH);
}
@Override
public Object clone() {
IType t = null;
try {
t = (IType) super.clone();
} catch (CloneNotSupportedException e) {
// Not going to happen
}
return t;
}
@Override
public String toString() {
return ASTTypeUtil.getType(this);
}
public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
int firstByte= ITypeMarshalBuffer.ARRAY;
int flags= 0;
short nval= -1;
IValue val= null;
if (isConst()) flags |= 0x01;
if (isVolatile()) flags |= 0x02;
if (isRestrict()) flags |= 0x04;
if (isStatic()) flags |= 0x08;
if (isVariableLength()) flags |= 0x10;
if (flags != 0) {
firstByte |= ITypeMarshalBuffer.FLAG1;
}
val= getSize();
if (val != null) {
firstByte |= ITypeMarshalBuffer.FLAG2;
Long num= val.numericalValue();
if (num != null) {
long l= num;
if (l>=0 && l <= Short.MAX_VALUE) {
nval= (short) l;
firstByte |= ITypeMarshalBuffer.FLAG3;
}
}
}
buffer.putByte((byte) firstByte);
if (flags != 0) {
buffer.putByte((byte) flags);
}
if (nval >= 0) {
buffer.putShort(nval);
} else if (val != null) {
buffer.marshalValue(val);
}
buffer.marshalType(getType());
}
public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int flags= 0;
IValue value= null;
if ( (firstByte & ITypeMarshalBuffer.FLAG1) != 0) {
flags= buffer.getByte();
}
if ((firstByte & ITypeMarshalBuffer.FLAG3) != 0) {
value = Value.create(buffer.getShort());
} else if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0) {
value = buffer.unmarshalValue();
}
IType nested= buffer.unmarshalType();
CArrayType result= new CArrayType(nested, (flags & 0x01) != 0, (flags & 0x02) != 0, (flags & 0x04) != 0, value);
result.setIsStatic((flags & 0x08) != 0);
result.setIsVariableLength((flags & 0x10) != 0);
return result;
}
@Deprecated
public IASTExpression getArraySizeExpression() {
if (sizeExpression != null)
return sizeExpression;
return null;
}
}