/******************************************************************************* * Copyright (c) 2004, 2014 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 * Sergey Prigogin (Google) *******************************************************************************/ 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.IntegralValue; import org.eclipse.cdt.internal.core.dom.parser.ValueFactory; import org.eclipse.core.runtime.CoreException; public class CArrayType implements ICArrayType, ITypeContainer, ISerializableType { IType type; private IASTExpression sizeExpression; private IValue value= IntegralValue.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; } @Override 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()); } @Override public IType getType() { return type; } @Override 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(); } @Override public boolean isConst() { return isConst; } @Override public boolean isRestrict() { return isRestrict; } @Override public boolean isVolatile() { return isVolatile; } @Override public boolean isStatic() { return isStatic; } @Override public boolean isVariableLength() { return isVariableSized; } @Override public IValue getSize() { if (value != IntegralValue.NOT_INITIALIZED) return value; if (sizeExpression == null) return value= null; return value= ValueFactory.create(sizeExpression); } @Override public boolean hasSize() { return value == IntegralValue.NOT_INITIALIZED ? sizeExpression != null : value != null; } @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); } @Override public void marshal(ITypeMarshalBuffer buffer) throws CoreException { short firstBytes = ITypeMarshalBuffer.ARRAY_TYPE; long nval= -1; IValue val= null; if (isConst()) firstBytes |= ITypeMarshalBuffer.FLAG1; if (isVolatile()) firstBytes |= ITypeMarshalBuffer.FLAG2; if (isRestrict()) firstBytes |= ITypeMarshalBuffer.FLAG3; if (isStatic()) firstBytes |= ITypeMarshalBuffer.FLAG4; if (isVariableLength()) firstBytes |= ITypeMarshalBuffer.FLAG5; val= getSize(); if (val != null) { firstBytes |= ITypeMarshalBuffer.FLAG6; Number num= val.numberValue(); if (num != null) { nval= num.longValue(); if (nval >= 0) { firstBytes |= ITypeMarshalBuffer.FLAG7; } } } buffer.putShort(firstBytes); if (nval >= 0) { buffer.putLong(nval); } else if (val != null) { buffer.marshalValue(val); } buffer.marshalType(getType()); } public static IType unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException { IValue value= null; if ((firstBytes & ITypeMarshalBuffer.FLAG7) != 0) { value = IntegralValue.create(buffer.getLong()); } else if ((firstBytes & ITypeMarshalBuffer.FLAG6) != 0) { value = buffer.unmarshalValue(); } IType nested= buffer.unmarshalType(); CArrayType result= new CArrayType(nested, (firstBytes & ITypeMarshalBuffer.FLAG1) != 0, (firstBytes & ITypeMarshalBuffer.FLAG2) != 0, (firstBytes & ITypeMarshalBuffer.FLAG3) != 0, value); result.setIsStatic((firstBytes & ITypeMarshalBuffer.FLAG4) != 0); result.setIsVariableLength((firstBytes & ITypeMarshalBuffer.FLAG5) != 0); return result; } @Override @Deprecated public IASTExpression getArraySizeExpression() { return sizeExpression; } }