Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergey Prigogin2009-08-02 06:57:30 +0000
committerSergey Prigogin2009-08-02 06:57:30 +0000
commit8510f0c0d233abba5717b72c8a514c26761b5a81 (patch)
treef9aa0740752c0556558a450b259d53b8bbfc8448
parente468788083f46e77c3138875353969eea11d2919 (diff)
downloadorg.eclipse.cdt-8510f0c0d233abba5717b72c8a514c26761b5a81.tar.gz
org.eclipse.cdt-8510f0c0d233abba5717b72c8a514c26761b5a81.tar.xz
org.eclipse.cdt-8510f0c0d233abba5717b72c8a514c26761b5a81.zip
Enum to int conversion. Bug 285368.
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java45
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTEnumerator.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java59
3 files changed, 102 insertions, 6 deletions
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 593a7e7d426..6eb4aebb988 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
@@ -7144,7 +7144,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);
@@ -7202,4 +7202,47 @@ public class AST2CPPTests extends AST2BaseTest {
parseAndCheckBindings(code, ParserLanguage.CPP);
}
+ // class A {
+ // friend inline void m(A p) {}
+ // };
+ //
+ // void test(A a) {
+ // m(a);
+ // }
+ public void _testInlineFriendFunction_284690() throws Exception {
+ final String code = getAboveComment();
+ parseAndCheckBindings(code, ParserLanguage.CPP);
+ }
+
+ // void f(int t);
+ // void f(unsigned int t);
+ // void f(long t);
+ //
+ // enum IntEnum { i1 };
+ // enum UnsignedEnum { u1 = 0x7FFFFFFF, u2 };
+ // enum LongEnum { l1 = -1, l2 = 0x7FFFFFFF, l3 };
+ //
+ // void test() {
+ // f(i1);
+ // f(u1);
+ // f(l1);
+ // }
+ 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());
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTEnumerator.java
index d774d55cbf3..cd3a25b91ef 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTEnumerator.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTEnumerator.java
@@ -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) {
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 c6cdc8ad0b9..bfadd7b1814 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,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;
+ }
+ }
}

Back to the top