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 3e024b0ab8d..a94f70ff3b0 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 @@ -139,6 +139,7 @@ import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethod; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; @@ -7233,6 +7234,134 @@ public class AST2CPPTests extends AST2TestBase { ba.assertNonProblem("f(!p)", 1); } + // template + // struct A { + // enum { + // e1 = 0, + // e2 = int(e1) + // }; + // }; + // + // template::e2> + // struct B; + // + // template + // struct B { + // void waldo(); + // }; + // + // void test(B& p) { + // p.waldo(); + // } + public void testDependentEnumeration_446711a() throws Exception { + parseAndCheckBindings(); + } + + // constexpr int f(int p) { return p; } + // constexpr long f(long p) { return p + 0x100000000L; } + // + // template + // struct A { + // enum { + // e1 = 0, + // e2 = f(e1) + // }; + // }; + // + // template::e2> + // struct B; + // + // template + // struct B { + // void waldo(); + // }; + // + // void test(B& p) { + // p.waldo(); + // } + public void testDependentEnumeration_446711b() throws Exception { + parseAndCheckBindings(); + } + + // constexpr int f(long p) { return p; } + // constexpr long f(int p) { return p + 0x100000000L; } + // + // template + // struct A { + // enum { + // e1 = 0L, + // e2 = f(e1) + // }; + // }; + // + // template::e2> + // struct B; + // + // template + // struct B { + // void waldo(); + // }; + // + // void test(B& p) { + // p.waldo(); + // } + public void testDependentEnumeration_446711c() throws Exception { + parseAndCheckBindings(); + } + + // constexpr int f(int p) { return p; } + // constexpr long f(long p) { return p + 0x100000000L; } + // + // template + // struct A { + // enum { + // e1 = v, + // e2 = f(e1) + // }; + // }; + // + // template::e2> + // struct B; + // + // template + // struct B { + // void waldo(); + // }; + // + // void test(B& p) { + // p.waldo(); + // } + public void _testDependentEnumeration_446711d() throws Exception { + parseAndCheckBindings(); + } + + // constexpr int f(int p) { return p; } + // constexpr long f(long p) { return p + 0x100000000L; } + // + // template + // struct A { + // enum { + // e1 = v, + // e2 = f(e1) + // }; + // }; + // + // template::e2> + // struct B; + // + // template + // struct B { + // void waldo(); + // }; + // + // void test(B& p) { + // p.waldo(); + // } + public void _testDependentEnumeration_446711e() throws Exception { + BindingAssertionHelper helper = getAssertionHelper(); + helper.assertProblemOnFirstIdentifier(".waldo()"); + } + // class S { // S(int); // }; @@ -8862,7 +8991,7 @@ public class AST2CPPTests extends AST2TestBase { bh.assertProblem("xl;", -1); } - // void f(int); + // constexpr int f(int); // enum class X {e1, e2= e1+2, e3}; // enum class Y {e1, e2= f(e1)+2, e3}; // enum A {e1, e2= e1+2, e3}; @@ -10634,15 +10763,15 @@ public class AST2CPPTests extends AST2TestBase { public void testUnderlyingTypeBuiltin_411196() throws Exception { BindingAssertionHelper helper = getAssertionHelper(); - assertSameType((ITypedef) helper.assertNonProblem("short1_type"), CPPVisitor.SHORT_TYPE); - assertSameType((ITypedef) helper.assertNonProblem("short2_type"), CPPVisitor.SHORT_TYPE); + assertSameType((ITypedef) helper.assertNonProblem("short1_type"), CPPBasicType.SHORT); + assertSameType((ITypedef) helper.assertNonProblem("short2_type"), CPPBasicType.SHORT); - assertSameType((ITypedef) helper.assertNonProblem("scoped_type"), CPPVisitor.INT_TYPE); + assertSameType((ITypedef) helper.assertNonProblem("scoped_type"), CPPBasicType.INT); - assertSameType((ITypedef) helper.assertNonProblem("unsigned_type"), CPPVisitor.UNSIGNED_INT); - assertSameType((ITypedef) helper.assertNonProblem("int_type"), CPPVisitor.INT_TYPE); - assertSameType((ITypedef) helper.assertNonProblem("ulong_type"), CPPVisitor.UNSIGNED_LONG); - assertSameType((ITypedef) helper.assertNonProblem("loong_type"), CPPVisitor.LONG_TYPE); + assertSameType((ITypedef) helper.assertNonProblem("unsigned_type"), CPPBasicType.UNSIGNED_INT); + assertSameType((ITypedef) helper.assertNonProblem("int_type"), CPPBasicType.INT); + assertSameType((ITypedef) helper.assertNonProblem("ulong_type"), CPPBasicType.UNSIGNED_LONG); + assertSameType((ITypedef) helper.assertNonProblem("loong_type"), CPPBasicType.LONG); } // namespace A { diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexGPPBindingResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexGPPBindingResolutionTest.java index a642cdfb82b..535b13aa0c7 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexGPPBindingResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexGPPBindingResolutionTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013 Nathan Ridge. + * Copyright (c) 2013, 2014 Nathan Ridge. * 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 @@ -10,12 +10,12 @@ *******************************************************************************/ package org.eclipse.cdt.internal.index.tests; +import junit.framework.TestSuite; + import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage; import org.eclipse.cdt.core.testplugin.TestScannerProvider; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; - -import junit.framework.TestSuite; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; /** * For testing resolution of bindings in C++ code with GNU extensions. @@ -107,14 +107,14 @@ public abstract class IndexGPPBindingResolutionTest extends IndexBindingResoluti // typedef underlying_type::type ulong_type; // typedef underlying_type::type loong_type; public void testUnderlyingTypeBuiltin_bug411196() throws Exception { - assertSameType((ITypedef) getBindingFromASTName("short1_type", 0), CPPVisitor.SHORT_TYPE); - assertSameType((ITypedef) getBindingFromASTName("short2_type", 0), CPPVisitor.SHORT_TYPE); + assertSameType((ITypedef) getBindingFromASTName("short1_type", 0), CPPBasicType.SHORT); + assertSameType((ITypedef) getBindingFromASTName("short2_type", 0), CPPBasicType.SHORT); - assertSameType((ITypedef) getBindingFromASTName("scoped_type", 0), CPPVisitor.INT_TYPE); + assertSameType((ITypedef) getBindingFromASTName("scoped_type", 0), CPPBasicType.INT); - assertSameType((ITypedef) getBindingFromASTName("unsigned_type", 0), CPPVisitor.UNSIGNED_INT); - assertSameType((ITypedef) getBindingFromASTName("int_type", 0), CPPVisitor.INT_TYPE); - assertSameType((ITypedef) getBindingFromASTName("ulong_type", 0), CPPVisitor.UNSIGNED_LONG); - assertSameType((ITypedef) getBindingFromASTName("loong_type", 0), CPPVisitor.LONG_TYPE); + assertSameType((ITypedef) getBindingFromASTName("unsigned_type", 0), CPPBasicType.UNSIGNED_INT); + assertSameType((ITypedef) getBindingFromASTName("int_type", 0), CPPBasicType.INT); + assertSameType((ITypedef) getBindingFromASTName("ulong_type", 0), CPPBasicType.UNSIGNED_LONG); + assertSameType((ITypedef) getBindingFromASTName("loong_type", 0), CPPBasicType.LONG); } } 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 64b910d26e1..2a7cbab91a8 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2013 Wind River Systems, Inc. and others. + * Copyright (c) 2008, 2014 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 @@ -12,12 +12,20 @@ package org.eclipse.cdt.internal.core.dom.parser; import org.eclipse.cdt.core.dom.ast.ASTVisitor; -import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBasicType; +import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTEnumerationSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPEnumerator; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; /** * Base class for C and C++ enumerators. @@ -113,9 +121,9 @@ public abstract class ASTEnumerator extends ASTNode implements IASTEnumerator, I if (integralValue == null) { IASTNode parent= getParent(); if (parent instanceof IASTInternalEnumerationSpecifier) { - IASTInternalEnumerationSpecifier ies= (IASTInternalEnumerationSpecifier) parent; - if (ies.startValueComputation()) { // Prevent infinite recursion. - createEnumValues((IASTEnumerationSpecifier) parent); + IASTInternalEnumerationSpecifier enumeration= (IASTInternalEnumerationSpecifier) parent; + if (enumeration.startValueComputation()) { // Prevent infinite recursion. + computeEnumValues(enumeration); } } if (integralValue == null) { @@ -125,28 +133,104 @@ public abstract class ASTEnumerator extends ASTNode implements IASTEnumerator, I return integralValue; } - private void createEnumValues(IASTEnumerationSpecifier parent) { - IValue previousExplicitValue = null; - int delta = 0; - IASTEnumerator[] etors= parent.getEnumerators(); - for (IASTEnumerator etor : etors) { - IValue val; - IASTExpression expr= etor.getValue(); - if (expr != null) { - val= Value.create(expr, Value.MAX_RECURSION_DEPTH); - previousExplicitValue = val; - delta = 1; - } else { - if (previousExplicitValue != null) { - val = Value.incrementedValue(previousExplicitValue, delta); - } else { - val = Value.create(delta); + private static void computeEnumValues(IASTInternalEnumerationSpecifier enumeration) { + try { + IType fixedType = null; + if (enumeration instanceof ICPPASTEnumerationSpecifier) { + IBinding binding = enumeration.getName().resolveBinding(); + if (binding instanceof ICPPEnumeration) { + fixedType = ((ICPPEnumeration) binding).getFixedType(); } - delta++; } - if (etor instanceof ASTEnumerator) { - ((ASTEnumerator) etor).integralValue= val; + IType type = fixedType == null ? CPPBasicType.INT : null; + IValue previousExplicitValue = null; + int delta = 0; + IASTEnumerator[] etors= enumeration.getEnumerators(); + for (IASTEnumerator etor : etors) { + IBinding etorBinding = etor.getName().resolveBinding(); + IValue val; + IASTExpression expr= etor.getValue(); + if (expr != null) { + val= Value.create(expr, Value.MAX_RECURSION_DEPTH); + previousExplicitValue = val; + delta = 1; + if (fixedType == null) { + type = expr.getExpressionType(); + type = SemanticUtil.getNestedType(type, SemanticUtil.CVTYPE | SemanticUtil.TDEF); + if (etorBinding instanceof CPPEnumerator) { + ((CPPEnumerator) etorBinding).setInternalType(type); + } + } + } else { + if (previousExplicitValue != null) { + val = Value.incrementedValue(previousExplicitValue, delta); + } else { + val = Value.create(delta); + } + delta++; + if (fixedType == null && type instanceof IBasicType) { + type = getTypeOfIncrementedValue((IBasicType) type, val); + if (etorBinding instanceof CPPEnumerator) { + ((CPPEnumerator) etorBinding).setInternalType(type); + } + } + } + if (etor instanceof ASTEnumerator) { + ((ASTEnumerator) etor).integralValue= val; + } } + } finally { + enumeration.finishValueComputation(); } } + + /** + * [dcl.enum] 7.2-5: + * "... the type of the initializing value is the same as the type of the initializing value of + * the preceding enumerator unless the incremented value is not representable in that type, in + * which case the type is an unspecified integral type sufficient to contain the incremented + * value. If no such type exists, the program is ill-formed." + * + * @param type the type of the previous value + * @param val the incremented value + * @return the type of the incremented value + */ + public static IBasicType getTypeOfIncrementedValue(IBasicType type, IValue val) { + Long numericalValue = val.numericalValue(); + if (numericalValue != null) { + long longValue = numericalValue.longValue(); + if ((type.getKind() != Kind.eInt && type.getKind() != Kind.eInt128) || + type.isShort()) { + type = type.isUnsigned() ? CPPBasicType.UNSIGNED_INT : CPPBasicType.INT; + } + if (!ArithmeticConversion.fitsIntoType(type, longValue)) { + if (!type.isUnsigned()) { + if (type.getKind() != Kind.eInt128) { + if (type.isLongLong()) { + type = CPPBasicType.UNSIGNED_INT128; + } else if (type.isLong()) { + type = CPPBasicType.UNSIGNED_LONG_LONG; + } else { + type = CPPBasicType.UNSIGNED_LONG; + } + } + } else { + if (type.getKind() == Kind.eInt128) { + if (longValue >= 0) { + type = CPPBasicType.UNSIGNED_INT128; + } + } else { + if (type.isLongLong()) { + type = CPPBasicType.INT128; + } else if (type.isLong()) { + type = CPPBasicType.LONG_LONG; + } else { + type = CPPBasicType.LONG; + } + } + } + } + } + return type; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java index 8024045af06..688df89f853 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2012 Wind River Systems, Inc. and others. + * Copyright (c) 2009, 2014 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 @@ -19,7 +19,6 @@ import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IType; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; @@ -196,7 +195,7 @@ public abstract class ArithmeticConversion { return unsignedType; } - // the signed has the higher rank + // The signed has the higher rank. if (signedRank.ordinal() > unsignedRank.ordinal()) { return signedType; } @@ -227,7 +226,7 @@ public abstract class ArithmeticConversion { return createBasicType(Kind.eInt, domain.getModifier()); case eChar32: - // Assuming 32 bits + // Assuming 32 bits. return createBasicType(Kind.eInt, domain.getModifier() | IBasicType.IS_UNSIGNED); case eInt: @@ -332,7 +331,7 @@ public abstract class ArithmeticConversion { } } - public static boolean fitsIntoType(ICPPBasicType basicTarget, long n) { + public static boolean fitsIntoType(IBasicType basicTarget, long n) { final Kind kind = basicTarget.getKind(); switch (kind) { case eInt: @@ -372,9 +371,9 @@ public abstract class ArithmeticConversion { } /** - * Make a best-effort guess at the sizeof() of an integral type. + * Makes a best-effort guess at the sizeof() of an integral type. */ - private static long getApproximateSize(ICPPBasicType type) { + private static long getApproximateSize(IBasicType type) { switch (type.getKind()) { case eChar: return 1; case eWChar: return 2; @@ -396,12 +395,13 @@ public abstract class ArithmeticConversion { /** * Checks whether a target integral type can represent all values of a source integral type. + * * @param target the target integral type * @param source the source integral type * @param point point for sizeof lookup * @return whether the target integral type can represent all values of the source integral type */ - public static boolean fitsIntoType(ICPPBasicType target, ICPPBasicType source, IASTNode point) { + public static boolean fitsIntoType(IBasicType target, IBasicType source, IASTNode point) { // A boolean cannot represent any other type. if (target.getKind() == Kind.eBoolean && source.getKind() != Kind.eBoolean) return false; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTInternalEnumerationSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTInternalEnumerationSpecifier.java index 90ae59b2811..df2bf5e32e1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTInternalEnumerationSpecifier.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTInternalEnumerationSpecifier.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2011 Wind River Systems, Inc. and others. + * Copyright (c) 2008, 2014 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 @@ -7,6 +7,7 @@ * * Contributors: * Markus Schorn - initial API and implementation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser; @@ -17,10 +18,20 @@ import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier; */ public interface IASTInternalEnumerationSpecifier extends IASTEnumerationSpecifier { /** - * Notifies that the value computation for the enumeration has started. Returns whether this is - * the first attempt to do so. + * Notifies that the value computation for the enumeration has started. + * Returns {@code true} if this is the first attempt to do so. */ boolean startValueComputation(); + + /** + * Notifies that the value computation for the enumeration has finished. + */ + void finishValueComputation(); + + /** + * Returns {@code true} if the value computation has started but hasn't finished yet. + */ + boolean isValueComputationInProgress(); /** * @since 5.1 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/SizeofCalculator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/SizeofCalculator.java index 387da41ee83..7ad41a90f8e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/SizeofCalculator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/SizeofCalculator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011, 2013 Google, Inc and others. + * Copyright (c) 2011, 2014 Google, 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 @@ -30,12 +30,12 @@ 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.ICPPClassType; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeTraits; /** * Calculator of in-memory size and alignment of types. @@ -85,7 +85,7 @@ public class SizeofCalculator { * @param type the type to get size and alignment for. * @param point a node belonging to the AST of the translation unit defining context for * the size calculation. - * @return size and alignment, or null if could not be calculated. + * @return size and alignment, or {@code null} if could not be calculated. */ public static SizeAndAlignment getSizeAndAlignment(IType type, IASTNode point) { SizeofCalculator calc = point == null ? @@ -173,7 +173,7 @@ public class SizeofCalculator { /** * Calculates size and alignment for the given type. * @param type the type to get size and alignment for. - * @return size and alignment, or null if could not be calculated. + * @return size and alignment, or {@code null} if could not be calculated. */ public SizeAndAlignment sizeAndAlignment(IType type) { type = SemanticUtil.getNestedType(type, SemanticUtil.CVTYPE | SemanticUtil.TDEF); @@ -183,8 +183,8 @@ public class SizeofCalculator { if (type instanceof IBasicType) { return sizeAndAlignment((IBasicType) type); } - // [expr.sizeof]/2: "When applied to a reference or a reference type, the - // result is the size of the referenced type." + // [expr.sizeof]/2: "When applied to a reference or a reference type, + // the result is the size of the referenced type." if (type instanceof ICPPReferenceType) { return sizeAndAlignment(((ICPPReferenceType) type).getType()); } @@ -207,7 +207,7 @@ public class SizeofCalculator { /** * Returns size and alignment of pointer types. - * @return size and alignment of pointer types, or null if unknown. + * @return size and alignment of pointer types, or {@code null} if unknown. */ public SizeAndAlignment sizeAndAlignmentOfPointer() { return sizeof_pointer; @@ -247,24 +247,11 @@ public class SizeofCalculator { } private SizeAndAlignment sizeAndAlignment(IEnumeration type) { - if (type instanceof ICPPEnumeration) { - IType fixedType = ((ICPPEnumeration) type).getFixedType(); - if (fixedType != null) { - return sizeAndAlignment(fixedType); - } + IType underlyingType = TypeTraits.underlyingType(type); + if (underlyingType instanceof IBasicType) { + return sizeAndAlignment((IBasicType) underlyingType); } - long range = Math.max(Math.abs(type.getMinValue()) - 1, Math.abs(type.getMaxValue())); - if (range >= (2 << 32)) - return size_8; - if (type.getMinValue() < 0) - range *= 2; - if (range >= (2 << 32)) - return size_8; - if (range >= (2 << 16)) - return size_4; - if (range >= (2 << 8)) - return size_2; - return SIZE_1; + return null; } private SizeAndAlignment sizeAndAlignment(IArrayType type) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTEnumerationSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTEnumerationSpecifier.java index ac6316af847..c4590f8180a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTEnumerationSpecifier.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTEnumerationSpecifier.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2011 IBM Corporation and others. + * Copyright (c) 2005, 2014 IBM Corporation 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 @@ -9,6 +9,7 @@ * John Camelon (IBM Rational Software) - Initial API and implementation * Markus Schorn (Wind River Systems) * Yuan Zhang / Beth Tibbitts (IBM Research) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.c; @@ -23,9 +24,11 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTInternalEnumerationSpecifier */ public class CASTEnumerationSpecifier extends CASTBaseDeclSpecifier implements IASTInternalEnumerationSpecifier, ICASTEnumerationSpecifier { - private IASTName name; - private boolean valuesComputed; - + private IASTName fName; + private Boolean fValuesComputed; + private IASTEnumerator[] fEnumerators = IASTEnumerator.EMPTY_ENUMERATOR_ARRAY; + private int fNumEnumerators; + public CASTEnumerationSpecifier() { } @@ -45,7 +48,7 @@ public class CASTEnumerationSpecifier extends CASTBaseDeclSpecifier } protected T copy(T copy, CopyStyle style) { - copy.setName(name == null ? null : name.copy(style)); + copy.setName(fName == null ? null : fName.copy(style)); for (IASTEnumerator enumerator : getEnumerators()) { copy.addEnumerator(enumerator == null ? null : enumerator.copy(style)); } @@ -54,38 +57,43 @@ public class CASTEnumerationSpecifier extends CASTBaseDeclSpecifier @Override public boolean startValueComputation() { - if (valuesComputed) + if (fValuesComputed != null) return false; - valuesComputed= true; + fValuesComputed= Boolean.FALSE; return true; } + @Override + public void finishValueComputation() { + fValuesComputed= Boolean.TRUE; + } + + @Override + public boolean isValueComputationInProgress() { + return fValuesComputed != null && !fValuesComputed; + } + @Override public void addEnumerator(IASTEnumerator enumerator) { assertNotFrozen(); if (enumerator != null) { enumerator.setParent(this); enumerator.setPropertyInParent(ENUMERATOR); - enumerators = ArrayUtil.appendAt(IASTEnumerator.class, enumerators, ++enumeratorsPos, enumerator); + fEnumerators = ArrayUtil.appendAt(fEnumerators, fNumEnumerators++, enumerator); } } @Override public IASTEnumerator[] getEnumerators() { - if (enumerators == null) return IASTEnumerator.EMPTY_ENUMERATOR_ARRAY; - enumerators = ArrayUtil.trimAt(IASTEnumerator.class, enumerators, enumeratorsPos); - return enumerators; + fEnumerators = ArrayUtil.trim(fEnumerators, fNumEnumerators); + return fEnumerators; } - private IASTEnumerator [] enumerators = null; - private int enumeratorsPos = -1; - - @Override public void setName(IASTName name) { assertNotFrozen(); - this.name = name; + this.fName = name; if (name != null) { name.setParent(this); name.setPropertyInParent(ENUMERATION_NAME); @@ -94,7 +102,7 @@ public class CASTEnumerationSpecifier extends CASTBaseDeclSpecifier @Override public IASTName getName() { - return name; + return fName; } @Override @@ -106,7 +114,7 @@ public class CASTEnumerationSpecifier extends CASTBaseDeclSpecifier default: break; } } - if (name != null && !name.accept(action)) + if (fName != null && !fName.accept(action)) return false; IASTEnumerator[] etors = getEnumerators(); for (int i = 0; i < etors.length; i++) { @@ -125,7 +133,7 @@ public class CASTEnumerationSpecifier extends CASTBaseDeclSpecifier @Override public int getRoleForName(IASTName n) { - if (this.name == n) + if (this.fName == n) return r_definition; return r_unclear; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTEnumerationSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTEnumerationSpecifier.java index 6424e2d816c..2793df0597e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTEnumerationSpecifier.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTEnumerationSpecifier.java @@ -9,6 +9,7 @@ * John Camelon (IBM) - Initial API and implementation * Markus Schorn (Wind River Systems) * Thomas Corbat (IFS) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -21,7 +22,7 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.parser.IASTInternalEnumerationSpecifier; /** - * AST node for c++ enumeration specifiers. + * AST node for C++ enumeration specifiers. */ public class CPPASTEnumerationSpecifier extends CPPASTBaseDeclSpecifier implements IASTInternalEnumerationSpecifier, ICPPASTEnumerationSpecifier { @@ -30,10 +31,10 @@ public class CPPASTEnumerationSpecifier extends CPPASTBaseDeclSpecifier private IASTName fName; private ICPPASTDeclSpecifier fBaseType; - private IASTEnumerator[] fItems; - private int fItemPos= -1; + private IASTEnumerator[] fEnumerators = IASTEnumerator.EMPTY_ENUMERATOR_ARRAY; + private int fNumEnumerators; - private boolean fValuesComputed; + private Boolean fValuesComputed; private CPPEnumScope fScope; public CPPASTEnumerationSpecifier() { @@ -64,30 +65,37 @@ public class CPPASTEnumerationSpecifier extends CPPASTBaseDeclSpecifier @Override public boolean startValueComputation() { - if (fValuesComputed) + if (fValuesComputed != null) return false; - fValuesComputed= true; + fValuesComputed= Boolean.FALSE; return true; } + @Override + public void finishValueComputation() { + fValuesComputed= Boolean.TRUE; + } + + @Override + public boolean isValueComputationInProgress() { + return fValuesComputed != null && !fValuesComputed; + } + @Override public void addEnumerator(IASTEnumerator enumerator) { assertNotFrozen(); if (enumerator != null) { enumerator.setParent(this); enumerator.setPropertyInParent(ENUMERATOR); - fItems = ArrayUtil.appendAt( IASTEnumerator.class, fItems, ++fItemPos, enumerator ); + fEnumerators = ArrayUtil.appendAt(fEnumerators, fNumEnumerators++, enumerator); } } @Override public IASTEnumerator[] getEnumerators() { - if (fItems == null) - return IASTEnumerator.EMPTY_ENUMERATOR_ARRAY; - - fItems = ArrayUtil.trimAt(IASTEnumerator.class, fItems, fItemPos); - return fItems; + fEnumerators = ArrayUtil.trim(fEnumerators, fNumEnumerators); + return fEnumerators; } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBasicType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBasicType.java index b448baf4c3c..742c307c6a4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBasicType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBasicType.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2012 IBM Corporation and others. + * Copyright (c) 2004, 2014 IBM Corporation 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 @@ -31,11 +31,22 @@ import org.eclipse.core.runtime.CoreException; * Built-in c++ type. */ public class CPPBasicType implements ICPPBasicType, ISerializableType { - private static final int FROM_STRING_LITERAL = 1 << 31; public static final CPPBasicType BOOLEAN = new CPPBasicType(Kind.eBoolean, 0, null); public static final CPPBasicType NULL_PTR = new CPPBasicType(Kind.eNullPtr, 0, null); public static final CPPBasicType UNSPECIFIED_TYPE = new CPPBasicType(Kind.eUnspecified, 0); - + public static final CPPBasicType SHORT = new CPPBasicType(Kind.eInt, IBasicType.IS_SHORT); + public static final CPPBasicType INT = new CPPBasicType(Kind.eInt, 0); + public static final CPPBasicType LONG = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG); + public static final CPPBasicType LONG_LONG = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG_LONG); + public static final CPPBasicType INT128 = new CPPBasicType(Kind.eInt128, 0); + public static final CPPBasicType UNSIGNED_SHORT = new CPPBasicType(Kind.eInt, IBasicType.IS_SHORT | IBasicType.IS_UNSIGNED); + public static final CPPBasicType UNSIGNED_INT = new CPPBasicType(Kind.eInt, IBasicType.IS_UNSIGNED); + public static final CPPBasicType UNSIGNED_LONG = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG | IBasicType.IS_UNSIGNED); + public static final CPPBasicType UNSIGNED_LONG_LONG = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG_LONG | IBasicType.IS_UNSIGNED); + public static final CPPBasicType UNSIGNED_INT128 = new CPPBasicType(Kind.eInt128, IBasicType.IS_UNSIGNED); + + private static final int FROM_STRING_LITERAL = 1 << 31; + private final Kind fKind; private final int fModifiers; private Long fAssociatedValue; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java index aefcbfff50e..e6e8040aa2d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013 Nathan Ridge and others. + * Copyright (c) 2013, 2014 Nathan Ridge 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 @@ -8,6 +8,7 @@ * Contributors: * Nathan Ridge - Initial API and implementation * Marc-Andre Laperle (Ericsson) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -99,13 +100,12 @@ public class CPPEnumerationSpecialization extends CPPSpecialization implements I return enumerator; } - // The specialized enumerators are already computed, just need - // to look up the right one. + // The specialized enumerators are already computed, just need to look up the right one. IEnumerator[] unspecializedEnumerators = getSpecializedBinding().getEnumerators(); for (int i = 0; i < fEnumerators.length; ++i) { if (enumerator.equals(unspecializedEnumerators[i])) return fEnumerators[i]; } - return null; + return enumerator; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerator.java index e6faff54cc9..e782ee83bbf 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2010 IBM Corporation and others. + * Copyright (c) 2004, 2014 IBM Corporation 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 @@ -8,32 +8,36 @@ * Contributors: * Andrew Niefer (IBM Corporation) - initial API and implementation * Markus Schorn (Wind River Systems) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.DOMException; -import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; -import org.eclipse.cdt.core.dom.ast.IEnumerator; 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.cpp.ICPPBlockScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.parser.ASTEnumerator; +import org.eclipse.cdt.internal.core.dom.parser.IASTInternalEnumerationSpecifier; +import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.core.runtime.PlatformObject; /** - * Binding for a c++ enumerator. + * Binding for a C++ enumerator. */ -public class CPPEnumerator extends PlatformObject implements IEnumerator, ICPPInternalBinding { +public class CPPEnumerator extends PlatformObject + implements ICPPInternalEnumerator, ICPPInternalBinding { private IASTName enumName; + private IType internalType; /** * @param enumerator @@ -75,10 +79,38 @@ public class CPPEnumerator extends PlatformObject implements IEnumerator, ICPPIn @Override public IType getType() { IASTEnumerator etor = (IASTEnumerator) enumName.getParent(); - IASTEnumerationSpecifier enumSpec = (IASTEnumerationSpecifier) etor.getParent(); + IASTInternalEnumerationSpecifier enumSpec = (IASTInternalEnumerationSpecifier) etor.getParent(); + if (enumSpec.isValueComputationInProgress()) { + // During value computation enumerators can be referenced only by initializer + // expressions of other enumerators of the same enumeration. Return the internal type + // of the enumerator ([dcl.enum] 7.2-5). + if (internalType != null) + return internalType; + ICPPEnumeration binding = (ICPPEnumeration) enumSpec.getName().resolveBinding(); + IType fixedType = binding.getFixedType(); + return fixedType != null ? fixedType : ProblemType.UNKNOWN_FOR_EXPRESSION; + } return (IType) enumSpec.getName().resolveBinding(); } + @Override + public IType getInternalType() { + if (internalType == null) { + getValue(); // Trigger value and internal type computation. + } + return internalType; + } + + /** + * Sets the internal type of the enumerator. The enumerator has this type between the opening + * and the closing braces of the enumeration ([dcl.enum] 7.2-5). + * + * @param type the integral type of the enumerator's initializing value + */ + public void setInternalType(IType type) { + internalType = type; + } + @Override public String[] getQualifiedName() { return CPPVisitor.getQualifiedName(this); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeratorSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeratorSpecialization.java index b3c3ca4516e..9986671700b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeratorSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeratorSpecialization.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013 Nathan Ridge. + * Copyright (c) 2013, 2014 Nathan Ridge. * 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 @@ -7,6 +7,7 @@ * * Contributors: * Nathan Ridge - Initial API and implementation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -19,13 +20,15 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; /** * Binding for a specialization of an enumerator. */ -public class CPPEnumeratorSpecialization extends CPPSpecialization implements IEnumerator { +public class CPPEnumeratorSpecialization extends CPPSpecialization implements ICPPInternalEnumerator { private final IValue fValue; + private final IType fInternalType; public CPPEnumeratorSpecialization(IEnumerator specialized, ICPPEnumerationSpecialization owner, - ICPPTemplateParameterMap argumentMap, IValue value) { + ICPPTemplateParameterMap argumentMap, IValue value, IType internalType) { super(specialized, owner, argumentMap); fValue = value; + fInternalType = internalType; } @Override @@ -42,4 +45,9 @@ public class CPPEnumeratorSpecialization extends CPPSpecialization implements IE public IValue getValue() { return fValue; } + + @Override + public IType getInternalType() { + return fInternalType; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalEnumerator.java new file mode 100644 index 00000000000..3cb8e8fc89e --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalEnumerator.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2014 Google, 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: + * Sergey Prigogin (Google) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.core.dom.ast.IType; + +/** + * Non API methods for C++ enumerators. + */ +public interface ICPPInternalEnumerator extends IEnumerator { + /** + * Returns the internal type of the enumerator. The enumerator has this type between the opening + * and the closing braces of the enumeration ([dcl.enum] 7.2-5). + * + * @param type the integral type of the enumerator's initializing value + */ + IType getInternalType(); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 59986c798a3..408fe5aea02 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -42,6 +42,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTTypeId; 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.IEnumerator; import org.eclipse.cdt.core.dom.ast.IFunctionType; @@ -106,6 +107,7 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArraySet; import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode; +import org.eclipse.cdt.internal.core.dom.parser.ASTEnumerator; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope; @@ -116,6 +118,7 @@ import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPAliasTemplateInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArrayType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassTemplatePartialSpecialization; @@ -161,6 +164,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalClassTemplate; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalEnumerator; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownMember; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownMemberClass; @@ -958,22 +962,7 @@ public class CPPTemplates { IType type= instantiateType(aliasTemplate.getType(), tpMap, -1, getSpecializationContext(owner), point); spec = new CPPAliasTemplateInstance(decl.getNameCharArray(), aliasTemplate, type); } else if (decl instanceof ICPPEnumeration) { - ICPPClassSpecialization within = getSpecializationContext(owner); - ICPPEnumeration enumeration = (ICPPEnumeration) decl; - IType fixedType = instantiateType(enumeration.getFixedType(), tpMap, -1, within, point); - CPPEnumerationSpecialization specializedEnumeration = - new CPPEnumerationSpecialization(enumeration, owner, tpMap, fixedType); - IEnumerator[] enumerators = enumeration.getEnumerators(); - IEnumerator[] specializedEnumerators = new IEnumerator[enumerators.length]; - for (int i = 0; i < enumerators.length; ++i) { - IEnumerator enumerator = enumerators[i]; - IValue specializedValue = - instantiateValue(enumerator.getValue(), tpMap, -1, within, Value.MAX_RECURSION_DEPTH, point); - specializedEnumerators[i] = - new CPPEnumeratorSpecialization(enumerator, specializedEnumeration, tpMap, specializedValue); - } - specializedEnumeration.setEnumerators(specializedEnumerators); - spec = specializedEnumeration; + spec = instantiateEnumeration((ICPPEnumeration) decl, getSpecializationContext(owner), tpMap, point); } else if (decl instanceof IEnumerator) { IEnumerator enumerator = (IEnumerator) decl; ICPPEnumeration enumeration = (ICPPEnumeration) enumerator.getOwner(); @@ -1008,6 +997,38 @@ public class CPPTemplates { return spec; } + private static IBinding instantiateEnumeration(ICPPEnumeration enumeration, ICPPClassSpecialization within, + final ICPPTemplateParameterMap tpMap, IASTNode point) { + IType fixedType = instantiateType(enumeration.getFixedType(), tpMap, -1, within, point); + CPPEnumerationSpecialization specializedEnumeration = + new CPPEnumerationSpecialization(enumeration, within, tpMap, fixedType); + IEnumerator[] enumerators = enumeration.getEnumerators(); + IEnumerator[] specializedEnumerators = new IEnumerator[enumerators.length]; + specializedEnumeration.setEnumerators(specializedEnumerators); + IType previousInternalType = CPPBasicType.INT; + for (int i = 0; i < enumerators.length; ++i) { + IEnumerator enumerator = enumerators[i]; + IValue specializedValue = + instantiateValue(enumerator.getValue(), tpMap, -1, within, Value.MAX_RECURSION_DEPTH, point); + IType internalType = null; + if (fixedType == null && enumerator instanceof ICPPInternalEnumerator) { + internalType = ((ICPPInternalEnumerator) enumerator).getInternalType(); + if (internalType != null) { + internalType = instantiateType(internalType, tpMap, -1, within, point); + } else { + if (previousInternalType instanceof IBasicType) { + internalType = ASTEnumerator.getTypeOfIncrementedValue((IBasicType) previousInternalType, specializedValue); + } } + if (internalType != null) { + previousInternalType = internalType; + } + } + specializedEnumerators[i] = new CPPEnumeratorSpecialization(enumerator, + specializedEnumeration, tpMap, specializedValue, internalType); + } + return specializedEnumeration; + } + private static ICPPClassSpecialization getSpecializationContext(IBinding owner) { if (!(owner instanceof ICPPClassSpecialization)) return null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index e7633f5a959..d989bebf7f3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -81,7 +81,6 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IBasicType; -import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.IEnumeration; @@ -227,18 +226,6 @@ import org.eclipse.cdt.internal.core.index.IIndexScope; * Collection of methods to extract information from a C++ translation unit. */ public class CPPVisitor extends ASTQueries { - public static final CPPBasicType SHORT_TYPE = new CPPBasicType(Kind.eInt, IBasicType.IS_SHORT); - public static final CPPBasicType INT_TYPE = new CPPBasicType(Kind.eInt, 0); - public static final CPPBasicType LONG_TYPE = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG); - public static final CPPBasicType LONG_LONG_TYPE = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG_LONG); - public static final CPPBasicType INT128_TYPE = new CPPBasicType(Kind.eInt128, 0); - - public static final CPPBasicType UNSIGNED_SHORT = new CPPBasicType(Kind.eInt, IBasicType.IS_SHORT | IBasicType.IS_UNSIGNED); - public static final CPPBasicType UNSIGNED_INT = new CPPBasicType(Kind.eInt, IBasicType.IS_UNSIGNED); - public static final CPPBasicType UNSIGNED_LONG = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG | IBasicType.IS_UNSIGNED); - public static final CPPBasicType UNSIGNED_LONG_LONG = new CPPBasicType(Kind.eInt, IBasicType.IS_LONG_LONG | IBasicType.IS_UNSIGNED); - public static final CPPBasicType UNSIGNED_INT128 = new CPPBasicType(Kind.eInt128, IBasicType.IS_UNSIGNED); - public static final String BEGIN_STR = "begin"; //$NON-NLS-1$ public static final char[] BEGIN = BEGIN_STR.toCharArray(); public static final char[] END = "end".toCharArray(); //$NON-NLS-1$ @@ -481,6 +468,13 @@ public class CPPVisitor extends ASTQueries { } return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION); } + // [dcl.enum] 7.2-5 + // "The underlying type can be explicitly specified using enum-base; + // if not explicitly specified, the underlying type of a scoped + // enumeration type is int." + if (fixedType == null && specifier.isScoped()) { + fixedType = CPPBasicType.INT; + } return new CPPEnumeration(specifier, fixedType); } @@ -2356,7 +2350,7 @@ public class CPPVisitor extends ASTQueries { public static IType getPointerDiffType(final IASTNode point) { IType t= getStdType(point, PTRDIFF_T); - return t != null ? t : LONG_TYPE; + return t != null ? t : CPPBasicType.LONG; } private static IType getStdType(final IASTNode node, char[] name) { @@ -2382,12 +2376,12 @@ public class CPPVisitor extends ASTQueries { public static IType get_type_info(IASTNode point) { IType t= getStdType(point, TYPE_INFO); - return t != null ? t : INT_TYPE; + return t != null ? t : CPPBasicType.INT; } public static IType get_SIZE_T(IASTNode sizeofExpr) { IType t= getStdType(sizeofExpr, SIZE_T); - return t != null ? t : UNSIGNED_LONG; + return t != null ? t : CPPBasicType.UNSIGNED_LONG; } public static ICPPClassTemplate get_initializer_list(IASTNode node) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java index 7f8581367f7..4b787fd356c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2013 Wind River Systems, Inc. and others. + * Copyright (c) 2012, 2014 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 @@ -20,6 +20,7 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType; import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; @@ -53,6 +54,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalEnumerator; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.core.runtime.CoreException; @@ -253,14 +255,13 @@ public class EvalID extends CPPDependentEvaluation { IType type= ((IEnumerator) binding).getType(); if (type instanceof ICPPEnumeration) { ICPPEnumeration enumType= (ICPPEnumeration) type; - if (enumType.asScope() == CPPVisitor.getContainingScope(expr)) { - // C++0x: 7.2-5 - type= enumType.getFixedType(); - if (type == null) { - // This is a simplification, the actual type is determined - // - in an implementation dependent manner - by the value - // of the enumerator. - type= CPPSemantics.INT_TYPE; + // [dcl.enum] 7.2-5 + if (isInsideEnum(expr, enumType)) { + if (binding instanceof ICPPInternalEnumerator) { + type = enumType.getFixedType(); + if (type == null) { + type = ((ICPPInternalEnumerator) binding).getInternalType(); + } } return new EvalBinding(binding, type, expr); } @@ -274,6 +275,17 @@ public class EvalID extends CPPDependentEvaluation { return EvalFixed.INCOMPLETE; } + /** + * Returns {@code true} if the given node is located inside the given enum. + */ + private static boolean isInsideEnum(IASTNode node, ICPPEnumeration enumBinding) { + IASTEnumerator enumeratorNode = CPPVisitor.findAncestorWithType(node, IASTEnumerator.class); + if (enumeratorNode == null) + return false; + IBinding enumerator = enumeratorNode.getName().getBinding(); + return enumerator != null && enumBinding == enumerator.getOwner(); + } + private static IType withinNonStaticMethod(IASTExpression expr) { IASTNode parent= expr.getParent(); while (parent != null && !(parent instanceof ICPPASTFunctionDefinition)) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeTraits.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeTraits.java index 81d1e595e6a..8ea0e108d7e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeTraits.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeTraits.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 Google, Inc and others. + * Copyright (c) 2012, 2014 Google, 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 @@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPUnaryTypeTransformation.Operator; import org.eclipse.cdt.core.dom.ast.cpp.SemanticQueries; import org.eclipse.cdt.internal.core.dom.parser.ArithmeticConversion; import org.eclipse.cdt.internal.core.dom.parser.ProblemType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnaryTypeTransformation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper.MethodKind; @@ -38,6 +39,19 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper.MethodKind; * A collection of static methods for determining type traits. */ public class TypeTraits { + private static final ICPPBasicType[] SIGNED_UNDERLYING_ENUM_TYPES = { + CPPBasicType.INT, + CPPBasicType.LONG, + CPPBasicType.LONG_LONG, + CPPBasicType.INT128 + }; + private static final ICPPBasicType[] UNSIGNED_UNDERLYING_ENUM_TYPES = { + CPPBasicType.UNSIGNED_INT, + CPPBasicType.UNSIGNED_LONG, + CPPBasicType.UNSIGNED_LONG_LONG, + CPPBasicType.UNSIGNED_INT128 + }; + private TypeTraits() {} /** @@ -342,17 +356,11 @@ public class TypeTraits { } else { ICPPEnumeration enumeration = (ICPPEnumeration) type; - // [dcl.enum] p5 - // "The underlying type can be explicitly specified using enum-base; - // if not explicitly specified, the underlying type of a scoped - // enumeration type is int." IType fixedType = enumeration.getFixedType(); if (fixedType != null) return fixedType; - if (enumeration.isScoped()) - return CPPVisitor.INT_TYPE; - // [dcl.enum] p6 + // [dcl.enum] 7.2-6: // "For an enumeration whose underlying type is not fixed, the // underlying type is an integral type that can represent all // the numerator values defined in the enumeration. ... It is @@ -363,28 +371,22 @@ public class TypeTraits { // the underlying type is as if the enumeration had a single // enumerator with value 0." if (enumeration.getEnumerators().length == 0) - return CPPVisitor.INT_TYPE; - if (enumeration.getMinValue() < 0 || enumeration.getMaxValue() < 0) { - return smallestFittingType(enumeration, - CPPVisitor.INT_TYPE, - CPPVisitor.LONG_TYPE, - CPPVisitor.LONG_LONG_TYPE, - CPPVisitor.INT128_TYPE); + return CPPBasicType.INT; + long minValue = enumeration.getMinValue(); + long maxValue = enumeration.getMaxValue(); + if (minValue < 0 || maxValue < 0) { + return smallestFittingType(minValue, maxValue, SIGNED_UNDERLYING_ENUM_TYPES); } else { - return smallestFittingType(enumeration, - CPPVisitor.UNSIGNED_INT, - CPPVisitor.UNSIGNED_LONG, - CPPVisitor.UNSIGNED_LONG_LONG, - CPPVisitor.UNSIGNED_INT128); + return smallestFittingType(minValue, maxValue, UNSIGNED_UNDERLYING_ENUM_TYPES); } } } - - private static IBasicType smallestFittingType(ICPPEnumeration enumeration, ICPPBasicType... types) { - for (int i = 0; i < types.length - 1; ++i) { - if (ArithmeticConversion.fitsIntoType(types[i], enumeration.getMinValue()) - && ArithmeticConversion.fitsIntoType(types[i], enumeration.getMaxValue())) { - return types[i]; + + private static IBasicType smallestFittingType(long minValue, long maxValue, ICPPBasicType[] types) { + for (ICPPBasicType type : types) { + if (ArithmeticConversion.fitsIntoType(type, minValue) + && ArithmeticConversion.fitsIntoType(type, maxValue)) { + return type; } } return types[types.length - 1]; // Assume it fits into the largest type provided. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java index ac013cae8ca..20c9c4e816d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java @@ -16,7 +16,6 @@ import org.eclipse.cdt.core.CCorePlugin; 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.IEnumerator; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IQualifierType; @@ -74,6 +73,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnaryTypeTransformation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalEnumerator; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownMember; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownMemberClass; @@ -578,8 +578,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { return new CompositeCPPUsingDeclarationSpecialization(this, (ICPPUsingDeclaration) binding); } else if (binding instanceof ICPPEnumeration) { return new CompositeCPPEnumerationSpecialization(this, (ICPPEnumeration) binding); - } else if (binding instanceof IEnumerator) { - return new CompositeCPPEnumeratorSpecialization(this, (IEnumerator) binding); + } else if (binding instanceof ICPPInternalEnumerator) { + return new CompositeCPPEnumeratorSpecialization(this, (ICPPInternalEnumerator) binding); } else { throw new CompositingNotImplementedError("Composite binding unavailable for " + binding + " " + binding.getClass()); //$NON-NLS-1$ //$NON-NLS-2$ } @@ -655,8 +655,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { result = def == null ? null : new CompositeCPPEnumeration(this, def); } else if (binding instanceof ICPPFunction) { result = new CompositeCPPFunction(this, (ICPPFunction) binding); - } else if (binding instanceof IEnumerator) { - result = new CompositeCPPEnumerator(this, (IEnumerator) binding); + } else if (binding instanceof ICPPInternalEnumerator) { + result = new CompositeCPPEnumerator(this, (ICPPInternalEnumerator) binding); } else if (binding instanceof ITypedef) { result = new CompositeCPPTypedef(this, (ICPPBinding) binding); } else if (binding instanceof IIndexMacroContainer) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumerator.java index e91a26ea793..2e633e20796 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumerator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumerator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2009 Symbian Software Systems and others. + * Copyright (c) 2007, 2014 Symbian Software Systems 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 @@ -7,32 +7,38 @@ * * Contributors: * Andrew Ferguson (Symbian) - Initial implementation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.index.composite.cpp; -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.internal.core.dom.parser.cpp.ICPPInternalEnumerator; import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; -class CompositeCPPEnumerator extends CompositeCPPBinding implements IEnumerator { - public CompositeCPPEnumerator(ICompositesFactory cf, IEnumerator rbinding) { +class CompositeCPPEnumerator extends CompositeCPPBinding implements ICPPInternalEnumerator { + public CompositeCPPEnumerator(ICompositesFactory cf, ICPPInternalEnumerator rbinding) { super(cf, rbinding); } @Override public IType getType() { - IType type = ((IEnumerator) rbinding).getType(); + IType type = ((ICPPInternalEnumerator) rbinding).getType(); return cf.getCompositeType(type); } @Override public IValue getValue() { - return ((IEnumerator) rbinding).getValue(); + return ((ICPPInternalEnumerator) rbinding).getValue(); } @Override public String toString() { return getName(); } + + @Override + public IType getInternalType() { + return ((ICPPInternalEnumerator) rbinding).getInternalType(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumeratorSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumeratorSpecialization.java index bc6ad7c1ec6..98e75dd3439 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumeratorSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumeratorSpecialization.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013 Google, Inc and others. + * Copyright (c) 2013, 2014 Google, 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 @@ -11,15 +11,15 @@ package org.eclipse.cdt.internal.core.index.composite.cpp; import org.eclipse.cdt.core.dom.ast.IBinding; -import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalEnumerator; import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; class CompositeCPPEnumeratorSpecialization extends CompositeCPPEnumerator implements ICPPSpecialization { - public CompositeCPPEnumeratorSpecialization(ICompositesFactory cf, IEnumerator delegate) { + public CompositeCPPEnumeratorSpecialization(ICompositesFactory cf, ICPPInternalEnumerator delegate) { super(cf, delegate); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index b0e2bb7a679..a5edefd302b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -251,11 +251,14 @@ public class PDOM extends PlatformObject implements IPDOM { * CDT 8.4 development (versions not supported on the 8.3.x branch) * 170.0 - Unconditionally store arguments of EvalTypeId, bug 430230. * 171.0 - Replacement headers for Organize Includes, bug 414692. - * 172.0 - Store default values for function parameters, bug 432701. + * #172.0# - Store default values for function parameters, bug 432701. <> + * + * CDT 8.6 development (versions not supported on the 8.5.x branch) + * 180.0 - Internal types of enumerators, bug 446711. */ - private static final int MIN_SUPPORTED_VERSION= version(172, 0); - private static final int MAX_SUPPORTED_VERSION= version(172, Short.MAX_VALUE); - private static final int DEFAULT_VERSION = version(172, 0); + private static final int MIN_SUPPORTED_VERSION= version(180, 0); + private static final int MAX_SUPPORTED_VERSION= version(180, Short.MAX_VALUE); + private static final int DEFAULT_VERSION = version(180, 0); private static int version(int major, int minor) { return (major << 16) + minor; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPEnumerator.java index ff2f767d2e1..2e71635919b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPEnumerator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPEnumerator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013 Google, Inc and others. + * Copyright (c) 2013, 2014 Google, 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 @@ -10,11 +10,11 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.cpp; -import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalEnumerator; import org.eclipse.cdt.internal.core.pdom.dom.IPDOMBinding; /** * Interface for a c++ enumerator stored in the index. */ -public interface IPDOMCPPEnumerator extends IEnumerator, IPDOMBinding { +public interface IPDOMCPPEnumerator extends ICPPInternalEnumerator, IPDOMBinding { } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java index 7a87448d77f..39470ea4a09 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java @@ -258,6 +258,6 @@ class PDOMCPPEnumerationSpecialization extends PDOMCPPSpecialization return i < enumerators.length ? enumerators[i] : enumerator; } } - return null; + return enumerator; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerator.java index 3e28624a9cd..89eb26525ba 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2013 QNX Software Systems and others. + * Copyright (c) 2006, 2014 QNX Software Systems 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 @@ -17,7 +17,9 @@ import org.eclipse.cdt.core.dom.ast.IBinding; 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.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.Value; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalEnumerator; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; import org.eclipse.cdt.internal.core.pdom.db.Database; @@ -30,14 +32,22 @@ import org.eclipse.core.runtime.CoreException; */ class PDOMCPPEnumerator extends PDOMCPPBinding implements IPDOMCPPEnumerator { private static final int VALUE= PDOMCPPBinding.RECORD_SIZE; + private static final int INTERNAL_TYPE= VALUE + Database.VALUE_SIZE; @SuppressWarnings("hiding") - protected static final int RECORD_SIZE = VALUE + Database.VALUE_SIZE; + protected static final int RECORD_SIZE = INTERNAL_TYPE + Database.TYPE_SIZE; - public PDOMCPPEnumerator(PDOMLinkage linkage, PDOMNode parent, IEnumerator enumerator) + public PDOMCPPEnumerator(PDOMLinkage linkage, PDOMNode parent, ICPPInternalEnumerator enumerator) throws CoreException { super(linkage, parent, enumerator.getNameCharArray()); - storeValue(enumerator); + IValue value= enumerator.getValue(); + if (value != null) { + linkage.storeValue(record + VALUE, value); + } + IType internalType = enumerator.getInternalType(); + if (internalType != null) { + linkage.storeType(record + INTERNAL_TYPE, internalType); + } } public PDOMCPPEnumerator(PDOMLinkage linkage, long record) { @@ -54,17 +64,14 @@ class PDOMCPPEnumerator extends PDOMCPPBinding implements IPDOMCPPEnumerator { return IIndexCPPBindingConstants.CPPENUMERATOR; } - private void storeValue(IEnumerator enumerator) throws CoreException { - IValue value= enumerator.getValue(); - if (value != null) { - getLinkage().storeValue(record + VALUE, value); - } - } - @Override public void update(PDOMLinkage linkage, IBinding newBinding) throws CoreException { - if (newBinding instanceof IEnumerator) - storeValue((IEnumerator) newBinding); + if (newBinding instanceof IEnumerator) { + IValue value= ((IEnumerator) newBinding).getValue(); + if (value != null) { + getLinkage().storeValue(record + VALUE, value); + } + } } @Override @@ -74,7 +81,17 @@ class PDOMCPPEnumerator extends PDOMCPPBinding implements IPDOMCPPEnumerator { return (IType) owner; return null; } - + + @Override + public IType getInternalType() { + try { + return getLinkage().loadType(record + INTERNAL_TYPE); + } catch (CoreException e) { + CCorePlugin.log(e); + } + return ProblemType.UNKNOWN_FOR_EXPRESSION; + } + @Override public IValue getValue() { try { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeratorSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeratorSpecialization.java index 8ef93ddd74c..352031e46dc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeratorSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeratorSpecialization.java @@ -16,7 +16,9 @@ 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.cpp.ICPPSpecialization; +import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.Value; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalEnumerator; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; import org.eclipse.cdt.internal.core.pdom.db.Database; @@ -30,14 +32,22 @@ import org.eclipse.core.runtime.CoreException; */ class PDOMCPPEnumeratorSpecialization extends PDOMCPPSpecialization implements IPDOMCPPEnumerator { private static final int VALUE= PDOMCPPSpecialization.RECORD_SIZE; + private static final int INTERNAL_TYPE= VALUE + Database.VALUE_SIZE; @SuppressWarnings("hiding") - protected static final int RECORD_SIZE = VALUE + Database.VALUE_SIZE; + protected static final int RECORD_SIZE = INTERNAL_TYPE + Database.TYPE_SIZE; public PDOMCPPEnumeratorSpecialization(PDOMCPPLinkage linkage, PDOMNode parent, - IEnumerator enumerator, PDOMBinding specialized) throws CoreException { + ICPPInternalEnumerator enumerator, PDOMBinding specialized) throws CoreException { super(linkage, parent, (ICPPSpecialization) enumerator, specialized); - storeValue(enumerator); + IValue value= enumerator.getValue(); + if (value != null) { + getLinkage().storeValue(record + VALUE, value); + } + IType internalType = enumerator.getInternalType(); + if (internalType != null) { + linkage.storeType(record + INTERNAL_TYPE, internalType); + } } public PDOMCPPEnumeratorSpecialization(PDOMLinkage linkage, long record) { @@ -54,17 +64,14 @@ class PDOMCPPEnumeratorSpecialization extends PDOMCPPSpecialization implements I return IIndexCPPBindingConstants.CPP_ENUMERATOR_SPECIALIZATION; } - private void storeValue(IEnumerator enumerator) throws CoreException { - IValue value= enumerator.getValue(); - if (value != null) { - getLinkage().storeValue(record + VALUE, value); - } - } - @Override public void update(PDOMLinkage linkage, IBinding newBinding) throws CoreException { - if (newBinding instanceof IEnumerator) - storeValue((IEnumerator) newBinding); + if (newBinding instanceof IEnumerator) { + IValue value= ((IEnumerator) newBinding).getValue(); + if (value != null) { + getLinkage().storeValue(record + VALUE, value); + } + } } @Override @@ -75,6 +82,16 @@ class PDOMCPPEnumeratorSpecialization extends PDOMCPPSpecialization implements I return null; } + @Override + public IType getInternalType() { + try { + return getLinkage().loadType(record + INTERNAL_TYPE); + } catch (CoreException e) { + CCorePlugin.log(e); + } + return ProblemType.UNKNOWN_FOR_EXPRESSION; + } + @Override public IValue getValue() { try { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java index 3ced60545d2..3a4af863c8b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2013 QNX Software Systems and others. + * Copyright (c) 2005, 2014 QNX Software Systems 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 @@ -101,6 +101,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownMember; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalEnumerator; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinary; @@ -539,9 +540,9 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { pdomBinding = new PDOMCPPUsingDeclaration(this, parent, (ICPPUsingDeclaration) binding); } else if (binding instanceof ICPPEnumeration) { pdomBinding = new PDOMCPPEnumeration(this, parent, (ICPPEnumeration) binding); - } else if (binding instanceof IEnumerator) { + } else if (binding instanceof ICPPInternalEnumerator) { assert parent instanceof ICPPEnumeration; - pdomBinding = new PDOMCPPEnumerator(this, parent, (IEnumerator) binding); + pdomBinding = new PDOMCPPEnumerator(this, parent, (ICPPInternalEnumerator) binding); if (parent instanceof ICPPEnumeration && !((ICPPEnumeration) parent).isScoped()) { parent2= parent.getParentNode(); if (parent2 == null) { @@ -673,8 +674,8 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { result= new PDOMCPPUsingDeclarationSpecialization(this, parent, (ICPPUsingDeclaration) special, orig); } else if (special instanceof ICPPEnumeration) { result= new PDOMCPPEnumerationSpecialization(this, parent, (ICPPEnumeration) special, orig); - } else if (special instanceof IEnumerator) { - result= new PDOMCPPEnumeratorSpecialization(this, parent, (IEnumerator) special, orig); + } else if (special instanceof ICPPInternalEnumerator) { + result= new PDOMCPPEnumeratorSpecialization(this, parent, (ICPPInternalEnumerator) special, orig); } return result; @@ -685,7 +686,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { final long fileLocalRec= type.getLocalToFileRec(); IScope scope = binding.getCompositeScope(); if (scope instanceof ICPPClassScope) { - List old= new ArrayList(); + List old= new ArrayList<>(); if (type instanceof ICPPClassType) { ArrayUtil.addAll(old, ClassTypeHelper.getImplicitMethods((ICPPClassType) type, point)); }