mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 02:06:01 +02:00
Arithmetic conversions for unary and binary expressions, bug 231859.
This commit is contained in:
parent
1ccd6348b9
commit
16944a0de7
19 changed files with 1191 additions and 255 deletions
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
//
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue