1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 17:05:26 +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');
// }
public void testWideCharacterLiteralTypes_Bug270892() throws Exception {
IASTTranslationUnit tu = parse( getAboveComment(), ParserLanguage.CPP );
IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP);
CPPNameCollector col = new CPPNameCollector();
tu.accept(col);
@ -7301,14 +7301,33 @@ public class AST2CPPTests extends AST2BaseTest {
// void f(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() {
// f(e1); // problem on f
// f(i1);
// f(u1);
// f(l1);
// }
public void _testEnumToIntConversion_285368() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
public void testEnumToIntConversion_285368() throws Exception {
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
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) {
IASTEnumerator[] etors= parent.getEnumerators();
int cv= -1;
long cv= -1;
boolean isknown= true;
for (IASTEnumerator etor : etors) {
cv++;
@ -134,7 +134,7 @@ public abstract class ASTEnumerator extends ASTNode implements IASTEnumerator, I
isknown= false;
if (nv != null) {
isknown= true;
cv= nv.intValue();
cv= nv.longValue();
}
}
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.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.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
@ -52,7 +54,9 @@ 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
* [over.best.ics] 13.3.3.1
@ -669,7 +673,14 @@ public class Conversions {
}
} else if (src instanceof IEnumeration) {
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;
}
/**
* Attempts conversions and returns whether the conversion succeeded.
* [4.7] Integral conversions
@ -815,4 +826,46 @@ 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;
}
}
}