From 16944a0de71433953e8078b854426ae327560f7d Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Fri, 9 Oct 2009 12:04:23 +0000 Subject: [PATCH] Arithmetic conversions for unary and binary expressions, bug 231859. --- .../core/parser/tests/ast2/AST2CPPTests.java | 4 +- .../cdt/core/parser/tests/ast2/AST2Tests.java | 542 ++++++++++++++++++ .../eclipse/cdt/core/dom/ast/IBasicType.java | 35 ++ .../cdt/core/dom/ast/cpp/ICPPBasicType.java | 13 +- .../core/dom/parser/ArithmeticConversion.java | 305 ++++++++++ .../dom/parser/GCCBuiltinSymbolProvider.java | 42 +- .../dom/parser/c/CASTBinaryExpression.java | 20 +- .../dom/parser/c/CASTLiteralExpression.java | 8 +- .../dom/parser/c/CASTUnaryExpression.java | 23 +- .../dom/parser/c/CArithmeticConversion.java | 35 ++ .../core/dom/parser/c/CBasicType.java | 62 +- .../parser/cpp/CPPASTBinaryExpression.java | 28 +- .../dom/parser/cpp/CPPASTUnaryExpression.java | 22 +- .../parser/cpp/CPPArithmeticConversion.java | 35 ++ .../core/dom/parser/cpp/CPPBasicType.java | 63 +- .../dom/parser/cpp/semantics/Conversions.java | 52 +- .../eclipse/cdt/internal/core/pdom/PDOM.java | 7 +- .../core/pdom/dom/c/PDOMCBasicType.java | 122 ++-- .../core/pdom/dom/cpp/PDOMCPPBasicType.java | 28 +- 19 files changed, 1191 insertions(+), 255 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CArithmeticConversion.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPArithmeticConversion.java diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 22eac693164..294e554511f 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -7325,12 +7325,12 @@ public class AST2CPPTests extends AST2BaseTest { IType t2 = f2.getType().getParameterTypes()[0]; assertTrue(t2 instanceof ICPPBasicType); 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); IType t3 = f3.getType().getParameterTypes()[0]; assertTrue(t3 instanceof ICPPBasicType); 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; diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java index 15960b222d2..57b9e3c4b97 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java @@ -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.IVariable; 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.ICASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTDesignatedInitializer; @@ -6308,6 +6309,547 @@ public class AST2Tests extends AST2BaseTest { 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]; // diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IBasicType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IBasicType.java index 42eba47db76..222fc10fd78 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IBasicType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IBasicType.java @@ -24,6 +24,36 @@ public interface IBasicType extends IType { enum Kind { 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 @@ -32,6 +62,11 @@ public interface IBasicType extends IType { */ Kind getKind(); + /** + * This returns the combination of modifier bits for this type. + * @since 5.2 + */ + int getModifiers(); public boolean isSigned(); public boolean isUnsigned(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPBasicType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPBasicType.java index fd850f88f87..f7cb2d7bd8f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPBasicType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPBasicType.java @@ -18,19 +18,18 @@ import org.eclipse.cdt.core.dom.ast.IBasicType; * @noimplement This interface is not intended to be implemented by clients. */ public interface ICPPBasicType extends IBasicType { - public static final int IS_LONG = 1; - public static final int IS_SHORT = 1 << 1; - public static final int IS_SIGNED = 1 << 2; - public static final int IS_UNSIGNED = 1 << 3; - 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; + /** + * @deprecated, don't use the constant, more flags may be added for supporting future c++ standards. + */ + @Deprecated public static final int LAST = IS_LONG_LONG; /** * @return a combination of qualifiers. * @since 4.0 + * @deprecated use {@link #getModifiers()}, instead. */ + @Deprecated public int getQualifierBits(); /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java new file mode 100644 index 00000000000..a2d440d98b5 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java @@ -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; + } + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/GCCBuiltinSymbolProvider.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/GCCBuiltinSymbolProvider.java index f42f56c0451..fea6c0468e2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/GCCBuiltinSymbolProvider.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/GCCBuiltinSymbolProvider.java @@ -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.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.IFunctionType; 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.IValue; 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.ICPPParameter; 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_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_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_int = new CBasicType(Kind.eInt, 0); c_int_p = new CPointerType(c_int, 0); - c_long_double = new CBasicType(Kind.eDouble, CBasicType.IS_LONG); - c_long_double_complex = new CBasicType(Kind.eDouble, CBasicType.IS_LONG | CBasicType.IS_COMPLEX); + c_long_double = new CBasicType(Kind.eDouble, IBasicType.IS_LONG); + 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_int = new CBasicType(Kind.eInt, CBasicType.IS_LONG); - c_long_long_int = new CBasicType(Kind.eInt, CBasicType.IS_LONGLONG); - c_signed_long_int = new CBasicType(Kind.eInt, CBasicType.IS_LONG | CBasicType.IS_SIGNED); - c_unsigned_int = new CBasicType(Kind.eInt, CBasicType.IS_UNSIGNED); - c_unsigned_long = new CBasicType(Kind.eInt, CBasicType.IS_LONG | CBasicType.IS_UNSIGNED); - c_unsigned_long_long = new CBasicType(Kind.eInt, CBasicType.IS_LONGLONG | CBasicType.IS_UNSIGNED); + c_long_int = new CBasicType(Kind.eInt, IBasicType.IS_LONG); + c_long_long_int = new CBasicType(Kind.eInt, IBasicType.IS_LONG_LONG); + c_signed_long_int = new CBasicType(Kind.eInt, IBasicType.IS_LONG | IBasicType.IS_SIGNED); + c_unsigned_int = new CBasicType(Kind.eInt, IBasicType.IS_UNSIGNED); + c_unsigned_long = new CBasicType(Kind.eInt, IBasicType.IS_LONG | IBasicType.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_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_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_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_int = new CPPBasicType(Kind.eInt, 0); cpp_int_p = new CPPPointerType(cpp_int); - cpp_long_int = new CPPBasicType(Kind.eInt, ICPPBasicType.IS_LONG); - cpp_long_double = new CPPBasicType(Kind.eDouble, ICPPBasicType.IS_LONG); - cpp_long_double_complex = new CPPBasicType(Kind.eDouble, ICPPBasicType.IS_LONG | ICPPBasicType.IS_COMPLEX, null); + cpp_long_int = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG); + cpp_long_double = new CPPBasicType(Kind.eDouble, IBasicType.IS_LONG); + 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_long_int = new CPPBasicType(Kind.eInt, ICPPBasicType.IS_LONG_LONG, null); - cpp_signed_long_int = new CPPBasicType(Kind.eInt, ICPPBasicType.IS_LONG | ICPPBasicType.IS_SIGNED); + cpp_long_long_int = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG_LONG, null); + 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_long = new CPPBasicType(Kind.eInt, ICPPBasicType.IS_UNSIGNED | ICPPBasicType.IS_LONG); - cpp_unsigned_long_long = new CPPBasicType(Kind.eInt, ICPPBasicType.IS_UNSIGNED | ICPPBasicType.IS_LONG_LONG, null); + cpp_unsigned_int = new CPPBasicType(Kind.eInt, IBasicType.IS_UNSIGNED); + cpp_unsigned_long = new CPPBasicType(Kind.eInt, IBasicType.IS_UNSIGNED | IBasicType.IS_LONG); + 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_va_list = new CPPFunctionType(cpp_char_p, new IType[0]); // assumed: char* va_list(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java index fee8a61af55..631430e0466 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java @@ -127,7 +127,13 @@ public class CASTBinaryExpression extends ASTNode implements } 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) { case op_lessEqual: case op_lessThan: @@ -139,24 +145,20 @@ public class CASTBinaryExpression extends ASTNode implements case op_notequals: return new CBasicType(Kind.eInt, 0, this); case IASTBinaryExpression.op_plus: - IType t2 = getOperand2().getExpressionType(); - if (CVisitor.unwrapTypedefs(t2) instanceof IPointerType) { + if (t2 instanceof IPointerType) { return t2; } break; case IASTBinaryExpression.op_minus: - t2= getOperand2().getExpressionType(); - if (CVisitor.unwrapTypedefs(t2) instanceof IPointerType) { - IType t1 = getOperand1().getExpressionType(); - if (CVisitor.unwrapTypedefs(t1) instanceof IPointerType) { + if (t2 instanceof IPointerType) { + if (t1 instanceof IPointerType) { return CVisitor.getPtrDiffType(this); } return t1; } break; } - return getOperand1().getExpressionType(); + return t1; } - } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTLiteralExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTLiteralExpression.java index 4bb65cbdad6..e7f275d33b5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTLiteralExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTLiteralExpression.java @@ -111,7 +111,7 @@ public class CASTLiteralExpression extends ASTNode implements IASTLiteralExpress kind= Kind.eFloat; break; case 'l': case 'L': - flags |= CBasicType.IS_LONG; + flags |= IBasicType.IS_LONG; break; } } @@ -143,13 +143,13 @@ public class CASTLiteralExpression extends ASTNode implements IASTLiteralExpress int flags= 0; if (unsigned) { - flags |= CBasicType.IS_UNSIGNED; + flags |= IBasicType.IS_UNSIGNED; } if (makelong > 1) { - flags |= CBasicType.IS_LONGLONG; + flags |= IBasicType.IS_LONG_LONG; } else if (makelong == 1) { - flags |= CBasicType.IS_LONG; + flags |= IBasicType.IS_LONG; } return new CBasicType(IBasicType.Kind.eInt, flags, this); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTUnaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTUnaryExpression.java index 4628de96277..ad91cb843fd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTUnaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTUnaryExpression.java @@ -99,14 +99,27 @@ public class CASTUnaryExpression extends ASTNode implements IASTUnaryExpression, } public IType getExpressionType() { - IType type = getOperand().getExpressionType(); + final IType exprType = getOperand().getExpressionType(); + IType type = CVisitor.unwrapTypedefs(exprType); int op = getOperator(); - if (op == IASTUnaryExpression.op_star && (type instanceof IPointerType || type instanceof IArrayType)) { - return ((ITypeContainer) type).getType(); - } else if (op == IASTUnaryExpression.op_amper) { + 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 type; + return exprType; // return the original } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CArithmeticConversion.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CArithmeticConversion.java new file mode 100644 index 00000000000..7e0ed61a7a2 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CArithmeticConversion.java @@ -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); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CBasicType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CBasicType.java index 21f6448552b..3c8e2b99588 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CBasicType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CBasicType.java @@ -20,21 +20,13 @@ import org.eclipse.cdt.core.dom.ast.c.ICBasicType; import org.eclipse.cdt.internal.core.index.IIndexType; 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 int qualifiers = 0; + private int fModifiers = 0; 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 ( (qualifiers & (IS_COMPLEX | IS_IMAGINARY)) != 0) { + if ( (modifiers & (IS_COMPLEX | IS_IMAGINARY)) != 0) { fKind= Kind.eFloat; } else { fKind= Kind.eInt; @@ -42,12 +34,12 @@ public class CBasicType implements ICBasicType { } else { fKind= kind; } - this.qualifiers = qualifiers; + fModifiers = modifiers; this.value = value; } - public CBasicType(Kind kind, int qualifiers) { - this(kind, qualifiers, null); + public CBasicType(Kind kind, int modifiers) { + this(kind, modifiers, null); } public CBasicType(ICASTSimpleDeclSpecifier sds) { @@ -55,13 +47,13 @@ public class CBasicType implements ICBasicType { } private static int getQualifiers(ICASTSimpleDeclSpecifier sds) { - return ( sds.isLong() ? CBasicType.IS_LONG : 0 ) | - ( sds.isShort() ? CBasicType.IS_SHORT : 0 ) | - ( sds.isSigned() ? CBasicType.IS_SIGNED: 0 ) | - ( sds.isUnsigned()? CBasicType.IS_UNSIGNED : 0 ) | - ( sds.isLongLong()? CBasicType.IS_LONGLONG : 0 ) | - ( sds.isComplex() ? CBasicType.IS_COMPLEX : 0 ) | - ( sds.isImaginary()?CBasicType.IS_IMAGINARY : 0 ); + 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) { @@ -86,25 +78,29 @@ public class CBasicType implements ICBasicType { public Kind getKind() { return fKind; } + + public int getModifiers() { + return fModifiers; + } public boolean isSigned() { - return (qualifiers & IS_SIGNED) != 0; + return (fModifiers & IS_SIGNED) != 0; } public boolean isUnsigned() { - return (qualifiers & IS_UNSIGNED) != 0; + return (fModifiers & IS_UNSIGNED) != 0; } public boolean isShort() { - return (qualifiers & IS_SHORT) != 0; + return (fModifiers & IS_SHORT) != 0; } public boolean isLong() { - return (qualifiers & IS_LONG) != 0; + return (fModifiers & IS_LONG) != 0; } public boolean isLongLong() { - return (qualifiers & IS_LONGLONG) != 0; + return (fModifiers & IS_LONG_LONG) != 0; } public boolean isSameType(IType obj) { @@ -113,19 +109,19 @@ public class CBasicType implements ICBasicType { if( obj instanceof ITypedef || obj instanceof IIndexType) 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; } if (fKind == Kind.eInt) { //signed int and int are equivalent - return (qualifiers & ~IS_SIGNED) == (cObj.qualifiers & ~IS_SIGNED); + return (fModifiers & ~IS_SIGNED) == (cObj.getModifiers() & ~IS_SIGNED); } 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() */ public boolean isComplex() { - return ( qualifiers & IS_COMPLEX) != 0; + return ( fModifiers & IS_COMPLEX) != 0; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.c.ICBasicType#isImaginary() */ public boolean isImaginary() { - return ( qualifiers & IS_IMAGINARY) != 0; + return ( fModifiers & IS_IMAGINARY) != 0; } @Deprecated diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java index e70fb60b26e..2b511f24fa5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java @@ -183,19 +183,23 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr } } - IType type1 = getOperand1().getExpressionType(); - IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1); - if (ultimateType1 instanceof IProblemBinding) { + final int op = getOperator(); + IType type1 = SemanticUtil.getUltimateTypeUptoPointers(getOperand1().getExpressionType()); + if (type1 instanceof IProblemBinding) { return type1; } - IType type2 = getOperand2().getExpressionType(); - IType ultimateType2 = SemanticUtil.getUltimateTypeUptoPointers(type2); - if (ultimateType2 instanceof IProblemBinding) { + IType type2 = SemanticUtil.getUltimateTypeUptoPointers(getOperand2().getExpressionType()); + if (type2 instanceof IProblemBinding) { return type2; } - final int op = getOperator(); + IType type= CPPArithmeticConversion.convertCppOperandTypes(op, type1, type2); + if (type != null) { + return type; + } + + switch (op) { case IASTBinaryExpression.op_lessEqual: case IASTBinaryExpression.op_lessThan: @@ -207,16 +211,16 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr case IASTBinaryExpression.op_notequals: return new CPPBasicType(Kind.eBoolean, 0, this); case IASTBinaryExpression.op_plus: - if (ultimateType2 instanceof IPointerType) { - return ultimateType2; + if (type2 instanceof IPointerType) { + return type2; } break; case IASTBinaryExpression.op_minus: - if (ultimateType2 instanceof IPointerType) { - if (ultimateType1 instanceof IPointerType) { + if (type2 instanceof IPointerType) { + if (type1 instanceof IPointerType) { return CPPVisitor.getPointerDiffType(this); } - return ultimateType1; + return type1; } break; case ICPPASTBinaryExpression.op_pmarrow: diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java index 7b3196be10e..2e3698f1fdc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java @@ -245,20 +245,30 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres } - IType type= operand.getExpressionType(); - type = SemanticUtil.getNestedType(type, TDEF | REF); + IType origType= operand.getExpressionType(); + IType type = SemanticUtil.getUltimateTypeUptoPointers(origType); IType operator = findOperatorReturnType(); if(operator != null) { return operator; } - if(op == op_not) { + switch (op) { + case op_not: 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; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPArithmeticConversion.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPArithmeticConversion.java new file mode 100644 index 00000000000..f1749cd8b2a --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPArithmeticConversion.java @@ -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); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBasicType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBasicType.java index f3ffafafbe3..31e2cab9a0c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBasicType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBasicType.java @@ -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.IASTExpression; 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.ITypedef; 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 static int UNIQUE_TYPE_QUALIFIER= -1; private final Kind fKind; - private final int fQualifierBits; + private final int fModifiers; private IASTExpression fExpression; public CPPBasicType(Kind kind, int qualifiers, IASTExpression expression) { @@ -42,7 +43,7 @@ public class CPPBasicType implements ICPPBasicType { } else { fKind= kind; } - fQualifierBits= qualifiers; + fModifiers= qualifiers; fExpression= expression; } @@ -51,21 +52,21 @@ public class CPPBasicType implements ICPPBasicType { } 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= - ( sds.isLong() ? ICPPBasicType.IS_LONG : 0 ) | - ( sds.isShort() ? ICPPBasicType.IS_SHORT : 0 ) | - ( sds.isSigned() ? ICPPBasicType.IS_SIGNED: 0 ) | - ( sds.isUnsigned()? ICPPBasicType.IS_UNSIGNED : 0 ); + ( sds.isLong() ? IBasicType.IS_LONG : 0 ) | + ( sds.isShort() ? IBasicType.IS_SHORT : 0 ) | + ( sds.isSigned() ? IBasicType.IS_SIGNED: 0 ) | + ( sds.isUnsigned()? IBasicType.IS_UNSIGNED : 0 ); if (sds instanceof IGPPASTSimpleDeclSpecifier) { IGPPASTSimpleDeclSpecifier gsds= (IGPPASTSimpleDeclSpecifier) sds; qualifiers |= - ( gsds.isLongLong()? ICPPBasicType.IS_LONG_LONG : 0 ) | - ( gsds.isComplex() ? ICPPBasicType.IS_COMPLEX : 0 ) | - ( gsds.isImaginary()?ICPPBasicType.IS_IMAGINARY : 0 ); + ( gsds.isLongLong()? IBasicType.IS_LONG_LONG : 0 ) | + ( gsds.isComplex() ? IBasicType.IS_COMPLEX : 0 ) | + ( gsds.isImaginary()?IBasicType.IS_IMAGINARY : 0 ); } return qualifiers; } @@ -100,24 +101,24 @@ public class CPPBasicType implements ICPPBasicType { if (object == this) return true; - if (fQualifierBits == -1) + if (fModifiers == -1) return false; if (object instanceof ITypedef || object instanceof IIndexType) return object.isSameType(this); - if (!(object instanceof CPPBasicType)) + if (!(object instanceof ICPPBasicType)) return false; - CPPBasicType t = (CPPBasicType) object; - if (fKind != t.fKind) + ICPPBasicType t = (ICPPBasicType) object; + if (fKind != t.getKind()) return false; if (fKind == Kind.eInt) { //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() { @@ -125,31 +126,31 @@ public class CPPBasicType implements ICPPBasicType { } public boolean isSigned() { - return (fQualifierBits & IS_SIGNED) != 0; + return (fModifiers & IS_SIGNED) != 0; } public boolean isUnsigned() { - return (fQualifierBits & IS_UNSIGNED) != 0; + return (fModifiers & IS_UNSIGNED) != 0; } public boolean isShort() { - return (fQualifierBits & IS_SHORT) != 0; + return (fModifiers & IS_SHORT) != 0; } public boolean isLong() { - return (fQualifierBits & IS_LONG) != 0; + return (fModifiers & IS_LONG) != 0; } public boolean isLongLong() { - return (fQualifierBits & IS_LONG_LONG) != 0; + return (fModifiers & IS_LONG_LONG) != 0; } public boolean isComplex() { - return (fQualifierBits & IS_COMPLEX) != 0; + return (fModifiers & IS_COMPLEX) != 0; } public boolean isImaginary() { - return (fQualifierBits & IS_IMAGINARY) != 0; + return (fModifiers & IS_IMAGINARY) != 0; } @Override @@ -174,15 +175,21 @@ public class CPPBasicType implements ICPPBasicType { return fExpression; } - public int getQualifierBits() { - return fQualifierBits; + public int getModifiers() { + return fModifiers; } - + @Override public String toString() { return ASTTypeUtil.getType(this); } - + + @Deprecated + public int getQualifierBits() { + return getModifiers(); + } + + @Deprecated public int getType() { switch (fKind) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java index 3acb5ce3901..05260c97a47 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java @@ -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.IBinding; 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.IPointerType; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IQualifierType; 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.cpp.ICPPBase; 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.ICPPSpecialization; 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.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType; @@ -55,8 +54,6 @@ import org.eclipse.core.runtime.CoreException; */ public class Conversions { 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 @@ -676,8 +673,9 @@ public class Conversions { } else if (src instanceof IEnumeration) { if (tKind == Kind.eInt || tKind == Kind.eUnspecified) { if (trg instanceof ICPPBasicType) { - int qualifiers = getEnumIntType((IEnumeration) src); - if (qualifiers == ((ICPPBasicType) trg).getQualifierBits()) { + int qualifiers = ArithmeticConversion.getEnumIntTypeModifiers((IEnumeration) src); + int targetModifiers = ((ICPPBasicType) trg).getModifiers(); + if (qualifiers == (targetModifiers & (IBasicType.IS_LONG | IBasicType.IS_LONG_LONG | IBasicType.IS_SHORT | IBasicType.IS_UNSIGNED))) { canPromote = true; } } else { @@ -828,46 +826,4 @@ public class Conversions { 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; - } - } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index 2f9e688ef21..f57c4a7dd64 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -184,10 +184,11 @@ public class PDOM extends PlatformObject implements IPDOM { * 90.0 - support for array sizes, bug 269926 * 91.0 - storing unknown bindings other than unknown class types, bug 284686. * 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 MAX_SUPPORTED_VERSION= version(92, Short.MAX_VALUE); - private static final int DEFAULT_VERSION = version(92, 0); + private static final int MIN_SUPPORTED_VERSION= version(93, 0); + private static final int MAX_SUPPORTED_VERSION= version(93, Short.MAX_VALUE); + private static final int DEFAULT_VERSION = version(93, 0); private static int version(int major, int minor) { return (major << 16) + minor; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCBasicType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCBasicType.java index 2c8c40377a6..eb0003f1799 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCBasicType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCBasicType.java @@ -36,13 +36,7 @@ class PDOMCBasicType extends PDOMNode implements ICBasicType, IIndexType { @SuppressWarnings("hiding") public static final int RECORD_SIZE = PDOMNode.RECORD_SIZE + 4; - public static final int IS_LONG = 0x1; - 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; + private int fModifiers= -1; public PDOMCBasicType(PDOMLinkage linkage, long record) { super(linkage, record); @@ -54,16 +48,7 @@ class PDOMCBasicType extends PDOMNode implements ICBasicType, IIndexType { Database db = getDB(); db.putChar(record + TYPE_ID, (char)type.getKind().ordinal()); - char flags = 0; - 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; - - + char flags = (char) type.getModifiers(); 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 public int getType() { final Kind kind = getKind(); @@ -114,53 +153,4 @@ class PDOMCBasicType extends PDOMNode implements ICBasicType, IIndexType { public IASTExpression getValue() throws DOMException { 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; - } - } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPBasicType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPBasicType.java index 43192c3322a..e9d0d55d11c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPBasicType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPBasicType.java @@ -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.DOMException; 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.ITypedef; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; @@ -29,7 +30,7 @@ import org.eclipse.core.runtime.CoreException; /** * 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 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) { try { fFlags= getDB().getShort(record + QUALIFIER_FLAGS); @@ -115,33 +116,38 @@ class PDOMCPPBasicType extends PDOMNode implements ICPPBasicType, IIndexType { } return fFlags; } + + @Deprecated + public final int getQualifierBits() { + return getModifiers(); + } public boolean isLong() { - return (getQualifierBits() & IS_LONG) != 0; + return (getModifiers() & IS_LONG) != 0; } public boolean isShort() { - return (getQualifierBits() & IS_SHORT) != 0; + return (getModifiers() & IS_SHORT) != 0; } public boolean isSigned() { - return (getQualifierBits() & IS_SIGNED) != 0; + return (getModifiers() & IS_SIGNED) != 0; } public boolean isUnsigned() { - return (getQualifierBits() & IS_UNSIGNED) != 0; + return (getModifiers() & IS_UNSIGNED) != 0; } public boolean isComplex() { - return (getQualifierBits() & IS_COMPLEX) != 0; + return (getModifiers() & IS_COMPLEX) != 0; } public boolean isImaginary() { - return (getQualifierBits() & IS_IMAGINARY) != 0; + return (getModifiers() & IS_IMAGINARY) != 0; } public boolean isLongLong() { - return (getQualifierBits() & IS_LONG_LONG) != 0; + return (getModifiers() & IS_LONG_LONG) != 0; } public boolean isSameType(IType rhs) { @@ -158,9 +164,9 @@ class PDOMCPPBasicType extends PDOMNode implements ICPPBasicType, IIndexType { if (kind == Kind.eInt) { // 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