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 {