diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/IntArray.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/IntArray.java new file mode 100644 index 00000000000..ba5a8b312c2 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/IntArray.java @@ -0,0 +1,151 @@ +/******************************************************************************* + * Copyright (c) 2012 Google, Inc and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sergey Prigogin (Google) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.parser.util; + +import java.util.Arrays; + +/** + * Automatically growing integer array. + * + * @since 5.5 + */ +public class IntArray { + private static final int INITIAL_CAPACITY = 10; + private static final int[] EMPTY_ARRAY = {}; + + private int[] buffer = EMPTY_ARRAY; + private int size; + + public IntArray() { + } + + public IntArray(int initialCapacity) { + this.buffer = new int[initialCapacity]; + } + + public int size() { + return size; + } + + public boolean isEmpty() { + return size == 0; + } + + public void add(int value) { + grow(size + 1); + buffer[size++] = value; + } + + public void add(int index, int value) { + checkBounds(index); + grow(size + 1); + System.arraycopy(buffer, index, buffer, index + 1, size - index); + buffer[index] = value; + size++; + } + + public void addAll(IntArray other) { + grow(size + other.size()); + System.arraycopy(other.buffer, 0, buffer, size, other.size); + size += other.size; + return; + } + + public void addAll(int[] array) { + grow(size + array.length); + System.arraycopy(array, 0, buffer, size, array.length); + size += array.length; + return; + } + + public int remove(int index) { + checkBounds(index); + int old = buffer[index]; + int n = size - index - 1; + if (n > 0) { + System.arraycopy(buffer, index + 1, buffer, index, n); + } + return old; + } + + public void remove(int from, int to) { + checkBounds(from); + checkBounds(to); + System.arraycopy(buffer, to, buffer, from, size - to); + } + + public void clear() { + size = 0; + } + + public int get(int index) { + checkRange(index); + return buffer[index]; + } + + public int set(int index, int value) { + checkBounds(index); + int old = buffer[index]; + buffer[index] = value; + return old; + } + + public int[] toArray() { + return size == 0 ? EMPTY_ARRAY : Arrays.copyOf(buffer, size); + } + + public void trimToSize() { + if (size == 0) { + buffer = EMPTY_ARRAY; + } else if (size < buffer.length) { + buffer = Arrays.copyOf(buffer, size); + } + } + + public void ensureCapacity(int minCapacity) { + if (minCapacity > 0) { + grow(minCapacity); + } + } + + private void grow(int minCapacity) { + if (minCapacity < 0) // Overflow + throw new OutOfMemoryError(); + + int capacity = buffer.length; + if (minCapacity > capacity) { + int newCapacity = capacity == 0 ? INITIAL_CAPACITY : capacity + (capacity >> 1); + // newCapacity may be negative due to overflow. + if (newCapacity < minCapacity) + newCapacity = minCapacity; + // newCapacity is guaranteed to be non negative. + try { + buffer = Arrays.copyOf(buffer, newCapacity); + } catch (OutOfMemoryError e) { + // Try again it case we were too aggressive in reserving capacity. + buffer = Arrays.copyOf(buffer, minCapacity); + } + } + } + + private void checkBounds(int index) { + if (index < 0) { + throw new IndexOutOfBoundsException("Negative index: " + index); //$NON-NLS-1$ + } + checkRange(index); + } + + private void checkRange(int index) { + if (index >= size) { + throw new IndexOutOfBoundsException("Index: " + index + ", size: " + size); //$NON-NLS-1$//$NON-NLS-2$ + } + } +} 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 701b9e71d74..8f1b1295048 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 @@ -215,7 +215,7 @@ public class Value implements IValue { } /** - * Tests whether the value is a template parameter (or parameter pack). + * Tests whether the value is a template parameter (or a parameter pack). * * @return the parameter id of the parameter, or -1 if it is not a template * parameter. @@ -225,25 +225,20 @@ public class Value implements IValue { if (eval instanceof EvalBinding) { IBinding binding = ((EvalBinding) eval).getBinding(); if (binding instanceof ICPPTemplateParameter) { - ((ICPPTemplateParameter) binding).getParameterID(); + return ((ICPPTemplateParameter) binding).getParameterID(); } } return -1; } /** - * Tests whether the value directly references some template parameter. + * Tests whether the value references some template parameter. */ - // TODO(sprigogin): The semantics of "directly" is unclear. public static boolean referencesTemplateParameter(IValue tval) { - // 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; + ICPPEvaluation eval = tval.getEvaluation(); + if (eval == null) + return false; + return eval.referencesTemplateParameter(); } /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java index 8a2dff09a33..c2fb4dcb4b2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java @@ -53,7 +53,7 @@ public class CPPASTFieldReference extends ASTNode private boolean isDeref; private IASTImplicitName[] implicitNames; private ICPPEvaluation fEvaluation; - + public CPPASTFieldReference() { } @@ -74,11 +74,7 @@ public class CPPASTFieldReference extends ASTNode copy.setFieldOwner(owner == null ? null : owner.copy(style)); copy.isTemplate = isTemplate; copy.isDeref = isDeref; - copy.setOffsetAndLength(this); - if (style == CopyStyle.withLocations) { - copy.setCopyLocation(this); - } - return copy; + return copy(copy, style); } @Override @@ -282,7 +278,7 @@ public class CPPASTFieldReference extends ASTNode if (n instanceof ICPPASTTemplateId) { args= CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) n); } - return new EvalID(ownerEval, qualifier, name.getSimpleID(), false, qualifier != null, args); + return new EvalID(ownerEval, qualifier, name.getSimpleID(), false, true, args); } @Override 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 48d743d2697..aed832e59a4 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 @@ -76,4 +76,10 @@ public interface ICPPEvaluation extends ISerializableEvaluation { * @noreference This method is not intended to be referenced by clients. */ int determinePackSize(ICPPTemplateParameterMap tpMap); + + /** + * Checks if the evaluation references a template parameter either directly or though nested + * evaluations. + */ + boolean referencesTemplateParameter(); } 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 696a8db4a1d..911c8cc1062 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,7 @@ public class EvalBinary extends CPPEvaluation { @Override public IValue getValue(IASTNode point) { - if (fOverload != null) { + if (getOverload(point) != null) { // TODO(sprigogin): Simulate execution of a function call. return Value.create(this); } @@ -319,4 +319,9 @@ public class EvalBinary extends CPPEvaluation { public int determinePackSize(ICPPTemplateParameterMap tpMap) { return CPPTemplates.combinePackSize(fArg1.determinePackSize(tpMap), fArg2.determinePackSize(tpMap)); } + + @Override + public boolean referencesTemplateParameter() { + return fArg1.referencesTemplateParameter() || fArg2.referencesTemplateParameter(); + } } 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 d89d8ddd6e9..707e19f45e3 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 @@ -141,4 +141,9 @@ public class EvalBinaryTypeId extends CPPEvaluation { return CPPTemplates.combinePackSize(CPPTemplates.determinePackSize(fType1, tpMap), CPPTemplates.determinePackSize(fType2, tpMap)); } + + @Override + public boolean referencesTemplateParameter() { + return false; + } } 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 1427b733c63..ee5b09c13c0 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 @@ -269,4 +269,9 @@ public class EvalBinding extends CPPEvaluation { return r; } + + @Override + public boolean referencesTemplateParameter() { + return fBinding instanceof ICPPTemplateParameter; + } } 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 2cf29f4343b..752cb08797c 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,7 +68,6 @@ 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; @@ -194,4 +193,13 @@ public class EvalComma extends CPPEvaluation { } return r; } + + @Override + public boolean referencesTemplateParameter() { + for (ICPPEvaluation arg : fArguments) { + if (arg.referencesTemplateParameter()) + return true; + } + return false; + } } 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 1175d6b8e72..dcc6c627d06 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 @@ -25,7 +25,8 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.core.runtime.CoreException; /** - * Performs evaluation of an expression. + * Performs evaluation of a compound statement expression. Most but not all methods + * delegate to the evaluation of the last expression in the compound one. */ public class EvalCompound extends CPPEvaluation { private final ICPPEvaluation fDelegate; @@ -97,4 +98,9 @@ public class EvalCompound extends CPPEvaluation { public int determinePackSize(ICPPTemplateParameterMap tpMap) { return fDelegate.determinePackSize(tpMap); } + + @Override + public boolean referencesTemplateParameter() { + return fDelegate.referencesTemplateParameter(); + } } \ 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 772928eac3b..d918929a3c2 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 @@ -344,4 +344,11 @@ public class EvalConditional extends CPPEvaluation { r = CPPTemplates.combinePackSize(r, fPositive.determinePackSize(tpMap)); return r; } + + @Override + public boolean referencesTemplateParameter() { + return fCondition.referencesTemplateParameter() || + (fPositive != null && fPositive.referencesTemplateParameter()) || + fNegative.referencesTemplateParameter(); + } } 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 f3892911125..9ae762f8c2d 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 @@ -163,4 +163,9 @@ public class EvalFixed extends CPPEvaluation { public int determinePackSize(ICPPTemplateParameterMap tpMap) { return CPPTemplates.determinePackSize(fValue, tpMap); } + + @Override + public boolean referencesTemplateParameter() { + return false; + } } \ 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 eba7284d57d..f574db24ece 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 @@ -199,4 +199,13 @@ public class EvalFunctionCall extends CPPEvaluation { } return r; } + + @Override + public boolean referencesTemplateParameter() { + for (ICPPEvaluation arg : fArguments) { + if (arg.referencesTemplateParameter()) + return true; + } + return false; + } } 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 fbf64b923a8..d645aa6032b 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 @@ -181,4 +181,9 @@ public class EvalFunctionSet extends CPPEvaluation { } return r; } + + @Override + public boolean referencesTemplateParameter() { + return false; + } } 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 7f4d466af0a..ec83268aa3a 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 @@ -299,10 +299,10 @@ public class EvalID extends CPPEvaluation { 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, templateArgs, point); + data.qualified = fQualified; try { - CPPSemantics.lookup(data, ownerType.getScope()); + CPPSemantics.lookup(data, ownerType.getCompositeScope()); } catch (DOMException e) { } IBinding[] bindings = data.getFoundBindings(); @@ -327,4 +327,9 @@ public class EvalID extends CPPEvaluation { } return r; } + + @Override + public boolean referencesTemplateParameter() { + return fFieldOwner.referencesTemplateParameter(); + } } 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 02469d272ef..e1d4b237e29 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 @@ -125,4 +125,13 @@ public class EvalInitList extends CPPEvaluation { } return r; } + + @Override + public boolean referencesTemplateParameter() { + for (ICPPEvaluation clause : fClauses) { + if (clause.referencesTemplateParameter()) + return true; + } + return false; + } } \ 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 ff097057121..7e164f70ecd 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 @@ -338,4 +338,9 @@ public class EvalMemberAccess extends CPPEvaluation { public int determinePackSize(ICPPTemplateParameterMap tpMap) { return CPPTemplates.determinePackSize(fOwnerType, tpMap); } + + @Override + public boolean referencesTemplateParameter() { + return false; + } } 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 50719af6fd0..6e8ef088d12 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 @@ -167,4 +167,13 @@ public class EvalTypeId extends CPPEvaluation { } return r; } + + @Override + public boolean referencesTemplateParameter() { + for (ICPPEvaluation arg : fArguments) { + if (arg.referencesTemplateParameter()) + return true; + } + return false; + } } 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 1f44ac738e5..ab728bf6462 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,7 @@ public class EvalUnary extends CPPEvaluation { @Override public IValue getValue(IASTNode point) { - if (fOverload != null) { + if (getOverload(point) != null) { // TODO(sprigogin): Simulate execution of a function call. return Value.create(this); } @@ -261,4 +261,9 @@ public class EvalUnary extends CPPEvaluation { public int determinePackSize(ICPPTemplateParameterMap tpMap) { return fArgument.determinePackSize(tpMap); } + + @Override + public boolean referencesTemplateParameter() { + return fArgument.referencesTemplateParameter(); + } } 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 6fe24993a15..993b032ded9 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 @@ -235,4 +235,9 @@ public class EvalUnaryTypeID extends CPPEvaluation { public int determinePackSize(ICPPTemplateParameterMap tpMap) { return CPPTemplates.determinePackSize(fOrigType, tpMap); } + + @Override + public boolean referencesTemplateParameter() { + return false; + } }