1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 299911. Work in progress. 20 tests are currently failing.

This commit is contained in:
Sergey Prigogin 2012-07-24 20:34:45 -07:00
parent e606c63656
commit 5b2d7b16f7
22 changed files with 678 additions and 817 deletions

View file

@ -7,9 +7,12 @@
*
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
/**
* Models a value of a variable, enumerator or expression.
*
@ -19,27 +22,33 @@ package org.eclipse.cdt.core.dom.ast;
*/
public interface IValue {
/**
* Returns the value as a number, or <code>null</code> if this is not possible.
* Returns the value as a number, or {@code null} if it is not possible.
*/
Long numericalValue();
/**
* Returns an internal representation of the expression that builds up
* the value. It is suitable for instantiating dependent values but may not be
* used for the purpose of displaying values.
* Returns the evaluation object if this value is dependent, or {@code null} otherwise.
* If {@link #numericalValue()} returns {@code null}, {@link #getEvaluation()} returns
* not {@code null} and vice versa.
* @noreference This method is not intended to be referenced by clients.
*/
char[] getInternalExpression();
ICPPEvaluation getEvaluation();
/**
* A value may be dependent on template parameters, in which case a list
* of unknown bindings is maintained for later instantiation.
*/
IBinding[] getUnknownBindings();
/**
* Returns a signature containing both the internal representation and
* the unknown bindings. The representation is sufficient to distinguish values
* for the purpose of instantiation, it may not be used to display the value.
* Returns a signature uniquely identifying the value. Two values with identical
* signatures are guaranteed to be equal.
*/
char[] getSignature();
/**
* @deprecated Returns an empty character array.
*/
@Deprecated
char[] getInternalExpression();
/**
* @deprecated Returns an empty array.
*/
@Deprecated
IBinding[] getUnknownBindings();
}

View file

@ -329,7 +329,7 @@ public class CharArrayUtils {
}
/**
* Find an array of chars in an array of arrays of chars.
* Finds an array of chars in an array of arrays of chars.
* @return offset where the array was found or <code>-1</code>
*/
public static int indexOf(final char[] searchFor, final char[][] searchIn) {
@ -340,4 +340,15 @@ public class CharArrayUtils {
}
return -1;
}
/**
* Converts a {@link StringBuilder} to a character array.
* @since 5.5
*/
public static char[] extractChars(StringBuilder buf) {
final int len = buf.length();
char[] result= new char[len];
buf.getChars(0, len, result, 0);
return result;
}
}

View file

@ -69,4 +69,11 @@ public interface ICPPEvaluation extends ISerializableEvaluation {
*/
ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point);
/**
* Determines size of the template parameter pack.
*
* @noreference This method is not intended to be referenced by clients.
*/
int determinePackSize(ICPPTemplateParameterMap tpMap);
}

View file

@ -15,6 +15,8 @@ import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableType;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
@ -45,6 +47,10 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
return fBuffer.toString();
}
public char[] getSignature() {
return CharArrayUtils.extractChars(fBuffer);
}
@Override
public void marshalBinding(IBinding binding) throws CoreException {
if (binding instanceof ISerializableType) {
@ -53,12 +59,11 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
putByte(NULL_TYPE);
} else {
appendSeparator();
IBinding owner= binding.getOwner();
if (owner instanceof IType) {
ASTTypeUtil.appendType((IType) owner, true, fBuffer);
fBuffer.append("::"); //$NON-NLS-1$
if (binding instanceof ICPPBinding) {
fBuffer.append(ASTTypeUtil.getQualifiedName((ICPPBinding) binding));
} else {
fBuffer.append(binding.getNameCharArray());
}
fBuffer.append(binding.getName());
}
}
@ -223,6 +228,6 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
CCorePlugin.log(e);
return new char[] { '?' };
}
return buf.toString().toCharArray();
return buf.getSignature();
}
}

View file

@ -51,7 +51,6 @@ import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAmbiguousTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
@ -138,6 +137,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDeclarationSpecialization;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalTemplateDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalClassTemplate;
@ -153,9 +153,9 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMod
* type instantiation.
*/
public class CPPTemplates {
private static final int PACK_SIZE_DEFER = -1;
private static final int PACK_SIZE_FAIL = -2;
private static final int PACK_SIZE_NOT_FOUND = Integer.MAX_VALUE;
static final int PACK_SIZE_DEFER = -1;
static final int PACK_SIZE_FAIL = -2;
static final int PACK_SIZE_NOT_FOUND = Integer.MAX_VALUE;
private static final ICPPFunction[] NO_FUNCTIONS = {};
static enum TypeSelection { PARAMETERS, RETURN_TYPE, PARAMETERS_AND_RETURN_TYPE }
@ -225,7 +225,7 @@ public class CPPTemplates {
}
if (isPack) {
int packOffset= numParams - 1;
int packOffset= numParams-1;
int packSize= numArgs - packOffset;
ICPPTemplateArgument[] pack= new ICPPTemplateArgument[packSize];
System.arraycopy(arguments, packOffset, pack, 0, packSize);
@ -402,7 +402,7 @@ public class CPPTemplates {
for (int i = 0; i < arguments.length; i++) {
ICPPTemplateArgument arg = arguments[i];
if (arg.isPackExpansion()) {
if (i != arguments.length - 1) {
if (i != arguments.length-1) {
return arguments;
}
havePackExpansion= true;
@ -421,10 +421,10 @@ public class CPPTemplates {
// More arguments allowed if we have a parameter pack.
if (tparCount < argCount) {
if (tpars[tparCount - 1].isParameterPack())
if (tpars[tparCount-1].isParameterPack())
return arguments;
if (havePackExpansion && tparCount + 1 == argCount)
if (havePackExpansion && tparCount+1 == argCount)
return arguments;
return null;
}
@ -434,7 +434,7 @@ public class CPPTemplates {
return arguments;
// Fewer arguments are allowed with default arguments
if (tpars[tparCount - 1].isParameterPack())
if (tpars[tparCount-1].isParameterPack())
tparCount--;
if (tparCount == argCount)
@ -862,43 +862,20 @@ public class CPPTemplates {
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
if (value == null)
return null;
IBinding[] unknowns= value.getUnknownBindings();
IBinding[] resolvedUnknowns= null;
if (unknowns.length != 0) {
for (int i = 0; i < unknowns.length; i++) {
IBinding unknown= unknowns[i];
IBinding resolved= unknown;
if (unknown instanceof ICPPUnknownBinding) {
try {
resolved= resolveUnknown((ICPPUnknownBinding) unknown, tpMap, packOffset, within, point);
} catch (DOMException e) {
return Value.UNKNOWN;
}
}
if (resolvedUnknowns != null) {
resolvedUnknowns[i]= resolved;
} else if (resolved != unknown) {
resolvedUnknowns= new IBinding[unknowns.length];
System.arraycopy(unknowns, 0, resolvedUnknowns, 0, i);
resolvedUnknowns[i]= resolved;
}
}
}
if (resolvedUnknowns != null)
return Value.reevaluate(value, packOffset, resolvedUnknowns, tpMap, maxdepth);
if (Value.referencesTemplateParameter(value))
return Value.reevaluate(value, packOffset, unknowns, tpMap, maxdepth);
return value;
ICPPEvaluation evaluation = value.getEvaluation();
if (evaluation == null)
return value;
ICPPEvaluation instantiated = evaluation.instantiate(tpMap, packOffset, within, maxdepth, point);
if (instantiated == evaluation)
return value;
return instantiated.getValue(point);
}
public static boolean containsParameterPack(IType type) {
return determinePackSize(type, CPPTemplateParameterMap.EMPTY) == PACK_SIZE_DEFER;
}
private static int determinePackSize(IType type, ICPPTemplateParameterMap tpMap) {
static int determinePackSize(IType type, ICPPTemplateParameterMap tpMap) {
if (type instanceof ICPPFunctionType) {
final ICPPFunctionType ft = (ICPPFunctionType) type;
final IType rt = ft.getReturnType();
@ -907,7 +884,7 @@ public class CPPTemplates {
return r;
IType[] ps = ft.getParameterTypes();
for (IType pt : ps) {
r= combine(r, determinePackSize(pt, tpMap));
r= combinePackSize(r, determinePackSize(pt, tpMap));
if (r < 0)
return r;
}
@ -915,37 +892,17 @@ public class CPPTemplates {
}
if (type instanceof ICPPTemplateParameter) {
final ICPPTemplateParameter tpar = (ICPPTemplateParameter) type;
if (tpar.isParameterPack()) {
ICPPTemplateArgument[] args= tpMap.getPackExpansion(tpar);
if (args != null)
return args.length;
return PACK_SIZE_DEFER;
}
return PACK_SIZE_NOT_FOUND;
return determinePackSize((ICPPTemplateParameter) type, tpMap);
}
int r= PACK_SIZE_NOT_FOUND;
if (type instanceof ICPPUnknownBinding) {
if (type instanceof ICPPDeferredClassInstance) {
ICPPDeferredClassInstance dcl= (ICPPDeferredClassInstance) type;
ICPPTemplateArgument[] args = dcl.getTemplateArguments();
for (ICPPTemplateArgument arg : args) {
r= combine(r, determinePackSize(arg, tpMap));
if (r < 0)
return r;
}
}
IBinding binding= ((ICPPUnknownBinding) type).getOwner();
if (binding instanceof IType)
r= combine(r, determinePackSize((IType) binding, tpMap));
return r;
return determinePackSize((ICPPUnknownBinding) type, tpMap);
}
if (type instanceof ICPPParameterPackType)
return PACK_SIZE_NOT_FOUND;
int r= PACK_SIZE_NOT_FOUND;
if (type instanceof IArrayType) {
IArrayType at= (IArrayType) type;
IValue asize= at.getSize();
@ -956,12 +913,54 @@ public class CPPTemplates {
if (type instanceof ITypeContainer) {
final ITypeContainer typeContainer = (ITypeContainer) type;
r= combine(r, determinePackSize(typeContainer.getType(), tpMap));
r= combinePackSize(r, determinePackSize(typeContainer.getType(), tpMap));
}
return r;
}
private static int combine(int ps1, int ps2) {
static int determinePackSize(ICPPTemplateParameter tpar, ICPPTemplateParameterMap tpMap) {
if (tpar.isParameterPack()) {
ICPPTemplateArgument[] args= tpMap.getPackExpansion(tpar);
if (args != null)
return args.length;
return PACK_SIZE_DEFER;
}
return PACK_SIZE_NOT_FOUND;
}
static int determinePackSize(ICPPUnknownBinding binding, ICPPTemplateParameterMap tpMap) {
int r= PACK_SIZE_NOT_FOUND;
if (binding instanceof ICPPDeferredClassInstance) {
ICPPDeferredClassInstance dcl= (ICPPDeferredClassInstance) binding;
ICPPTemplateArgument[] args = dcl.getTemplateArguments();
for (ICPPTemplateArgument arg : args) {
r= combinePackSize(r, determinePackSize(arg, tpMap));
if (r < 0)
return r;
}
}
IBinding ownerBinding= binding.getOwner();
if (ownerBinding instanceof IType)
r= combinePackSize(r, determinePackSize((IType) ownerBinding, tpMap));
return r;
}
static int determinePackSize(IValue value, ICPPTemplateParameterMap tpMap) {
ICPPEvaluation eval = value.getEvaluation();
if (eval == null)
return PACK_SIZE_NOT_FOUND;
return ((CPPEvaluation) eval).determinePackSize(tpMap);
}
static int determinePackSize(ICPPTemplateArgument arg, ICPPTemplateParameterMap tpMap) {
if (arg.isTypeValue())
return determinePackSize(arg.getTypeValue(), tpMap);
return determinePackSize(arg.getNonTypeValue(), tpMap);
}
static int combinePackSize(int ps1, int ps2) {
if (ps1 < 0 || ps2 == PACK_SIZE_NOT_FOUND)
return ps1;
if (ps2 < 0 || ps1 == PACK_SIZE_NOT_FOUND)
@ -971,35 +970,6 @@ public class CPPTemplates {
return ps1;
}
private static int determinePackSize(IValue value, ICPPTemplateParameterMap tpMap) {
int r= PACK_SIZE_NOT_FOUND;
IBinding[] unknown= value.getUnknownBindings();
for (IBinding binding : unknown) {
if (binding instanceof IType) {
r= combine(r, determinePackSize((IType) binding, tpMap));
if (r < 0)
return r;
}
}
int[] tpars= Value.getParameterPackReferences(value);
for (int parID : tpars) {
ICPPTemplateArgument[] args= tpMap.getPackExpansion(parID);
if (args != null) {
r= combine(r, args.length);
if (r < 0)
return r;
}
return PACK_SIZE_DEFER;
}
return r;
}
private static int determinePackSize(ICPPTemplateArgument arg, ICPPTemplateParameterMap tpMap) {
if (arg.isTypeValue())
return determinePackSize(arg.getTypeValue(), tpMap);
return determinePackSize(arg.getNonTypeValue(), tpMap);
}
/**
* Instantiates types contained in an array.
* @param types an array of types
@ -1025,7 +995,7 @@ public class CPPTemplates {
} else if (packSize == PACK_SIZE_DEFER) {
newType= origType;
} else {
IType[] newResult= new IType[result.length + packSize - 1];
IType[] newResult= new IType[result.length+packSize-1];
System.arraycopy(result, 0, newResult, 0, j);
result= newResult;
for (int k= 0; k < packSize; k++) {
@ -1168,7 +1138,7 @@ public class CPPTemplates {
return type;
}
// The parameter types need to be adjusted.
for (int i= 0; i < params.length; i++) {
for (int i=0; i<params.length; i++) {
IType p= params[i];
if (!isDependentType(p)) {
params[i]= CPPVisitor.adjustParameterType(p, true);
@ -1396,7 +1366,7 @@ public class CPPTemplates {
int depIDCount= 0;
IASTName owner= null;
final IASTName[] ns= qname.getNames();
for (int i = 0; i < ns.length - 1; i++) {
for (int i = 0; i < ns.length-1; i++) {
IASTName n= ns[i];
if (n instanceof ICPPASTTemplateId) {
if (depIDCount > 0 || usesTemplateParameter((ICPPASTTemplateId) n, tparnames)) {
@ -1439,17 +1409,17 @@ public class CPPTemplates {
b= b.getOwner();
}
if (depIDCount > 0) {
nestingLevel += depIDCount;
nestingLevel+= depIDCount;
} else if (consumesTDecl < tdeclCount && !lastIsTemplate) {
nestingLevel++;
lastIsTemplate= true;
}
} else {
nestingLevel += depIDCount;
nestingLevel+= depIDCount;
node= outerMostTDecl.getParent();
while (node != null) {
if (node instanceof ICPPASTInternalTemplateDeclaration) {
nestingLevel += ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1;
nestingLevel+= ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1;
break;
}
node= node.getParent();
@ -1462,7 +1432,7 @@ public class CPPTemplates {
node= outerMostTDecl.getParent();
while (node != null) {
if (node instanceof ICPPASTInternalTemplateDeclaration) {
nestingLevel += ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1;
nestingLevel+= ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1;
break;
}
node= node.getParent();
@ -1471,7 +1441,7 @@ public class CPPTemplates {
}
node= innerMostTDecl;
while (node instanceof ICPPASTInternalTemplateDeclaration) {
while(node instanceof ICPPASTInternalTemplateDeclaration) {
if (--nestingLevel < 0)
nestingLevel= 0;
tdecl= (ICPPASTInternalTemplateDeclaration) node;
@ -1501,7 +1471,7 @@ public class CPPTemplates {
private static CharArraySet collectTemplateParameterNames(ICPPASTTemplateDeclaration tdecl) {
CharArraySet set= new CharArraySet(4);
while (true) {
while(true) {
ICPPASTTemplateParameter[] pars = tdecl.getTemplateParameters();
for (ICPPASTTemplateParameter par : pars) {
IASTName name= CPPTemplates.getTemplateParameterName(par);
@ -1521,7 +1491,7 @@ public class CPPTemplates {
private static boolean usesTemplateParameter(final ICPPASTTemplateId id, final CharArraySet names) {
final boolean[] result= {false};
ASTVisitor v= new ASTVisitor(false) {
{ shouldVisitNames= true; shouldVisitAmbiguousNodes= true; }
{ shouldVisitNames= true; shouldVisitAmbiguousNodes=true;}
@Override
public int visit(IASTName name) {
if (name instanceof ICPPASTTemplateId)
@ -1613,7 +1583,7 @@ public class CPPTemplates {
}
private static ICPPASTInternalTemplateDeclaration getDirectlyEnclosingTemplateDeclaration(
ICPPASTInternalTemplateDeclaration tdecl) {
ICPPASTInternalTemplateDeclaration tdecl ) {
final IASTNode parent= tdecl.getParent();
if (parent instanceof ICPPASTInternalTemplateDeclaration)
return (ICPPASTInternalTemplateDeclaration) parent;
@ -1681,7 +1651,7 @@ public class CPPTemplates {
if (args.length != specArgs.length) {
return false;
}
for (int i= 0; i < args.length; i++) {
for (int i=0; i < args.length; i++) {
if (!specArgs[i].isSameValue(args[i]))
return false;
}
@ -1707,10 +1677,6 @@ public class CPPTemplates {
IType type= expr.getExpressionType();
IValue value= Value.create((IASTExpression) arg, Value.MAX_RECURSION_DEPTH);
result[i]= new CPPTemplateArgument(value, type);
} else if (arg instanceof ICPPASTAmbiguousTemplateArgument) {
throw new IllegalArgumentException(id.getRawSignature()
+ " contains an ambiguous template argument at position " + i + " in " //$NON-NLS-1$ //$NON-NLS-2$
+ id.getContainingFilename());
} else {
throw new IllegalArgumentException("Unexpected type: " + arg.getClass().getName()); //$NON-NLS-1$
}
@ -1797,7 +1763,7 @@ public class CPPTemplates {
static ICPPFunction[] instantiateConversionTemplates(ICPPFunction[] functions, IType conversionType, IASTNode point) {
boolean checkedForDependentType= false;
ICPPFunction[] result= functions;
int i= 0;
int i=0;
boolean done= false;
for (ICPPFunction f : functions) {
ICPPFunction inst = f;
@ -1998,7 +1964,7 @@ public class CPPTemplates {
}
private static IType[] concat(final IType t, IType[] types) {
IType[] result= new IType[types.length + 1];
IType[] result= new IType[types.length+1];
result[0]= t;
System.arraycopy(types, 0, result, 1, types.length);
return result;
@ -2221,8 +2187,8 @@ public class CPPTemplates {
private static boolean matchTemplateTemplateParameters(ICPPTemplateParameter[] pParams,
ICPPTemplateParameter[] aParams) throws DOMException {
int pi= 0;
int ai= 0;
int pi=0;
int ai=0;
while (pi < pParams.length && ai < aParams.length) {
final ICPPTemplateParameter pp = pParams[pi];
final ICPPTemplateParameter ap = aParams[ai];
@ -2255,9 +2221,8 @@ public class CPPTemplates {
}
if (!matchTemplateTemplateParameters(((ICPPTemplateTemplateParameter) pp).getTemplateParameters(),
((ICPPTemplateTemplateParameter) ap).getTemplateParameters())) {
((ICPPTemplateTemplateParameter) ap).getTemplateParameters()) )
return false;
}
}
}
if (!pp.isParameterPack())

View file

@ -108,7 +108,32 @@ public class EvalBinary extends CPPEvaluation {
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
if (fOverload != null) {
// TODO(sprigogin): Simulate execution of a function call.
return Value.create(this);
}
IValue v1 = fArg1.getValue(point);
IValue v2 = fArg2.getValue(point);
switch (fOperator) {
case IASTBinaryExpression.op_equals:
if (v1.equals(v2))
return Value.create(1);
break;
case IASTBinaryExpression.op_notequals:
if (v1.equals(v2))
return Value.create(0);
break;
}
Long num1 = v1.numericalValue();
if (num1 != null) {
Long num2 = v2.numericalValue();
if (num2 != null) {
return Value.evaluateBinaryExpression(fOperator, num1, num2);
}
}
return Value.create(this);
}
@Override
@ -289,4 +314,9 @@ public class EvalBinary extends CPPEvaluation {
return this;
return new EvalBinary(fOperator, arg1, arg2);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
return CPPTemplates.combinePackSize(fArg1.determinePackSize(tpMap), fArg2.determinePackSize(tpMap));
}
}

View file

@ -20,12 +20,14 @@ import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.core.runtime.CoreException;
@ -78,7 +80,16 @@ public class EvalBinaryTypeId extends CPPEvaluation {
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
if (isValueDependent())
return Value.create(this);
switch (fOperator) {
case __is_base_of:
if (!(fType1 instanceof ICPPClassType) || !(fType1 instanceof ICPPClassType))
return Value.UNKNOWN;
return Value.create(ClassTypeHelper.isSubclass((ICPPClassType) fType2, (ICPPClassType) fType1));
}
return Value.create(this);
}
@Override
@ -124,4 +135,10 @@ public class EvalBinaryTypeId extends CPPEvaluation {
return this;
return new EvalBinaryTypeId(fOperator, type1, type2);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
return CPPTemplates.combinePackSize(CPPTemplates.determinePackSize(fType1, tpMap),
CPPTemplates.determinePackSize(fType2, tpMap));
}
}

View file

@ -26,9 +26,13 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.IInternalVariable;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
@ -164,7 +168,21 @@ public class EvalBinding extends CPPEvaluation {
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
if (isValueDependent())
return Value.create(this);
IValue value= null;
if (fBinding instanceof IInternalVariable) {
value= ((IInternalVariable) fBinding).getInitialValue(Value.MAX_RECURSION_DEPTH);
} else if (fBinding instanceof IVariable) {
value= ((IVariable) fBinding).getInitialValue();
} else if (fBinding instanceof IEnumerator) {
value= ((IEnumerator) fBinding).getValue();
}
if (value == null)
value = Value.UNKNOWN;
return value;
}
@Override
@ -223,4 +241,32 @@ public class EvalBinding extends CPPEvaluation {
return this;
return new EvalBinding(binding, getFixedType());
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
if (fBinding instanceof IEnumerator) {
return CPPTemplates.determinePackSize(((IEnumerator) fBinding).getValue(), tpMap);
}
if (fBinding instanceof ICPPTemplateNonTypeParameter) {
return CPPTemplates.determinePackSize((ICPPTemplateNonTypeParameter) fBinding, tpMap);
}
if (fBinding instanceof ICPPUnknownBinding) {
return CPPTemplates.determinePackSize((ICPPUnknownBinding) fBinding, tpMap);
}
IBinding binding = fBinding;
if (fBinding instanceof ICPPSpecialization) {
binding = ((ICPPSpecialization) fBinding).getSpecializedBinding();
}
int r = CPPTemplates.PACK_SIZE_NOT_FOUND;
if (binding instanceof ICPPTemplateDefinition) {
ICPPTemplateParameter[] parameters = ((ICPPTemplateDefinition) binding).getTemplateParameters();
for (ICPPTemplateParameter param : parameters) {
r = CPPTemplates.combinePackSize(r, CPPTemplates.determinePackSize(param, tpMap));
}
}
return r;
}
}

View file

@ -68,6 +68,7 @@ public class EvalComma extends CPPEvaluation {
@Override
public boolean isValueDependent() {
// TODO(sprigogin): Should the value depend only on the last argument?
for (ICPPEvaluation arg : fArguments) {
if (arg.isValueDependent())
return true;
@ -126,12 +127,18 @@ public class EvalComma extends CPPEvaluation {
return typeFromFunctionCall(last);
}
}
return fArguments[fArguments.length-1].getTypeOrFunctionSet(point);
return fArguments[fArguments.length - 1].getTypeOrFunctionSet(point);
}
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
ICPPFunction[] overloads = getOverloads(point);
if (overloads.length > 0) {
// TODO(sprigogin): Simulate execution of a function call.
return Value.create(this);
}
return fArguments[fArguments.length - 1].getValue(point);
}
@Override
@ -143,7 +150,7 @@ public class EvalComma extends CPPEvaluation {
return valueCategoryFromFunctionCall(last);
}
}
return fArguments[fArguments.length-1].getValueCategory(point);
return fArguments[fArguments.length - 1].getValueCategory(point);
}
@Override
@ -178,4 +185,13 @@ public class EvalComma extends CPPEvaluation {
return this;
return new EvalComma(args);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
int r = CPPTemplates.PACK_SIZE_NOT_FOUND;
for (ICPPEvaluation arg : fArguments) {
r = CPPTemplates.combinePackSize(r, arg.determinePackSize(tpMap));
}
return r;
}
}

View file

@ -21,7 +21,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.core.runtime.CoreException;
@ -66,7 +65,7 @@ public class EvalCompound extends CPPEvaluation {
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
return fDelegate.getValue(point);
}
@Override
@ -93,4 +92,9 @@ public class EvalCompound extends CPPEvaluation {
return this;
return new EvalCompound(delegate);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
return fDelegate.determinePackSize(tpMap);
}
}

View file

@ -108,7 +108,18 @@ public class EvalConditional extends CPPEvaluation {
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
IValue condValue = fCondition.getValue(point);
if (condValue == Value.UNKNOWN)
return Value.UNKNOWN;
Long cond = condValue.numericalValue();
if (cond != null) {
if (cond.longValue() != 0) {
return fPositive == null ? condValue : fPositive.getValue(point);
} else {
return fNegative.getValue(point);
}
}
return Value.create(this);
}
@Override
@ -324,4 +335,13 @@ public class EvalConditional extends CPPEvaluation {
return this;
return new EvalConditional(condition, positive, negative, fPositiveThrows, fNegativeThrows);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
int r = fCondition.determinePackSize(tpMap);
r = CPPTemplates.combinePackSize(r, fNegative.determinePackSize(tpMap));
if (fPositive != null)
r = CPPTemplates.combinePackSize(r, fPositive.determinePackSize(tpMap));
return r;
}
}

View file

@ -158,4 +158,9 @@ public class EvalFixed extends CPPEvaluation {
return this;
return new EvalFixed(type, fValueCategory, value);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
return CPPTemplates.determinePackSize(fValue, tpMap);
}
}

View file

@ -135,7 +135,10 @@ public class EvalFunctionCall extends CPPEvaluation {
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
if (isValueDependent())
return Value.create(this);
// TODO(sprigogin): Simulate execution of a function call.
return Value.UNKNOWN;
}
@Override
@ -170,7 +173,7 @@ public class EvalFunctionCall extends CPPEvaluation {
for (int i = 0; i < args.length; i++) {
args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation();
}
return new EvalComma(args);
return new EvalFunctionCall(args);
}
@Override
@ -187,4 +190,13 @@ public class EvalFunctionCall extends CPPEvaluation {
return this;
return new EvalFunctionCall(args);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
int r = CPPTemplates.PACK_SIZE_NOT_FOUND;
for (ICPPEvaluation arg : fArguments) {
r = CPPTemplates.combinePackSize(r, arg.determinePackSize(tpMap));
}
return r;
}
}

View file

@ -171,4 +171,14 @@ public class EvalFunctionSet extends CPPEvaluation {
return this;
return new EvalFunctionSet(new CPPFunctionSet(functions, arguments, null), fAddressOf);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
int r = CPPTemplates.PACK_SIZE_NOT_FOUND;
ICPPTemplateArgument[] templateArguments = fFunctionSet.getTemplateArguments();
for (ICPPTemplateArgument arg : templateArguments) {
r = CPPTemplates.combinePackSize(r, CPPTemplates.determinePackSize(arg, tpMap));
}
return r;
}
}

View file

@ -70,6 +70,9 @@ public class EvalID extends CPPEvaluation {
fTemplateArgs= templateArgs;
}
/**
* Returns the field owner expression, or {@code null}.
*/
public ICPPEvaluation getFieldOwner() {
return fFieldOwner;
}
@ -90,6 +93,9 @@ public class EvalID extends CPPEvaluation {
return fQualified;
}
/**
* Returns the template arguments, or {@code null} if there are no template arguments.
*/
public ICPPTemplateArgument[] getTemplateArgs() {
return fTemplateArgs;
}
@ -121,7 +127,7 @@ public class EvalID extends CPPEvaluation {
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
return Value.create(this);
}
@Override
@ -256,14 +262,19 @@ public class EvalID extends CPPEvaluation {
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
ICPPTemplateArgument[] arguments = fTemplateArgs;
try {
arguments = CPPTemplates.instantiateArguments(fTemplateArgs, tpMap, packOffset, within, point);
} catch (DOMException e) {
CCorePlugin.log(e);
ICPPTemplateArgument[] templateArgs = fTemplateArgs;
if (templateArgs != null) {
try {
templateArgs = CPPTemplates.instantiateArguments(templateArgs, tpMap, packOffset, within, point);
} catch (DOMException e) {
CCorePlugin.log(e);
}
}
ICPPEvaluation fieldOwner = fFieldOwner.instantiate(tpMap, packOffset, within, maxdepth, point);
ICPPEvaluation fieldOwner = fFieldOwner;
if (fieldOwner != null) {
fieldOwner = fieldOwner.instantiate(tpMap, packOffset, within, maxdepth, point);
}
IBinding nameOwner = fNameOwner;
if (fNameOwner instanceof ICPPTemplateParameter) {
ICPPTemplateArgument argument = tpMap.getArgument((ICPPTemplateParameter) fNameOwner);
@ -280,16 +291,16 @@ public class EvalID extends CPPEvaluation {
CCorePlugin.log(e);
}
}
if (Arrays.equals(arguments, fTemplateArgs) && fieldOwner == fFieldOwner && nameOwner == fNameOwner)
if (Arrays.equals(templateArgs, fTemplateArgs) && fieldOwner == fFieldOwner && nameOwner == fNameOwner)
return this;
if (nameOwner == null)
nameOwner = (IBinding) fFieldOwner.getTypeOrFunctionSet(point);
if (nameOwner == null && fieldOwner != null)
nameOwner = (IBinding) fieldOwner.getTypeOrFunctionSet(point);
if (nameOwner instanceof ICompositeType) {
if (nameOwner instanceof ICompositeType && point != null) {
ICompositeType ownerType = (ICompositeType) nameOwner;
// TODO(sprigogin): Is this the right way to do lookup, or should findBindings be used instead?
LookupData data = new LookupData(fName, fTemplateArgs, point);
LookupData data = new LookupData(fName, templateArgs, point);
try {
CPPSemantics.lookup(data, ownerType.getScope());
} catch (DOMException e) {
@ -305,6 +316,15 @@ public class EvalID extends CPPEvaluation {
}
}
return new EvalID(fieldOwner, nameOwner, fName, fAddressOf, fQualified, arguments);
return new EvalID(fieldOwner, nameOwner, fName, fAddressOf, fQualified, templateArgs);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
int r = fFieldOwner.determinePackSize(tpMap);
for (ICPPTemplateArgument arg : fTemplateArgs) {
r = CPPTemplates.combinePackSize(r, CPPTemplates.determinePackSize(arg, tpMap));
}
return r;
}
}

View file

@ -74,7 +74,9 @@ public class EvalInitList extends CPPEvaluation {
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
if (isValueDependent())
return Value.create(this);
return Value.UNKNOWN; // TODO(sprigogin): Is this correct?
}
@Override
@ -97,7 +99,7 @@ public class EvalInitList extends CPPEvaluation {
for (int i = 0; i < args.length; i++) {
args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation();
}
return new EvalComma(args);
return new EvalInitList(args);
}
@Override
@ -114,4 +116,13 @@ public class EvalInitList extends CPPEvaluation {
return this;
return new EvalInitList(clauses);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
int r = CPPTemplates.PACK_SIZE_NOT_FOUND;
for (ICPPEvaluation arg : fClauses) {
r = CPPTemplates.combinePackSize(r, arg.determinePackSize(tpMap));
}
return r;
}
}

View file

@ -254,7 +254,16 @@ public class EvalMemberAccess extends CPPEvaluation {
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
if (fMember instanceof IEnumerator) {
return ((IEnumerator) fMember).getValue();
}
if (fMember instanceof IVariable) {
return ((IVariable) fMember).getInitialValue();
}
if (fMember instanceof IFunction) {
return Value.UNKNOWN;
}
return Value.create(this);
}
@Override
@ -324,4 +333,9 @@ public class EvalMemberAccess extends CPPEvaluation {
}
return new EvalMemberAccess(ownerType, fOwnerValueCategory, member, fIsPointerDeref);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
return CPPTemplates.determinePackSize(fOwnerType, tpMap);
}
}

View file

@ -19,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
@ -73,7 +74,20 @@ public class EvalTypeId extends CPPEvaluation {
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
if (isValueDependent())
return Value.create(this);
if (fArguments == null)
return Value.UNKNOWN;
if (isTypeDependent())
return Value.create(this);
if (fOutputType instanceof ICPPClassType) {
// TODO(sprigogin): Simulate execution of a ctor call.
return Value.UNKNOWN;
}
if (fArguments.length == 1)
return fArguments[0].getValue(point);
return Value.UNKNOWN;
}
@Override
@ -144,4 +158,13 @@ public class EvalTypeId extends CPPEvaluation {
return this;
return new EvalTypeId(type, args);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
int r = CPPTemplates.determinePackSize(fInputType, tpMap);
for (ICPPEvaluation arg : fArguments) {
r = CPPTemplates.combinePackSize(r, arg.determinePackSize(tpMap));
}
return r;
}
}

View file

@ -205,7 +205,17 @@ public class EvalUnary extends CPPEvaluation {
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
if (fOverload != null) {
// TODO(sprigogin): Simulate execution of a function call.
return Value.create(this);
}
IValue val = fArgument.getValue(point);
Long num = val.numericalValue();
if (num != null) {
return Value.evaluateUnaryExpression(fOperator, num);
}
return Value.create(this);
}
@Override
@ -246,4 +256,9 @@ public class EvalUnary extends CPPEvaluation {
return this;
return new EvalUnary(fOperator, argument);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
return fArgument.determinePackSize(tpMap);
}
}

View file

@ -34,6 +34,8 @@ import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_typeof;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
@ -41,6 +43,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator;
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
@ -148,7 +152,56 @@ public class EvalUnaryTypeID extends CPPEvaluation {
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
if (isValueDependent())
return Value.create(this);
switch (fOperator) {
case op_sizeof: {
if (point == null)
return Value.UNKNOWN;
SizeAndAlignment info = new SizeofCalculator(point.getTranslationUnit()).sizeAndAlignment(fOrigType);
return info == null ? Value.UNKNOWN : Value.create(info.size);
}
case op_alignof: {
if (point == null)
return Value.UNKNOWN;
SizeAndAlignment info = new SizeofCalculator(point.getTranslationUnit()).sizeAndAlignment(fOrigType);
return info == null ? Value.UNKNOWN : Value.create(info.alignment);
}
case op_typeid:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_has_nothrow_copy:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_has_nothrow_constructor:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_has_trivial_assign:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_has_trivial_constructor:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_has_trivial_copy:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_has_trivial_destructor:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_has_virtual_destructor:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_is_abstract:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_is_class:
return Value.create(fOrigType instanceof ICompositeType && ((ICompositeType) fOrigType).getKey() != ICompositeType.k_union);
case op_is_empty:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_is_enum:
return Value.create(fOrigType instanceof IEnumeration);
case op_is_pod:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_is_polymorphic:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_is_union:
return Value.create(fOrigType instanceof ICompositeType && ((ICompositeType) fOrigType).getKey() == ICompositeType.k_union);
case op_typeof:
return Value.UNKNOWN; // TODO(sprigogin): Implement
}
return Value.create(this);
}
@Override
@ -177,4 +230,9 @@ public class EvalUnaryTypeID extends CPPEvaluation {
return this;
return new EvalUnaryTypeID(fOperator, type);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
return CPPTemplates.determinePackSize(fOrigType, tpMap);
}
}

View file

@ -425,16 +425,13 @@ public class CPPCompositesFactory extends AbstractCompositeFactory {
public IValue getCompositeValue(IValue v) {
if (v == null)
return null;
IBinding[] b= v.getUnknownBindings();
if (b.length == 0)
ICPPEvaluation eval = v.getEvaluation();
if (eval == null)
return v;
ICPPUnknownBinding[] b2= new ICPPUnknownBinding[b.length];
for (int i = 0; i < b2.length; i++) {
b2[i]= (ICPPUnknownBinding) getCompositeBinding((IIndexFragmentBinding) b[i]);
}
return Value.fromInternalRepresentation(v.getInternalExpression(), b2);
eval = getCompositeEvaluation(eval);
return Value.fromInternalRepresentation(eval);
}
private ICPPNamespace[] getNamespaces(IBinding rbinding) throws CoreException {