1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 10:16:03 +02:00

Arithmetic conversions for unary and binary expressions, bug 231859.

This commit is contained in:
Markus Schorn 2009-10-09 12:04:23 +00:00
parent 1ccd6348b9
commit 16944a0de7
19 changed files with 1191 additions and 255 deletions

View file

@ -7325,12 +7325,12 @@ public class AST2CPPTests extends AST2BaseTest {
IType t2 = f2.getType().getParameterTypes()[0]; IType t2 = f2.getType().getParameterTypes()[0];
assertTrue(t2 instanceof ICPPBasicType); assertTrue(t2 instanceof ICPPBasicType);
assertEquals(IBasicType.t_int, ((ICPPBasicType) t2).getType()); assertEquals(IBasicType.t_int, ((ICPPBasicType) t2).getType());
assertEquals(ICPPBasicType.IS_UNSIGNED, ((ICPPBasicType) t2).getQualifierBits()); assertEquals(IBasicType.IS_UNSIGNED, ((ICPPBasicType) t2).getQualifierBits());
ICPPFunction f3 = ba.assertNonProblem("f(l1)", 1, ICPPFunction.class); ICPPFunction f3 = ba.assertNonProblem("f(l1)", 1, ICPPFunction.class);
IType t3 = f3.getType().getParameterTypes()[0]; IType t3 = f3.getType().getParameterTypes()[0];
assertTrue(t3 instanceof ICPPBasicType); assertTrue(t3 instanceof ICPPBasicType);
assertEquals(IBasicType.t_int, ((ICPPBasicType) t3).getType()); assertEquals(IBasicType.t_int, ((ICPPBasicType) t3).getType());
assertEquals(ICPPBasicType.IS_LONG, ((ICPPBasicType) t3).getQualifierBits()); assertEquals(IBasicType.IS_LONG, ((ICPPBasicType) t3).getQualifierBits());
} }
// typedef enum enum_name enum_name; // typedef enum enum_name enum_name;

View file

@ -89,6 +89,7 @@ import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.c.ICASTArrayModifier; import org.eclipse.cdt.core.dom.ast.c.ICASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.c.ICASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.c.ICASTDesignatedInitializer; import org.eclipse.cdt.core.dom.ast.c.ICASTDesignatedInitializer;
@ -6308,6 +6309,547 @@ public class AST2Tests extends AST2BaseTest {
parseAndCheckBindings(getAboveComment(), ParserLanguage.C); parseAndCheckBindings(getAboveComment(), ParserLanguage.C);
} }
//
// long double longDouble = 1.0;
// double _double = 1.0;
// float _float= 1.0;
// signed long long int longLongInt = 1;
// signed long int longInt = 1;
// signed int _int = 1;
// signed short int shortInt = 1;
// signed char _char = 1;
//
// float var;
// void test() {
// /* The following should all be long double */
// var = longDouble + longDouble;
// var = longDouble + _double;
// var = longDouble + _float;
// var = longDouble + longLongInt;
// var = longDouble + longInt;
// var = longDouble + _int;
// var = longDouble + shortInt;
// var = longDouble + _char;
//
// var = longDouble + longDouble;
// var = _double + longDouble;
// var = _float + longDouble;
// var = longLongInt + longDouble;
// var = longInt + longDouble;
// var = _int + longDouble;
// var = shortInt + longDouble;
// var = _char + longDouble;
//
// }
//
public void testTypePromotion_long_double() throws Exception {
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit ast = parseAndCheckBindings(getAboveComment(), lang);
IASTFunctionDefinition func = null;
for (IASTDeclaration d : ast.getDeclarations()) {
if (d instanceof IASTFunctionDefinition) {
func = (IASTFunctionDefinition) d;
break;
}
}
assertNotNull(func);
IASTStatement[] bodyStmts = ((IASTCompoundStatement) func.getBody()).getStatements();
for (IASTStatement stmt : bodyStmts) {
IASTBinaryExpression expr1 = (IASTBinaryExpression) ((IASTBinaryExpression) ((IASTExpressionStatement) stmt)
.getExpression()).getOperand2();
IType type1 = expr1.getExpressionType();
assertEquals(Kind.eDouble, ((IBasicType) type1).getKind());
assertTrue(((IBasicType) type1).isLong());
}
}
}
//
// double _double = 1.0;
// float _float= 1.0;
// long long int longLongInt = 1;
// long int longInt = 1;
// int _int = 1;
// short int shortInt = 1;
// char _char = 1;
//
// float var;
// void test() {
// /* The following should all be double */
// var = _double + _double;
// var = _double + _float;
// var = _double + longLongInt;
// var = _double + longInt;
// var = _double + _int;
// var = _double + shortInt;
// var = _double + _char;
//
// var = _float + _double;
// var = longLongInt + _double;
// var = longInt + _double;
// var = _int + _double;
// var = shortInt + _double;
// var = _char + _double;
//
// }
//
public void testTypePromotion_double() throws Exception {
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit ast = parseAndCheckBindings(getAboveComment(), lang);
IASTFunctionDefinition func = null;
for (IASTDeclaration d : ast.getDeclarations()) {
if (d instanceof IASTFunctionDefinition) {
func = (IASTFunctionDefinition) d;
break;
}
}
assertNotNull(func);
IASTStatement[] bodyStmts = ((IASTCompoundStatement) func.getBody()).getStatements();
for (IASTStatement stmt : bodyStmts) {
IASTBinaryExpression expr1 = (IASTBinaryExpression) ((IASTBinaryExpression) ((IASTExpressionStatement) stmt)
.getExpression()).getOperand2();
IType type1 = expr1.getExpressionType();
assertEquals(Kind.eDouble, ((IBasicType) type1).getKind());
assertFalse(((IBasicType) type1).isLong());
}
}
}
//
// float _float= 1.0;
// long long int longLongInt = 1;
// long int longInt = 1;
// int _int = 1;
// short int shortInt = 1;
// char _char = 1;
//
// float var;
// void test() {
// /* The following should all be float */
// var = _float + longLongInt;
// var = _float + longInt;
// var = _float + _int;
// var = _float + shortInt;
// var = _float + _char;
//
// var = longLongInt + _float;
// var = longInt + _float;
// var = _int + _float;
// var = shortInt + _float;
// var = _char + _float;
//
// }
//
public void testTypePromotion_float() throws Exception {
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit ast = parseAndCheckBindings(getAboveComment(), lang);
IASTFunctionDefinition func = null;
for (IASTDeclaration d : ast.getDeclarations()) {
if (d instanceof IASTFunctionDefinition) {
func = (IASTFunctionDefinition) d;
break;
}
}
assertNotNull(func);
IASTStatement[] bodyStmts = ((IASTCompoundStatement) func.getBody()).getStatements();
for (IASTStatement stmt : bodyStmts) {
IASTBinaryExpression expr1 = (IASTBinaryExpression) ((IASTBinaryExpression) ((IASTExpressionStatement) stmt)
.getExpression()).getOperand2();
IType type1 = expr1.getExpressionType();
assertEquals(Kind.eFloat, ((IBasicType) type1).getKind());
}
}
}
// long long int longLongInt = 1;
// long int longInt = 1;
// int _int = 1;
// short int shortInt = 1;
// char _char = 1;
//
// float var;
// void test() {
// /* The following should all be long long int */
// var = longLongInt + longLongInt;
// var = longLongInt + longInt;
// var = longLongInt + _int;
// var = longLongInt + shortInt;
// var = longLongInt + _char;
//
// var = longLongInt + longLongInt;
// var = longInt + longLongInt;
// var = _int + longLongInt;
// var = shortInt + longLongInt;
// var = _char + longLongInt;
//
// }
//
public void testTypePromotion_longlongint() throws Exception {
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit ast = parseAndCheckBindings(getAboveComment(), lang, true); // support for long long
IASTFunctionDefinition func = null;
for (IASTDeclaration d : ast.getDeclarations()) {
if (d instanceof IASTFunctionDefinition) {
func = (IASTFunctionDefinition) d;
break;
}
}
assertNotNull(func);
IASTStatement[] bodyStmts = ((IASTCompoundStatement) func.getBody()).getStatements();
for (IASTStatement stmt : bodyStmts) {
IASTBinaryExpression expr1 = (IASTBinaryExpression) ((IASTBinaryExpression) ((IASTExpressionStatement) stmt)
.getExpression()).getOperand2();
IType type1 = expr1.getExpressionType();
assertEquals(Kind.eInt, ((IBasicType) type1).getKind());
assertTrue(((IBasicType) type1).isLongLong());
}
}
}
//
// long long int longLongInt = 1;
// long int longInt = 1;
// int _int = 1;
// short int shortInt = 1;
// char _char = 1;
//
// float var;
// void test() {
// /* The following should all be long int */
// var = longInt + longInt;
// var = longInt + _int;
// var = longInt + shortInt;
// var = longInt + _char;
//
// var = _int + longInt;
// var = shortInt + longInt;
// var = _char + longInt;
//
// }
//
public void testTypePromotion_longint() throws Exception {
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit ast = parseAndCheckBindings(getAboveComment(), lang);
IASTFunctionDefinition func = null;
for (IASTDeclaration d : ast.getDeclarations()) {
if (d instanceof IASTFunctionDefinition) {
func = (IASTFunctionDefinition) d;
break;
}
}
assertNotNull(func);
IASTStatement[] bodyStmts = ((IASTCompoundStatement) func.getBody()).getStatements();
for (IASTStatement stmt : bodyStmts) {
IASTBinaryExpression expr1 = (IASTBinaryExpression) ((IASTBinaryExpression) ((IASTExpressionStatement) stmt)
.getExpression()).getOperand2();
IType type1 = expr1.getExpressionType();
assertEquals(Kind.eInt, ((IBasicType) type1).getKind());
assertTrue(((IBasicType) type1).isLong());
}
}
}
//
// int _int = 1;
// short int shortInt = 1;
// char _char = 1;
//
// float var;
// void test() {
// /* The following should all be int */
// var = _int + _int;
// var = _int + shortInt;
// var = _int + _char;
//
// var = shortInt + _int;
// var = _char + _int;
//
// }
//
public void testTypePromotion_int() throws Exception {
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit ast = parseAndCheckBindings(getAboveComment(), lang);
IASTFunctionDefinition func = null;
for (IASTDeclaration d : ast.getDeclarations()) {
if (d instanceof IASTFunctionDefinition) {
func = (IASTFunctionDefinition) d;
break;
}
}
assertNotNull(func);
IASTStatement[] bodyStmts = ((IASTCompoundStatement) func.getBody()).getStatements();
for (IASTStatement stmt : bodyStmts) {
IASTBinaryExpression expr1 = (IASTBinaryExpression) ((IASTBinaryExpression) ((IASTExpressionStatement) stmt)
.getExpression()).getOperand2();
IType type1 = expr1.getExpressionType();
assertEquals(Kind.eInt, ((IBasicType) type1).getKind());
assertFalse(((IBasicType) type1).isLong());
assertFalse(((IBasicType) type1).isShort());
}
}
}
//
// short int shortInt = 1;
// char _char = 1;
//
// float var;
// void test() {
// /* The following should all be signed int */
// var = shortInt + shortInt;
// var = shortInt + _char;
//
// var = _char + shortInt;
//
// }
//
public void testTypePromotion_short_int() throws Exception {
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit ast = parseAndCheckBindings(getAboveComment(), lang);
IASTFunctionDefinition func = null;
for (IASTDeclaration d : ast.getDeclarations()) {
if (d instanceof IASTFunctionDefinition) {
func = (IASTFunctionDefinition) d;
break;
}
}
assertNotNull(func);
IASTStatement[] bodyStmts = ((IASTCompoundStatement) func.getBody()).getStatements();
for (IASTStatement stmt : bodyStmts) {
IASTBinaryExpression expr1 = (IASTBinaryExpression) ((IASTBinaryExpression) ((IASTExpressionStatement) stmt)
.getExpression()).getOperand2();
IBasicType type1 = (IBasicType) expr1.getExpressionType();
assertEquals(Kind.eInt, type1.getKind());
assertFalse(type1.isUnsigned());
assertFalse(type1.isLong());
assertFalse(type1.isShort());
}
}
}
//
// char _char = 1;
//
// float var;
// void test() {
// /* The following should all be signed int */
// var = _char + _char;
// }
//
public void testTypePromotion_char() throws Exception {
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit ast = parseAndCheckBindings(getAboveComment(), lang);
IASTFunctionDefinition func = null;
for (IASTDeclaration d : ast.getDeclarations()) {
if (d instanceof IASTFunctionDefinition) {
func = (IASTFunctionDefinition) d;
break;
}
}
assertNotNull(func);
IASTStatement[] bodyStmts = ((IASTCompoundStatement) func.getBody()).getStatements();
for (IASTStatement stmt : bodyStmts) {
IASTBinaryExpression expr1 = (IASTBinaryExpression) ((IASTBinaryExpression) ((IASTExpressionStatement) stmt)
.getExpression()).getOperand2();
IBasicType type1 = (IBasicType) expr1.getExpressionType();
assertEquals(Kind.eInt, type1.getKind());
assertFalse(type1.isUnsigned());
assertFalse(type1.isLong());
assertFalse(type1.isShort());
}
}
}
//
// char _char = 1;
// signed char signedChar = 1;
// unsigned char unsignedChar = 1;
// signed int signedInt = 1;
// unsigned int unsignedInt = 1;
// signed long int signedLongInt = 1;
// unsigned long int unsignedLongInt = 1;
// signed long long int longLongInt = 1;
// unsigned long long int unsignedlongLongInt = 1;
// unsigned long long var = 1;
// void test() {
// /* (0) Should be an signed int */
// var = signedChar + unsignedChar;
//
// /* (1) Should be an signed int */
// var = unsignedChar + signedChar;
//
// /* (2) Should be a signed int*/
// var = unsignedChar + signedInt;
//
// /* (3) Should be an unsigned int*/
// var = unsignedInt + signedChar;
//
// /* (4) Should be a signed long int */
// var = signedLongInt + unsignedInt;
//
// /* (5) Should be an unsigned long int*/
// var = signedLongInt + unsignedLongInt;
//
// /* (6) Should be an unsigned long int*/
// var = unsignedLongInt + signedLongInt;
// }
//
//
public void testTypePromotion_signedAndUnsignedInts() throws Exception {
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit ast = parseAndCheckBindings(getAboveComment(), lang);
IASTFunctionDefinition func = null;
for (IASTDeclaration d : ast.getDeclarations()) {
if (d instanceof IASTFunctionDefinition) {
func = (IASTFunctionDefinition) d;
break;
}
}
assertNotNull(func);
IASTStatement[] bodyStmts = ((IASTCompoundStatement) func.getBody()).getStatements();
// /* (0) Should be an signed int */
// var = signedChar + unsignedChar;
{
IASTBinaryExpression expr = (IASTBinaryExpression) ((IASTBinaryExpression) ((IASTExpressionStatement) bodyStmts[0])
.getExpression()).getOperand2();
IBasicType type1 = (IBasicType) expr.getExpressionType();
assertEquals(Kind.eInt, type1.getKind());
assertFalse(type1.isUnsigned());
assertFalse(type1.isShort());
assertFalse(type1.isLong());
}
// /* (1) Should be an singed int */
// var = unsignedChar + signedChar;
{
IASTBinaryExpression expr = (IASTBinaryExpression) ((IASTBinaryExpression) ((IASTExpressionStatement) bodyStmts[1])
.getExpression()).getOperand2();
IBasicType type1 = (IBasicType) expr.getExpressionType();
assertEquals(Kind.eInt, type1.getKind());
assertFalse(type1.isUnsigned());
assertFalse(type1.isShort());
assertFalse(type1.isLong());
}
// /* (2) Should be a signed int*/
// var = unsignedChar + signedInt;
{
IASTBinaryExpression expr = (IASTBinaryExpression) ((IASTBinaryExpression) ((IASTExpressionStatement) bodyStmts[2])
.getExpression()).getOperand2();
IBasicType type1 = (IBasicType) expr.getExpressionType();
assertEquals(Kind.eInt, type1.getKind());
assertFalse(type1.isUnsigned());
assertFalse(type1.isShort());
assertFalse(type1.isLong());
assertFalse(type1.isLongLong());
}
// /* (3) Should be an unsigned int*/
// var = unsignedInt + signedChar;
{
IASTBinaryExpression expr = (IASTBinaryExpression) ((IASTBinaryExpression) ((IASTExpressionStatement) bodyStmts[3])
.getExpression()).getOperand2();
IBasicType type1 = (IBasicType) expr.getExpressionType();
assertEquals(Kind.eInt, type1.getKind());
assertTrue(type1.isUnsigned());
assertFalse(type1.isShort());
assertFalse(type1.isLong());
assertFalse(type1.isLongLong());
}
// /* (4) Should be a signed long int */
// var = signedLongInt + unsignedInt;
{
IASTBinaryExpression expr = (IASTBinaryExpression) ((IASTBinaryExpression) ((IASTExpressionStatement) bodyStmts[4])
.getExpression()).getOperand2();
IBasicType type1 = (IBasicType) expr.getExpressionType();
assertEquals(Kind.eInt, type1.getKind());
assertFalse(type1.isUnsigned());
assertFalse(type1.isShort());
assertTrue(type1.isLong());
assertFalse(type1.isLongLong());
}
// /* (5) Should be an unsigned long int*/
// var = signedLongInt + unsignedLongInt;
{
IASTBinaryExpression expr = (IASTBinaryExpression) ((IASTBinaryExpression) ((IASTExpressionStatement) bodyStmts[5])
.getExpression()).getOperand2();
IBasicType type1 = (IBasicType) expr.getExpressionType();
assertEquals(Kind.eInt, type1.getKind());
assertTrue(type1.isUnsigned());
assertFalse(type1.isShort());
assertTrue(type1.isLong());
assertFalse(type1.isLongLong());
}
// /* (6) Should be an unsigned long int*/
// var = unsignedLongInt + signedLongInt;
{
IASTBinaryExpression expr = (IASTBinaryExpression) ((IASTBinaryExpression) ((IASTExpressionStatement) bodyStmts[5])
.getExpression()).getOperand2();
IBasicType type1 = (IBasicType) expr.getExpressionType();
assertEquals(Kind.eInt, type1.getKind());
assertTrue(type1.isUnsigned());
assertFalse(type1.isShort());
assertTrue(type1.isLong());
assertFalse(type1.isLongLong());
}
}
}
// char c;
// void func() {
// c;
// -c;
// +c;
// ~c;
// }
public void testPromotionInUnaryExpressions() throws Exception {
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit ast = parseAndCheckBindings(getAboveComment(), lang);
IASTFunctionDefinition fdef= getDeclaration(ast, 1);
IASTExpression expr= getExpressionOfStatement(fdef, 0);
IBasicType t= (IBasicType) expr.getExpressionType();
assertEquals(Kind.eChar, t.getKind());
assertEquals(0, t.getModifiers());
for (int i = 1; i < 4; i++) {
expr= getExpressionOfStatement(fdef, i);
t= (IBasicType) expr.getExpressionType();
assertEquals(Kind.eInt, t.getKind()); // promoted to int
assertEquals(0, t.getModifiers());
}
}
}
// //
// int MyGlobal[10]; // int MyGlobal[10];
// //

View file

@ -24,6 +24,36 @@ public interface IBasicType extends IType {
enum Kind { enum Kind {
eUnspecified, eVoid, eChar, eWChar, eInt, eFloat, eDouble, eBoolean eUnspecified, eVoid, eChar, eWChar, eInt, eFloat, eDouble, eBoolean
} }
/**
* @since 5.2
*/
final int IS_LONG = 1;
/**
* @since 5.2
*/
final int IS_SHORT = 1 << 1;
/**
* @since 5.2
*/
final int IS_SIGNED = 1 << 2;
/**
* @since 5.2
*/
final int IS_UNSIGNED = 1 << 3;
/**
* @since 5.2
*/
final int IS_COMPLEX = 1 << 4;
/**
* @since 5.2
*/
final int IS_IMAGINARY = 1 << 5;
/**
* @since 5.2
*/
final int IS_LONG_LONG = 1 << 6;
/** /**
* This returns the kind of basic type you are looking at. The type is * This returns the kind of basic type you are looking at. The type is
@ -32,6 +62,11 @@ public interface IBasicType extends IType {
*/ */
Kind getKind(); Kind getKind();
/**
* This returns the combination of modifier bits for this type.
* @since 5.2
*/
int getModifiers();
public boolean isSigned(); public boolean isSigned();
public boolean isUnsigned(); public boolean isUnsigned();

View file

@ -18,19 +18,18 @@ import org.eclipse.cdt.core.dom.ast.IBasicType;
* @noimplement This interface is not intended to be implemented by clients. * @noimplement This interface is not intended to be implemented by clients.
*/ */
public interface ICPPBasicType extends IBasicType { public interface ICPPBasicType extends IBasicType {
public static final int IS_LONG = 1; /**
public static final int IS_SHORT = 1 << 1; * @deprecated, don't use the constant, more flags may be added for supporting future c++ standards.
public static final int IS_SIGNED = 1 << 2; */
public static final int IS_UNSIGNED = 1 << 3; @Deprecated
public static final int IS_COMPLEX = 1 << 4;
public static final int IS_IMAGINARY = 1 << 5;
public static final int IS_LONG_LONG = 1 << 6;
public static final int LAST = IS_LONG_LONG; public static final int LAST = IS_LONG_LONG;
/** /**
* @return a combination of qualifiers. * @return a combination of qualifiers.
* @since 4.0 * @since 4.0
* @deprecated use {@link #getModifiers()}, instead.
*/ */
@Deprecated
public int getQualifierBits(); public int getQualifierBits();
/** /**

View file

@ -0,0 +1,305 @@
/*******************************************************************************
* Copyright (c) 2009 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
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
/**
* Arithmetic conversions as required to compute the type of unary or binary expressions.
*/
public abstract class ArithmeticConversion {
private static final int DOMAIN_FLAGS = IBasicType.IS_IMAGINARY | IBasicType.IS_COMPLEX;
private enum Domain {
eReal(0),
eImaginary(IBasicType.IS_IMAGINARY),
eComplex(IBasicType.IS_COMPLEX);
private final int fModifier;
private Domain(int modifier) {
fModifier= modifier;
}
int getModifier() {
return fModifier;
}
}
private enum Rank {eInt, eLong, eLongLong}
protected abstract IBasicType createBasicType(IBasicType.Kind kind, int modifiers);
/**
* Performs an arithmetic conversion as described in section 6.3.1.8 of the C99 standard,
* or 5.0.9 of C++ standard
*/
public final IType convertOperandTypes(int operator, IType op1, IType op2) {
if (!isArithmeticOrEnum(op1) || !isArithmeticOrEnum(op2)) {
return null;
}
switch (operator) {
// Multiplicative operators
case IASTBinaryExpression.op_divide:
case IASTBinaryExpression.op_modulo:
case IASTBinaryExpression.op_multiply :
// Additive operators
case IASTBinaryExpression.op_minus :
case IASTBinaryExpression.op_plus :
// Bitwise operators
case IASTBinaryExpression.op_binaryAnd:
case IASTBinaryExpression.op_binaryOr:
case IASTBinaryExpression.op_binaryXor:
// Gcc's minimum/maximum operators
case IASTBinaryExpression.op_max :
case IASTBinaryExpression.op_min :
return convert(op1, op2);
case IASTBinaryExpression.op_shiftLeft :
case IASTBinaryExpression.op_shiftRight :
return promote(op1, getDomain(op1));
default:
return null;
}
}
public final IType promoteType(IType type) {
if (!isIntegralOrEnum(type))
return null;
return promote(type, getDomain(type));
}
private boolean isArithmeticOrEnum(IType op1) {
return op1 instanceof IBasicType || op1 instanceof IEnumeration;
}
private boolean isIntegralOrEnum(IType op1) {
if (op1 instanceof IEnumeration)
return true;
if (op1 instanceof IBasicType) {
Kind kind= ((IBasicType) op1).getKind();
switch(kind) {
case eBoolean:
case eChar:
case eInt:
case eWChar:
return true;
case eDouble:
case eFloat:
case eUnspecified:
case eVoid:
return false;
}
}
return false;
}
private final IType convert(IType type1, IType type2) {
Domain domain= getDomain(type1, type2);
// If either type is a long double, return that type
if (isLongDouble(type1)) {
return adjustDomain((IBasicType) type1, domain);
}
if (isLongDouble(type2)) {
return adjustDomain((IBasicType) type2, domain);
}
// Else if either type is a double return that type
if (isDouble(type1)) {
return adjustDomain((IBasicType) type1, domain);
}
if (isDouble(type2)) {
return adjustDomain((IBasicType) type2, domain);
}
// Else if either type is a float return that type
if (isFloat(type1)) {
return adjustDomain((IBasicType) type1, domain);
}
if (isFloat(type2)) {
return adjustDomain((IBasicType) type2, domain);
}
// We're dealing with integer types so perform integer promotion
IBasicType btype1 = promote(type1, domain);
IBasicType btype2 = promote(type2, domain);
if (btype1.isSameType(btype2)) {
return btype1;
}
if (btype1.isUnsigned() == btype2.isUnsigned()) {
return getIntegerRank(btype1).ordinal() >= getIntegerRank(btype2).ordinal() ? btype1 : btype2;
}
IBasicType unsignedType, signedType;
if (btype1.isUnsigned()) {
unsignedType= btype1;
signedType= btype2;
} else {
unsignedType= btype2;
signedType= btype1;
}
final Rank signedRank= getIntegerRank(signedType);
final Rank unsignedRank= getIntegerRank(unsignedType);
// same rank -> use unsigned
if (unsignedRank.ordinal() >= signedRank.ordinal()) {
return unsignedType;
}
// the signed has the higher rank
if (signedRank.ordinal() > unsignedRank.ordinal()) {
return signedType;
}
return createBasicType(signedType.getKind(), changeModifier(signedType.getModifiers(), IBasicType.IS_SIGNED, IBasicType.IS_UNSIGNED));
}
private IBasicType promote(IType type, Domain domain) {
if (type instanceof IEnumeration) {
return createBasicType(Kind.eInt, domain.getModifier() | getEnumIntTypeModifiers((IEnumeration) type));
} else if (type instanceof IBasicType) {
final IBasicType bt = (IBasicType) type;
final Kind kind = bt.getKind();
switch (kind) {
case eBoolean:
case eChar:
case eWChar:
return createBasicType(Kind.eInt, domain.getModifier());
case eInt:
if (bt.isShort())
return createBasicType(Kind.eInt, domain.getModifier());
return adjustDomain(bt, domain);
case eVoid:
case eUnspecified:
case eDouble:
case eFloat:
assert false;
}
}
return createBasicType(Kind.eInt, domain.getModifier());
}
private Domain getDomain(IType type1, IType type2) {
Domain d1= getDomain(type1);
Domain d2= getDomain(type2);
if (d1 == d2)
return d1;
return Domain.eComplex;
}
private Domain getDomain(IType type) {
if (type instanceof IBasicType) {
IBasicType bt= (IBasicType) type;
if (bt.isComplex())
return Domain.eComplex;
if (bt.isImaginary())
return Domain.eImaginary;
}
return Domain.eReal;
}
private IBasicType adjustDomain(IBasicType t, Domain d) {
Domain myDomain= getDomain(t);
if (myDomain == d)
return t;
return createBasicType(t.getKind(), changeModifier(t.getModifiers(), DOMAIN_FLAGS, d.getModifier()));
}
private int changeModifier(int modifiers, int remove, int add) {
return (modifiers & ~remove) | add;
}
private Rank getIntegerRank(IBasicType type) {
assert type.getKind() == Kind.eInt;
if (type.isLongLong())
return Rank.eLongLong;
if (type.isLong())
return Rank.eLong;
return Rank.eInt;
}
private boolean isLongDouble(IType type) {
if (type instanceof IBasicType) {
final IBasicType bt= (IBasicType) type;
return bt.isLong() && bt.getKind() == Kind.eDouble;
}
return false;
}
private static boolean isDouble(IType type) {
if (type instanceof IBasicType) {
final IBasicType bt= (IBasicType) type;
return bt.getKind() == Kind.eDouble;
}
return false;
}
private static boolean isFloat(IType type) {
if (type instanceof IBasicType) {
final IBasicType bt= (IBasicType) type;
return bt.getKind() == Kind.eFloat;
}
return false;
}
public static int getEnumIntTypeModifiers(IEnumeration enumeration) {
// mstodo cache min/max values of enumerations
long minValue = 0;
long maxValue = 0;
try {
IEnumerator[] enumerators = enumeration.getEnumerators();
for (IEnumerator enumerator : enumerators) {
IValue value = enumerator.getValue();
if (value != null) {
Long val = value.numericalValue();
if (val != null) {
long v = val.longValue();
if (minValue > v) {
minValue = v;
}
if (maxValue < v) {
maxValue = v;
}
}
}
}
} catch (DOMException e) {
return 0;
}
// TODO(sprigogin): Use values of __INT_MAX__ and __LONG_MAX__ macros
if (minValue >= Integer.MIN_VALUE && maxValue <= Integer.MAX_VALUE) {
return 0;
} else if (minValue >= 0 && maxValue <= 0xFFFFFFFFL) {
return IBasicType.IS_UNSIGNED;
} else if (minValue >= Long.MIN_VALUE && maxValue <= Long.MAX_VALUE) {
return IBasicType.IS_LONG;
} else {
// This branch is unreachable due to limitations of Java long type.
return IBasicType.IS_UNSIGNED | IBasicType.IS_LONG;
}
}
}

View file

@ -15,6 +15,7 @@ package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IParameter;
@ -22,7 +23,6 @@ import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.core.dom.parser.IBuiltinBindingsProvider; import org.eclipse.cdt.core.dom.parser.IBuiltinBindingsProvider;
@ -294,22 +294,22 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider {
c_const_char_p_r = new CPointerType(new CQualifierType(c_char, true, false, false), CPointerType.IS_RESTRICT); c_const_char_p_r = new CPointerType(new CQualifierType(c_char, true, false, false), CPointerType.IS_RESTRICT);
c_double = new CBasicType(Kind.eDouble, 0); c_double = new CBasicType(Kind.eDouble, 0);
c_double_complex = new CBasicType(Kind.eDouble, CBasicType.IS_COMPLEX); c_double_complex = new CBasicType(Kind.eDouble, IBasicType.IS_COMPLEX);
c_float = new CBasicType(Kind.eFloat, 0); c_float = new CBasicType(Kind.eFloat, 0);
c_float_complex = new CBasicType(Kind.eFloat, CBasicType.IS_COMPLEX); c_float_complex = new CBasicType(Kind.eFloat, IBasicType.IS_COMPLEX);
c_float_p = new CPointerType(c_float, 0); c_float_p = new CPointerType(c_float, 0);
c_int = new CBasicType(Kind.eInt, 0); c_int = new CBasicType(Kind.eInt, 0);
c_int_p = new CPointerType(c_int, 0); c_int_p = new CPointerType(c_int, 0);
c_long_double = new CBasicType(Kind.eDouble, CBasicType.IS_LONG); c_long_double = new CBasicType(Kind.eDouble, IBasicType.IS_LONG);
c_long_double_complex = new CBasicType(Kind.eDouble, CBasicType.IS_LONG | CBasicType.IS_COMPLEX); c_long_double_complex = new CBasicType(Kind.eDouble, IBasicType.IS_LONG | IBasicType.IS_COMPLEX);
c_long_double_p = new CPointerType(c_long_double, 0); c_long_double_p = new CPointerType(c_long_double, 0);
c_long_int = new CBasicType(Kind.eInt, CBasicType.IS_LONG); c_long_int = new CBasicType(Kind.eInt, IBasicType.IS_LONG);
c_long_long_int = new CBasicType(Kind.eInt, CBasicType.IS_LONGLONG); c_long_long_int = new CBasicType(Kind.eInt, IBasicType.IS_LONG_LONG);
c_signed_long_int = new CBasicType(Kind.eInt, CBasicType.IS_LONG | CBasicType.IS_SIGNED); c_signed_long_int = new CBasicType(Kind.eInt, IBasicType.IS_LONG | IBasicType.IS_SIGNED);
c_unsigned_int = new CBasicType(Kind.eInt, CBasicType.IS_UNSIGNED); c_unsigned_int = new CBasicType(Kind.eInt, IBasicType.IS_UNSIGNED);
c_unsigned_long = new CBasicType(Kind.eInt, CBasicType.IS_LONG | CBasicType.IS_UNSIGNED); c_unsigned_long = new CBasicType(Kind.eInt, IBasicType.IS_LONG | IBasicType.IS_UNSIGNED);
c_unsigned_long_long = new CBasicType(Kind.eInt, CBasicType.IS_LONGLONG | CBasicType.IS_UNSIGNED); c_unsigned_long_long = new CBasicType(Kind.eInt, IBasicType.IS_LONG_LONG | IBasicType.IS_UNSIGNED);
c_va_list = new CFunctionType(c_char_p, new IType[0]); // assumed: char* va_list(); c_va_list = new CFunctionType(c_char_p, new IType[0]); // assumed: char* va_list();
c_size_t = c_unsigned_long; // assumed unsigned long int c_size_t = c_unsigned_long; // assumed unsigned long int
@ -330,22 +330,22 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider {
cpp_const_char_p_r = new GPPPointerType(new CPPQualifierType(cpp_char, true, false), false, false, true); cpp_const_char_p_r = new GPPPointerType(new CPPQualifierType(cpp_char, true, false), false, false, true);
cpp_double = new CPPBasicType(Kind.eDouble, 0); cpp_double = new CPPBasicType(Kind.eDouble, 0);
cpp_double_complex = new CPPBasicType(Kind.eDouble, ICPPBasicType.IS_COMPLEX, null); cpp_double_complex = new CPPBasicType(Kind.eDouble, IBasicType.IS_COMPLEX, null);
cpp_float = new CPPBasicType(Kind.eFloat, 0); cpp_float = new CPPBasicType(Kind.eFloat, 0);
cpp_float_complex = new CPPBasicType(Kind.eFloat, ICPPBasicType.IS_COMPLEX, null); cpp_float_complex = new CPPBasicType(Kind.eFloat, IBasicType.IS_COMPLEX, null);
cpp_float_p = new CPPPointerType(cpp_float); cpp_float_p = new CPPPointerType(cpp_float);
cpp_int = new CPPBasicType(Kind.eInt, 0); cpp_int = new CPPBasicType(Kind.eInt, 0);
cpp_int_p = new CPPPointerType(cpp_int); cpp_int_p = new CPPPointerType(cpp_int);
cpp_long_int = new CPPBasicType(Kind.eInt, ICPPBasicType.IS_LONG); cpp_long_int = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG);
cpp_long_double = new CPPBasicType(Kind.eDouble, ICPPBasicType.IS_LONG); cpp_long_double = new CPPBasicType(Kind.eDouble, IBasicType.IS_LONG);
cpp_long_double_complex = new CPPBasicType(Kind.eDouble, ICPPBasicType.IS_LONG | ICPPBasicType.IS_COMPLEX, null); cpp_long_double_complex = new CPPBasicType(Kind.eDouble, IBasicType.IS_LONG | IBasicType.IS_COMPLEX, null);
cpp_long_double_p = new CPPPointerType(cpp_long_double); cpp_long_double_p = new CPPPointerType(cpp_long_double);
cpp_long_long_int = new CPPBasicType(Kind.eInt, ICPPBasicType.IS_LONG_LONG, null); cpp_long_long_int = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG_LONG, null);
cpp_signed_long_int = new CPPBasicType(Kind.eInt, ICPPBasicType.IS_LONG | ICPPBasicType.IS_SIGNED); cpp_signed_long_int = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG | IBasicType.IS_SIGNED);
cpp_unsigned_int = new CPPBasicType(Kind.eInt, ICPPBasicType.IS_UNSIGNED); cpp_unsigned_int = new CPPBasicType(Kind.eInt, IBasicType.IS_UNSIGNED);
cpp_unsigned_long = new CPPBasicType(Kind.eInt, ICPPBasicType.IS_UNSIGNED | ICPPBasicType.IS_LONG); cpp_unsigned_long = new CPPBasicType(Kind.eInt, IBasicType.IS_UNSIGNED | IBasicType.IS_LONG);
cpp_unsigned_long_long = new CPPBasicType(Kind.eInt, ICPPBasicType.IS_UNSIGNED | ICPPBasicType.IS_LONG_LONG, null); cpp_unsigned_long_long = new CPPBasicType(Kind.eInt, IBasicType.IS_UNSIGNED | IBasicType.IS_LONG_LONG, null);
cpp_size_t = cpp_unsigned_long; // assumed unsigned long int cpp_size_t = cpp_unsigned_long; // assumed unsigned long int
cpp_va_list = new CPPFunctionType(cpp_char_p, new IType[0]); // assumed: char* va_list(); cpp_va_list = new CPPFunctionType(cpp_char_p, new IType[0]); // assumed: char* va_list();

View file

@ -127,7 +127,13 @@ public class CASTBinaryExpression extends ASTNode implements
} }
public IType getExpressionType() { public IType getExpressionType() {
int op = getOperator(); final int op = getOperator();
final IType t1= CVisitor.unwrapTypedefs(getOperand1().getExpressionType());
final IType t2= CVisitor.unwrapTypedefs(getOperand2().getExpressionType());
IType type= CArithmeticConversion.convertCOperandTypes(op, t1, t2);
if (type != null) {
return type;
}
switch(op) { switch(op) {
case op_lessEqual: case op_lessEqual:
case op_lessThan: case op_lessThan:
@ -139,24 +145,20 @@ public class CASTBinaryExpression extends ASTNode implements
case op_notequals: case op_notequals:
return new CBasicType(Kind.eInt, 0, this); return new CBasicType(Kind.eInt, 0, this);
case IASTBinaryExpression.op_plus: case IASTBinaryExpression.op_plus:
IType t2 = getOperand2().getExpressionType(); if (t2 instanceof IPointerType) {
if (CVisitor.unwrapTypedefs(t2) instanceof IPointerType) {
return t2; return t2;
} }
break; break;
case IASTBinaryExpression.op_minus: case IASTBinaryExpression.op_minus:
t2= getOperand2().getExpressionType(); if (t2 instanceof IPointerType) {
if (CVisitor.unwrapTypedefs(t2) instanceof IPointerType) { if (t1 instanceof IPointerType) {
IType t1 = getOperand1().getExpressionType();
if (CVisitor.unwrapTypedefs(t1) instanceof IPointerType) {
return CVisitor.getPtrDiffType(this); return CVisitor.getPtrDiffType(this);
} }
return t1; return t1;
} }
break; break;
} }
return getOperand1().getExpressionType(); return t1;
} }
} }

View file

@ -111,7 +111,7 @@ public class CASTLiteralExpression extends ASTNode implements IASTLiteralExpress
kind= Kind.eFloat; kind= Kind.eFloat;
break; break;
case 'l': case 'L': case 'l': case 'L':
flags |= CBasicType.IS_LONG; flags |= IBasicType.IS_LONG;
break; break;
} }
} }
@ -143,13 +143,13 @@ public class CASTLiteralExpression extends ASTNode implements IASTLiteralExpress
int flags= 0; int flags= 0;
if (unsigned) { if (unsigned) {
flags |= CBasicType.IS_UNSIGNED; flags |= IBasicType.IS_UNSIGNED;
} }
if (makelong > 1) { if (makelong > 1) {
flags |= CBasicType.IS_LONGLONG; flags |= IBasicType.IS_LONG_LONG;
} else if (makelong == 1) { } else if (makelong == 1) {
flags |= CBasicType.IS_LONG; flags |= IBasicType.IS_LONG;
} }
return new CBasicType(IBasicType.Kind.eInt, flags, this); return new CBasicType(IBasicType.Kind.eInt, flags, this);
} }

View file

@ -99,14 +99,27 @@ public class CASTUnaryExpression extends ASTNode implements IASTUnaryExpression,
} }
public IType getExpressionType() { public IType getExpressionType() {
IType type = getOperand().getExpressionType(); final IType exprType = getOperand().getExpressionType();
IType type = CVisitor.unwrapTypedefs(exprType);
int op = getOperator(); int op = getOperator();
if (op == IASTUnaryExpression.op_star && (type instanceof IPointerType || type instanceof IArrayType)) { switch(op) {
return ((ITypeContainer) type).getType(); case op_star:
} else if (op == IASTUnaryExpression.op_amper) { if (type instanceof IPointerType || type instanceof IArrayType) {
return ((ITypeContainer) type).getType();
}
break;
case op_amper:
return new CPointerType(type, 0); 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 type; return exprType; // return the original
} }
} }

View file

@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2009 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
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.internal.core.dom.parser.ArithmeticConversion;
public class CArithmeticConversion extends ArithmeticConversion {
private static CArithmeticConversion sInstance= new CArithmeticConversion();
public static IType convertCOperandTypes(int operator, IType t1, IType t2) {
return sInstance.convertOperandTypes(operator, t1, t2);
}
public static IType promoteCType(IType type) {
return sInstance.promoteType(type);
}
private CArithmeticConversion() {}
@Override
protected IBasicType createBasicType(Kind kind, int modifiers) {
return new CBasicType(kind, modifiers);
}
}

View file

@ -20,21 +20,13 @@ import org.eclipse.cdt.core.dom.ast.c.ICBasicType;
import org.eclipse.cdt.internal.core.index.IIndexType; import org.eclipse.cdt.internal.core.index.IIndexType;
public class CBasicType implements ICBasicType { public class CBasicType implements ICBasicType {
public final static int IS_LONG = 1;
public final static int IS_LONGLONG = 1 << 1;
public final static int IS_SHORT = 1 << 2;
public final static int IS_SIGNED = 1 << 3;
public final static int IS_UNSIGNED = 1 << 4;
public final static int IS_COMPLEX = 1 << 5;
public final static int IS_IMAGINARY= 1 << 6;
private final Kind fKind; private final Kind fKind;
private int qualifiers = 0; private int fModifiers = 0;
private IASTExpression value = null; private IASTExpression value = null;
public CBasicType(Kind kind, int qualifiers, IASTExpression value ){ public CBasicType(Kind kind, int modifiers, IASTExpression value ){
if (kind == Kind.eUnspecified) { if (kind == Kind.eUnspecified) {
if ( (qualifiers & (IS_COMPLEX | IS_IMAGINARY)) != 0) { if ( (modifiers & (IS_COMPLEX | IS_IMAGINARY)) != 0) {
fKind= Kind.eFloat; fKind= Kind.eFloat;
} else { } else {
fKind= Kind.eInt; fKind= Kind.eInt;
@ -42,12 +34,12 @@ public class CBasicType implements ICBasicType {
} else { } else {
fKind= kind; fKind= kind;
} }
this.qualifiers = qualifiers; fModifiers = modifiers;
this.value = value; this.value = value;
} }
public CBasicType(Kind kind, int qualifiers) { public CBasicType(Kind kind, int modifiers) {
this(kind, qualifiers, null); this(kind, modifiers, null);
} }
public CBasicType(ICASTSimpleDeclSpecifier sds) { public CBasicType(ICASTSimpleDeclSpecifier sds) {
@ -55,13 +47,13 @@ public class CBasicType implements ICBasicType {
} }
private static int getQualifiers(ICASTSimpleDeclSpecifier sds) { private static int getQualifiers(ICASTSimpleDeclSpecifier sds) {
return ( sds.isLong() ? CBasicType.IS_LONG : 0 ) | return ( sds.isLong() ? IS_LONG : 0 ) |
( sds.isShort() ? CBasicType.IS_SHORT : 0 ) | ( sds.isShort() ? IS_SHORT : 0 ) |
( sds.isSigned() ? CBasicType.IS_SIGNED: 0 ) | ( sds.isSigned() ? IS_SIGNED: 0 ) |
( sds.isUnsigned()? CBasicType.IS_UNSIGNED : 0 ) | ( sds.isUnsigned()? IS_UNSIGNED : 0 ) |
( sds.isLongLong()? CBasicType.IS_LONGLONG : 0 ) | ( sds.isLongLong()? IS_LONG_LONG : 0 ) |
( sds.isComplex() ? CBasicType.IS_COMPLEX : 0 ) | ( sds.isComplex() ? IS_COMPLEX : 0 ) |
( sds.isImaginary()?CBasicType.IS_IMAGINARY : 0 ); ( sds.isImaginary()?IS_IMAGINARY : 0 );
} }
private static Kind getKind(ICASTSimpleDeclSpecifier sds) { private static Kind getKind(ICASTSimpleDeclSpecifier sds) {
@ -86,25 +78,29 @@ public class CBasicType implements ICBasicType {
public Kind getKind() { public Kind getKind() {
return fKind; return fKind;
} }
public int getModifiers() {
return fModifiers;
}
public boolean isSigned() { public boolean isSigned() {
return (qualifiers & IS_SIGNED) != 0; return (fModifiers & IS_SIGNED) != 0;
} }
public boolean isUnsigned() { public boolean isUnsigned() {
return (qualifiers & IS_UNSIGNED) != 0; return (fModifiers & IS_UNSIGNED) != 0;
} }
public boolean isShort() { public boolean isShort() {
return (qualifiers & IS_SHORT) != 0; return (fModifiers & IS_SHORT) != 0;
} }
public boolean isLong() { public boolean isLong() {
return (qualifiers & IS_LONG) != 0; return (fModifiers & IS_LONG) != 0;
} }
public boolean isLongLong() { public boolean isLongLong() {
return (qualifiers & IS_LONGLONG) != 0; return (fModifiers & IS_LONG_LONG) != 0;
} }
public boolean isSameType(IType obj) { public boolean isSameType(IType obj) {
@ -113,19 +109,19 @@ public class CBasicType implements ICBasicType {
if( obj instanceof ITypedef || obj instanceof IIndexType) if( obj instanceof ITypedef || obj instanceof IIndexType)
return obj.isSameType( this ); return obj.isSameType( this );
if (!(obj instanceof CBasicType)) return false; if (!(obj instanceof ICBasicType)) return false;
CBasicType cObj = (CBasicType)obj; ICBasicType cObj = (ICBasicType)obj;
if (fKind != cObj.fKind) { if (fKind != cObj.getKind()) {
return false; return false;
} }
if (fKind == Kind.eInt) { if (fKind == Kind.eInt) {
//signed int and int are equivalent //signed int and int are equivalent
return (qualifiers & ~IS_SIGNED) == (cObj.qualifiers & ~IS_SIGNED); return (fModifiers & ~IS_SIGNED) == (cObj.getModifiers() & ~IS_SIGNED);
} else { } else {
return (qualifiers == cObj.qualifiers); return (fModifiers == cObj.getModifiers());
} }
} }
@ -149,14 +145,14 @@ public class CBasicType implements ICBasicType {
* @see org.eclipse.cdt.core.dom.ast.c.ICBasicType#isComplex() * @see org.eclipse.cdt.core.dom.ast.c.ICBasicType#isComplex()
*/ */
public boolean isComplex() { public boolean isComplex() {
return ( qualifiers & IS_COMPLEX) != 0; return ( fModifiers & IS_COMPLEX) != 0;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.c.ICBasicType#isImaginary() * @see org.eclipse.cdt.core.dom.ast.c.ICBasicType#isImaginary()
*/ */
public boolean isImaginary() { public boolean isImaginary() {
return ( qualifiers & IS_IMAGINARY) != 0; return ( fModifiers & IS_IMAGINARY) != 0;
} }
@Deprecated @Deprecated

View file

@ -183,19 +183,23 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
} }
} }
IType type1 = getOperand1().getExpressionType(); final int op = getOperator();
IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1); IType type1 = SemanticUtil.getUltimateTypeUptoPointers(getOperand1().getExpressionType());
if (ultimateType1 instanceof IProblemBinding) { if (type1 instanceof IProblemBinding) {
return type1; return type1;
} }
IType type2 = getOperand2().getExpressionType(); IType type2 = SemanticUtil.getUltimateTypeUptoPointers(getOperand2().getExpressionType());
IType ultimateType2 = SemanticUtil.getUltimateTypeUptoPointers(type2); if (type2 instanceof IProblemBinding) {
if (ultimateType2 instanceof IProblemBinding) {
return type2; return type2;
} }
final int op = getOperator(); IType type= CPPArithmeticConversion.convertCppOperandTypes(op, type1, type2);
if (type != null) {
return type;
}
switch (op) { switch (op) {
case IASTBinaryExpression.op_lessEqual: case IASTBinaryExpression.op_lessEqual:
case IASTBinaryExpression.op_lessThan: case IASTBinaryExpression.op_lessThan:
@ -207,16 +211,16 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
case IASTBinaryExpression.op_notequals: case IASTBinaryExpression.op_notequals:
return new CPPBasicType(Kind.eBoolean, 0, this); return new CPPBasicType(Kind.eBoolean, 0, this);
case IASTBinaryExpression.op_plus: case IASTBinaryExpression.op_plus:
if (ultimateType2 instanceof IPointerType) { if (type2 instanceof IPointerType) {
return ultimateType2; return type2;
} }
break; break;
case IASTBinaryExpression.op_minus: case IASTBinaryExpression.op_minus:
if (ultimateType2 instanceof IPointerType) { if (type2 instanceof IPointerType) {
if (ultimateType1 instanceof IPointerType) { if (type1 instanceof IPointerType) {
return CPPVisitor.getPointerDiffType(this); return CPPVisitor.getPointerDiffType(this);
} }
return ultimateType1; return type1;
} }
break; break;
case ICPPASTBinaryExpression.op_pmarrow: case ICPPASTBinaryExpression.op_pmarrow:

View file

@ -245,20 +245,30 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
} }
IType type= operand.getExpressionType(); IType origType= operand.getExpressionType();
type = SemanticUtil.getNestedType(type, TDEF | REF); IType type = SemanticUtil.getUltimateTypeUptoPointers(origType);
IType operator = findOperatorReturnType(); IType operator = findOperatorReturnType();
if(operator != null) { if(operator != null) {
return operator; return operator;
} }
if(op == op_not) { switch (op) {
case op_not:
return new CPPBasicType(Kind.eBoolean, 0); return new CPPBasicType(Kind.eBoolean, 0);
case op_minus:
case op_plus:
case op_tilde:
IType t= CPPArithmeticConversion.promoteCppType(type);
if (t != null) {
return t;
}
break;
} }
if (type instanceof CPPBasicType) {
((CPPBasicType) type).setFromExpression(this); if (origType instanceof CPPBasicType) {
((CPPBasicType) origType).setFromExpression(this);
} }
return type; return origType;
} }

View file

@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2009 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
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.internal.core.dom.parser.ArithmeticConversion;
public class CPPArithmeticConversion extends ArithmeticConversion {
private static CPPArithmeticConversion sInstance= new CPPArithmeticConversion();
public static IType convertCppOperandTypes(int operator, IType t1, IType t2) {
return sInstance.convertOperandTypes(operator, t1, t2);
}
public static IType promoteCppType(IType t) {
return sInstance.promoteType(t);
}
private CPPArithmeticConversion() {}
@Override
protected IBasicType createBasicType(Kind kind, int modifiers) {
return new CPPBasicType(kind, modifiers);
}
}

View file

@ -14,6 +14,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier;
@ -27,7 +28,7 @@ import org.eclipse.cdt.internal.core.index.IIndexType;
public class CPPBasicType implements ICPPBasicType { public class CPPBasicType implements ICPPBasicType {
public static int UNIQUE_TYPE_QUALIFIER= -1; public static int UNIQUE_TYPE_QUALIFIER= -1;
private final Kind fKind; private final Kind fKind;
private final int fQualifierBits; private final int fModifiers;
private IASTExpression fExpression; private IASTExpression fExpression;
public CPPBasicType(Kind kind, int qualifiers, IASTExpression expression) { public CPPBasicType(Kind kind, int qualifiers, IASTExpression expression) {
@ -42,7 +43,7 @@ public class CPPBasicType implements ICPPBasicType {
} else { } else {
fKind= kind; fKind= kind;
} }
fQualifierBits= qualifiers; fModifiers= qualifiers;
fExpression= expression; fExpression= expression;
} }
@ -51,21 +52,21 @@ public class CPPBasicType implements ICPPBasicType {
} }
public CPPBasicType(ICPPASTSimpleDeclSpecifier sds) { public CPPBasicType(ICPPASTSimpleDeclSpecifier sds) {
this (getKind(sds), getQualifiers(sds), null); this (getKind(sds), getModifiers(sds), null);
} }
private static int getQualifiers(ICPPASTSimpleDeclSpecifier sds) { private static int getModifiers(ICPPASTSimpleDeclSpecifier sds) {
int qualifiers= int qualifiers=
( sds.isLong() ? ICPPBasicType.IS_LONG : 0 ) | ( sds.isLong() ? IBasicType.IS_LONG : 0 ) |
( sds.isShort() ? ICPPBasicType.IS_SHORT : 0 ) | ( sds.isShort() ? IBasicType.IS_SHORT : 0 ) |
( sds.isSigned() ? ICPPBasicType.IS_SIGNED: 0 ) | ( sds.isSigned() ? IBasicType.IS_SIGNED: 0 ) |
( sds.isUnsigned()? ICPPBasicType.IS_UNSIGNED : 0 ); ( sds.isUnsigned()? IBasicType.IS_UNSIGNED : 0 );
if (sds instanceof IGPPASTSimpleDeclSpecifier) { if (sds instanceof IGPPASTSimpleDeclSpecifier) {
IGPPASTSimpleDeclSpecifier gsds= (IGPPASTSimpleDeclSpecifier) sds; IGPPASTSimpleDeclSpecifier gsds= (IGPPASTSimpleDeclSpecifier) sds;
qualifiers |= qualifiers |=
( gsds.isLongLong()? ICPPBasicType.IS_LONG_LONG : 0 ) | ( gsds.isLongLong()? IBasicType.IS_LONG_LONG : 0 ) |
( gsds.isComplex() ? ICPPBasicType.IS_COMPLEX : 0 ) | ( gsds.isComplex() ? IBasicType.IS_COMPLEX : 0 ) |
( gsds.isImaginary()?ICPPBasicType.IS_IMAGINARY : 0 ); ( gsds.isImaginary()?IBasicType.IS_IMAGINARY : 0 );
} }
return qualifiers; return qualifiers;
} }
@ -100,24 +101,24 @@ public class CPPBasicType implements ICPPBasicType {
if (object == this) if (object == this)
return true; return true;
if (fQualifierBits == -1) if (fModifiers == -1)
return false; return false;
if (object instanceof ITypedef || object instanceof IIndexType) if (object instanceof ITypedef || object instanceof IIndexType)
return object.isSameType(this); return object.isSameType(this);
if (!(object instanceof CPPBasicType)) if (!(object instanceof ICPPBasicType))
return false; return false;
CPPBasicType t = (CPPBasicType) object; ICPPBasicType t = (ICPPBasicType) object;
if (fKind != t.fKind) if (fKind != t.getKind())
return false; return false;
if (fKind == Kind.eInt) { if (fKind == Kind.eInt) {
//signed int and int are equivalent //signed int and int are equivalent
return (fQualifierBits & ~IS_SIGNED) == (t.fQualifierBits & ~IS_SIGNED); return (fModifiers & ~IS_SIGNED) == (t.getModifiers() & ~IS_SIGNED);
} }
return fQualifierBits == t.fQualifierBits; return fModifiers == t.getModifiers();
} }
public Kind getKind() { public Kind getKind() {
@ -125,31 +126,31 @@ public class CPPBasicType implements ICPPBasicType {
} }
public boolean isSigned() { public boolean isSigned() {
return (fQualifierBits & IS_SIGNED) != 0; return (fModifiers & IS_SIGNED) != 0;
} }
public boolean isUnsigned() { public boolean isUnsigned() {
return (fQualifierBits & IS_UNSIGNED) != 0; return (fModifiers & IS_UNSIGNED) != 0;
} }
public boolean isShort() { public boolean isShort() {
return (fQualifierBits & IS_SHORT) != 0; return (fModifiers & IS_SHORT) != 0;
} }
public boolean isLong() { public boolean isLong() {
return (fQualifierBits & IS_LONG) != 0; return (fModifiers & IS_LONG) != 0;
} }
public boolean isLongLong() { public boolean isLongLong() {
return (fQualifierBits & IS_LONG_LONG) != 0; return (fModifiers & IS_LONG_LONG) != 0;
} }
public boolean isComplex() { public boolean isComplex() {
return (fQualifierBits & IS_COMPLEX) != 0; return (fModifiers & IS_COMPLEX) != 0;
} }
public boolean isImaginary() { public boolean isImaginary() {
return (fQualifierBits & IS_IMAGINARY) != 0; return (fModifiers & IS_IMAGINARY) != 0;
} }
@Override @Override
@ -174,15 +175,21 @@ public class CPPBasicType implements ICPPBasicType {
return fExpression; return fExpression;
} }
public int getQualifierBits() { public int getModifiers() {
return fQualifierBits; return fModifiers;
} }
@Override @Override
public String toString() { public String toString() {
return ASTTypeUtil.getType(this); return ASTTypeUtil.getType(this);
} }
@Deprecated
public int getQualifierBits() {
return getModifiers();
}
@Deprecated @Deprecated
public int getType() { public int getType() {
switch (fKind) { switch (fKind) {

View file

@ -24,13 +24,11 @@ import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IQualifierType;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
@ -41,6 +39,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.internal.core.dom.parser.ArithmeticConversion;
import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType;
@ -55,8 +54,6 @@ import org.eclipse.core.runtime.CoreException;
*/ */
public class Conversions { public class Conversions {
enum UDCMode {allowUDC, noUDC, deferUDC} enum UDCMode {allowUDC, noUDC, deferUDC}
private static final int IS_LONG = ICPPBasicType.IS_LONG;
private static final int IS_UNSIGNED = ICPPBasicType.IS_UNSIGNED;
/** /**
* Computes the cost of an implicit conversion sequence * Computes the cost of an implicit conversion sequence
@ -676,8 +673,9 @@ public class Conversions {
} else if (src instanceof IEnumeration) { } else if (src instanceof IEnumeration) {
if (tKind == Kind.eInt || tKind == Kind.eUnspecified) { if (tKind == Kind.eInt || tKind == Kind.eUnspecified) {
if (trg instanceof ICPPBasicType) { if (trg instanceof ICPPBasicType) {
int qualifiers = getEnumIntType((IEnumeration) src); int qualifiers = ArithmeticConversion.getEnumIntTypeModifiers((IEnumeration) src);
if (qualifiers == ((ICPPBasicType) trg).getQualifierBits()) { int targetModifiers = ((ICPPBasicType) trg).getModifiers();
if (qualifiers == (targetModifiers & (IBasicType.IS_LONG | IBasicType.IS_LONG_LONG | IBasicType.IS_SHORT | IBasicType.IS_UNSIGNED))) {
canPromote = true; canPromote = true;
} }
} else { } else {
@ -828,46 +826,4 @@ public class Conversions {
return true; return true;
} }
/**
* Returns IS_LONG, IS_UNSIGNED qualifiers of the first of the following types that can represent
* all the values of an enumeration: int, unsigned int, long, or unsigned long.
* @param enumeration
* @return qualifiers of the corresponding integer type.
*/
private static int getEnumIntType(IEnumeration enumeration) {
long minValue = 0;
long maxValue = 0;
try {
IEnumerator[] enumerators = enumeration.getEnumerators();
for (IEnumerator enumerator : enumerators) {
IValue value = enumerator.getValue();
if (value != null) {
Long val = value.numericalValue();
if (val != null) {
long v = val.longValue();
if (minValue > v) {
minValue = v;
}
if (maxValue < v) {
maxValue = v;
}
}
}
}
} catch (DOMException e) {
return 0;
}
// TODO(sprigogin): Use values of __INT_MAX__ and __LONG_MAX__ macros
if (minValue >= Integer.MIN_VALUE && maxValue <= Integer.MAX_VALUE) {
return 0;
} else if (minValue >= 0 && maxValue <= 0xFFFFFFFFL) {
return IS_UNSIGNED;
} else if (minValue >= Long.MIN_VALUE && maxValue <= Long.MAX_VALUE) {
return IS_LONG;
} else {
// This branch is unreachable due to limitations of Java long type.
return IS_UNSIGNED | IS_LONG;
}
}
} }

View file

@ -184,10 +184,11 @@ public class PDOM extends PlatformObject implements IPDOM {
* 90.0 - support for array sizes, bug 269926 * 90.0 - support for array sizes, bug 269926
* 91.0 - storing unknown bindings other than unknown class types, bug 284686. * 91.0 - storing unknown bindings other than unknown class types, bug 284686.
* 92.0 - simplification of basic types, bug 231859. * 92.0 - simplification of basic types, bug 231859.
* 93.0 - further simplification of basic types, bug 231859.
*/ */
private static final int MIN_SUPPORTED_VERSION= version(92, 0); private static final int MIN_SUPPORTED_VERSION= version(93, 0);
private static final int MAX_SUPPORTED_VERSION= version(92, Short.MAX_VALUE); private static final int MAX_SUPPORTED_VERSION= version(93, Short.MAX_VALUE);
private static final int DEFAULT_VERSION = version(92, 0); private static final int DEFAULT_VERSION = version(93, 0);
private static int version(int major, int minor) { private static int version(int major, int minor) {
return (major << 16) + minor; return (major << 16) + minor;

View file

@ -36,13 +36,7 @@ class PDOMCBasicType extends PDOMNode implements ICBasicType, IIndexType {
@SuppressWarnings("hiding") @SuppressWarnings("hiding")
public static final int RECORD_SIZE = PDOMNode.RECORD_SIZE + 4; public static final int RECORD_SIZE = PDOMNode.RECORD_SIZE + 4;
public static final int IS_LONG = 0x1; private int fModifiers= -1;
public static final int IS_SHORT = 0x2;
public static final int IS_UNSIGNED = 0x4;
public static final int IS_SIGNED = 0x8;
public static final int IS_LONGLONG = 0x10;
public static final int IS_IMAGINARY = 0x20;
public static final int IS_COMPLEX = 0x40;
public PDOMCBasicType(PDOMLinkage linkage, long record) { public PDOMCBasicType(PDOMLinkage linkage, long record) {
super(linkage, record); super(linkage, record);
@ -54,16 +48,7 @@ class PDOMCBasicType extends PDOMNode implements ICBasicType, IIndexType {
Database db = getDB(); Database db = getDB();
db.putChar(record + TYPE_ID, (char)type.getKind().ordinal()); db.putChar(record + TYPE_ID, (char)type.getKind().ordinal());
char flags = 0; char flags = (char) type.getModifiers();
if (type.isLong()) flags |= IS_LONG;
if (type.isShort()) flags |= IS_SHORT;
if (type.isSigned()) flags |= IS_SIGNED;
if (type.isUnsigned()) flags |= IS_UNSIGNED;
if (type.isLongLong()) flags |= IS_LONGLONG;
if (type.isImaginary()) flags |= IS_IMAGINARY;
if (type.isComplex()) flags |= IS_COMPLEX;
db.putChar(record + FLAGS, flags); db.putChar(record + FLAGS, flags);
} }
@ -87,6 +72,60 @@ class PDOMCBasicType extends PDOMNode implements ICBasicType, IIndexType {
} }
} }
public boolean isLong() { return flagSet(IS_LONG); }
public boolean isShort() { return flagSet(IS_SHORT); }
public boolean isSigned() { return flagSet(IS_SIGNED); }
public boolean isUnsigned() { return flagSet(IS_UNSIGNED); }
public boolean isLongLong() { return flagSet(IS_LONG_LONG); }
public boolean isImaginary() { return flagSet(IS_IMAGINARY); }
public boolean isComplex() { return flagSet(IS_COMPLEX); }
public boolean isSameType(IType rhs) {
if( rhs instanceof ITypedef )
return rhs.isSameType( this );
if( !(rhs instanceof ICBasicType))
return false;
ICBasicType rhs1= (ICBasicType) rhs;
Kind kind = getKind();
if (kind != rhs1.getKind())
return false;
if (kind == Kind.eInt) {
//signed int and int are equivalent
return (getModifiers() & ~IS_SIGNED) == (rhs1.getModifiers() & ~IS_SIGNED);
} else {
return (getModifiers() == rhs1.getModifiers());
}
}
@Override
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
public int getModifiers() {
if (fModifiers == -1) {
try {
fModifiers= getDB().getChar(record + FLAGS);
} catch (CoreException e) {
CCorePlugin.log(e);
fModifiers= 0;
}
}
return fModifiers;
}
private boolean flagSet(int flag) {
return (getModifiers() & flag) != 0;
}
@Deprecated @Deprecated
public int getType() { public int getType() {
final Kind kind = getKind(); final Kind kind = getKind();
@ -114,53 +153,4 @@ class PDOMCBasicType extends PDOMNode implements ICBasicType, IIndexType {
public IASTExpression getValue() throws DOMException { public IASTExpression getValue() throws DOMException {
return null; return null;
} }
public boolean isLong() { return flagSet(IS_LONG); }
public boolean isShort() { return flagSet(IS_SHORT); }
public boolean isSigned() { return flagSet(IS_SIGNED); }
public boolean isUnsigned() { return flagSet(IS_UNSIGNED); }
public boolean isLongLong() { return flagSet(IS_LONGLONG); }
public boolean isImaginary() { return flagSet(IS_IMAGINARY); }
public boolean isComplex() { return flagSet(IS_COMPLEX); }
public boolean isSameType(IType rhs) {
if( rhs instanceof ITypedef )
return rhs.isSameType( this );
if( !(rhs instanceof ICBasicType))
return false;
ICBasicType rhs1= (ICBasicType) rhs;
return (rhs1.getKind() == getKind()
&& rhs1.isLong() == this.isLong()
&& rhs1.isShort() == this.isShort()
&& rhs1.isSigned() == this.isSigned()
&& rhs1.isUnsigned() == this.isUnsigned()
&& rhs1.isLongLong() == this.isLongLong()
&& rhs1.isComplex() == this.isComplex()
&& rhs1.isImaginary() == this.isImaginary());
}
@Override
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
private char getFlags() throws CoreException {
return getDB().getChar(record + FLAGS);
}
private boolean flagSet(int flag) {
try {
return (getFlags() & flag) != 0;
} catch (CoreException e) {
CCorePlugin.log(e);
return false;
}
}
} }

View file

@ -16,6 +16,7 @@ import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
@ -29,7 +30,7 @@ import org.eclipse.core.runtime.CoreException;
/** /**
* Models built-in c++ types. * Models built-in c++ types.
*/ */
class PDOMCPPBasicType extends PDOMNode implements ICPPBasicType, IIndexType { final class PDOMCPPBasicType extends PDOMNode implements ICPPBasicType, IIndexType {
private static final int TYPE_ID = PDOMNode.RECORD_SIZE + 0; // short private static final int TYPE_ID = PDOMNode.RECORD_SIZE + 0; // short
private static final int QUALIFIER_FLAGS = PDOMNode.RECORD_SIZE + 2; // short private static final int QUALIFIER_FLAGS = PDOMNode.RECORD_SIZE + 2; // short
@ -103,7 +104,7 @@ class PDOMCPPBasicType extends PDOMNode implements ICPPBasicType, IIndexType {
} }
} }
public int getQualifierBits() { public final int getModifiers() {
if (fFlags == -1) { if (fFlags == -1) {
try { try {
fFlags= getDB().getShort(record + QUALIFIER_FLAGS); fFlags= getDB().getShort(record + QUALIFIER_FLAGS);
@ -115,33 +116,38 @@ class PDOMCPPBasicType extends PDOMNode implements ICPPBasicType, IIndexType {
} }
return fFlags; return fFlags;
} }
@Deprecated
public final int getQualifierBits() {
return getModifiers();
}
public boolean isLong() { public boolean isLong() {
return (getQualifierBits() & IS_LONG) != 0; return (getModifiers() & IS_LONG) != 0;
} }
public boolean isShort() { public boolean isShort() {
return (getQualifierBits() & IS_SHORT) != 0; return (getModifiers() & IS_SHORT) != 0;
} }
public boolean isSigned() { public boolean isSigned() {
return (getQualifierBits() & IS_SIGNED) != 0; return (getModifiers() & IS_SIGNED) != 0;
} }
public boolean isUnsigned() { public boolean isUnsigned() {
return (getQualifierBits() & IS_UNSIGNED) != 0; return (getModifiers() & IS_UNSIGNED) != 0;
} }
public boolean isComplex() { public boolean isComplex() {
return (getQualifierBits() & IS_COMPLEX) != 0; return (getModifiers() & IS_COMPLEX) != 0;
} }
public boolean isImaginary() { public boolean isImaginary() {
return (getQualifierBits() & IS_IMAGINARY) != 0; return (getModifiers() & IS_IMAGINARY) != 0;
} }
public boolean isLongLong() { public boolean isLongLong() {
return (getQualifierBits() & IS_LONG_LONG) != 0; return (getModifiers() & IS_LONG_LONG) != 0;
} }
public boolean isSameType(IType rhs) { public boolean isSameType(IType rhs) {
@ -158,9 +164,9 @@ class PDOMCPPBasicType extends PDOMNode implements ICPPBasicType, IIndexType {
if (kind == Kind.eInt) { if (kind == Kind.eInt) {
// signed int and int are equivalent // signed int and int are equivalent
return (this.getQualifierBits() & ~ICPPBasicType.IS_SIGNED) == (rhs1.getQualifierBits() & ~ICPPBasicType.IS_SIGNED); return (getModifiers() & ~IBasicType.IS_SIGNED) == (rhs1.getModifiers() & ~IBasicType.IS_SIGNED);
} }
return (this.getQualifierBits() == rhs1.getQualifierBits()); return getModifiers() == rhs1.getModifiers();
} }
@Override @Override