diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IValue.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IValue.java index 2f8a2f46b99..c1e8b2b8223 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IValue.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IValue.java @@ -7,9 +7,12 @@ * * Contributors: * Markus Schorn - initial API and implementation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.core.dom.ast; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; + /** * Models a value of a variable, enumerator or expression. * @@ -19,27 +22,33 @@ package org.eclipse.cdt.core.dom.ast; */ public interface IValue { /** - * Returns the value as a number, or null if this is not possible. + * Returns the value as a number, or {@code null} if it is not possible. */ Long numericalValue(); - + /** - * Returns an internal representation of the expression that builds up - * the value. It is suitable for instantiating dependent values but may not be - * used for the purpose of displaying values. + * Returns the evaluation object if this value is dependent, or {@code null} otherwise. + * If {@link #numericalValue()} returns {@code null}, {@link #getEvaluation()} returns + * not {@code null} and vice versa. + * @noreference This method is not intended to be referenced by clients. */ - char[] getInternalExpression(); - + ICPPEvaluation getEvaluation(); + /** - * A value may be dependent on template parameters, in which case a list - * of unknown bindings is maintained for later instantiation. - */ - IBinding[] getUnknownBindings(); - - /** - * Returns a signature containing both the internal representation and - * the unknown bindings. The representation is sufficient to distinguish values - * for the purpose of instantiation, it may not be used to display the value. + * Returns a signature uniquely identifying the value. Two values with identical + * signatures are guaranteed to be equal. */ char[] getSignature(); + + /** + * @deprecated Returns an empty character array. + */ + @Deprecated + char[] getInternalExpression(); + + /** + * @deprecated Returns an empty array. + */ + @Deprecated + IBinding[] getUnknownBindings(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharArrayUtils.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharArrayUtils.java index b3d27ee7b3d..330878bb36c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharArrayUtils.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharArrayUtils.java @@ -329,7 +329,7 @@ public class CharArrayUtils { } /** - * Find an array of chars in an array of arrays of chars. + * Finds an array of chars in an array of arrays of chars. * @return offset where the array was found or -1 */ public static int indexOf(final char[] searchFor, final char[][] searchIn) { @@ -340,4 +340,15 @@ public class CharArrayUtils { } return -1; } + + /** + * Converts a {@link StringBuilder} to a character array. + * @since 5.5 + */ + public static char[] extractChars(StringBuilder buf) { + final int len = buf.length(); + char[] result= new char[len]; + buf.getChars(0, len, result, 0); + return result; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java index 41c7f5bb0b2..701b9e71d74 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2011 Wind River Systems, Inc. and others. + * Copyright (c) 2008, 2012 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 @@ -11,12 +11,6 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.IASTCastExpression; @@ -24,7 +18,6 @@ import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; -import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IBinding; @@ -32,13 +25,14 @@ 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.IVariable; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinding; import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator; import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException; import org.eclipse.cdt.internal.core.pdom.db.TypeMarshalBuffer; @@ -50,112 +44,64 @@ import org.eclipse.core.runtime.CoreException; */ public class Value implements IValue { public static final int MAX_RECURSION_DEPTH = 25; - public final static IValue UNKNOWN= new Value("".toCharArray(), ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY); //$NON-NLS-1$ - public final static IValue NOT_INITIALIZED= new Value("<__>".toCharArray(), ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY); //$NON-NLS-1$ - private static final int[] NO_INT = {}; + public static final Value UNKNOWN= new Value("".toCharArray(), null); //$NON-NLS-1$ + public static final Value NOT_INITIALIZED= new Value("<__>".toCharArray(), null); //$NON-NLS-1$ - private static final String SCOPE_OP = "::"; //$NON-NLS-1$ private static final char UNIQUE_CHAR = '_'; - private static final char TEMPLATE_PARAM_CHAR = '#'; - private static final char TEMPLATE_PARAM_PACK_CHAR = '`'; - private static final char REFERENCE_CHAR = '&'; - private static final char UNARY_OP_CHAR = '$'; - private static final char BINARY_OP_CHAR = '@'; - private static final char CONDITIONAL_CHAR= '?'; - - private static final char SEPARATOR = ','; private final static IValue[] TYPICAL= { - new Value(new char[] {'0'}, ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY), - new Value(new char[] {'1'}, ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY), - new Value(new char[] {'2'}, ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY), - new Value(new char[] {'3'}, ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY), - new Value(new char[] {'4'}, ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY), - new Value(new char[] {'5'}, ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY), - new Value(new char[] {'6'}, ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY)}; + new Value(new char[] {'0'}, null), + new Value(new char[] {'1'}, null), + new Value(new char[] {'2'}, null), + new Value(new char[] {'3'}, null), + new Value(new char[] {'4'}, null), + new Value(new char[] {'5'}, null), + new Value(new char[] {'6'}, null)}; - private static class Reevaluation { - public final char[] fExpression; - private final int fPackOffset; - public int pos= 0; - public final Map fUnknownSigs; - public final List fUnknowns; - public final IBinding[] fResolvedUnknown; - public final ICPPTemplateParameterMap fMap; - - public Reevaluation(char[] expr, int packOffset, Map unknownSigs, - List unknowns, IBinding[] resolvedUnknowns, ICPPTemplateParameterMap map) { - fExpression= expr; - fPackOffset= packOffset; - fUnknownSigs= unknownSigs; - fUnknowns= unknowns; - fResolvedUnknown= resolvedUnknowns; - fMap= map; - } - - public void nextSeparator() throws UnknownValueException { - final char[] expression = fExpression; - final int len = expression.length; - int idx = pos; - while (idx < len) { - if (expression[idx++] == SEPARATOR) - break; - } - pos= idx; - } - } - private static class UnknownValueException extends Exception {} private static UnknownValueException UNKNOWN_EX= new UnknownValueException(); private static int sUnique= 0; - private final char[] fExpression; - private final ICPPUnknownBinding[] fUnknownBindings; + // The following invariant always holds: (fFixedValue == null) != (fEvaluation == null) + private final char[] fFixedValue; + private final ICPPEvaluation fEvaluation; private char[] fSignature; - private Value(char[] rep, ICPPUnknownBinding[] unknown) { - assert rep != null; - fExpression= rep; - fUnknownBindings= unknown; + private Value(char[] fixedValue, ICPPEvaluation evaluation) { + assert (fixedValue == null) != (evaluation == null); + fFixedValue = fixedValue; + fEvaluation = evaluation; } @Override - public char[] getInternalExpression() { - return fExpression; + public Long numericalValue() { + return fFixedValue == null ? null : parseLong(fFixedValue); } @Override - public IBinding[] getUnknownBindings() { - return fUnknownBindings; + public ICPPEvaluation getEvaluation() { + return fEvaluation; } @Override public char[] getSignature() { if (fSignature == null) { - if (fUnknownBindings.length == 0) { - fSignature= fExpression; - } else { - StringBuilder buf= new StringBuilder(); - buf.append(fExpression); - buf.append('['); - for (int i = 0; i < fUnknownBindings.length; i++) { - if (i > 0) - buf.append(','); - buf.append(getSignatureForUnknown(fUnknownBindings[i])); - } - buf.append(']'); - final int end= buf.length(); - fSignature= new char[end]; - buf.getChars(0, end, fSignature, 0); - } + fSignature = fFixedValue != null ? fFixedValue : fEvaluation.getSignature(); } return fSignature; } + @Deprecated @Override - public Long numericalValue() { - return parseLong(fExpression); + public char[] getInternalExpression() { + return CharArrayUtils.EMPTY_CHAR_ARRAY; + } + + @Deprecated + @Override + public IBinding[] getUnknownBindings() { + return IBinding.EMPTY_BINDING_ARRAY; } public void marshall(ITypeMarshalBuffer buf) throws CoreException { @@ -174,11 +120,7 @@ public class Value implements IValue { } } else { buf.putByte((ITypeMarshalBuffer.VALUE)); - buf.putCharArray(fExpression); - buf.putShort((short) fUnknownBindings.length); - for (ICPPUnknownBinding b : fUnknownBindings) { - buf.marshalBinding(b); - } + fEvaluation.marshal(buf, true); } } } @@ -198,48 +140,26 @@ public class Value implements IValue { return Value.create(val); } - char[] expr = buf.getCharArray(); - final int len= buf.getShort(); - ICPPUnknownBinding[] unknowns= new ICPPUnknownBinding[len]; - for (int i = 0; i < unknowns.length; i++) { - final ICPPUnknownBinding unknown = (ICPPUnknownBinding) buf.unmarshalBinding(); - if (unknown == null) { - return Value.UNKNOWN; - } - unknowns[i]= unknown; - } - return new Value(expr, unknowns); + ISerializableEvaluation eval= buf.unmarshalEvaluation(); + if (eval instanceof ICPPEvaluation) + return new Value(null, (ICPPEvaluation) eval); + return Value.UNKNOWN; } @Override public int hashCode() { - return CharArrayUtils.hash(fExpression); + return CharArrayUtils.hash(getSignature()); } @Override public boolean equals(Object obj) { - if (!(obj instanceof IValue)) { + if (!(obj instanceof Value)) { return false; } - final IValue rhs = (IValue) obj; - if (!CharArrayUtils.equals(fExpression, rhs.getInternalExpression())) - return false; - - IBinding[] rhsUnknowns= rhs.getUnknownBindings(); - if (fUnknownBindings.length != rhsUnknowns.length) - return false; - - for (int i = 0; i < rhsUnknowns.length; i++) { - final IBinding rhsUnknown = rhsUnknowns[i]; - if (rhsUnknown instanceof ICPPUnknownBinding) { - if (!getSignatureForUnknown((ICPPUnknownBinding) rhsUnknown).equals(getSignatureForUnknown(fUnknownBindings[i]))) { - return false; - } - } else { - return false; - } - } - return true; + final Value rhs = (Value) obj; + if (fFixedValue != null) + return CharArrayUtils.equals(fFixedValue, rhs.fFixedValue); + return CharArrayUtils.equals(getSignature(), rhs.getSignature()); } @Override @@ -253,41 +173,59 @@ public class Value implements IValue { public static IValue create(long value) { if (value >=0 && value < TYPICAL.length) return TYPICAL[(int) value]; - return new Value(toCharArray(value), ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY); + return new Value(toCharArray(value), null); + } + + /** + * Creates a value object representing the given boolean value. + */ + public static IValue create(boolean value) { + return create(value ? 1 : 0); } /** * Creates a value representing the given template parameter. */ public static IValue create(ICPPTemplateNonTypeParameter tntp) { - final String expr = createTemplateParamExpression(tntp.getParameterID(), tntp.isParameterPack()); - return new Value(expr.toCharArray(), ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY); - } - - private static String createTemplateParamExpression(int id, boolean isPack) { - StringBuilder buf= new StringBuilder(); - buf.append(isPack ? TEMPLATE_PARAM_PACK_CHAR : TEMPLATE_PARAM_CHAR); - buf.append(Integer.toHexString(id)); - return buf.toString(); + EvalBinding eval = new EvalBinding(tntp, null); + return new Value(null, eval); } /** - * Tests whether the value is a template parameter (or parameter pack), - * returns the parameter id of the parameter, or -1 if it is not a template parameter. + * Create a value wrapping the given evaluation. + */ + public static IValue create(ICPPEvaluation eval) { + return new Value(null, eval); + } + + public static IValue evaluateBinaryExpression(final int op, final long v1, final long v2) { + try { + return create(combineBinary(op, v1, v2)); + } catch (UnknownValueException e) { + } + return UNKNOWN; + } + + public static IValue evaluateUnaryExpression(final int unaryOp, final long value) { + try { + return create(combineUnary(unaryOp, value)); + } catch (UnknownValueException e) { + } + return UNKNOWN; + } + + /** + * Tests whether the value is a template parameter (or parameter pack). + * + * @return the parameter id of the parameter, or -1 if it is not a template + * parameter. */ public static int isTemplateParameter(IValue tval) { - final char[] rep= tval.getInternalExpression(); - if (rep.length > 0) { - final char c = rep[0]; - if (c == TEMPLATE_PARAM_CHAR || c == TEMPLATE_PARAM_PACK_CHAR) { - for (int i = 1; i < rep.length; i++) { - if (rep[i] == SEPARATOR) - return -1; - } - try { - return parseHex(rep, 1); - } catch (UnknownValueException e) { - } + ICPPEvaluation eval = tval.getEvaluation(); + if (eval instanceof EvalBinding) { + IBinding binding = ((EvalBinding) eval).getBinding(); + if (binding instanceof ICPPTemplateParameter) { + ((ICPPTemplateParameter) binding).getParameterID(); } } return -1; @@ -296,63 +234,23 @@ public class Value implements IValue { /** * Tests whether the value directly references some template parameter. */ + // TODO(sprigogin): The semantics of "directly" is unclear. public static boolean referencesTemplateParameter(IValue tval) { - final char[] rep= tval.getInternalExpression(); - for (char element : rep) { - if (element == TEMPLATE_PARAM_CHAR || element == TEMPLATE_PARAM_PACK_CHAR) - return true; - } - return false; + // TODO(sprigogin): Implementation of this method is probably incomplete since it interprets "directly" in a very direct way. The old code is kept below for reference. + return isTemplateParameter(tval) >= 0; +// final char[] rep= tval.getInternalExpression(); +// for (char element : rep) { +// if (element == TEMPLATE_PARAM_CHAR || element == TEMPLATE_PARAM_PACK_CHAR) +// return true; +// } +// return false; } /** * Tests whether the value depends on a template parameter. */ public static boolean isDependentValue(IValue nonTypeValue) { - final char[] rep= nonTypeValue.getInternalExpression(); - for (final char c : rep) { - if (c == REFERENCE_CHAR || c == TEMPLATE_PARAM_CHAR || c == TEMPLATE_PARAM_PACK_CHAR) - return true; - } - return false; - } - - /** - * Collects all references to parameter packs. - */ - public static int[] getParameterPackReferences(IValue value) { - final char[] rep= value.getInternalExpression(); - int result= -1; - List array= null; - for (int i=0; i(2); - array.add(result); - } - array.add(ref); - } - } catch (UnknownValueException e) { - } - } - } - if (array != null) { - int[] ra= new int[array.size()]; - for (int i = 0; i < ra.length; i++) { - ra[i]= array.get(i); - } - return ra; - } - if (result != -1) - return new int[] {result}; - - return NO_INT; + return nonTypeValue.getEvaluation() != null; } /** @@ -360,19 +258,14 @@ public class Value implements IValue { */ public static IValue create(IASTExpression expr, int maxRecursionDepth) { try { - Map unknownSigs= new HashMap(); - List unknown= new ArrayList(); - Object obj= evaluate(expr, unknownSigs, unknown, maxRecursionDepth); - if (obj instanceof Number) - return create(((Number) obj).longValue()); + Object obj= evaluate(expr, maxRecursionDepth); + if (obj instanceof Long) + return create(((Long) obj).longValue()); - ICPPUnknownBinding[] ua; - if (unknown.isEmpty()) { - ua= ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY; - } else { - ua= unknown.toArray(new ICPPUnknownBinding[unknown.size()]); + if (expr instanceof ICPPASTInitializerClause) { + ICPPEvaluation evaluation = ((ICPPASTInitializerClause) expr).getEvaluation(); + return new Value(null, evaluation); } - return new Value(((String)obj).toCharArray(), ua); } catch (UnknownValueException e) { } return UNKNOWN; @@ -381,15 +274,8 @@ public class Value implements IValue { /** * Creates a value off its canonical representation. */ - public static IValue fromInternalRepresentation(char[] rep, ICPPUnknownBinding[] unknown) { - if (CharArrayUtils.equals(rep, UNKNOWN.getInternalExpression())) - return UNKNOWN; - - Long l= parseLong(rep); - if (l != null) - return create(l.longValue()); - - return new Value(rep, unknown); + public static IValue fromInternalRepresentation(ICPPEvaluation evaluation) { + return new Value(null, evaluation); } /** @@ -399,67 +285,59 @@ public class Value implements IValue { StringBuilder buf= new StringBuilder(10); buf.append(UNIQUE_CHAR); buf.append(++sUnique); - return new Value(extractChars(buf), ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY); + return new Value(CharArrayUtils.extractChars(buf), null); } /** * Computes the canonical representation of the value of the expression. - * Returns a {@code Number} for numerical values or a {@code String}, otherwise. + * Returns a {@code Long} for numerical values or {@code null}, otherwise. * @throws UnknownValueException */ - private static Object evaluate(IASTExpression e, Map unknownSigs, - List unknowns, int maxdepth) throws UnknownValueException { - if (maxdepth < 0 || e == null) + private static Long evaluate(IASTExpression exp, int maxdepth) throws UnknownValueException { + if (maxdepth < 0 || exp == null) throw UNKNOWN_EX; - if (e instanceof IASTArraySubscriptExpression) { + if (exp instanceof IASTArraySubscriptExpression) { throw UNKNOWN_EX; } - if (e instanceof IASTBinaryExpression) { - return evaluateBinaryExpression((IASTBinaryExpression) e, unknownSigs, unknowns, maxdepth); + if (exp instanceof IASTBinaryExpression) { + return evaluateBinaryExpression((IASTBinaryExpression) exp, maxdepth); } - if (e instanceof IASTCastExpression) { // must be ahead of unary - return evaluate(((IASTCastExpression) e).getOperand(), unknownSigs, unknowns, maxdepth); + if (exp instanceof IASTCastExpression) { // must be ahead of unary + return evaluate(((IASTCastExpression) exp).getOperand(), maxdepth); } - if (e instanceof IASTUnaryExpression) { - return evaluateUnaryExpression((IASTUnaryExpression) e, unknownSigs, unknowns, maxdepth); + if (exp instanceof IASTUnaryExpression) { + return evaluateUnaryExpression((IASTUnaryExpression) exp, maxdepth); } - if (e instanceof IASTConditionalExpression) { - IASTConditionalExpression cexpr= (IASTConditionalExpression) e; - Object o= evaluate(cexpr.getLogicalConditionExpression(), unknownSigs, unknowns, maxdepth); - if (o instanceof Number) { - Number v= (Number) o; - if (v.longValue() == 0) { - return evaluate(cexpr.getNegativeResultExpression(), unknownSigs, unknowns, maxdepth); - } - final IASTExpression pe = cexpr.getPositiveResultExpression(); - if (pe == null) // gnu-extension allows to omit the positive expression. - return o; - return evaluate(pe, unknownSigs, unknowns, maxdepth); + if (exp instanceof IASTConditionalExpression) { + IASTConditionalExpression cexpr= (IASTConditionalExpression) exp; + Long v= evaluate(cexpr.getLogicalConditionExpression(), maxdepth); + if (v == null) + return null; + if (v.longValue() == 0) { + return evaluate(cexpr.getNegativeResultExpression(), maxdepth); } - final IASTExpression pe = cexpr.getPositiveResultExpression(); - Object po= pe == null ? o : evaluate(pe, unknownSigs, unknowns, maxdepth); - Object neg= evaluate(cexpr.getNegativeResultExpression(), unknownSigs, unknowns, maxdepth); - return "" + CONDITIONAL_CHAR + SEPARATOR + o.toString() + SEPARATOR + po.toString() + //$NON-NLS-1$ - SEPARATOR + neg.toString(); + if (pe == null) // gnu-extension allows to omit the positive expression. + return v; + return evaluate(pe, maxdepth); } - if (e instanceof IASTIdExpression) { - IBinding b= ((IASTIdExpression) e).getName().resolvePreBinding(); - return evaluateBinding(b, unknownSigs, unknowns, maxdepth); + if (exp instanceof IASTIdExpression) { + IBinding b= ((IASTIdExpression) exp).getName().resolvePreBinding(); + return evaluateBinding(b, maxdepth); } - if (e instanceof IASTLiteralExpression) { - IASTLiteralExpression litEx= (IASTLiteralExpression) e; + if (exp instanceof IASTLiteralExpression) { + IASTLiteralExpression litEx= (IASTLiteralExpression) exp; switch (litEx.getKind()) { case IASTLiteralExpression.lk_false: case IASTLiteralExpression.lk_nullptr: - return 0; + return Long.valueOf(0); case IASTLiteralExpression.lk_true: - return 1; + return Long.valueOf(1); case IASTLiteralExpression.lk_integer_constant: try { return ExpressionEvaluator.getNumber(litEx.getValue()); - } catch (EvalException e1) { + } catch (EvalException e) { throw UNKNOWN_EX; } case IASTLiteralExpression.lk_char_constant: @@ -468,13 +346,13 @@ public class Value implements IValue { if (image.length > 1 && image[0] == 'L') return ExpressionEvaluator.getChar(image, 2); return ExpressionEvaluator.getChar(image, 1); - } catch (EvalException e1) { + } catch (EvalException e) { throw UNKNOWN_EX; } } } - if (e instanceof IASTTypeIdExpression) { - IASTTypeIdExpression typeIdEx = (IASTTypeIdExpression) e; + if (exp instanceof IASTTypeIdExpression) { + IASTTypeIdExpression typeIdEx = (IASTTypeIdExpression) exp; switch (typeIdEx.getOperator()) { case IASTTypeIdExpression.op_sizeof: final IType type; @@ -493,18 +371,16 @@ public class Value implements IValue { /** * Extract a value off a binding. */ - private static Object evaluateBinding(IBinding b, Map unknownSigs, - List unknowns, int maxdepth) throws UnknownValueException { + private static Long evaluateBinding(IBinding b, int maxdepth) throws UnknownValueException { if (b instanceof IType) { throw UNKNOWN_EX; } if (b instanceof ICPPTemplateNonTypeParameter) { - final ICPPTemplateNonTypeParameter tp = (ICPPTemplateNonTypeParameter) b; - return createTemplateParamExpression(tp.getParameterID(), tp.isParameterPack()); + return null; } if (b instanceof ICPPUnknownBinding) { - return createReference((ICPPUnknownBinding) b, unknownSigs, unknowns); + return null; } IValue value= null; @@ -515,78 +391,22 @@ public class Value implements IValue { } else if (b instanceof IEnumerator) { value= ((IEnumerator) b).getValue(); } - if (value != null) - return evaluateValue(value, unknownSigs, unknowns); + if (value != null && value != Value.UNKNOWN) { + return value.numericalValue(); + } throw UNKNOWN_EX; } - private static Object createReference(ICPPUnknownBinding unknown, - Map unknownSigs, List unknowns) { - String sig= getSignatureForUnknown(unknown); - Integer idx= unknownSigs.get(sig); - if (idx == null) { - idx= unknownSigs.size(); - unknownSigs.put(sig, idx); - unknowns.add(unknown); - } - return "" + REFERENCE_CHAR + idx.toString(); //$NON-NLS-1$ - } - - private static Object evaluateValue(IValue cv, Map unknownSigs, - List unknowns) throws UnknownValueException { - if (cv == Value.UNKNOWN) - throw UNKNOWN_EX; - - Long lv= cv.numericalValue(); - if (lv != null) - return lv; - - final IBinding[] oldUnknowns = cv.getUnknownBindings(); - final char[] expr= cv.getInternalExpression(); - if (oldUnknowns.length == 0) - return new String(expr); - - StringBuilder buf= new StringBuilder(expr.length); - boolean skipToSeparator= false; - for (int i = 0; i < expr.length; i++) { - final char c= expr[i]; - switch (c) { - case REFERENCE_CHAR: { - int idx= parseNonNegative(expr, i + 1); - if (idx >= oldUnknowns.length) - throw UNKNOWN_EX; - final IBinding old = oldUnknowns[idx]; - if (!(old instanceof ICPPUnknownBinding)) - throw UNKNOWN_EX; - - buf.append(createReference((ICPPUnknownBinding) old, unknownSigs, unknowns)); - skipToSeparator= true; - break; - } - case SEPARATOR: - skipToSeparator= false; - buf.append(c); - break; - default: - if (!skipToSeparator) - buf.append(c); - break; - } - } - return buf.toString(); - } - - private static Object evaluateUnaryExpression(IASTUnaryExpression ue, - Map unknownSigs, List unknowns, int maxdepth) + private static Long evaluateUnaryExpression(IASTUnaryExpression exp, int maxdepth) throws UnknownValueException { - final int unaryOp= ue.getOperator(); + final int unaryOp= exp.getOperator(); if (unaryOp == IASTUnaryExpression.op_sizeof) { - final IASTExpression operand = ue.getOperand(); + final IASTExpression operand = exp.getOperand(); if (operand != null) { IType type = operand.getExpressionType(); - ASTTranslationUnit ast = (ASTTranslationUnit) ue.getTranslationUnit(); + ASTTranslationUnit ast = (ASTTranslationUnit) exp.getTranslationUnit(); SizeofCalculator calculator = ast.getSizeofCalculator(); SizeAndAlignment info = calculator.sizeAndAlignment(type); if (info != null) @@ -600,338 +420,109 @@ public class Value implements IValue { throw UNKNOWN_EX; } - final Object value= evaluate(ue.getOperand(), unknownSigs, unknowns, maxdepth); + final Long value= evaluate(exp.getOperand(), maxdepth); + if (value == null) + return null; return combineUnary(unaryOp, value); } - private static Object combineUnary(final int unaryOp, final Object value) throws UnknownValueException { + private static long combineUnary(final int unaryOp, final long value) throws UnknownValueException { switch (unaryOp) { case IASTUnaryExpression.op_bracketedPrimary: case IASTUnaryExpression.op_plus: return value; } - if (value instanceof Number) { - long v= ((Number) value).longValue(); - switch (unaryOp) { - case IASTUnaryExpression.op_prefixIncr: - case IASTUnaryExpression.op_postFixIncr: - return ++v; - case IASTUnaryExpression.op_prefixDecr: - case IASTUnaryExpression.op_postFixDecr: - return --v; - case IASTUnaryExpression.op_minus: - return -v; - case IASTUnaryExpression.op_tilde: - return ~v; - case IASTUnaryExpression.op_not: - return v == 0 ? 1 : 0; - } - throw UNKNOWN_EX; - } - switch (unaryOp) { case IASTUnaryExpression.op_prefixIncr: case IASTUnaryExpression.op_postFixIncr: + return value + 1; case IASTUnaryExpression.op_prefixDecr: case IASTUnaryExpression.op_postFixDecr: + return value - 1; case IASTUnaryExpression.op_minus: + return -value; case IASTUnaryExpression.op_tilde: + return ~value; case IASTUnaryExpression.op_not: - return "" + UNARY_OP_CHAR + unaryOp + SEPARATOR + value.toString(); //$NON-NLS-1$ + return value == 0 ? 1 : 0; } throw UNKNOWN_EX; } - private static Object evaluateBinaryExpression(IASTBinaryExpression be, - Map unknownSigs, List unknowns, int maxdepth) + private static Long evaluateBinaryExpression(IASTBinaryExpression exp, int maxdepth) throws UnknownValueException { - final Object o1= evaluate(be.getOperand1(), unknownSigs, unknowns, maxdepth); - final Object o2= evaluate(be.getOperand2(), unknownSigs, unknowns, maxdepth); + final int op= exp.getOperator(); + switch (op) { + case IASTBinaryExpression.op_equals: + if (exp.getOperand1().equals(exp.getOperand2())) + return Long.valueOf(1); + break; + case IASTBinaryExpression.op_notequals: + if (exp.getOperand1().equals(exp.getOperand2())) + return Long.valueOf(0); + break; + } + + final Long o1= evaluate(exp.getOperand1(), maxdepth); + if (o1 == null) + return null; + final Long o2= evaluate(exp.getOperand2(), maxdepth); + if (o2 == null) + return null; - final int op= be.getOperator(); return combineBinary(op, o1, o2); } - private static Object combineBinary(final int op, final Object o1, final Object o2) + private static long combineBinary(final int op, final long v1, final long v2) throws UnknownValueException { - if (o1 instanceof Number && o2 instanceof Number) { - long v1= ((Number) o1).longValue(); - long v2= ((Number) o2).longValue(); - switch (op) { - case IASTBinaryExpression.op_multiply: - return v1 * v2; - case IASTBinaryExpression.op_divide: - if (v2 == 0) - throw UNKNOWN_EX; - return v1 / v2; - case IASTBinaryExpression.op_modulo: - if (v2 == 0) - throw UNKNOWN_EX; - return v1 % v2; - case IASTBinaryExpression.op_plus: - return v1 + v2; - case IASTBinaryExpression.op_minus: - return v1 - v2; - case IASTBinaryExpression.op_shiftLeft: - return v1 << v2; - case IASTBinaryExpression.op_shiftRight: - return v1 >> v2; - case IASTBinaryExpression.op_lessThan: - return v1 < v2 ? 1 : 0; - case IASTBinaryExpression.op_greaterThan: - return v1 > v2 ? 1 : 0; - case IASTBinaryExpression.op_lessEqual: - return v1 <= v2 ? 1 : 0; - case IASTBinaryExpression.op_greaterEqual: - return v1 >= v2 ? 1 : 0; - case IASTBinaryExpression.op_binaryAnd: - return v1 & v2; - case IASTBinaryExpression.op_binaryXor: - return v1 ^ v2; - case IASTBinaryExpression.op_binaryOr: - return v1 | v2; - case IASTBinaryExpression.op_logicalAnd: - return v1 != 0 && v2 != 0 ? 1 : 0; - case IASTBinaryExpression.op_logicalOr: - return v1 != 0 || v2 != 0 ? 1 : 0; - case IASTBinaryExpression.op_equals: - return v1 == v2 ? 1 : 0; - case IASTBinaryExpression.op_notequals: - return v1 != v2 ? 1 : 0; - case IASTBinaryExpression.op_max: - return Math.max(v1, v2); - case IASTBinaryExpression.op_min: - return Math.min(v1, v2); - } - throw UNKNOWN_EX; - } switch (op) { case IASTBinaryExpression.op_multiply: + return v1 * v2; case IASTBinaryExpression.op_divide: + if (v2 == 0) + throw UNKNOWN_EX; + return v1 / v2; case IASTBinaryExpression.op_modulo: + if (v2 == 0) + throw UNKNOWN_EX; + return v1 % v2; case IASTBinaryExpression.op_plus: + return v1 + v2; case IASTBinaryExpression.op_minus: + return v1 - v2; case IASTBinaryExpression.op_shiftLeft: + return v1 << v2; case IASTBinaryExpression.op_shiftRight: + return v1 >> v2; case IASTBinaryExpression.op_lessThan: + return v1 < v2 ? 1 : 0; case IASTBinaryExpression.op_greaterThan: + return v1 > v2 ? 1 : 0; case IASTBinaryExpression.op_lessEqual: + return v1 <= v2 ? 1 : 0; case IASTBinaryExpression.op_greaterEqual: + return v1 >= v2 ? 1 : 0; case IASTBinaryExpression.op_binaryAnd: + return v1 & v2; case IASTBinaryExpression.op_binaryXor: + return v1 ^ v2; case IASTBinaryExpression.op_binaryOr: + return v1 | v2; case IASTBinaryExpression.op_logicalAnd: + return v1 != 0 && v2 != 0 ? 1 : 0; case IASTBinaryExpression.op_logicalOr: - case IASTBinaryExpression.op_max: - case IASTBinaryExpression.op_min: - break; + return v1 != 0 || v2 != 0 ? 1 : 0; case IASTBinaryExpression.op_equals: - if (o1.equals(o2)) - return 1; - break; + return v1 == v2 ? 1 : 0; case IASTBinaryExpression.op_notequals: - if (o1.equals(o2)) - return 0; - break; - default: - throw UNKNOWN_EX; + return v1 != v2 ? 1 : 0; + case IASTBinaryExpression.op_max: + return Math.max(v1, v2); + case IASTBinaryExpression.op_min: + return Math.min(v1, v2); } - - return "" + BINARY_OP_CHAR + op + SEPARATOR + o1.toString() + SEPARATOR + o2.toString(); //$NON-NLS-1$ - } - - public static IValue reevaluate(IValue val, int packOffset, IBinding[] resolvedUnknowns, - ICPPTemplateParameterMap map, int maxdepth) { - try { - Map unknownSigs= new HashMap(); - List unknown= new ArrayList(); - Reevaluation reeval= new Reevaluation(val.getInternalExpression(), packOffset, - unknownSigs, unknown, - resolvedUnknowns, map); - Object obj= reevaluate(reeval, maxdepth); - if (reeval.pos != reeval.fExpression.length) - return UNKNOWN; - - if (obj instanceof Number) - return create(((Number) obj).longValue()); - - ICPPUnknownBinding[] ua; - if (unknown.isEmpty()) { - ua= ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY; - } else { - ua= unknown.toArray(new ICPPUnknownBinding[unknown.size()]); - } - return new Value(((String)obj).toCharArray(), ua); - } catch (UnknownValueException e) { - } - return UNKNOWN; - } - - private static Object reevaluate(Reevaluation reeval, int maxdepth) - throws UnknownValueException { - if (maxdepth < 0) - throw UNKNOWN_EX; - - final int idx= reeval.pos; - final char[] buf= reeval.fExpression; - final int length = buf.length; - if (idx >= length) - throw UNKNOWN_EX; - - final char c= buf[idx]; - switch (c) { - case BINARY_OP_CHAR: - int op= parseNonNegative(buf, idx + 1); - reeval.nextSeparator(); - Object o1= reevaluate(reeval, maxdepth); - Object o2= reevaluate(reeval, maxdepth); - return combineBinary(op, o1, o2); - case UNARY_OP_CHAR: - op= parseNonNegative(buf, idx + 1); - reeval.nextSeparator(); - o1= reevaluate(reeval, maxdepth); - return combineUnary(op, o1); - case CONDITIONAL_CHAR: - reeval.nextSeparator(); - Object cond= reevaluate(reeval, maxdepth); - Object po= reevaluate(reeval, maxdepth); - Object neg= reevaluate(reeval, maxdepth); - if (cond instanceof Number) { - Number v= (Number) cond; - if (v.longValue() == 0) { - return neg; - } - return po; - } - return "" + CONDITIONAL_CHAR + SEPARATOR + cond.toString() + SEPARATOR + //$NON-NLS-1$ - po.toString() + SEPARATOR + neg.toString(); - case REFERENCE_CHAR: - int num= parseNonNegative(buf, idx + 1); - final IBinding[] resolvedUnknowns= reeval.fResolvedUnknown; - if (num >= resolvedUnknowns.length) - throw UNKNOWN_EX; - reeval.nextSeparator(); - return evaluateBinding(resolvedUnknowns[num], reeval.fUnknownSigs, reeval.fUnknowns, maxdepth); - - case TEMPLATE_PARAM_CHAR: - num= parseHex(buf, idx + 1); - reeval.nextSeparator(); - ICPPTemplateArgument arg = reeval.fMap.getArgument(num); - if (arg != null) { - IValue val= arg.getNonTypeValue(); - if (val == null) - throw UNKNOWN_EX; - return evaluateValue(val, reeval.fUnknownSigs, reeval.fUnknowns); - } - return createTemplateParamExpression(num, false); - - case TEMPLATE_PARAM_PACK_CHAR: - num= parseHex(buf, idx + 1); - reeval.nextSeparator(); - arg= null; - if (reeval.fPackOffset >= 0) { - ICPPTemplateArgument[] args= reeval.fMap.getPackExpansion(num); - if (args != null && reeval.fPackOffset < args.length) { - arg= args[reeval.fPackOffset]; - } - } - if (arg != null) { - IValue val= arg.getNonTypeValue(); - if (val == null) - throw UNKNOWN_EX; - return evaluateValue(val, reeval.fUnknownSigs, reeval.fUnknowns); - } - return createTemplateParamExpression(num, true); - - default: - reeval.nextSeparator(); - return parseLong(buf, idx); - } - } - - /** - * Parses a non negative int. - */ - private static int parseNonNegative(char[] value, int offset) throws UnknownValueException { - final long maxvalue= Integer.MAX_VALUE/10; - final int len= value.length; - int result = 0; - boolean ok= false; - for (; offset < len; offset++) { - final int digit= (value[offset] - '0'); - if (digit < 0 || digit > 9) - break; - if (result > maxvalue) - return -1; - - result= result * 10 + digit; - ok= true; - } - if (!ok) - throw UNKNOWN_EX; - return result; - } - - /** - * Parses a a hex value. - */ - private static int parseHex(char[] value, int offset) throws UnknownValueException { - int result = 0; - boolean ok= false; - final int len= value.length; - for (; offset < len; offset++) { - int digit= (value[offset] - '0'); - if (digit < 0 || digit > 9) { - digit += '0' - 'a' + 10; - if (digit < 10 || digit > 15) { - digit += 'a' - 'A'; - if (digit < 10 || digit > 15) { - break; - } - } - } - if ((result & 0xf0000000) != 0) - throw UNKNOWN_EX; - - result= (result << 4) + digit; - ok= true; - } - if (!ok) - throw UNKNOWN_EX; - - return result; - } - - /** - * Parses a long. - */ - private static long parseLong(char[] value, int offset) throws UnknownValueException { - final long maxvalue= Long.MAX_VALUE / 10; - final int len= value.length; - boolean negative= false; - long result = 0; - - boolean ok= false; - if (offset < len && value[offset] == '-') { - negative = true; - offset++; - } - for (; offset < len; offset++) { - final int digit= (value[offset] - '0'); - if (digit < 0 || digit > 9) - break; - - if (result > maxvalue) - throw UNKNOWN_EX; - - result= result * 10 + digit; - ok= true; - } - if (!ok) - throw UNKNOWN_EX; - - return negative ? -result : result; + throw UNKNOWN_EX; } /** @@ -963,37 +554,12 @@ public class Value implements IValue { return negative ? -result : result; } - /** - * Computes a signature for an unknown binding. - */ - private static String getSignatureForUnknown(ICPPUnknownBinding binding) { - IBinding owner= binding.getOwner(); - if (owner instanceof IType) { - StringBuilder buf= new StringBuilder(); - ASTTypeUtil.appendType((IType) owner, true, buf); - return buf.append(SCOPE_OP).append(binding.getName()).toString(); - } - return binding.getName(); - } - /** * Converts long to a char array */ private static char[] toCharArray(long value) { StringBuilder buf= new StringBuilder(); buf.append(value); - return extractChars(buf); - } - - private static char[] extractChars(StringBuilder buf) { - final int len = buf.length(); - char[] result= new char[len]; - buf.getChars(0, len, result, 0); - return result; - } - - public static IValue create(ICPPEvaluation eval, IASTNode point) { - // Compute value of evaluation - return Value.UNKNOWN; + return CharArrayUtils.extractChars(buf); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java index 28a371e02be..48d743d2697 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java @@ -69,4 +69,11 @@ public interface ICPPEvaluation extends ISerializableEvaluation { */ ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, int maxdepth, IASTNode point); + + /** + * Determines size of the template parameter pack. + * + * @noreference This method is not intended to be referenced by clients. + */ + int determinePackSize(ICPPTemplateParameterMap tpMap); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java index 69460068b57..9bd224ccac0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java @@ -15,6 +15,8 @@ import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; 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.ICPPBinding; +import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableType; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; @@ -45,6 +47,10 @@ public abstract class CPPEvaluation implements ICPPEvaluation { return fBuffer.toString(); } + public char[] getSignature() { + return CharArrayUtils.extractChars(fBuffer); + } + @Override public void marshalBinding(IBinding binding) throws CoreException { if (binding instanceof ISerializableType) { @@ -53,12 +59,11 @@ public abstract class CPPEvaluation implements ICPPEvaluation { putByte(NULL_TYPE); } else { appendSeparator(); - IBinding owner= binding.getOwner(); - if (owner instanceof IType) { - ASTTypeUtil.appendType((IType) owner, true, fBuffer); - fBuffer.append("::"); //$NON-NLS-1$ + if (binding instanceof ICPPBinding) { + fBuffer.append(ASTTypeUtil.getQualifiedName((ICPPBinding) binding)); + } else { + fBuffer.append(binding.getNameCharArray()); } - fBuffer.append(binding.getName()); } } @@ -223,6 +228,6 @@ public abstract class CPPEvaluation implements ICPPEvaluation { CCorePlugin.log(e); return new char[] { '?' }; } - return buf.toString().toCharArray(); + return buf.getSignature(); } } \ No newline at end of file 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 acec6713497..b4f594d148a 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 @@ -51,7 +51,6 @@ import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.IValue; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAmbiguousTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; @@ -138,6 +137,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDeclarationSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalTemplateDeclaration; 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.ICPPInstanceCache; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalClassTemplate; @@ -153,9 +153,9 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMod * type instantiation. */ public class CPPTemplates { - private static final int PACK_SIZE_DEFER = -1; - private static final int PACK_SIZE_FAIL = -2; - private static final int PACK_SIZE_NOT_FOUND = Integer.MAX_VALUE; + static final int PACK_SIZE_DEFER = -1; + static final int PACK_SIZE_FAIL = -2; + static final int PACK_SIZE_NOT_FOUND = Integer.MAX_VALUE; private static final ICPPFunction[] NO_FUNCTIONS = {}; static enum TypeSelection { PARAMETERS, RETURN_TYPE, PARAMETERS_AND_RETURN_TYPE } @@ -225,7 +225,7 @@ public class CPPTemplates { } if (isPack) { - int packOffset= numParams - 1; + int packOffset= numParams-1; int packSize= numArgs - packOffset; ICPPTemplateArgument[] pack= new ICPPTemplateArgument[packSize]; System.arraycopy(arguments, packOffset, pack, 0, packSize); @@ -402,7 +402,7 @@ public class CPPTemplates { for (int i = 0; i < arguments.length; i++) { ICPPTemplateArgument arg = arguments[i]; if (arg.isPackExpansion()) { - if (i != arguments.length - 1) { + if (i != arguments.length-1) { return arguments; } havePackExpansion= true; @@ -421,10 +421,10 @@ public class CPPTemplates { // More arguments allowed if we have a parameter pack. if (tparCount < argCount) { - if (tpars[tparCount - 1].isParameterPack()) + if (tpars[tparCount-1].isParameterPack()) return arguments; - if (havePackExpansion && tparCount + 1 == argCount) + if (havePackExpansion && tparCount+1 == argCount) return arguments; return null; } @@ -434,7 +434,7 @@ public class CPPTemplates { return arguments; // Fewer arguments are allowed with default arguments - if (tpars[tparCount - 1].isParameterPack()) + if (tpars[tparCount-1].isParameterPack()) tparCount--; if (tparCount == argCount) @@ -862,43 +862,20 @@ public class CPPTemplates { ICPPClassSpecialization within, int maxdepth, IASTNode point) { if (value == null) return null; - IBinding[] unknowns= value.getUnknownBindings(); - IBinding[] resolvedUnknowns= null; - if (unknowns.length != 0) { - for (int i = 0; i < unknowns.length; i++) { - IBinding unknown= unknowns[i]; - IBinding resolved= unknown; - if (unknown instanceof ICPPUnknownBinding) { - try { - resolved= resolveUnknown((ICPPUnknownBinding) unknown, tpMap, packOffset, within, point); - } catch (DOMException e) { - return Value.UNKNOWN; - } - } - if (resolvedUnknowns != null) { - resolvedUnknowns[i]= resolved; - } else if (resolved != unknown) { - resolvedUnknowns= new IBinding[unknowns.length]; - System.arraycopy(unknowns, 0, resolvedUnknowns, 0, i); - resolvedUnknowns[i]= resolved; - } - } - } - - if (resolvedUnknowns != null) - return Value.reevaluate(value, packOffset, resolvedUnknowns, tpMap, maxdepth); - - if (Value.referencesTemplateParameter(value)) - return Value.reevaluate(value, packOffset, unknowns, tpMap, maxdepth); - - return value; + ICPPEvaluation evaluation = value.getEvaluation(); + if (evaluation == null) + return value; + ICPPEvaluation instantiated = evaluation.instantiate(tpMap, packOffset, within, maxdepth, point); + if (instantiated == evaluation) + return value; + return instantiated.getValue(point); } public static boolean containsParameterPack(IType type) { return determinePackSize(type, CPPTemplateParameterMap.EMPTY) == PACK_SIZE_DEFER; } - private static int determinePackSize(IType type, ICPPTemplateParameterMap tpMap) { + static int determinePackSize(IType type, ICPPTemplateParameterMap tpMap) { if (type instanceof ICPPFunctionType) { final ICPPFunctionType ft = (ICPPFunctionType) type; final IType rt = ft.getReturnType(); @@ -907,7 +884,7 @@ public class CPPTemplates { return r; IType[] ps = ft.getParameterTypes(); for (IType pt : ps) { - r= combine(r, determinePackSize(pt, tpMap)); + r= combinePackSize(r, determinePackSize(pt, tpMap)); if (r < 0) return r; } @@ -915,37 +892,17 @@ public class CPPTemplates { } if (type instanceof ICPPTemplateParameter) { - final ICPPTemplateParameter tpar = (ICPPTemplateParameter) type; - if (tpar.isParameterPack()) { - ICPPTemplateArgument[] args= tpMap.getPackExpansion(tpar); - if (args != null) - return args.length; - return PACK_SIZE_DEFER; - } - return PACK_SIZE_NOT_FOUND; + return determinePackSize((ICPPTemplateParameter) type, tpMap); } - int r= PACK_SIZE_NOT_FOUND; if (type instanceof ICPPUnknownBinding) { - if (type instanceof ICPPDeferredClassInstance) { - ICPPDeferredClassInstance dcl= (ICPPDeferredClassInstance) type; - ICPPTemplateArgument[] args = dcl.getTemplateArguments(); - for (ICPPTemplateArgument arg : args) { - r= combine(r, determinePackSize(arg, tpMap)); - if (r < 0) - return r; - } - } - IBinding binding= ((ICPPUnknownBinding) type).getOwner(); - if (binding instanceof IType) - r= combine(r, determinePackSize((IType) binding, tpMap)); - - return r; + return determinePackSize((ICPPUnknownBinding) type, tpMap); } if (type instanceof ICPPParameterPackType) return PACK_SIZE_NOT_FOUND; + int r= PACK_SIZE_NOT_FOUND; if (type instanceof IArrayType) { IArrayType at= (IArrayType) type; IValue asize= at.getSize(); @@ -956,12 +913,54 @@ public class CPPTemplates { if (type instanceof ITypeContainer) { final ITypeContainer typeContainer = (ITypeContainer) type; - r= combine(r, determinePackSize(typeContainer.getType(), tpMap)); + r= combinePackSize(r, determinePackSize(typeContainer.getType(), tpMap)); } return r; } - private static int combine(int ps1, int ps2) { + static int determinePackSize(ICPPTemplateParameter tpar, ICPPTemplateParameterMap tpMap) { + if (tpar.isParameterPack()) { + ICPPTemplateArgument[] args= tpMap.getPackExpansion(tpar); + if (args != null) + return args.length; + return PACK_SIZE_DEFER; + } + return PACK_SIZE_NOT_FOUND; + } + + static int determinePackSize(ICPPUnknownBinding binding, ICPPTemplateParameterMap tpMap) { + int r= PACK_SIZE_NOT_FOUND; + if (binding instanceof ICPPDeferredClassInstance) { + ICPPDeferredClassInstance dcl= (ICPPDeferredClassInstance) binding; + ICPPTemplateArgument[] args = dcl.getTemplateArguments(); + for (ICPPTemplateArgument arg : args) { + r= combinePackSize(r, determinePackSize(arg, tpMap)); + if (r < 0) + return r; + } + } + IBinding ownerBinding= binding.getOwner(); + if (ownerBinding instanceof IType) + r= combinePackSize(r, determinePackSize((IType) ownerBinding, tpMap)); + + return r; + } + + static int determinePackSize(IValue value, ICPPTemplateParameterMap tpMap) { + ICPPEvaluation eval = value.getEvaluation(); + if (eval == null) + return PACK_SIZE_NOT_FOUND; + + return ((CPPEvaluation) eval).determinePackSize(tpMap); + } + + static int determinePackSize(ICPPTemplateArgument arg, ICPPTemplateParameterMap tpMap) { + if (arg.isTypeValue()) + return determinePackSize(arg.getTypeValue(), tpMap); + return determinePackSize(arg.getNonTypeValue(), tpMap); + } + + static int combinePackSize(int ps1, int ps2) { if (ps1 < 0 || ps2 == PACK_SIZE_NOT_FOUND) return ps1; if (ps2 < 0 || ps1 == PACK_SIZE_NOT_FOUND) @@ -971,35 +970,6 @@ public class CPPTemplates { return ps1; } - private static int determinePackSize(IValue value, ICPPTemplateParameterMap tpMap) { - int r= PACK_SIZE_NOT_FOUND; - IBinding[] unknown= value.getUnknownBindings(); - for (IBinding binding : unknown) { - if (binding instanceof IType) { - r= combine(r, determinePackSize((IType) binding, tpMap)); - if (r < 0) - return r; - } - } - int[] tpars= Value.getParameterPackReferences(value); - for (int parID : tpars) { - ICPPTemplateArgument[] args= tpMap.getPackExpansion(parID); - if (args != null) { - r= combine(r, args.length); - if (r < 0) - return r; - } - return PACK_SIZE_DEFER; - } - return r; - } - - private static int determinePackSize(ICPPTemplateArgument arg, ICPPTemplateParameterMap tpMap) { - if (arg.isTypeValue()) - return determinePackSize(arg.getTypeValue(), tpMap); - return determinePackSize(arg.getNonTypeValue(), tpMap); - } - /** * Instantiates types contained in an array. * @param types an array of types @@ -1025,7 +995,7 @@ public class CPPTemplates { } else if (packSize == PACK_SIZE_DEFER) { newType= origType; } else { - IType[] newResult= new IType[result.length + packSize - 1]; + IType[] newResult= new IType[result.length+packSize-1]; System.arraycopy(result, 0, newResult, 0, j); result= newResult; for (int k= 0; k < packSize; k++) { @@ -1168,7 +1138,7 @@ public class CPPTemplates { return type; } // The parameter types need to be adjusted. - for (int i= 0; i < params.length; i++) { + for (int i=0; i 0 || usesTemplateParameter((ICPPASTTemplateId) n, tparnames)) { @@ -1439,17 +1409,17 @@ public class CPPTemplates { b= b.getOwner(); } if (depIDCount > 0) { - nestingLevel += depIDCount; + nestingLevel+= depIDCount; } else if (consumesTDecl < tdeclCount && !lastIsTemplate) { nestingLevel++; lastIsTemplate= true; } } else { - nestingLevel += depIDCount; + nestingLevel+= depIDCount; node= outerMostTDecl.getParent(); while (node != null) { if (node instanceof ICPPASTInternalTemplateDeclaration) { - nestingLevel += ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1; + nestingLevel+= ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1; break; } node= node.getParent(); @@ -1462,7 +1432,7 @@ public class CPPTemplates { node= outerMostTDecl.getParent(); while (node != null) { if (node instanceof ICPPASTInternalTemplateDeclaration) { - nestingLevel += ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1; + nestingLevel+= ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1; break; } node= node.getParent(); @@ -1471,7 +1441,7 @@ public class CPPTemplates { } node= innerMostTDecl; - while (node instanceof ICPPASTInternalTemplateDeclaration) { + while(node instanceof ICPPASTInternalTemplateDeclaration) { if (--nestingLevel < 0) nestingLevel= 0; tdecl= (ICPPASTInternalTemplateDeclaration) node; @@ -1501,7 +1471,7 @@ public class CPPTemplates { private static CharArraySet collectTemplateParameterNames(ICPPASTTemplateDeclaration tdecl) { CharArraySet set= new CharArraySet(4); - while (true) { + while(true) { ICPPASTTemplateParameter[] pars = tdecl.getTemplateParameters(); for (ICPPASTTemplateParameter par : pars) { IASTName name= CPPTemplates.getTemplateParameterName(par); @@ -1521,7 +1491,7 @@ public class CPPTemplates { private static boolean usesTemplateParameter(final ICPPASTTemplateId id, final CharArraySet names) { final boolean[] result= {false}; ASTVisitor v= new ASTVisitor(false) { - { shouldVisitNames= true; shouldVisitAmbiguousNodes= true; } + { shouldVisitNames= true; shouldVisitAmbiguousNodes=true;} @Override public int visit(IASTName name) { if (name instanceof ICPPASTTemplateId) @@ -1613,7 +1583,7 @@ public class CPPTemplates { } private static ICPPASTInternalTemplateDeclaration getDirectlyEnclosingTemplateDeclaration( - ICPPASTInternalTemplateDeclaration tdecl) { + ICPPASTInternalTemplateDeclaration tdecl ) { final IASTNode parent= tdecl.getParent(); if (parent instanceof ICPPASTInternalTemplateDeclaration) return (ICPPASTInternalTemplateDeclaration) parent; @@ -1681,7 +1651,7 @@ public class CPPTemplates { if (args.length != specArgs.length) { return false; } - for (int i= 0; i < args.length; i++) { + for (int i=0; i < args.length; i++) { if (!specArgs[i].isSameValue(args[i])) return false; } @@ -1707,10 +1677,6 @@ public class CPPTemplates { IType type= expr.getExpressionType(); IValue value= Value.create((IASTExpression) arg, Value.MAX_RECURSION_DEPTH); result[i]= new CPPTemplateArgument(value, type); - } else if (arg instanceof ICPPASTAmbiguousTemplateArgument) { - throw new IllegalArgumentException(id.getRawSignature() - + " contains an ambiguous template argument at position " + i + " in " //$NON-NLS-1$ //$NON-NLS-2$ - + id.getContainingFilename()); } else { throw new IllegalArgumentException("Unexpected type: " + arg.getClass().getName()); //$NON-NLS-1$ } @@ -1797,7 +1763,7 @@ public class CPPTemplates { static ICPPFunction[] instantiateConversionTemplates(ICPPFunction[] functions, IType conversionType, IASTNode point) { boolean checkedForDependentType= false; ICPPFunction[] result= functions; - int i= 0; + int i=0; boolean done= false; for (ICPPFunction f : functions) { ICPPFunction inst = f; @@ -1998,7 +1964,7 @@ public class CPPTemplates { } private static IType[] concat(final IType t, IType[] types) { - IType[] result= new IType[types.length + 1]; + IType[] result= new IType[types.length+1]; result[0]= t; System.arraycopy(types, 0, result, 1, types.length); return result; @@ -2221,8 +2187,8 @@ public class CPPTemplates { private static boolean matchTemplateTemplateParameters(ICPPTemplateParameter[] pParams, ICPPTemplateParameter[] aParams) throws DOMException { - int pi= 0; - int ai= 0; + int pi=0; + int ai=0; while (pi < pParams.length && ai < aParams.length) { final ICPPTemplateParameter pp = pParams[pi]; final ICPPTemplateParameter ap = aParams[ai]; @@ -2255,9 +2221,8 @@ public class CPPTemplates { } if (!matchTemplateTemplateParameters(((ICPPTemplateTemplateParameter) pp).getTemplateParameters(), - ((ICPPTemplateTemplateParameter) ap).getTemplateParameters())) { + ((ICPPTemplateTemplateParameter) ap).getTemplateParameters()) ) return false; - } } } if (!pp.isParameterPack()) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java index 287193e6200..696a8db4a1d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java @@ -108,7 +108,32 @@ public class EvalBinary extends CPPEvaluation { @Override public IValue getValue(IASTNode point) { - return Value.create(this, point); + if (fOverload != null) { + // TODO(sprigogin): Simulate execution of a function call. + return Value.create(this); + } + + IValue v1 = fArg1.getValue(point); + IValue v2 = fArg2.getValue(point); + switch (fOperator) { + case IASTBinaryExpression.op_equals: + if (v1.equals(v2)) + return Value.create(1); + break; + case IASTBinaryExpression.op_notequals: + if (v1.equals(v2)) + return Value.create(0); + break; + } + + Long num1 = v1.numericalValue(); + if (num1 != null) { + Long num2 = v2.numericalValue(); + if (num2 != null) { + return Value.evaluateBinaryExpression(fOperator, num1, num2); + } + } + return Value.create(this); } @Override @@ -289,4 +314,9 @@ public class EvalBinary extends CPPEvaluation { return this; return new EvalBinary(fOperator, arg1, arg2); } + + @Override + public int determinePackSize(ICPPTemplateParameterMap tpMap) { + return CPPTemplates.combinePackSize(fArg1.determinePackSize(tpMap), fArg2.determinePackSize(tpMap)); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java index 200528f18f3..d89d8ddd6e9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java @@ -20,12 +20,14 @@ import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; 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.CPPBasicType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.core.runtime.CoreException; @@ -78,7 +80,16 @@ public class EvalBinaryTypeId extends CPPEvaluation { @Override public IValue getValue(IASTNode point) { - return Value.create(this, point); + if (isValueDependent()) + return Value.create(this); + + switch (fOperator) { + case __is_base_of: + if (!(fType1 instanceof ICPPClassType) || !(fType1 instanceof ICPPClassType)) + return Value.UNKNOWN; + return Value.create(ClassTypeHelper.isSubclass((ICPPClassType) fType2, (ICPPClassType) fType1)); + } + return Value.create(this); } @Override @@ -124,4 +135,10 @@ public class EvalBinaryTypeId extends CPPEvaluation { return this; return new EvalBinaryTypeId(fOperator, type1, type2); } + + @Override + public int determinePackSize(ICPPTemplateParameterMap tpMap) { + return CPPTemplates.combinePackSize(CPPTemplates.determinePackSize(fType1, tpMap), + CPPTemplates.determinePackSize(fType2, tpMap)); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java index f7d9e02e0ea..1427b733c63 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java @@ -26,9 +26,13 @@ import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; +import org.eclipse.cdt.internal.core.dom.parser.IInternalVariable; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ProblemType; @@ -164,7 +168,21 @@ public class EvalBinding extends CPPEvaluation { @Override public IValue getValue(IASTNode point) { - return Value.create(this, point); + if (isValueDependent()) + return Value.create(this); + + IValue value= null; + if (fBinding instanceof IInternalVariable) { + value= ((IInternalVariable) fBinding).getInitialValue(Value.MAX_RECURSION_DEPTH); + } else if (fBinding instanceof IVariable) { + value= ((IVariable) fBinding).getInitialValue(); + } else if (fBinding instanceof IEnumerator) { + value= ((IEnumerator) fBinding).getValue(); + } + if (value == null) + value = Value.UNKNOWN; + + return value; } @Override @@ -223,4 +241,32 @@ public class EvalBinding extends CPPEvaluation { return this; return new EvalBinding(binding, getFixedType()); } + + @Override + public int determinePackSize(ICPPTemplateParameterMap tpMap) { + if (fBinding instanceof IEnumerator) { + return CPPTemplates.determinePackSize(((IEnumerator) fBinding).getValue(), tpMap); + } + if (fBinding instanceof ICPPTemplateNonTypeParameter) { + return CPPTemplates.determinePackSize((ICPPTemplateNonTypeParameter) fBinding, tpMap); + } + if (fBinding instanceof ICPPUnknownBinding) { + return CPPTemplates.determinePackSize((ICPPUnknownBinding) fBinding, tpMap); + } + + IBinding binding = fBinding; + if (fBinding instanceof ICPPSpecialization) { + binding = ((ICPPSpecialization) fBinding).getSpecializedBinding(); + } + + int r = CPPTemplates.PACK_SIZE_NOT_FOUND; + if (binding instanceof ICPPTemplateDefinition) { + ICPPTemplateParameter[] parameters = ((ICPPTemplateDefinition) binding).getTemplateParameters(); + for (ICPPTemplateParameter param : parameters) { + r = CPPTemplates.combinePackSize(r, CPPTemplates.determinePackSize(param, tpMap)); + } + } + + return r; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java index 970f22afe81..2cf29f4343b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java @@ -68,6 +68,7 @@ public class EvalComma extends CPPEvaluation { @Override public boolean isValueDependent() { + // TODO(sprigogin): Should the value depend only on the last argument? for (ICPPEvaluation arg : fArguments) { if (arg.isValueDependent()) return true; @@ -126,12 +127,18 @@ public class EvalComma extends CPPEvaluation { return typeFromFunctionCall(last); } } - return fArguments[fArguments.length-1].getTypeOrFunctionSet(point); + return fArguments[fArguments.length - 1].getTypeOrFunctionSet(point); } @Override public IValue getValue(IASTNode point) { - return Value.create(this, point); + ICPPFunction[] overloads = getOverloads(point); + if (overloads.length > 0) { + // TODO(sprigogin): Simulate execution of a function call. + return Value.create(this); + } + + return fArguments[fArguments.length - 1].getValue(point); } @Override @@ -143,7 +150,7 @@ public class EvalComma extends CPPEvaluation { return valueCategoryFromFunctionCall(last); } } - return fArguments[fArguments.length-1].getValueCategory(point); + return fArguments[fArguments.length - 1].getValueCategory(point); } @Override @@ -178,4 +185,13 @@ public class EvalComma extends CPPEvaluation { return this; return new EvalComma(args); } + + @Override + public int determinePackSize(ICPPTemplateParameterMap tpMap) { + int r = CPPTemplates.PACK_SIZE_NOT_FOUND; + for (ICPPEvaluation arg : fArguments) { + r = CPPTemplates.combinePackSize(r, arg.determinePackSize(tpMap)); + } + return r; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalCompound.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalCompound.java index f926d275632..1175d6b8e72 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalCompound.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalCompound.java @@ -21,7 +21,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; 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.ICPPEvaluation; import org.eclipse.core.runtime.CoreException; @@ -66,7 +65,7 @@ public class EvalCompound extends CPPEvaluation { @Override public IValue getValue(IASTNode point) { - return Value.create(this, point); + return fDelegate.getValue(point); } @Override @@ -93,4 +92,9 @@ public class EvalCompound extends CPPEvaluation { return this; return new EvalCompound(delegate); } + + @Override + public int determinePackSize(ICPPTemplateParameterMap tpMap) { + return fDelegate.determinePackSize(tpMap); + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java index 1ce00dddc1c..772928eac3b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java @@ -108,7 +108,18 @@ public class EvalConditional extends CPPEvaluation { @Override public IValue getValue(IASTNode point) { - return Value.create(this, point); + IValue condValue = fCondition.getValue(point); + if (condValue == Value.UNKNOWN) + return Value.UNKNOWN; + Long cond = condValue.numericalValue(); + if (cond != null) { + if (cond.longValue() != 0) { + return fPositive == null ? condValue : fPositive.getValue(point); + } else { + return fNegative.getValue(point); + } + } + return Value.create(this); } @Override @@ -324,4 +335,13 @@ public class EvalConditional extends CPPEvaluation { return this; return new EvalConditional(condition, positive, negative, fPositiveThrows, fNegativeThrows); } + + @Override + public int determinePackSize(ICPPTemplateParameterMap tpMap) { + int r = fCondition.determinePackSize(tpMap); + r = CPPTemplates.combinePackSize(r, fNegative.determinePackSize(tpMap)); + if (fPositive != null) + r = CPPTemplates.combinePackSize(r, fPositive.determinePackSize(tpMap)); + return r; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFixed.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFixed.java index a985473ba7a..f3892911125 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFixed.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFixed.java @@ -158,4 +158,9 @@ public class EvalFixed extends CPPEvaluation { return this; return new EvalFixed(type, fValueCategory, value); } + + @Override + public int determinePackSize(ICPPTemplateParameterMap tpMap) { + return CPPTemplates.determinePackSize(fValue, tpMap); + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java index b8d8e7808e9..eba7284d57d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java @@ -135,7 +135,10 @@ public class EvalFunctionCall extends CPPEvaluation { @Override public IValue getValue(IASTNode point) { - return Value.create(this, point); + if (isValueDependent()) + return Value.create(this); + // TODO(sprigogin): Simulate execution of a function call. + return Value.UNKNOWN; } @Override @@ -170,7 +173,7 @@ public class EvalFunctionCall extends CPPEvaluation { for (int i = 0; i < args.length; i++) { args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation(); } - return new EvalComma(args); + return new EvalFunctionCall(args); } @Override @@ -187,4 +190,13 @@ public class EvalFunctionCall extends CPPEvaluation { return this; return new EvalFunctionCall(args); } + + @Override + public int determinePackSize(ICPPTemplateParameterMap tpMap) { + int r = CPPTemplates.PACK_SIZE_NOT_FOUND; + for (ICPPEvaluation arg : fArguments) { + r = CPPTemplates.combinePackSize(r, arg.determinePackSize(tpMap)); + } + return r; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java index 70f8e72d589..fbf64b923a8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java @@ -171,4 +171,14 @@ public class EvalFunctionSet extends CPPEvaluation { return this; return new EvalFunctionSet(new CPPFunctionSet(functions, arguments, null), fAddressOf); } + + @Override + public int determinePackSize(ICPPTemplateParameterMap tpMap) { + int r = CPPTemplates.PACK_SIZE_NOT_FOUND; + ICPPTemplateArgument[] templateArguments = fFunctionSet.getTemplateArguments(); + for (ICPPTemplateArgument arg : templateArguments) { + r = CPPTemplates.combinePackSize(r, CPPTemplates.determinePackSize(arg, tpMap)); + } + return r; + } } 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 eeae6cc797c..7f4d466af0a 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 @@ -70,6 +70,9 @@ public class EvalID extends CPPEvaluation { fTemplateArgs= templateArgs; } + /** + * Returns the field owner expression, or {@code null}. + */ public ICPPEvaluation getFieldOwner() { return fFieldOwner; } @@ -90,6 +93,9 @@ public class EvalID extends CPPEvaluation { return fQualified; } + /** + * Returns the template arguments, or {@code null} if there are no template arguments. + */ public ICPPTemplateArgument[] getTemplateArgs() { return fTemplateArgs; } @@ -121,7 +127,7 @@ public class EvalID extends CPPEvaluation { @Override public IValue getValue(IASTNode point) { - return Value.create(this, point); + return Value.create(this); } @Override @@ -256,14 +262,19 @@ public class EvalID extends CPPEvaluation { @Override public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, int maxdepth, IASTNode point) { - ICPPTemplateArgument[] arguments = fTemplateArgs; - try { - arguments = CPPTemplates.instantiateArguments(fTemplateArgs, tpMap, packOffset, within, point); - } catch (DOMException e) { - CCorePlugin.log(e); + ICPPTemplateArgument[] templateArgs = fTemplateArgs; + if (templateArgs != null) { + try { + templateArgs = CPPTemplates.instantiateArguments(templateArgs, tpMap, packOffset, within, point); + } catch (DOMException e) { + CCorePlugin.log(e); + } } - ICPPEvaluation fieldOwner = fFieldOwner.instantiate(tpMap, packOffset, within, maxdepth, point); + ICPPEvaluation fieldOwner = fFieldOwner; + if (fieldOwner != null) { + fieldOwner = fieldOwner.instantiate(tpMap, packOffset, within, maxdepth, point); + } IBinding nameOwner = fNameOwner; if (fNameOwner instanceof ICPPTemplateParameter) { ICPPTemplateArgument argument = tpMap.getArgument((ICPPTemplateParameter) fNameOwner); @@ -280,16 +291,16 @@ public class EvalID extends CPPEvaluation { CCorePlugin.log(e); } } - if (Arrays.equals(arguments, fTemplateArgs) && fieldOwner == fFieldOwner && nameOwner == fNameOwner) + if (Arrays.equals(templateArgs, fTemplateArgs) && fieldOwner == fFieldOwner && nameOwner == fNameOwner) return this; - if (nameOwner == null) - nameOwner = (IBinding) fFieldOwner.getTypeOrFunctionSet(point); + if (nameOwner == null && fieldOwner != null) + nameOwner = (IBinding) fieldOwner.getTypeOrFunctionSet(point); - if (nameOwner instanceof ICompositeType) { + if (nameOwner instanceof ICompositeType && point != null) { ICompositeType ownerType = (ICompositeType) nameOwner; // TODO(sprigogin): Is this the right way to do lookup, or should findBindings be used instead? - LookupData data = new LookupData(fName, fTemplateArgs, point); + LookupData data = new LookupData(fName, templateArgs, point); try { CPPSemantics.lookup(data, ownerType.getScope()); } catch (DOMException e) { @@ -305,6 +316,15 @@ public class EvalID extends CPPEvaluation { } } - return new EvalID(fieldOwner, nameOwner, fName, fAddressOf, fQualified, arguments); + return new EvalID(fieldOwner, nameOwner, fName, fAddressOf, fQualified, templateArgs); + } + + @Override + public int determinePackSize(ICPPTemplateParameterMap tpMap) { + int r = fFieldOwner.determinePackSize(tpMap); + for (ICPPTemplateArgument arg : fTemplateArgs) { + r = CPPTemplates.combinePackSize(r, CPPTemplates.determinePackSize(arg, tpMap)); + } + return r; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java index 96e97581088..02469d272ef 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java @@ -74,7 +74,9 @@ public class EvalInitList extends CPPEvaluation { @Override public IValue getValue(IASTNode point) { - return Value.create(this, point); + if (isValueDependent()) + return Value.create(this); + return Value.UNKNOWN; // TODO(sprigogin): Is this correct? } @Override @@ -97,7 +99,7 @@ public class EvalInitList extends CPPEvaluation { for (int i = 0; i < args.length; i++) { args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation(); } - return new EvalComma(args); + return new EvalInitList(args); } @Override @@ -114,4 +116,13 @@ public class EvalInitList extends CPPEvaluation { return this; return new EvalInitList(clauses); } + + @Override + public int determinePackSize(ICPPTemplateParameterMap tpMap) { + int r = CPPTemplates.PACK_SIZE_NOT_FOUND; + for (ICPPEvaluation arg : fClauses) { + r = CPPTemplates.combinePackSize(r, arg.determinePackSize(tpMap)); + } + return r; + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalMemberAccess.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalMemberAccess.java index fc60209bfed..ff097057121 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalMemberAccess.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalMemberAccess.java @@ -254,7 +254,16 @@ public class EvalMemberAccess extends CPPEvaluation { @Override public IValue getValue(IASTNode point) { - return Value.create(this, point); + if (fMember instanceof IEnumerator) { + return ((IEnumerator) fMember).getValue(); + } + if (fMember instanceof IVariable) { + return ((IVariable) fMember).getInitialValue(); + } + if (fMember instanceof IFunction) { + return Value.UNKNOWN; + } + return Value.create(this); } @Override @@ -324,4 +333,9 @@ public class EvalMemberAccess extends CPPEvaluation { } return new EvalMemberAccess(ownerType, fOwnerValueCategory, member, fIsPointerDeref); } + + @Override + public int determinePackSize(ICPPTemplateParameterMap tpMap) { + return CPPTemplates.determinePackSize(fOwnerType, tpMap); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java index e78725f1552..50719af6fd0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java @@ -19,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; @@ -73,7 +74,20 @@ public class EvalTypeId extends CPPEvaluation { @Override public IValue getValue(IASTNode point) { - return Value.create(this, point); + if (isValueDependent()) + return Value.create(this); + if (fArguments == null) + return Value.UNKNOWN; + + if (isTypeDependent()) + return Value.create(this); + if (fOutputType instanceof ICPPClassType) { + // TODO(sprigogin): Simulate execution of a ctor call. + return Value.UNKNOWN; + } + if (fArguments.length == 1) + return fArguments[0].getValue(point); + return Value.UNKNOWN; } @Override @@ -144,4 +158,13 @@ public class EvalTypeId extends CPPEvaluation { return this; return new EvalTypeId(type, args); } + + @Override + public int determinePackSize(ICPPTemplateParameterMap tpMap) { + int r = CPPTemplates.determinePackSize(fInputType, tpMap); + for (ICPPEvaluation arg : fArguments) { + r = CPPTemplates.combinePackSize(r, arg.determinePackSize(tpMap)); + } + return r; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java index ac40c69ebb4..1f44ac738e5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java @@ -205,7 +205,17 @@ public class EvalUnary extends CPPEvaluation { @Override public IValue getValue(IASTNode point) { - return Value.create(this, point); + if (fOverload != null) { + // TODO(sprigogin): Simulate execution of a function call. + return Value.create(this); + } + + IValue val = fArgument.getValue(point); + Long num = val.numericalValue(); + if (num != null) { + return Value.evaluateUnaryExpression(fOperator, num); + } + return Value.create(this); } @Override @@ -246,4 +256,9 @@ public class EvalUnary extends CPPEvaluation { return this; return new EvalUnary(fOperator, argument); } + + @Override + public int determinePackSize(ICPPTemplateParameterMap tpMap) { + return fArgument.determinePackSize(tpMap); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java index 03170775389..6fe24993a15 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java @@ -34,6 +34,8 @@ import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_typeof; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; @@ -41,6 +43,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ProblemType; +import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator; +import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment; import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; @@ -148,7 +152,56 @@ public class EvalUnaryTypeID extends CPPEvaluation { @Override public IValue getValue(IASTNode point) { - return Value.create(this, point); + if (isValueDependent()) + return Value.create(this); + + switch (fOperator) { + case op_sizeof: { + if (point == null) + return Value.UNKNOWN; + SizeAndAlignment info = new SizeofCalculator(point.getTranslationUnit()).sizeAndAlignment(fOrigType); + return info == null ? Value.UNKNOWN : Value.create(info.size); + } + case op_alignof: { + if (point == null) + return Value.UNKNOWN; + SizeAndAlignment info = new SizeofCalculator(point.getTranslationUnit()).sizeAndAlignment(fOrigType); + return info == null ? Value.UNKNOWN : Value.create(info.alignment); + } + case op_typeid: + return Value.UNKNOWN; // TODO(sprigogin): Implement + case op_has_nothrow_copy: + return Value.UNKNOWN; // TODO(sprigogin): Implement + case op_has_nothrow_constructor: + return Value.UNKNOWN; // TODO(sprigogin): Implement + case op_has_trivial_assign: + return Value.UNKNOWN; // TODO(sprigogin): Implement + case op_has_trivial_constructor: + return Value.UNKNOWN; // TODO(sprigogin): Implement + case op_has_trivial_copy: + return Value.UNKNOWN; // TODO(sprigogin): Implement + case op_has_trivial_destructor: + return Value.UNKNOWN; // TODO(sprigogin): Implement + case op_has_virtual_destructor: + return Value.UNKNOWN; // TODO(sprigogin): Implement + case op_is_abstract: + return Value.UNKNOWN; // TODO(sprigogin): Implement + case op_is_class: + return Value.create(fOrigType instanceof ICompositeType && ((ICompositeType) fOrigType).getKey() != ICompositeType.k_union); + case op_is_empty: + return Value.UNKNOWN; // TODO(sprigogin): Implement + case op_is_enum: + return Value.create(fOrigType instanceof IEnumeration); + case op_is_pod: + return Value.UNKNOWN; // TODO(sprigogin): Implement + case op_is_polymorphic: + return Value.UNKNOWN; // TODO(sprigogin): Implement + case op_is_union: + return Value.create(fOrigType instanceof ICompositeType && ((ICompositeType) fOrigType).getKey() == ICompositeType.k_union); + case op_typeof: + return Value.UNKNOWN; // TODO(sprigogin): Implement + } + return Value.create(this); } @Override @@ -177,4 +230,9 @@ public class EvalUnaryTypeID extends CPPEvaluation { return this; return new EvalUnaryTypeID(fOperator, type); } + + @Override + public int determinePackSize(ICPPTemplateParameterMap tpMap) { + return CPPTemplates.determinePackSize(fOrigType, tpMap); + } } 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 482571a9c84..45f376da9bc 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 @@ -425,16 +425,13 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { public IValue getCompositeValue(IValue v) { if (v == null) return null; - - IBinding[] b= v.getUnknownBindings(); - if (b.length == 0) + + ICPPEvaluation eval = v.getEvaluation(); + if (eval == null) return v; - - ICPPUnknownBinding[] b2= new ICPPUnknownBinding[b.length]; - for (int i = 0; i < b2.length; i++) { - b2[i]= (ICPPUnknownBinding) getCompositeBinding((IIndexFragmentBinding) b[i]); - } - return Value.fromInternalRepresentation(v.getInternalExpression(), b2); + + eval = getCompositeEvaluation(eval); + return Value.fromInternalRepresentation(eval); } private ICPPNamespace[] getNamespaces(IBinding rbinding) throws CoreException {