1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-28 19:35:36 +02:00

Enum to int conversion. Bug 285368.

This commit is contained in:
Sergey Prigogin 2009-08-02 05:39:59 +00:00
parent 4554f2baf8
commit d2b0c2f46b
3 changed files with 83 additions and 11 deletions

View file

@ -7122,7 +7122,7 @@ public class AST2CPPTests extends AST2BaseTest {
// foo(L'a'); // foo(L'a');
// } // }
public void testWideCharacterLiteralTypes_Bug270892() throws Exception { public void testWideCharacterLiteralTypes_Bug270892() throws Exception {
IASTTranslationUnit tu = parse( getAboveComment(), ParserLanguage.CPP ); IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP);
CPPNameCollector col = new CPPNameCollector(); CPPNameCollector col = new CPPNameCollector();
tu.accept(col); tu.accept(col);
@ -7301,14 +7301,33 @@ public class AST2CPPTests extends AST2BaseTest {
// void f(int t); // void f(int t);
// void f(unsigned int t); // void f(unsigned int t);
// void f(long t);
// //
// enum E { e1 }; // enum IntEnum { i1 };
// enum UnsignedEnum { u1 = 0x7FFFFFFF, u2 };
// enum LongEnum { l1 = -1, l2 = 0x7FFFFFFF, l3 };
// //
// void test() { // void test() {
// f(e1); // problem on f // f(i1);
// f(u1);
// f(l1);
// } // }
public void _testEnumToIntConversion_285368() throws Exception { public void testEnumToIntConversion_285368() throws Exception {
final String code = getAboveComment(); BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
parseAndCheckBindings(code, ParserLanguage.CPP); ICPPFunction f1 = ba.assertNonProblem("f(i1)", 1, ICPPFunction.class);
IType t1 = f1.getType().getParameterTypes()[0];
assertTrue(t1 instanceof ICPPBasicType);
assertEquals(IBasicType.t_int, ((ICPPBasicType) t1).getType());
assertEquals(0, ((ICPPBasicType) t1).getQualifierBits());
ICPPFunction f2 = ba.assertNonProblem("f(u1)", 1, ICPPFunction.class);
IType t2 = f2.getType().getParameterTypes()[0];
assertTrue(t2 instanceof ICPPBasicType);
assertEquals(IBasicType.t_int, ((ICPPBasicType) t2).getType());
assertEquals(ICPPBasicType.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());
} }
} }

View file

@ -123,7 +123,7 @@ public abstract class ASTEnumerator extends ASTNode implements IASTEnumerator, I
private void createEnumValues(IASTEnumerationSpecifier parent) { private void createEnumValues(IASTEnumerationSpecifier parent) {
IASTEnumerator[] etors= parent.getEnumerators(); IASTEnumerator[] etors= parent.getEnumerators();
int cv= -1; long cv= -1;
boolean isknown= true; boolean isknown= true;
for (IASTEnumerator etor : etors) { for (IASTEnumerator etor : etors) {
cv++; cv++;
@ -134,7 +134,7 @@ public abstract class ASTEnumerator extends ASTNode implements IASTEnumerator, I
isknown= false; isknown= false;
if (nv != null) { if (nv != null) {
isknown= true; isknown= true;
cv= nv.intValue(); cv= nv.longValue();
} }
} }
if (etor instanceof ASTEnumerator) { if (etor instanceof ASTEnumerator) {

View file

@ -24,11 +24,13 @@ import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IQualifierType;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
@ -52,7 +54,9 @@ import org.eclipse.core.runtime.CoreException;
*/ */
public class Conversions { public class Conversions {
enum UDCMode {allowUDC, noUDC, deferUDC} enum UDCMode {allowUDC, noUDC, deferUDC}
private static final int IS_LONG = ICPPBasicType.IS_LONG;
private static final int IS_UNSIGNED = ICPPBasicType.IS_UNSIGNED;
/** /**
* Computes the cost of an implicit conversion sequence * Computes the cost of an implicit conversion sequence
* [over.best.ics] 13.3.3.1 * [over.best.ics] 13.3.3.1
@ -669,7 +673,14 @@ public class Conversions {
} }
} else if (src instanceof IEnumeration) { } else if (src instanceof IEnumeration) {
if (tType == IBasicType.t_int || tType == IBasicType.t_unspecified) { if (tType == IBasicType.t_int || tType == IBasicType.t_unspecified) {
canPromote= true; if (trg instanceof ICPPBasicType) {
int qualifiers = getEnumIntType((IEnumeration) src);
if (qualifiers == ((ICPPBasicType) trg).getQualifierBits()) {
canPromote = true;
}
} else {
canPromote = true;
}
} }
} }
} }
@ -679,7 +690,7 @@ public class Conversions {
} }
return false; return false;
} }
/** /**
* Attempts conversions and returns whether the conversion succeeded. * Attempts conversions and returns whether the conversion succeeded.
* [4.7] Integral conversions * [4.7] Integral conversions
@ -815,4 +826,46 @@ public class Conversions {
return true; return true;
} }
/**
* Returns IS_LONG, IS_UNSIGNED qualifiers of the first of the following types that can represent
* all the values of an enumeration: int, unsigned int, long, or unsigned long.
* @param enumeration
* @return qualifiers of the corresponding integer type.
*/
private static int getEnumIntType(IEnumeration enumeration) {
long minValue = 0;
long maxValue = 0;
try {
IEnumerator[] enumerators = enumeration.getEnumerators();
for (IEnumerator enumerator : enumerators) {
IValue value = enumerator.getValue();
if (value != null) {
Long val = value.numericalValue();
if (val != null) {
long v = val.longValue();
if (minValue > v) {
minValue = v;
}
if (maxValue < v) {
maxValue = v;
}
}
}
}
} catch (DOMException e) {
return 0;
}
// TODO(sprigogin): Use values of __INT_MAX__ and __LONG_MAX__ macros
if (minValue >= Integer.MIN_VALUE && maxValue <= Integer.MAX_VALUE) {
return 0;
} else if (minValue >= 0 && maxValue <= 0xFFFFFFFFL) {
return IS_UNSIGNED;
} else if (minValue >= Long.MIN_VALUE && maxValue <= Long.MAX_VALUE) {
return IS_LONG;
} else {
// This branch is unreachable due to limitations of Java long type.
return IS_UNSIGNED | IS_LONG;
}
}
} }