diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
index d1a4e75a18e..6a844012c8f 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
@@ -3184,7 +3184,7 @@ public class AST2TemplateTests extends AST2BaseTest {
// cb.b = 6;
// func(cb);
// }
- public void _testTemplateMetaProgramming_245027() throws Exception {
+ public void testTemplateMetaProgramming_245027() throws Exception {
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
ICPPMethod method= ba.assertNonProblem("method();", 6, ICPPMethod.class);
ICPPVariable a= ba.assertNonProblem("a =", 1, ICPPVariable.class);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java
index 63b6b8e7d48..c7e84dad164 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java
@@ -139,8 +139,9 @@ public class ASTTypeUtil {
* @since 5.1
*/
public static String getArgumentString(ICPPTemplateArgument arg, boolean normalize) {
- if (arg.isNonTypeValue())
- return arg.getNonTypeValue().getCanonicalRepresentation();
+ IValue val= arg.getNonTypeValue();
+ if (val != null)
+ return new String(val.getSignature());
return getType(arg.getTypeValue(), normalize);
}
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 aa3f02378a0..875312a19b6 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
@@ -23,9 +23,22 @@ public interface IValue {
Long numericalValue();
/**
- * Returns a canonical representation that is suitable for distinguishing
- * constant values for the purpose of template instantiation.
- * The representation may not be used to display the value.
+ * 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.
*/
- String getCanonicalRepresentation();
+ char[] getInternalExpression();
+
+ /**
+ * 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.
+ */
+ char[] getSignature();
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateParameterMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateParameterMap.java
index 59e21f693bf..68d022b0c58 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateParameterMap.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateParameterMap.java
@@ -14,14 +14,15 @@ package org.eclipse.cdt.core.dom.ast.cpp;
/**
* Models the mapping of template parameters to values.
* @since 5.1
+ * @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPTemplateParameterMap {
/**
- * Returns the value for the template parameter at the given position.
- * @see ICPPTemplateParameter#getParameterPosition()
+ * Returns the value for the template parameter with the given id.
+ * @see ICPPTemplateParameter#getParameterID()
*/
- public ICPPTemplateArgument getArgument(int paramPosition);
+ public ICPPTemplateArgument getArgument(int paramID);
/**
* Returns the value for the template parameter in the map, or null
if
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 e2e81d9d495..8bb0dc0a2f2 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
@@ -10,7 +10,12 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
-import org.eclipse.cdt.core.dom.ast.ASTSignatureUtil;
+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.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
@@ -25,9 +30,10 @@ 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.ICPPBinding;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
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.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator;
@@ -39,49 +45,135 @@ import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalExce
*/
public class Value implements IValue {
public static final int MAX_RECURSION_DEPTH = 25;
- public final static IValue UNKNOWN= new Value(""); //$NON-NLS-1$
+ public final static IValue UNKNOWN= new Value("".toCharArray(), ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY); //$NON-NLS-1$
- private final static IValue[] TYPICAL= {new Value(String.valueOf(0)),
- new Value(String.valueOf(1)), new Value(String.valueOf(2)), new Value(String.valueOf(3)),
- new Value(String.valueOf(4)), new Value(String.valueOf(5)), new Value(String.valueOf(6))};
+ 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 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)};
+ private static class Reevaluation {
+ public final char[] fExpression;
+ public int pos=0;
+ public final Map fUnknownSigs;
+ public final List fUnknowns;
+ public final IBinding[] fResolvedUnknown;
+ public final ICPPTemplateParameterMap fMap;
+ public Reevaluation(char[] expr, Map unknownSigs, List unknowns, IBinding[] resolvedUnknowns, ICPPTemplateParameterMap map) {
+ fExpression= expr;
+ fUnknownSigs= unknownSigs;
+ fUnknowns= unknowns;
+ fResolvedUnknown= resolvedUnknowns;
+ fMap= map;
+ }
+ public void nextSeperator() 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 String fValue;
- private Value(String rep) {
+ private final char[] fExpression;
+ private final ICPPUnknownBinding[] fUnknownBindings;
+ private char[] fSignature;
+
+ private Value(char[] rep, ICPPUnknownBinding[] unknown) {
assert rep != null;
- fValue= rep;
+ fExpression= rep;
+ fUnknownBindings= unknown;
}
- public String getCanonicalRepresentation() {
- return fValue;
+
+ public char[] getInternalExpression() {
+ return fExpression;
}
- public Long numericalValue() {
- try {
- return Long.parseLong(fValue);
- } catch (NumberFormatException e) {
+ public IBinding[] getUnknownBindings() {
+ return fUnknownBindings;
+ }
+
+ 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);
+ }
}
- return null;
+ return fSignature;
+ }
+
+ public Long numericalValue() {
+ return parseLong(fExpression);
}
@Override
public int hashCode() {
- return fValue.hashCode();
+ return CharArrayUtils.hash(fExpression);
}
+
@Override
public boolean equals(Object obj) {
if (!(obj instanceof IValue)) {
return false;
}
- return fValue.equals(((IValue) obj).getCanonicalRepresentation());
+ 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;
}
@Override
public String toString() {
- return fValue;
+ return new String(getSignature());
}
/**
@@ -90,37 +182,68 @@ public class Value implements IValue {
public static IValue create(long value) {
if (value >=0 && value < TYPICAL.length)
return TYPICAL[(int) value];
- return new Value(String.valueOf(value));
+ return new Value(toCharArray(value), ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY);
}
/**
* Creates a value representing the given template parameter.
*/
public static IValue create(ICPPTemplateNonTypeParameter tntp) {
- return new Value(evaluate(tntp));
+ final String expr = createTemplateParamExpression(tntp.getParameterID());
+ return new Value(expr.toCharArray(), ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY);
+ }
+
+ private static String createTemplateParamExpression(int id) {
+ StringBuilder buf= new StringBuilder();
+ buf.append(TEMPLATE_PARAM_CHAR);
+ buf.append(Integer.toHexString(id));
+ return buf.toString();
}
/**
* Tests whether the value is a template parameter, returns the parameter id of the
- * parameter, or null
if it is not a template parameter.
+ * parameter, or -1
if it is not a template parameter.
*/
public static int isTemplateParameter(IValue tval) {
- final String rep= tval.getCanonicalRepresentation();
- if (rep.indexOf('#') == 0 && rep.indexOf(',') == -1) {
- try {
- return Integer.parseInt(rep.substring(1), 16);
- } catch (NumberFormatException e) {
+ final char[] rep= tval.getInternalExpression();
+ if (rep.length > 0) {
+ if (rep[0] == TEMPLATE_PARAM_CHAR) {
+ for (int i = 1; i < rep.length; i++) {
+ if (rep[i] == SEPARATOR)
+ return -1;
+ }
+ try {
+ return parseHex(rep, 1);
+ } catch (UnknownValueException e) {
+ }
}
}
return -1;
}
+
+ /**
+ * Tests whether the value directly references some template parameter.
+ */
+ public static boolean referencesTemplateParameter(IValue tval) {
+ final char[] rep= tval.getInternalExpression();
+ for (int i = 0; i < rep.length; i++) {
+ if (rep[i] == TEMPLATE_PARAM_CHAR)
+ return true;
+ }
+ return false;
+ }
/**
* Tests whether the value depends on a template parameter.
*/
public static boolean isDependentValue(IValue nonTypeValue) {
- final String rep= nonTypeValue.getCanonicalRepresentation();
- return rep.indexOf('#') >= 0;
+ final char[] rep= nonTypeValue.getInternalExpression();
+ for (int i = 0; i < rep.length; i++) {
+ final char c = rep[i];
+ if (c == REFERENCE_CHAR || c == TEMPLATE_PARAM_CHAR)
+ return true;
+ }
+ return false;
}
/**
@@ -128,10 +251,19 @@ public class Value implements IValue {
*/
public static IValue create(IASTExpression expr, int maxRecursionDepth) {
try {
- Object obj= evaluate(expr, maxRecursionDepth);
- if (obj instanceof Long)
- return create(((Long) obj).longValue());
- return new Value(obj.toString());
+ Map unknownSigs= new HashMap();
+ List unknown= new ArrayList();
+ Object obj= evaluate(expr, unknownSigs, unknown, maxRecursionDepth);
+ 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;
@@ -140,104 +272,78 @@ public class Value implements IValue {
/**
* Creates a value off its canonical representation.
*/
- public static IValue fromCanonicalRepresentation(String rep) {
- if (rep.equals(UNKNOWN.getCanonicalRepresentation()))
+ public static IValue fromInternalRepresentation(char[] rep, ICPPUnknownBinding[] unknown) {
+ if (CharArrayUtils.equals(rep, UNKNOWN.getInternalExpression()))
return UNKNOWN;
- try {
- return create(Long.parseLong(rep));
- } catch (NumberFormatException e) {}
+ Long l= parseLong(rep);
+ if (l != null)
+ return create(l.longValue());
- return new Value(rep);
+ return new Value(rep, unknown);
}
/**
* Creates a unique value needed during template instantiation.
*/
public static IValue unique() {
- return new Value("@" + (++sUnique)); //$NON-NLS-1$
+ StringBuilder buf= new StringBuilder(10);
+ buf.append(UNIQUE_CHAR);
+ buf.append(++sUnique);
+ return new Value(extractChars(buf), ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY);
}
/**
- * Computes the canonical representation of the value of the expression. Returns a {@code Long} for
- * numerical values or a {@code String}, otherwise.
+ * Computes the canonical representation of the value of the expression.
+ * Returns a {@code Number} for numerical values or a {@code String}, otherwise.
* @throws UnknownValueException
*/
- @SuppressWarnings("nls")
- private static Object evaluate(IASTExpression e, int maxdepth) throws UnknownValueException {
+ private static Object evaluate(IASTExpression e, Map unknownSigs, List unknowns, int maxdepth) throws UnknownValueException {
if (maxdepth < 0 || e == null)
throw UNKNOWN_EX;
if (e instanceof IASTArraySubscriptExpression) {
- IASTArraySubscriptExpression sub= (IASTArraySubscriptExpression) e;
- return evaluate(sub.getArrayExpression(), maxdepth) + "," +
- evaluate(sub.getSubscriptExpression(), maxdepth) + ",[]";
+ throw UNKNOWN_EX;
}
if (e instanceof IASTBinaryExpression) {
- return evaluateBinaryExpression((IASTBinaryExpression) e, maxdepth);
+ return evaluateBinaryExpression((IASTBinaryExpression) e, unknownSigs, unknowns, maxdepth);
}
if (e instanceof IASTCastExpression) { // must be ahead of unary
- return evaluate(((IASTCastExpression) e).getOperand(), maxdepth);
+ return evaluate(((IASTCastExpression) e).getOperand(), unknownSigs, unknowns, maxdepth);
}
if (e instanceof IASTUnaryExpression) {
- return evaluateUnaryExpression((IASTUnaryExpression) e, maxdepth);
+ return evaluateUnaryExpression((IASTUnaryExpression) e, unknownSigs, unknowns, maxdepth);
}
if (e instanceof IASTConditionalExpression) {
IASTConditionalExpression cexpr= (IASTConditionalExpression) e;
- Object o= evaluate(cexpr.getLogicalConditionExpression(), maxdepth);
+ Object o= evaluate(cexpr.getLogicalConditionExpression(), unknownSigs, unknowns, maxdepth);
if (o instanceof Long) {
Long v= (Long) o;
if (v.longValue() == 0) {
- return evaluate(cexpr.getNegativeResultExpression(), maxdepth);
+ 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, maxdepth);
+ return evaluate(pe, unknownSigs, unknowns, maxdepth);
}
final IASTExpression pe = cexpr.getPositiveResultExpression();
- Object po= pe == null ? o : evaluate(pe, maxdepth);
- return o + "," + evaluate(cexpr.getNegativeResultExpression(), maxdepth) + "," + po + '?';
+ 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() + SEPARATOR + neg.toString();
}
if (e instanceof IASTIdExpression) {
IBinding b= CPPASTNameBase.resolvePreBinding(((IASTIdExpression) e).getName());
- if (b instanceof ICPPTemplateParameter) {
- if (b instanceof ICPPTemplateNonTypeParameter) {
- return evaluate((ICPPTemplateParameter) b);
- }
- throw UNKNOWN_EX;
- }
- IValue cv= null;
- if (b instanceof IInternalVariable) {
- cv= ((IInternalVariable) b).getInitialValue(maxdepth-1);
- } else if (b instanceof IVariable) {
- cv= ((IVariable) b).getInitialValue();
- } else if (b instanceof IEnumerator) {
- cv= ((IEnumerator) b).getValue();
- } else if (b instanceof ICPPUnknownBinding && !(b instanceof IType)) {
- return "#0x0fffffff";
- // mstodo unknown bindings must be stored with the value, such that they can
- // be instantiated lated on, bug 245027
- }
- if (cv != null)
- return toObject(cv);
-
- try {
- if (b instanceof ICPPBinding)
- return ((ICPPBinding) b).getQualifiedName();
- return b.getName();
- } catch (DOMException e1) {
- throw UNKNOWN_EX;
- }
+ return evaluateBinding(b, unknownSigs, unknowns, maxdepth);
}
if (e instanceof IASTLiteralExpression) {
IASTLiteralExpression litEx= (IASTLiteralExpression) e;
switch (litEx.getKind()) {
case IASTLiteralExpression.lk_false:
- return "0";
+ return 0;
case IASTLiteralExpression.lk_true:
- return "1";
+ return 1;
case IASTLiteralExpression.lk_integer_constant:
try {
return ExpressionEvaluator.getNumber(litEx.getValue());
@@ -259,28 +365,104 @@ public class Value implements IValue {
throw UNKNOWN_EX;
}
- private static Object toObject(IValue cv) throws UnknownValueException {
+ /**
+ * Extract a value off a binding.
+ */
+ private static Object evaluateBinding(IBinding b, Map unknownSigs, List unknowns, int maxdepth) throws UnknownValueException {
+ if (b instanceof IType) {
+ throw UNKNOWN_EX;
+ }
+ if (b instanceof ICPPTemplateNonTypeParameter)
+ return createTemplateParamExpression(((ICPPTemplateNonTypeParameter) b).getParameterID());
+
+ if (b instanceof ICPPUnknownBinding) {
+ return createReference((ICPPUnknownBinding) b, unknownSigs, unknowns);
+ }
+
+ IValue value= null;
+ if (b instanceof IInternalVariable) {
+ value= ((IInternalVariable) b).getInitialValue(maxdepth-1);
+ } else if (b instanceof IVariable) {
+ value= ((IVariable) b).getInitialValue();
+ } else if (b instanceof IEnumerator) {
+ value= ((IEnumerator) b).getValue();
+ }
+ if (value != null)
+ return evaluateValue(value, unknownSigs, unknowns);
+
+ 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();
+ }
+
+ 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;
- return cv.getCanonicalRepresentation();
+
+ 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();
}
- @SuppressWarnings("nls")
- private static String evaluate(ICPPTemplateParameter param) {
- return "#" + Integer.toHexString(param.getParameterID());
- }
-
- @SuppressWarnings("nls")
- private static Object evaluateUnaryExpression(IASTUnaryExpression ue, int maxdepth) throws UnknownValueException {
+ private static Object evaluateUnaryExpression(IASTUnaryExpression ue, Map unknownSigs, List unknowns, int maxdepth) throws UnknownValueException {
final int unaryOp= ue.getOperator();
if (unaryOp == IASTUnaryExpression.op_amper || unaryOp == IASTUnaryExpression.op_star)
throw UNKNOWN_EX;
- final Object value= evaluate(ue.getOperand(), maxdepth);
+ final Object value= evaluate(ue.getOperand(), unknownSigs, unknowns, maxdepth);
+ return combineUnary(unaryOp, value);
+ }
+
+ private static Object combineUnary(final int unaryOp, final Object value) throws UnknownValueException {
+ switch (unaryOp) {
+ case IASTUnaryExpression.op_bracketedPrimary:
+ case IASTUnaryExpression.op_plus:
+ return value;
+ }
+
if (value instanceof Long) {
long v= (Long) value;
switch(unaryOp) {
@@ -290,9 +472,6 @@ public class Value implements IValue {
case IASTUnaryExpression.op_prefixDecr :
case IASTUnaryExpression.op_postFixDecr:
return --v;
- case IASTUnaryExpression.op_bracketedPrimary:
- case IASTUnaryExpression.op_plus:
- return value;
case IASTUnaryExpression.op_minus:
return -v;
case IASTUnaryExpression.op_tilde:
@@ -300,22 +479,32 @@ public class Value implements IValue {
case IASTUnaryExpression.op_not:
return v == 0 ? 1 : 0;
}
- }
- switch (unaryOp) {
- case IASTUnaryExpression.op_bracketedPrimary:
- case IASTUnaryExpression.op_plus:
- return value;
- }
+ throw UNKNOWN_EX;
+ }
- return value + "," + ASTSignatureUtil.getUnaryOperatorString(ue);
+ switch (unaryOp) {
+ case IASTUnaryExpression.op_prefixIncr:
+ case IASTUnaryExpression.op_postFixIncr:
+ case IASTUnaryExpression.op_prefixDecr :
+ case IASTUnaryExpression.op_postFixDecr:
+ case IASTUnaryExpression.op_minus:
+ case IASTUnaryExpression.op_tilde:
+ case IASTUnaryExpression.op_not:
+ return UNARY_OP_CHAR + unaryOp + SEPARATOR + value.toString();
+ }
+ throw UNKNOWN_EX;
}
- @SuppressWarnings("nls")
- private static Object evaluateBinaryExpression(IASTBinaryExpression be, int maxdepth) throws UnknownValueException {
- final Object o1= evaluate(be.getOperand1(), maxdepth);
- final Object o2= evaluate(be.getOperand2(), maxdepth);
+ private static Object evaluateBinaryExpression(IASTBinaryExpression be,
+ Map unknownSigs, List unknowns, 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= be.getOperator();
+ return combineBinary(op, o1, o2);
+ }
+
+ private static Object combineBinary(final int op, final Object o1, final Object o2) throws UnknownValueException {
if (o1 instanceof Long && o2 instanceof Long) {
long v1= (Long) o1;
long v2= (Long) o2;
@@ -365,14 +554,274 @@ public class Value implements IValue {
case IASTBinaryExpression.op_min:
return Math.min(v1, v2);
}
+ throw UNKNOWN_EX;
}
switch (op) {
+ case IASTBinaryExpression.op_multiply:
+ case IASTBinaryExpression.op_divide:
+ case IASTBinaryExpression.op_modulo:
+ case IASTBinaryExpression.op_plus:
+ case IASTBinaryExpression.op_minus:
+ case IASTBinaryExpression.op_shiftLeft:
+ case IASTBinaryExpression.op_shiftRight:
+ case IASTBinaryExpression.op_lessThan:
+ case IASTBinaryExpression.op_greaterThan:
+ case IASTBinaryExpression.op_lessEqual:
+ case IASTBinaryExpression.op_greaterEqual:
+ case IASTBinaryExpression.op_binaryAnd:
+ case IASTBinaryExpression.op_binaryXor:
+ case IASTBinaryExpression.op_binaryOr:
+ case IASTBinaryExpression.op_logicalAnd:
+ case IASTBinaryExpression.op_logicalOr:
+ case IASTBinaryExpression.op_max:
+ case IASTBinaryExpression.op_min:
+ break;
case IASTBinaryExpression.op_equals:
- return o1.equals(o2) ? 1 : 0;
+ if (o1.equals(o2))
+ return 1;
+ break;
case IASTBinaryExpression.op_notequals:
- return !o1.equals(o2) ? 1 : 0;
+ if (o1.equals(o2))
+ return 0;
+ break;
+ default:
+ throw UNKNOWN_EX;
}
- return o1 + "," + o2 + "," + ASTSignatureUtil.getBinaryOperatorString(be);
+ return BINARY_OP_CHAR + op + SEPARATOR + o1.toString() + SEPARATOR + o2.toString();
+ }
+
+ public static IValue reevaluate(IValue val, IBinding[] resolvedUnknowns, ICPPTemplateParameterMap map, int maxdepth) {
+ try {
+ Map unknownSigs= new HashMap();
+ List unknown= new ArrayList();
+ Reevaluation reeval= new Reevaluation(val.getInternalExpression(),
+ unknownSigs, unknown,
+ resolvedUnknowns, map);
+ Object obj= reevaluate(reeval, maxdepth);
+ if (reeval.pos != reeval.fExpression.length)
+ return UNKNOWN;
+
+ 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()]);
+ }
+ 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.nextSeperator();
+ 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.nextSeperator();
+ o1= reevaluate(reeval, maxdepth);
+ return combineUnary(op, o1);
+ case CONDITIONAL_CHAR:
+ reeval.nextSeperator();
+ Object cond= reevaluate(reeval, maxdepth);
+ Object po= reevaluate(reeval, maxdepth);
+ Object neg= reevaluate(reeval, maxdepth);
+ if (cond instanceof Long) {
+ Long v= (Long) cond;
+ if (v.longValue() == 0) {
+ return neg;
+ }
+ return po;
+ }
+ return CONDITIONAL_CHAR + SEPARATOR + cond.toString() + SEPARATOR + 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.nextSeperator();
+ return evaluateBinding(resolvedUnknowns[num], reeval.fUnknownSigs, reeval.fUnknowns, maxdepth);
+
+ case TEMPLATE_PARAM_CHAR:
+ num= parseHex(buf, idx+1);
+ reeval.nextSeperator();
+ 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);
+
+ default:
+ reeval.nextSeperator();
+ 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;
+ }
+
+ /**
+ * Parses a long, returns null
if not possible
+ */
+ private static Long parseLong(char[] value) {
+ final long maxvalue= Long.MAX_VALUE/10;
+ final int len= value.length;
+ boolean negative= false;
+ long result = 0;
+ int i= 0;
+
+ if (len > 0 && value[0] == '-') {
+ negative = true;
+ i++;
+ }
+ if (i==len)
+ return null;
+
+ for(; i< len; i++) {
+ if (result > maxvalue)
+ return null;
+
+ final int digit= (value[i]- '0');
+ if (digit < 0 || digit > 9)
+ return null;
+ result= result*10 + digit;
+ }
+ return negative ? -result : result;
+ }
+
+ /**
+ * Computes a signature for an unknown binding.
+ */
+ private static String getSignatureForUnknown(ICPPUnknownBinding binding) {
+ try {
+ IBinding owner= binding.getOwner();
+ if (owner instanceof IType) {
+ return ASTTypeUtil.getType((IType) owner, true) + SCOPE_OP + binding.getName();
+ }
+ } catch (DOMException e) {
+ // ignore qualification
+ }
+ 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;
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldSpecialization.java
index 3dddadfac83..5afae0f97df 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldSpecialization.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldSpecialization.java
@@ -91,9 +91,9 @@ public class CPPFieldSpecialization extends CPPSpecialization implements ICPPFie
if (field instanceof IInternalVariable) {
v= ((IInternalVariable) field).getInitialValue(maxRecursionDepth);
} else {
- v= specializeValue(getField().getInitialValue());
+ v= getField().getInitialValue();
}
- value= specializeValue(v);
+ value= specializeValue(v, maxRecursionDepth);
}
return value;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSpecialization.java
index 2238c39ff55..4be0e055518 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSpecialization.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSpecialization.java
@@ -59,8 +59,12 @@ public abstract class CPPSpecialization extends PlatformObject implements ICPPSp
}
}
- public IValue specializeValue(IValue value) {
- return CPPTemplates.instantiateValue(value, getTemplateParameterMap());
+ public IValue specializeValue(IValue value, int maxdepth) {
+ if (owner instanceof ICPPClassSpecialization) {
+ return CPPTemplates.instantiateValue(value, getTemplateParameterMap(), (ICPPClassSpecialization) owner, maxdepth);
+ } else {
+ return CPPTemplates.instantiateValue(value, getTemplateParameterMap(), null, maxdepth);
+ }
}
public IBinding getSpecializedBinding() {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPUnknownBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPUnknownBinding.java
index 205286015e0..f02f0b6820c 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPUnknownBinding.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPUnknownBinding.java
@@ -19,7 +19,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
* Represents the binding for a dependent name within a template declaration.
*/
public interface ICPPUnknownBinding extends ICPPBinding {
-
+ ICPPUnknownBinding[] EMPTY_UNKNOWN_BINDING_ARRAY = {};
+
/**
* Returns the scope this binding represents.
* @throws DOMException
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 eb30b9d6da3..6ffd8c6e480 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
@@ -122,6 +122,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTemplateParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedefSpecialization;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClass;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownFunction;
@@ -712,19 +713,38 @@ public class CPPTemplates {
return spec;
}
- public static IValue instantiateValue(IValue value, ICPPTemplateParameterMap tpMap) {
+ public static IValue instantiateValue(IValue value, ICPPTemplateParameterMap tpMap, ICPPClassSpecialization within, int maxdepth) {
if (value == null)
return null;
- // mstodo- instantiate values correctly
- int parPos= Value.isTemplateParameter(value);
- if (parPos >= 0) {
- ICPPTemplateArgument arg = tpMap.getArgument(parPos);
- if (arg != null) {
- IValue mappedValue = arg.getNonTypeValue();
- if (mappedValue != null)
- return mappedValue;
+ 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, within);
+ } 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, resolvedUnknowns, tpMap, maxdepth);
+
+ if (Value.referencesTemplateParameter(value))
+ return Value.reevaluate(value, unknowns, tpMap, maxdepth);
+
return value;
}
@@ -867,7 +887,7 @@ public class CPPTemplates {
ICPPTemplateParameterMap tpMap, ICPPClassSpecialization within) {
if (arg.isNonTypeValue()) {
final IValue orig= arg.getNonTypeValue();
- final IValue inst= instantiateValue(orig, tpMap);
+ final IValue inst= instantiateValue(orig, tpMap, within, Value.MAX_RECURSION_DEPTH);
if (orig == inst)
return arg;
return new CPPTemplateArgument(inst, arg.getTypeOfNonTypeValue());
@@ -1899,7 +1919,7 @@ public class CPPTemplates {
if (map != null && pType != null) {
pType= instantiateType(pType, map, null);
}
- if (isNonTypeArgumentConvertible(pType, argType)) {
+ if (argType instanceof ICPPUnknownType || isNonTypeArgumentConvertible(pType, argType)) {
return new CPPTemplateArgument(arg.getNonTypeValue(), pType);
}
return null;
@@ -2047,11 +2067,15 @@ public class CPPTemplates {
if (!t.equals(owner) && newArgs != arguments) {
result= new CPPUnknownClassInstance((ICPPUnknownBinding) t, ucli.getUnknownName(), newArgs);
}
- } else if (unknown instanceof ICPPUnknownClassType) {
- if (!t.equals(owner)) {
- result= new CPPUnknownClass((ICPPUnknownBinding)t, ((ICPPUnknownClassType)unknown).getUnknownName());
+ } else if (!t.equals(owner)) {
+ if (unknown instanceof ICPPUnknownClassType) {
+ result= new CPPUnknownClass((ICPPUnknownBinding)t, unknown.getUnknownName());
+ } else if (unknown instanceof IFunction) {
+ result= new CPPUnknownClass((ICPPUnknownBinding)t, unknown.getUnknownName());
+ } else {
+ result= new CPPUnknownBinding((ICPPUnknownBinding) t, unknown.getUnknownName());
}
- }
+ }
} else if (t instanceof ICPPClassType) {
IScope s = ((ICPPClassType) t).getCompositeScope();
if (s != null && ASTInternal.isFullyCached(s)) {
@@ -2081,7 +2105,7 @@ public class CPPTemplates {
return result;
}
-
+
private static IBinding resolveDeferredClassInstance(ICPPDeferredClassInstance dci, ICPPTemplateParameterMap tpMap, ICPPClassSpecialization within) {
ICPPTemplateArgument[] arguments = dci.getTemplateArguments();
ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments(arguments, tpMap, within);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
index 26a3057fb04..75621c6fdc7 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
@@ -168,11 +168,12 @@ public class PDOM extends PlatformObject implements IPDOM {
* 76.0 - support for exception specification, bug 252697
* 77.0 - support for parameter annotations, bug 254520
* 78.0 - support for updating class templates, bug 254520
+ * 79.0 - instantiation of values, bug 245027
*/
private static int version(int major, int minor) {
return major << 16 + minor;
}
- public static final int MAJOR_VERSION = 78;
+ public static final int MAJOR_VERSION = 79;
public static final int MINOR_VERSION = 0; // minor versions must be compatible
public static final int CURRENT_VERSION= version(MAJOR_VERSION, MINOR_VERSION);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java
index 16b8faa9291..f2fea7cf248 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java
@@ -383,6 +383,13 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
public String toString() {
return getLinkageName();
}
-
-
+
+ /**
+ * Usually bindings are added on behalf of a name, only. For unknown values we need to
+ * add further bindings.
+ * @throws CoreException
+ */
+ public PDOMBinding addUnknownValue(IBinding binding) throws CoreException {
+ return null;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMValue.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMValue.java
new file mode 100644
index 00000000000..e6da5ee943f
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMValue.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.pdom.dom;
+
+import org.eclipse.cdt.core.dom.ast.IBinding;
+import org.eclipse.cdt.core.dom.ast.IValue;
+import org.eclipse.cdt.internal.core.dom.parser.Value;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
+import org.eclipse.cdt.internal.core.pdom.db.Database;
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * Helper class for storing values in the index.
+ */
+public class PDOMValue {
+
+ /**
+ * Stores a value and returns the offset of where it was stored.
+ * @throws CoreException
+ */
+ public static int store(Database db, PDOMLinkage linkage, IValue val) throws CoreException {
+ if (val == null)
+ return 0;
+
+ final IBinding[] unknown= val.getUnknownBindings();
+ int[] unknownRecs= {};
+ if (unknown.length != 0) {
+ unknownRecs= new int[unknown.length];
+ for (int i = 0; i < unknown.length; i++) {
+ PDOMNode node= linkage.addUnknownValue(unknown[i]);
+ if (node == null) {
+ return store(db, linkage, Value.UNKNOWN);
+ }
+ unknownRecs[i]= node.getRecord();
+ }
+ }
+
+ final short len= (short) Math.min(unknown.length, (Database.MAX_MALLOC_SIZE-6)/4);
+ final int block= db.malloc(6+4*len);
+ final int repRec= db.newString(val.getInternalExpression()).getRecord();
+
+ db.putShort(block, len);
+ db.putInt(block+2, repRec);
+
+ int p= block+6;
+ for (int i = 0; i < len; i++) {
+ db.putInt(p, unknownRecs[i]);
+ p+= 4;
+ }
+ return block;
+ }
+
+ /**
+ * Restores a value from the given record
+ * @throws CoreException
+ */
+ public static IValue restore(Database db, PDOMLinkage linkage, int valRec) throws CoreException {
+ if (valRec == 0)
+ return null;
+
+ final int len= db.getShort(valRec);
+ final int repRec = db.getInt(valRec+2);
+ final char[] rep= db.getString(repRec).getChars();
+
+ if (len == 0)
+ return Value.fromInternalRepresentation(rep, ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY);
+
+ ICPPUnknownBinding[] unknown= new ICPPUnknownBinding[len];
+ int p= valRec+6;
+ for (int i = 0; i < unknown.length; i++) {
+ int rec= db.getInt(p);
+ PDOMNode node= linkage.getNode(rec);
+ if (node instanceof ICPPUnknownBinding) {
+ unknown[i]= (ICPPUnknownBinding) node;
+ } else {
+ return Value.UNKNOWN;
+ }
+ p+= 4;
+ }
+ return Value.fromInternalRepresentation(rep, unknown);
+ }
+
+
+ /**
+ * Deletes a value stored at the given record.
+ */
+ public static void delete(Database db, int valueRec) throws CoreException {
+ if (valueRec == 0)
+ return;
+ final int repRec = db.getInt(valueRec+2);
+ db.getString(repRec).delete();
+ db.free(valueRec);
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCVariable.java
index 7786f24997a..d70c70bc41f 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCVariable.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCVariable.java
@@ -20,7 +20,6 @@ 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.internal.core.Util;
-import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.c.CVariableReadWriteFlags;
import org.eclipse.cdt.internal.core.index.IIndexCBindingConstants;
import org.eclipse.cdt.internal.core.pdom.PDOM;
@@ -29,6 +28,7 @@ import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
+import org.eclipse.cdt.internal.core.pdom.dom.PDOMValue;
import org.eclipse.core.runtime.CoreException;
/**
@@ -76,7 +76,8 @@ class PDOMCVariable extends PDOMBinding implements IVariable {
private void setValue(final Database db, IVariable variable) throws CoreException {
IValue val= variable.getInitialValue();
- db.putInt(record + VALUE_OFFSET, val == null ? 0 : db.newString(val.getCanonicalRepresentation()).getRecord());
+ int valrec= PDOMValue.store(db, getLinkage(), val);
+ db.putInt(record + VALUE_OFFSET, valrec);
}
@Override
@@ -94,8 +95,7 @@ class PDOMCVariable extends PDOMBinding implements IVariable {
if (mytype != null)
linkage.deleteType(mytype, record);
- if (valueRec != 0)
- db.getString(valueRec).delete();
+ PDOMValue.delete(db, valueRec);
} catch (DOMException e) {
throw new CoreException(Util.createStatus(e));
}
@@ -135,9 +135,7 @@ class PDOMCVariable extends PDOMBinding implements IVariable {
try {
final Database db = pdom.getDB();
int valRec = db.getInt(record + VALUE_OFFSET);
- if (valRec == 0)
- return null;
- return Value.fromCanonicalRepresentation(db.getString(valRec).getString());
+ return PDOMValue.restore(db, getLinkage(), valRec);
} catch (CoreException e) {
CCorePlugin.log(e);
return null;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPArgumentList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPArgumentList.java
index cb1a5681a93..b136f535f58 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPArgumentList.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPArgumentList.java
@@ -11,14 +11,14 @@
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import org.eclipse.cdt.core.dom.ast.IType;
+import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
-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.CPPTemplateArgument;
import org.eclipse.cdt.internal.core.pdom.db.Database;
-import org.eclipse.cdt.internal.core.pdom.db.IString;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
+import org.eclipse.cdt.internal.core.pdom.dom.PDOMValue;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
@@ -45,8 +45,8 @@ public class PDOMCPPArgumentList {
final PDOMNode type= linkage.addType(parent, arg.getTypeOfNonTypeValue());
// type can be null, if it is a local type
db.putInt(p, type == null ? 0 : type.getRecord());
- final IString s= db.newString(arg.getNonTypeValue().getCanonicalRepresentation());
- db.putInt(p+4, s.getRecord());
+ int valueRec= PDOMValue.store(db, linkage, arg.getNonTypeValue());
+ db.putInt(p+4, valueRec);
} else {
final PDOMNode type= linkage.addType(parent, arg.getTypeValue());
// type can be null, if it is a local type.
@@ -74,9 +74,7 @@ public class PDOMCPPArgumentList {
linkage.deleteType(t, parent.getRecord());
}
final int nonTypeValueRec= db.getInt(p+4);
- if (nonTypeValueRec != 0) {
- db.getString(nonTypeValueRec).delete();
- }
+ PDOMValue.delete(db, nonTypeValueRec);
p+= 8;
}
db.free(record);
@@ -102,8 +100,8 @@ public class PDOMCPPArgumentList {
final IType type= typeRec == 0 ? new CPPBasicType(-1,0) : (IType) linkage.getNode(typeRec);
final int nonTypeValRec= db.getInt(rec+4);
if (nonTypeValRec != 0) {
- final IString s= db.getString(nonTypeValRec);
- result[i]= new CPPTemplateArgument(Value.fromCanonicalRepresentation(s.getString()), type);
+ final IValue val= PDOMValue.restore(db, linkage, nonTypeValRec);
+ result[i]= new CPPTemplateArgument(val, type);
} else {
result[i]= new CPPTemplateArgument(type);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFieldSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFieldSpecialization.java
index 7909782c20d..87d0640a6ed 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFieldSpecialization.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFieldSpecialization.java
@@ -20,12 +20,13 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.internal.core.Util;
-import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
+import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
+import org.eclipse.cdt.internal.core.pdom.dom.PDOMValue;
import org.eclipse.core.runtime.CoreException;
/**
@@ -56,15 +57,14 @@ class PDOMCPPFieldSpecialization extends PDOMCPPSpecialization implements
try {
final Database db = pdom.getDB();
IType type = field.getType();
- PDOMNode typeNode = getLinkageImpl().addType(this, type);
+ final PDOMLinkage linkage = getLinkage();
+ PDOMNode typeNode = linkage.addType(this, type);
if (typeNode != null) {
db.putInt(record + TYPE, typeNode.getRecord());
}
IValue val= field.getInitialValue();
- if (val != null) {
- db.putInt(record + VALUE_OFFSET, db.newString(val.getCanonicalRepresentation()).getRecord());
- }
-
+ int rec= PDOMValue.store(db, linkage, val);
+ db.putInt(record + VALUE_OFFSET, rec);
} catch (DOMException e) {
throw new CoreException(Util.createStatus(e));
}
@@ -108,9 +108,7 @@ class PDOMCPPFieldSpecialization extends PDOMCPPSpecialization implements
try {
final Database db = pdom.getDB();
int valRec = db.getInt(record + VALUE_OFFSET);
- if (valRec == 0)
- return null;
- return Value.fromCanonicalRepresentation(db.getString(valRec).toString());
+ return PDOMValue.restore(db, getLinkage(), valRec);
} catch (CoreException e) {
CCorePlugin.log(e);
return null;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
index 76dac097995..66576d7a299 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java
@@ -222,6 +222,11 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
return pdomBinding;
}
+ @Override
+ public PDOMBinding addUnknownValue(IBinding binding) throws CoreException {
+ return addBinding(binding, null);
+ }
+
/**
* Adds or returns existing binding for the given one. If fromName
is not null
* then an existing binding is updated with the properties of the name.
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateNonTypeParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateNonTypeParameter.java
index 2ea00dfcf62..2967de2e6e3 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateNonTypeParameter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateNonTypeParameter.java
@@ -23,15 +23,14 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.internal.core.Util;
-import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.db.Database;
-import org.eclipse.cdt.internal.core.pdom.db.IString;
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
+import org.eclipse.cdt.internal.core.pdom.dom.PDOMValue;
import org.eclipse.core.runtime.CoreException;
/**
@@ -77,12 +76,10 @@ class PDOMCPPTemplateNonTypeParameter extends PDOMCPPBinding implements IPDOMMem
try {
final Database db = pdom.getDB();
int rec= db.getInt(record + DEFAULTVAL);
- if (rec == 0)
- return null;
- String val= db.getString(rec).getString();
+ IValue val= PDOMValue.restore(db, getLinkage(), rec);
if (val == null)
return null;
- return new CPPTemplateArgument(Value.fromCanonicalRepresentation(val), getType());
+ return new CPPTemplateArgument(val, getType());
} catch (CoreException e) {
CCorePlugin.log(e);
return null;
@@ -102,8 +99,8 @@ class PDOMCPPTemplateNonTypeParameter extends PDOMCPPBinding implements IPDOMMem
setType(linkage, newType);
if (mytype != null)
linkage.deleteType(mytype, record);
- if (setDefaultValue(db, ntp) && valueRec != 0) {
- db.getString(valueRec).delete();
+ if (setDefaultValue(db, ntp)) {
+ PDOMValue.delete(db, valueRec);
}
} catch (DOMException e) {
throw new CoreException(Util.createStatus(e));
@@ -119,8 +116,7 @@ class PDOMCPPTemplateNonTypeParameter extends PDOMCPPBinding implements IPDOMMem
}
Database db= pdom.getDB();
int valueRec= db.getInt(record + DEFAULTVAL);
- if (valueRec != 0)
- db.getString(valueRec).delete();
+ PDOMValue.delete(db, valueRec);
}
public short getParameterPosition() {
@@ -175,8 +171,8 @@ class PDOMCPPTemplateNonTypeParameter extends PDOMCPPBinding implements IPDOMMem
if (val != null) {
IValue sval= val.getNonTypeValue();
if (sval != null) {
- IString s= db.newString(sval.getCanonicalRepresentation());
- db.putInt(record + DEFAULTVAL, s.getRecord());
+ int valueRec= PDOMValue.store(db, getLinkage(), sval);
+ db.putInt(record + DEFAULTVAL, valueRec);
return true;
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateParameterMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateParameterMap.java
index 1c7b1d81eae..bbf6c4f8ec8 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateParameterMap.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateParameterMap.java
@@ -11,16 +11,16 @@
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import org.eclipse.cdt.core.dom.ast.IType;
+import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
-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.CPPTemplateArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.pdom.db.Database;
-import org.eclipse.cdt.internal.core.pdom.db.IString;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
+import org.eclipse.cdt.internal.core.pdom.dom.PDOMValue;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
@@ -50,8 +50,8 @@ public class PDOMCPPTemplateParameterMap {
final PDOMNode type= linkage.addType(parent, arg.getTypeOfNonTypeValue());
// type can be null, if it is local
db.putInt(p, type == null ? 0 : type.getRecord());
- final IString s= db.newString(arg.getNonTypeValue().getCanonicalRepresentation());
- db.putInt(p+4, s.getRecord());
+ int valueRec= PDOMValue.store(db, linkage, arg.getNonTypeValue());
+ db.putInt(p+4, valueRec);
} else {
final PDOMNode type= linkage.addType(parent, arg.getTypeValue());
// type can be null, if it is local
@@ -81,9 +81,7 @@ public class PDOMCPPTemplateParameterMap {
linkage.deleteType(t, parent.getRecord());
}
final int nonTypeValueRec= db.getInt(rec+4);
- if (nonTypeValueRec != 0) {
- db.getString(nonTypeValueRec).delete();
- }
+ PDOMValue.delete(db, nonTypeValueRec);
rec+= 8;
}
db.free(rec);
@@ -111,8 +109,8 @@ public class PDOMCPPTemplateParameterMap {
final int nonTypeValRec= db.getInt(rec+8);
ICPPTemplateArgument arg;
if (nonTypeValRec != 0) {
- final IString s= db.getString(nonTypeValRec);
- arg= new CPPTemplateArgument(Value.fromCanonicalRepresentation(s.getString()), type);
+ IValue val= PDOMValue.restore(db, linkage, nonTypeValRec);
+ arg= new CPPTemplateArgument(val, type);
} else {
arg= new CPPTemplateArgument(type);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPVariable.java
index 825822f79f5..a7f1cc12b2b 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPVariable.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPVariable.java
@@ -21,7 +21,6 @@ import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
import org.eclipse.cdt.internal.core.Util;
-import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVariableReadWriteFlags;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.pdom.PDOM;
@@ -30,6 +29,7 @@ import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
+import org.eclipse.cdt.internal.core.pdom.dom.PDOMValue;
import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCAnnotation;
import org.eclipse.core.runtime.CoreException;
@@ -78,7 +78,7 @@ class PDOMCPPVariable extends PDOMCPPBinding implements ICPPVariable {
private void setValue(Database db, IVariable variable) throws CoreException {
IValue val= variable.getInitialValue();
- int valueRec= val == null ? 0 : db.newString(val.getCanonicalRepresentation()).getRecord();
+ int valueRec= PDOMValue.store(db, getLinkage(), val);
db.putInt(record + VALUE_OFFSET, valueRec);
}
@@ -96,8 +96,7 @@ class PDOMCPPVariable extends PDOMCPPBinding implements ICPPVariable {
setValue(db, var);
if (mytype != null)
linkage.deleteType(mytype, record);
- if (valueRec != 0)
- db.getString(valueRec).delete();
+ PDOMValue.delete(db, valueRec);
} catch (DOMException e) {
throw new CoreException(Util.createStatus(e));
@@ -148,9 +147,7 @@ class PDOMCPPVariable extends PDOMCPPBinding implements ICPPVariable {
try {
final Database db = pdom.getDB();
int valRec = db.getInt(record + VALUE_OFFSET);
- if (valRec == 0)
- return null;
- return Value.fromCanonicalRepresentation(db.getString(valRec).getString());
+ return PDOMValue.restore(db, getLinkage(), valRec);
} catch (CoreException e) {
CCorePlugin.log(e);
return null;