mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 299911. Work in progress. 5 tests are still failing.
This commit is contained in:
parent
5b2d7b16f7
commit
e5c9fc3ee6
19 changed files with 266 additions and 25 deletions
|
@ -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$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 <code>-1</code> if it is not a template
|
* @return the parameter id of the parameter, or <code>-1</code> if it is not a template
|
||||||
* parameter.
|
* parameter.
|
||||||
|
@ -225,25 +225,20 @@ public class Value implements IValue {
|
||||||
if (eval instanceof EvalBinding) {
|
if (eval instanceof EvalBinding) {
|
||||||
IBinding binding = ((EvalBinding) eval).getBinding();
|
IBinding binding = ((EvalBinding) eval).getBinding();
|
||||||
if (binding instanceof ICPPTemplateParameter) {
|
if (binding instanceof ICPPTemplateParameter) {
|
||||||
((ICPPTemplateParameter) binding).getParameterID();
|
return ((ICPPTemplateParameter) binding).getParameterID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
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) {
|
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.
|
ICPPEvaluation eval = tval.getEvaluation();
|
||||||
return isTemplateParameter(tval) >= 0;
|
if (eval == null)
|
||||||
// final char[] rep= tval.getInternalExpression();
|
return false;
|
||||||
// for (char element : rep) {
|
return eval.referencesTemplateParameter();
|
||||||
// if (element == TEMPLATE_PARAM_CHAR || element == TEMPLATE_PARAM_PACK_CHAR)
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
// return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -53,7 +53,7 @@ public class CPPASTFieldReference extends ASTNode
|
||||||
private boolean isDeref;
|
private boolean isDeref;
|
||||||
private IASTImplicitName[] implicitNames;
|
private IASTImplicitName[] implicitNames;
|
||||||
private ICPPEvaluation fEvaluation;
|
private ICPPEvaluation fEvaluation;
|
||||||
|
|
||||||
public CPPASTFieldReference() {
|
public CPPASTFieldReference() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,11 +74,7 @@ public class CPPASTFieldReference extends ASTNode
|
||||||
copy.setFieldOwner(owner == null ? null : owner.copy(style));
|
copy.setFieldOwner(owner == null ? null : owner.copy(style));
|
||||||
copy.isTemplate = isTemplate;
|
copy.isTemplate = isTemplate;
|
||||||
copy.isDeref = isDeref;
|
copy.isDeref = isDeref;
|
||||||
copy.setOffsetAndLength(this);
|
return copy(copy, style);
|
||||||
if (style == CopyStyle.withLocations) {
|
|
||||||
copy.setCopyLocation(this);
|
|
||||||
}
|
|
||||||
return copy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -282,7 +278,7 @@ public class CPPASTFieldReference extends ASTNode
|
||||||
if (n instanceof ICPPASTTemplateId) {
|
if (n instanceof ICPPASTTemplateId) {
|
||||||
args= CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) n);
|
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
|
@Override
|
||||||
|
|
|
@ -76,4 +76,10 @@ public interface ICPPEvaluation extends ISerializableEvaluation {
|
||||||
* @noreference This method is not intended to be referenced by clients.
|
* @noreference This method is not intended to be referenced by clients.
|
||||||
*/
|
*/
|
||||||
int determinePackSize(ICPPTemplateParameterMap tpMap);
|
int determinePackSize(ICPPTemplateParameterMap tpMap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the evaluation references a template parameter either directly or though nested
|
||||||
|
* evaluations.
|
||||||
|
*/
|
||||||
|
boolean referencesTemplateParameter();
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ public class EvalBinary extends CPPEvaluation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IValue getValue(IASTNode point) {
|
public IValue getValue(IASTNode point) {
|
||||||
if (fOverload != null) {
|
if (getOverload(point) != null) {
|
||||||
// TODO(sprigogin): Simulate execution of a function call.
|
// TODO(sprigogin): Simulate execution of a function call.
|
||||||
return Value.create(this);
|
return Value.create(this);
|
||||||
}
|
}
|
||||||
|
@ -319,4 +319,9 @@ public class EvalBinary extends CPPEvaluation {
|
||||||
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
|
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
|
||||||
return CPPTemplates.combinePackSize(fArg1.determinePackSize(tpMap), fArg2.determinePackSize(tpMap));
|
return CPPTemplates.combinePackSize(fArg1.determinePackSize(tpMap), fArg2.determinePackSize(tpMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean referencesTemplateParameter() {
|
||||||
|
return fArg1.referencesTemplateParameter() || fArg2.referencesTemplateParameter();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,4 +141,9 @@ public class EvalBinaryTypeId extends CPPEvaluation {
|
||||||
return CPPTemplates.combinePackSize(CPPTemplates.determinePackSize(fType1, tpMap),
|
return CPPTemplates.combinePackSize(CPPTemplates.determinePackSize(fType1, tpMap),
|
||||||
CPPTemplates.determinePackSize(fType2, tpMap));
|
CPPTemplates.determinePackSize(fType2, tpMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean referencesTemplateParameter() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -269,4 +269,9 @@ public class EvalBinding extends CPPEvaluation {
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean referencesTemplateParameter() {
|
||||||
|
return fBinding instanceof ICPPTemplateParameter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,6 @@ public class EvalComma extends CPPEvaluation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValueDependent() {
|
public boolean isValueDependent() {
|
||||||
// TODO(sprigogin): Should the value depend only on the last argument?
|
|
||||||
for (ICPPEvaluation arg : fArguments) {
|
for (ICPPEvaluation arg : fArguments) {
|
||||||
if (arg.isValueDependent())
|
if (arg.isValueDependent())
|
||||||
return true;
|
return true;
|
||||||
|
@ -194,4 +193,13 @@ public class EvalComma extends CPPEvaluation {
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean referencesTemplateParameter() {
|
||||||
|
for (ICPPEvaluation arg : fArguments) {
|
||||||
|
if (arg.referencesTemplateParameter())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,8 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
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 {
|
public class EvalCompound extends CPPEvaluation {
|
||||||
private final ICPPEvaluation fDelegate;
|
private final ICPPEvaluation fDelegate;
|
||||||
|
@ -97,4 +98,9 @@ public class EvalCompound extends CPPEvaluation {
|
||||||
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
|
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
|
||||||
return fDelegate.determinePackSize(tpMap);
|
return fDelegate.determinePackSize(tpMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean referencesTemplateParameter() {
|
||||||
|
return fDelegate.referencesTemplateParameter();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -344,4 +344,11 @@ public class EvalConditional extends CPPEvaluation {
|
||||||
r = CPPTemplates.combinePackSize(r, fPositive.determinePackSize(tpMap));
|
r = CPPTemplates.combinePackSize(r, fPositive.determinePackSize(tpMap));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean referencesTemplateParameter() {
|
||||||
|
return fCondition.referencesTemplateParameter() ||
|
||||||
|
(fPositive != null && fPositive.referencesTemplateParameter()) ||
|
||||||
|
fNegative.referencesTemplateParameter();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,4 +163,9 @@ public class EvalFixed extends CPPEvaluation {
|
||||||
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
|
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
|
||||||
return CPPTemplates.determinePackSize(fValue, tpMap);
|
return CPPTemplates.determinePackSize(fValue, tpMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean referencesTemplateParameter() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -199,4 +199,13 @@ public class EvalFunctionCall extends CPPEvaluation {
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean referencesTemplateParameter() {
|
||||||
|
for (ICPPEvaluation arg : fArguments) {
|
||||||
|
if (arg.referencesTemplateParameter())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,4 +181,9 @@ public class EvalFunctionSet extends CPPEvaluation {
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean referencesTemplateParameter() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -299,10 +299,10 @@ public class EvalID extends CPPEvaluation {
|
||||||
|
|
||||||
if (nameOwner instanceof ICompositeType && point != null) {
|
if (nameOwner instanceof ICompositeType && point != null) {
|
||||||
ICompositeType ownerType = (ICompositeType) nameOwner;
|
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);
|
LookupData data = new LookupData(fName, templateArgs, point);
|
||||||
|
data.qualified = fQualified;
|
||||||
try {
|
try {
|
||||||
CPPSemantics.lookup(data, ownerType.getScope());
|
CPPSemantics.lookup(data, ownerType.getCompositeScope());
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
}
|
}
|
||||||
IBinding[] bindings = data.getFoundBindings();
|
IBinding[] bindings = data.getFoundBindings();
|
||||||
|
@ -327,4 +327,9 @@ public class EvalID extends CPPEvaluation {
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean referencesTemplateParameter() {
|
||||||
|
return fFieldOwner.referencesTemplateParameter();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,4 +125,13 @@ public class EvalInitList extends CPPEvaluation {
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean referencesTemplateParameter() {
|
||||||
|
for (ICPPEvaluation clause : fClauses) {
|
||||||
|
if (clause.referencesTemplateParameter())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -338,4 +338,9 @@ public class EvalMemberAccess extends CPPEvaluation {
|
||||||
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
|
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
|
||||||
return CPPTemplates.determinePackSize(fOwnerType, tpMap);
|
return CPPTemplates.determinePackSize(fOwnerType, tpMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean referencesTemplateParameter() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,4 +167,13 @@ public class EvalTypeId extends CPPEvaluation {
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean referencesTemplateParameter() {
|
||||||
|
for (ICPPEvaluation arg : fArguments) {
|
||||||
|
if (arg.referencesTemplateParameter())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -205,7 +205,7 @@ public class EvalUnary extends CPPEvaluation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IValue getValue(IASTNode point) {
|
public IValue getValue(IASTNode point) {
|
||||||
if (fOverload != null) {
|
if (getOverload(point) != null) {
|
||||||
// TODO(sprigogin): Simulate execution of a function call.
|
// TODO(sprigogin): Simulate execution of a function call.
|
||||||
return Value.create(this);
|
return Value.create(this);
|
||||||
}
|
}
|
||||||
|
@ -261,4 +261,9 @@ public class EvalUnary extends CPPEvaluation {
|
||||||
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
|
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
|
||||||
return fArgument.determinePackSize(tpMap);
|
return fArgument.determinePackSize(tpMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean referencesTemplateParameter() {
|
||||||
|
return fArgument.referencesTemplateParameter();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -235,4 +235,9 @@ public class EvalUnaryTypeID extends CPPEvaluation {
|
||||||
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
|
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
|
||||||
return CPPTemplates.determinePackSize(fOrigType, tpMap);
|
return CPPTemplates.determinePackSize(fOrigType, tpMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean referencesTemplateParameter() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue