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:
parent
4554f2baf8
commit
d2b0c2f46b
3 changed files with 83 additions and 11 deletions
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue