blob: 377d591ab315cbfd8b7c9548c8e6de6e958eccce [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 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 Rational Software) - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
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.IASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.c.ICASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.c.ICBasicType;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableType;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.core.runtime.CoreException;
public class CBasicType implements ICBasicType, ISerializableType {
private final Kind fKind;
private int fModifiers = 0;
private IASTExpression value = null;
public CBasicType(Kind kind, int modifiers, IASTExpression value) {
if (kind == Kind.eUnspecified) {
if ((modifiers & (IS_COMPLEX | IS_IMAGINARY)) != 0) {
fKind= Kind.eFloat;
} else {
fKind= Kind.eInt;
}
} else {
fKind= kind;
}
fModifiers = modifiers;
this.value = value;
}
public CBasicType(Kind kind, int modifiers) {
this(kind, modifiers, null);
}
public CBasicType(ICASTSimpleDeclSpecifier sds) {
this (getKind(sds), getQualifiers(sds), null);
}
private static int getQualifiers(ICASTSimpleDeclSpecifier sds) {
return (sds.isLong() ? IS_LONG : 0) |
(sds.isShort() ? IS_SHORT : 0) |
(sds.isSigned() ? IS_SIGNED: 0) |
(sds.isUnsigned() ? IS_UNSIGNED : 0) |
(sds.isLongLong() ? IS_LONG_LONG : 0) |
(sds.isComplex() ? IS_COMPLEX : 0) |
(sds.isImaginary() ? IS_IMAGINARY : 0);
}
private static Kind getKind(ICASTSimpleDeclSpecifier sds) {
switch (sds.getType()) {
case IASTSimpleDeclSpecifier.t_bool:
return Kind.eBoolean;
case IASTSimpleDeclSpecifier.t_char:
return Kind.eChar;
case IASTSimpleDeclSpecifier.t_double:
return Kind.eDouble;
case IASTSimpleDeclSpecifier.t_float:
return Kind.eFloat;
case IASTSimpleDeclSpecifier.t_int:
return Kind.eInt;
case IASTSimpleDeclSpecifier.t_void:
return Kind.eVoid;
default:
return Kind.eUnspecified;
}
}
@Override
public Kind getKind() {
return fKind;
}
@Override
public int getModifiers() {
return fModifiers;
}
@Override
public boolean isSigned() {
return (fModifiers & IS_SIGNED) != 0;
}
@Override
public boolean isUnsigned() {
return (fModifiers & IS_UNSIGNED) != 0;
}
@Override
public boolean isShort() {
return (fModifiers & IS_SHORT) != 0;
}
@Override
public boolean isLong() {
return (fModifiers & IS_LONG) != 0;
}
@Override
public boolean isLongLong() {
return (fModifiers & IS_LONG_LONG) != 0;
}
@Override
public boolean isSameType(IType obj) {
if (obj == this)
return true;
if (obj instanceof ITypedef)
return obj.isSameType(this);
if (!(obj instanceof ICBasicType)) return false;
ICBasicType cObj = (ICBasicType)obj;
if (fKind != cObj.getKind()) {
return false;
}
if (fKind == Kind.eInt) {
//signed int and int are equivalent
return (fModifiers & ~IS_SIGNED) == (cObj.getModifiers() & ~IS_SIGNED);
} else {
return (fModifiers == cObj.getModifiers());
}
}
@Override
public Object clone() {
IType t = null;
try {
t = (IType) super.clone();
} catch (CloneNotSupportedException e) {
//not going to happen
}
return t;
}
@Override
@Deprecated
public IASTExpression getValue() {
return value;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.c.ICBasicType#isComplex()
*/
@Override
public boolean isComplex() {
return (fModifiers & IS_COMPLEX) != 0;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.c.ICBasicType#isImaginary()
*/
@Override
public boolean isImaginary() {
return (fModifiers & IS_IMAGINARY) != 0;
}
@Override
public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
final int kind= getKind().ordinal();
final int shiftedKind= kind * ITypeMarshalBuffer.FLAG1;
final int modifiers= getModifiers();
if (shiftedKind < ITypeMarshalBuffer.FLAG4 && modifiers == 0) {
buffer.putByte((byte) (ITypeMarshalBuffer.BASIC_TYPE | shiftedKind));
} else {
buffer.putByte((byte) (ITypeMarshalBuffer.BASIC_TYPE | ITypeMarshalBuffer.FLAG4));
buffer.putByte((byte) kind);
buffer.putByte((byte) modifiers);
}
}
public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
final boolean dense= (firstByte & ITypeMarshalBuffer.FLAG4) == 0;
int modifiers= 0;
int kind;
if (dense) {
kind= (firstByte & (ITypeMarshalBuffer.FLAG4-1))/ITypeMarshalBuffer.FLAG1;
} else {
kind= buffer.getByte();
modifiers= buffer.getByte();
}
return new CBasicType(Kind.values()[kind], modifiers);
}
@Override
@Deprecated
public int getType() {
switch (fKind) {
case eBoolean:
return t_Bool;
case eChar:
case eWChar:
case eChar16:
case eChar32:
return t_char;
case eDouble:
return t_double;
case eFloat:
return t_float;
case eInt:
return t_int;
case eVoid:
return t_void;
case eUnspecified:
return t_unspecified;
case eNullPtr:
// Null pointer type cannot be expressed wit ha simple decl specifier.
break;
}
return t_unspecified;
}
@Override
public String toString() {
return ASTTypeUtil.getType(this);
}
}