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: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom.ast; 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. * Models a value of a variable, enumerator or expression.
* *
@ -19,27 +22,33 @@ package org.eclipse.cdt.core.dom.ast;
*/ */
public interface IValue { 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(); Long numericalValue();
/** /**
* Returns an internal representation of the expression that builds up * Returns the evaluation object if this value is dependent, or {@code null} otherwise.
* the value. It is suitable for instantiating dependent values but may not be * If {@link #numericalValue()} returns {@code null}, {@link #getEvaluation()} returns
* used for the purpose of displaying values. * 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 * Returns a signature uniquely identifying the value. Two values with identical
* of unknown bindings is maintained for later instantiation. * signatures are guaranteed to be equal.
*/
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(); 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> * @return offset where the array was found or <code>-1</code>
*/ */
public static int indexOf(final char[] searchFor, final char[][] searchIn) { public static int indexOf(final char[] searchFor, final char[][] searchIn) {
@ -340,4 +340,15 @@ public class CharArrayUtils {
} }
return -1; 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, ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point); 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.IBinding;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue; 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.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableType; import org.eclipse.cdt.internal.core.dom.parser.ISerializableType;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
@ -45,6 +47,10 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
return fBuffer.toString(); return fBuffer.toString();
} }
public char[] getSignature() {
return CharArrayUtils.extractChars(fBuffer);
}
@Override @Override
public void marshalBinding(IBinding binding) throws CoreException { public void marshalBinding(IBinding binding) throws CoreException {
if (binding instanceof ISerializableType) { if (binding instanceof ISerializableType) {
@ -53,12 +59,11 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
putByte(NULL_TYPE); putByte(NULL_TYPE);
} else { } else {
appendSeparator(); appendSeparator();
IBinding owner= binding.getOwner(); if (binding instanceof ICPPBinding) {
if (owner instanceof IType) { fBuffer.append(ASTTypeUtil.getQualifiedName((ICPPBinding) binding));
ASTTypeUtil.appendType((IType) owner, true, fBuffer); } else {
fBuffer.append("::"); //$NON-NLS-1$ fBuffer.append(binding.getNameCharArray());
} }
fBuffer.append(binding.getName());
} }
} }
@ -223,6 +228,6 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
CCorePlugin.log(e); CCorePlugin.log(e);
return new char[] { '?' }; 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.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IValue; 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;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; 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.CPPUsingDeclarationSpecialization;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalTemplateDeclaration; 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.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.ICPPInstanceCache;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalClassTemplate; 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. * type instantiation.
*/ */
public class CPPTemplates { public class CPPTemplates {
private static final int PACK_SIZE_DEFER = -1; static final int PACK_SIZE_DEFER = -1;
private static final int PACK_SIZE_FAIL = -2; static final int PACK_SIZE_FAIL = -2;
private static final int PACK_SIZE_NOT_FOUND = Integer.MAX_VALUE; static final int PACK_SIZE_NOT_FOUND = Integer.MAX_VALUE;
private static final ICPPFunction[] NO_FUNCTIONS = {}; private static final ICPPFunction[] NO_FUNCTIONS = {};
static enum TypeSelection { PARAMETERS, RETURN_TYPE, PARAMETERS_AND_RETURN_TYPE } static enum TypeSelection { PARAMETERS, RETURN_TYPE, PARAMETERS_AND_RETURN_TYPE }
@ -225,7 +225,7 @@ public class CPPTemplates {
} }
if (isPack) { if (isPack) {
int packOffset= numParams - 1; int packOffset= numParams-1;
int packSize= numArgs - packOffset; int packSize= numArgs - packOffset;
ICPPTemplateArgument[] pack= new ICPPTemplateArgument[packSize]; ICPPTemplateArgument[] pack= new ICPPTemplateArgument[packSize];
System.arraycopy(arguments, packOffset, pack, 0, packSize); System.arraycopy(arguments, packOffset, pack, 0, packSize);
@ -402,7 +402,7 @@ public class CPPTemplates {
for (int i = 0; i < arguments.length; i++) { for (int i = 0; i < arguments.length; i++) {
ICPPTemplateArgument arg = arguments[i]; ICPPTemplateArgument arg = arguments[i];
if (arg.isPackExpansion()) { if (arg.isPackExpansion()) {
if (i != arguments.length - 1) { if (i != arguments.length-1) {
return arguments; return arguments;
} }
havePackExpansion= true; havePackExpansion= true;
@ -421,10 +421,10 @@ public class CPPTemplates {
// More arguments allowed if we have a parameter pack. // More arguments allowed if we have a parameter pack.
if (tparCount < argCount) { if (tparCount < argCount) {
if (tpars[tparCount - 1].isParameterPack()) if (tpars[tparCount-1].isParameterPack())
return arguments; return arguments;
if (havePackExpansion && tparCount + 1 == argCount) if (havePackExpansion && tparCount+1 == argCount)
return arguments; return arguments;
return null; return null;
} }
@ -434,7 +434,7 @@ public class CPPTemplates {
return arguments; return arguments;
// Fewer arguments are allowed with default arguments // Fewer arguments are allowed with default arguments
if (tpars[tparCount - 1].isParameterPack()) if (tpars[tparCount-1].isParameterPack())
tparCount--; tparCount--;
if (tparCount == argCount) if (tparCount == argCount)
@ -862,43 +862,20 @@ public class CPPTemplates {
ICPPClassSpecialization within, int maxdepth, IASTNode point) { ICPPClassSpecialization within, int maxdepth, IASTNode point) {
if (value == null) if (value == null)
return null; return null;
IBinding[] unknowns= value.getUnknownBindings(); ICPPEvaluation evaluation = value.getEvaluation();
IBinding[] resolvedUnknowns= null; if (evaluation == null)
if (unknowns.length != 0) { return value;
for (int i = 0; i < unknowns.length; i++) { ICPPEvaluation instantiated = evaluation.instantiate(tpMap, packOffset, within, maxdepth, point);
IBinding unknown= unknowns[i]; if (instantiated == evaluation)
IBinding resolved= unknown; return value;
if (unknown instanceof ICPPUnknownBinding) { return instantiated.getValue(point);
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;
} }
public static boolean containsParameterPack(IType type) { public static boolean containsParameterPack(IType type) {
return determinePackSize(type, CPPTemplateParameterMap.EMPTY) == PACK_SIZE_DEFER; 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) { if (type instanceof ICPPFunctionType) {
final ICPPFunctionType ft = (ICPPFunctionType) type; final ICPPFunctionType ft = (ICPPFunctionType) type;
final IType rt = ft.getReturnType(); final IType rt = ft.getReturnType();
@ -907,7 +884,7 @@ public class CPPTemplates {
return r; return r;
IType[] ps = ft.getParameterTypes(); IType[] ps = ft.getParameterTypes();
for (IType pt : ps) { for (IType pt : ps) {
r= combine(r, determinePackSize(pt, tpMap)); r= combinePackSize(r, determinePackSize(pt, tpMap));
if (r < 0) if (r < 0)
return r; return r;
} }
@ -915,37 +892,17 @@ public class CPPTemplates {
} }
if (type instanceof ICPPTemplateParameter) { if (type instanceof ICPPTemplateParameter) {
final ICPPTemplateParameter tpar = (ICPPTemplateParameter) type; return determinePackSize((ICPPTemplateParameter) type, tpMap);
if (tpar.isParameterPack()) {
ICPPTemplateArgument[] args= tpMap.getPackExpansion(tpar);
if (args != null)
return args.length;
return PACK_SIZE_DEFER;
}
return PACK_SIZE_NOT_FOUND;
} }
int r= PACK_SIZE_NOT_FOUND;
if (type instanceof ICPPUnknownBinding) { if (type instanceof ICPPUnknownBinding) {
if (type instanceof ICPPDeferredClassInstance) { return determinePackSize((ICPPUnknownBinding) type, tpMap);
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;
} }
if (type instanceof ICPPParameterPackType) if (type instanceof ICPPParameterPackType)
return PACK_SIZE_NOT_FOUND; return PACK_SIZE_NOT_FOUND;
int r= PACK_SIZE_NOT_FOUND;
if (type instanceof IArrayType) { if (type instanceof IArrayType) {
IArrayType at= (IArrayType) type; IArrayType at= (IArrayType) type;
IValue asize= at.getSize(); IValue asize= at.getSize();
@ -956,12 +913,54 @@ public class CPPTemplates {
if (type instanceof ITypeContainer) { if (type instanceof ITypeContainer) {
final ITypeContainer typeContainer = (ITypeContainer) type; final ITypeContainer typeContainer = (ITypeContainer) type;
r= combine(r, determinePackSize(typeContainer.getType(), tpMap)); r= combinePackSize(r, determinePackSize(typeContainer.getType(), tpMap));
} }
return r; 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) if (ps1 < 0 || ps2 == PACK_SIZE_NOT_FOUND)
return ps1; return ps1;
if (ps2 < 0 || ps1 == PACK_SIZE_NOT_FOUND) if (ps2 < 0 || ps1 == PACK_SIZE_NOT_FOUND)
@ -971,35 +970,6 @@ public class CPPTemplates {
return ps1; 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. * Instantiates types contained in an array.
* @param types an array of types * @param types an array of types
@ -1025,7 +995,7 @@ public class CPPTemplates {
} else if (packSize == PACK_SIZE_DEFER) { } else if (packSize == PACK_SIZE_DEFER) {
newType= origType; newType= origType;
} else { } else {
IType[] newResult= new IType[result.length + packSize - 1]; IType[] newResult= new IType[result.length+packSize-1];
System.arraycopy(result, 0, newResult, 0, j); System.arraycopy(result, 0, newResult, 0, j);
result= newResult; result= newResult;
for (int k= 0; k < packSize; k++) { for (int k= 0; k < packSize; k++) {
@ -1168,7 +1138,7 @@ public class CPPTemplates {
return type; return type;
} }
// The parameter types need to be adjusted. // 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]; IType p= params[i];
if (!isDependentType(p)) { if (!isDependentType(p)) {
params[i]= CPPVisitor.adjustParameterType(p, true); params[i]= CPPVisitor.adjustParameterType(p, true);
@ -1396,7 +1366,7 @@ public class CPPTemplates {
int depIDCount= 0; int depIDCount= 0;
IASTName owner= null; IASTName owner= null;
final IASTName[] ns= qname.getNames(); 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]; IASTName n= ns[i];
if (n instanceof ICPPASTTemplateId) { if (n instanceof ICPPASTTemplateId) {
if (depIDCount > 0 || usesTemplateParameter((ICPPASTTemplateId) n, tparnames)) { if (depIDCount > 0 || usesTemplateParameter((ICPPASTTemplateId) n, tparnames)) {
@ -1439,17 +1409,17 @@ public class CPPTemplates {
b= b.getOwner(); b= b.getOwner();
} }
if (depIDCount > 0) { if (depIDCount > 0) {
nestingLevel += depIDCount; nestingLevel+= depIDCount;
} else if (consumesTDecl < tdeclCount && !lastIsTemplate) { } else if (consumesTDecl < tdeclCount && !lastIsTemplate) {
nestingLevel++; nestingLevel++;
lastIsTemplate= true; lastIsTemplate= true;
} }
} else { } else {
nestingLevel += depIDCount; nestingLevel+= depIDCount;
node= outerMostTDecl.getParent(); node= outerMostTDecl.getParent();
while (node != null) { while (node != null) {
if (node instanceof ICPPASTInternalTemplateDeclaration) { if (node instanceof ICPPASTInternalTemplateDeclaration) {
nestingLevel += ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1; nestingLevel+= ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1;
break; break;
} }
node= node.getParent(); node= node.getParent();
@ -1462,7 +1432,7 @@ public class CPPTemplates {
node= outerMostTDecl.getParent(); node= outerMostTDecl.getParent();
while (node != null) { while (node != null) {
if (node instanceof ICPPASTInternalTemplateDeclaration) { if (node instanceof ICPPASTInternalTemplateDeclaration) {
nestingLevel += ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1; nestingLevel+= ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1;
break; break;
} }
node= node.getParent(); node= node.getParent();
@ -1471,7 +1441,7 @@ public class CPPTemplates {
} }
node= innerMostTDecl; node= innerMostTDecl;
while (node instanceof ICPPASTInternalTemplateDeclaration) { while(node instanceof ICPPASTInternalTemplateDeclaration) {
if (--nestingLevel < 0) if (--nestingLevel < 0)
nestingLevel= 0; nestingLevel= 0;
tdecl= (ICPPASTInternalTemplateDeclaration) node; tdecl= (ICPPASTInternalTemplateDeclaration) node;
@ -1501,7 +1471,7 @@ public class CPPTemplates {
private static CharArraySet collectTemplateParameterNames(ICPPASTTemplateDeclaration tdecl) { private static CharArraySet collectTemplateParameterNames(ICPPASTTemplateDeclaration tdecl) {
CharArraySet set= new CharArraySet(4); CharArraySet set= new CharArraySet(4);
while (true) { while(true) {
ICPPASTTemplateParameter[] pars = tdecl.getTemplateParameters(); ICPPASTTemplateParameter[] pars = tdecl.getTemplateParameters();
for (ICPPASTTemplateParameter par : pars) { for (ICPPASTTemplateParameter par : pars) {
IASTName name= CPPTemplates.getTemplateParameterName(par); IASTName name= CPPTemplates.getTemplateParameterName(par);
@ -1521,7 +1491,7 @@ public class CPPTemplates {
private static boolean usesTemplateParameter(final ICPPASTTemplateId id, final CharArraySet names) { private static boolean usesTemplateParameter(final ICPPASTTemplateId id, final CharArraySet names) {
final boolean[] result= {false}; final boolean[] result= {false};
ASTVisitor v= new ASTVisitor(false) { ASTVisitor v= new ASTVisitor(false) {
{ shouldVisitNames= true; shouldVisitAmbiguousNodes= true; } { shouldVisitNames= true; shouldVisitAmbiguousNodes=true;}
@Override @Override
public int visit(IASTName name) { public int visit(IASTName name) {
if (name instanceof ICPPASTTemplateId) if (name instanceof ICPPASTTemplateId)
@ -1613,7 +1583,7 @@ public class CPPTemplates {
} }
private static ICPPASTInternalTemplateDeclaration getDirectlyEnclosingTemplateDeclaration( private static ICPPASTInternalTemplateDeclaration getDirectlyEnclosingTemplateDeclaration(
ICPPASTInternalTemplateDeclaration tdecl) { ICPPASTInternalTemplateDeclaration tdecl ) {
final IASTNode parent= tdecl.getParent(); final IASTNode parent= tdecl.getParent();
if (parent instanceof ICPPASTInternalTemplateDeclaration) if (parent instanceof ICPPASTInternalTemplateDeclaration)
return (ICPPASTInternalTemplateDeclaration) parent; return (ICPPASTInternalTemplateDeclaration) parent;
@ -1681,7 +1651,7 @@ public class CPPTemplates {
if (args.length != specArgs.length) { if (args.length != specArgs.length) {
return false; return false;
} }
for (int i= 0; i < args.length; i++) { for (int i=0; i < args.length; i++) {
if (!specArgs[i].isSameValue(args[i])) if (!specArgs[i].isSameValue(args[i]))
return false; return false;
} }
@ -1707,10 +1677,6 @@ public class CPPTemplates {
IType type= expr.getExpressionType(); IType type= expr.getExpressionType();
IValue value= Value.create((IASTExpression) arg, Value.MAX_RECURSION_DEPTH); IValue value= Value.create((IASTExpression) arg, Value.MAX_RECURSION_DEPTH);
result[i]= new CPPTemplateArgument(value, type); 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 { } else {
throw new IllegalArgumentException("Unexpected type: " + arg.getClass().getName()); //$NON-NLS-1$ 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) { static ICPPFunction[] instantiateConversionTemplates(ICPPFunction[] functions, IType conversionType, IASTNode point) {
boolean checkedForDependentType= false; boolean checkedForDependentType= false;
ICPPFunction[] result= functions; ICPPFunction[] result= functions;
int i= 0; int i=0;
boolean done= false; boolean done= false;
for (ICPPFunction f : functions) { for (ICPPFunction f : functions) {
ICPPFunction inst = f; ICPPFunction inst = f;
@ -1998,7 +1964,7 @@ public class CPPTemplates {
} }
private static IType[] concat(final IType t, IType[] types) { 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; result[0]= t;
System.arraycopy(types, 0, result, 1, types.length); System.arraycopy(types, 0, result, 1, types.length);
return result; return result;
@ -2221,8 +2187,8 @@ public class CPPTemplates {
private static boolean matchTemplateTemplateParameters(ICPPTemplateParameter[] pParams, private static boolean matchTemplateTemplateParameters(ICPPTemplateParameter[] pParams,
ICPPTemplateParameter[] aParams) throws DOMException { ICPPTemplateParameter[] aParams) throws DOMException {
int pi= 0; int pi=0;
int ai= 0; int ai=0;
while (pi < pParams.length && ai < aParams.length) { while (pi < pParams.length && ai < aParams.length) {
final ICPPTemplateParameter pp = pParams[pi]; final ICPPTemplateParameter pp = pParams[pi];
final ICPPTemplateParameter ap = aParams[ai]; final ICPPTemplateParameter ap = aParams[ai];
@ -2255,9 +2221,8 @@ public class CPPTemplates {
} }
if (!matchTemplateTemplateParameters(((ICPPTemplateTemplateParameter) pp).getTemplateParameters(), if (!matchTemplateTemplateParameters(((ICPPTemplateTemplateParameter) pp).getTemplateParameters(),
((ICPPTemplateTemplateParameter) ap).getTemplateParameters())) { ((ICPPTemplateTemplateParameter) ap).getTemplateParameters()) )
return false; return false;
}
} }
} }
if (!pp.isParameterPack()) if (!pp.isParameterPack())

View file

@ -108,7 +108,32 @@ public class EvalBinary extends CPPEvaluation {
@Override @Override
public IValue getValue(IASTNode point) { 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 @Override
@ -289,4 +314,9 @@ public class EvalBinary extends CPPEvaluation {
return this; return this;
return new EvalBinary(fOperator, arg1, arg2); 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.IType;
import org.eclipse.cdt.core.dom.ast.IValue; 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.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; 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.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; 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.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.Value; 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.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
@ -78,7 +80,16 @@ public class EvalBinaryTypeId extends CPPEvaluation {
@Override @Override
public IValue getValue(IASTNode point) { 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 @Override
@ -124,4 +135,10 @@ public class EvalBinaryTypeId extends CPPEvaluation {
return this; return this;
return new EvalBinaryTypeId(fOperator, type1, type2); 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.IValue;
import org.eclipse.cdt.core.dom.ast.IVariable; 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.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.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.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; 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.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; 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.ProblemType;
@ -164,7 +168,21 @@ public class EvalBinding extends CPPEvaluation {
@Override @Override
public IValue getValue(IASTNode point) { 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 @Override
@ -223,4 +241,32 @@ public class EvalBinding extends CPPEvaluation {
return this; return this;
return new EvalBinding(binding, getFixedType()); 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 @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;
@ -126,12 +127,18 @@ public class EvalComma extends CPPEvaluation {
return typeFromFunctionCall(last); return typeFromFunctionCall(last);
} }
} }
return fArguments[fArguments.length-1].getTypeOrFunctionSet(point); return fArguments[fArguments.length - 1].getTypeOrFunctionSet(point);
} }
@Override @Override
public IValue getValue(IASTNode point) { 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 @Override
@ -143,7 +150,7 @@ public class EvalComma extends CPPEvaluation {
return valueCategoryFromFunctionCall(last); return valueCategoryFromFunctionCall(last);
} }
} }
return fArguments[fArguments.length-1].getValueCategory(point); return fArguments[fArguments.length - 1].getValueCategory(point);
} }
@Override @Override
@ -178,4 +185,13 @@ public class EvalComma extends CPPEvaluation {
return this; return this;
return new EvalComma(args); 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.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; 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.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
@ -66,7 +65,7 @@ public class EvalCompound extends CPPEvaluation {
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue(IASTNode point) {
return Value.create(this, point); return fDelegate.getValue(point);
} }
@Override @Override
@ -93,4 +92,9 @@ public class EvalCompound extends CPPEvaluation {
return this; return this;
return new EvalCompound(delegate); 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 @Override
public IValue getValue(IASTNode point) { 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 @Override
@ -324,4 +335,13 @@ public class EvalConditional extends CPPEvaluation {
return this; return this;
return new EvalConditional(condition, positive, negative, fPositiveThrows, fNegativeThrows); 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 this;
return new EvalFixed(type, fValueCategory, value); 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 @Override
public IValue getValue(IASTNode point) { 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 @Override
@ -170,7 +173,7 @@ public class EvalFunctionCall extends CPPEvaluation {
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation(); args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation();
} }
return new EvalComma(args); return new EvalFunctionCall(args);
} }
@Override @Override
@ -187,4 +190,13 @@ public class EvalFunctionCall extends CPPEvaluation {
return this; return this;
return new EvalFunctionCall(args); 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 this;
return new EvalFunctionSet(new CPPFunctionSet(functions, arguments, null), fAddressOf); 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; fTemplateArgs= templateArgs;
} }
/**
* Returns the field owner expression, or {@code null}.
*/
public ICPPEvaluation getFieldOwner() { public ICPPEvaluation getFieldOwner() {
return fFieldOwner; return fFieldOwner;
} }
@ -90,6 +93,9 @@ public class EvalID extends CPPEvaluation {
return fQualified; return fQualified;
} }
/**
* Returns the template arguments, or {@code null} if there are no template arguments.
*/
public ICPPTemplateArgument[] getTemplateArgs() { public ICPPTemplateArgument[] getTemplateArgs() {
return fTemplateArgs; return fTemplateArgs;
} }
@ -121,7 +127,7 @@ public class EvalID extends CPPEvaluation {
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue(IASTNode point) {
return Value.create(this, point); return Value.create(this);
} }
@Override @Override
@ -256,14 +262,19 @@ public class EvalID extends CPPEvaluation {
@Override @Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset, public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point) { ICPPClassSpecialization within, int maxdepth, IASTNode point) {
ICPPTemplateArgument[] arguments = fTemplateArgs; ICPPTemplateArgument[] templateArgs = fTemplateArgs;
try { if (templateArgs != null) {
arguments = CPPTemplates.instantiateArguments(fTemplateArgs, tpMap, packOffset, within, point); try {
} catch (DOMException e) { templateArgs = CPPTemplates.instantiateArguments(templateArgs, tpMap, packOffset, within, point);
CCorePlugin.log(e); } 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; IBinding nameOwner = fNameOwner;
if (fNameOwner instanceof ICPPTemplateParameter) { if (fNameOwner instanceof ICPPTemplateParameter) {
ICPPTemplateArgument argument = tpMap.getArgument((ICPPTemplateParameter) fNameOwner); ICPPTemplateArgument argument = tpMap.getArgument((ICPPTemplateParameter) fNameOwner);
@ -280,16 +291,16 @@ public class EvalID extends CPPEvaluation {
CCorePlugin.log(e); CCorePlugin.log(e);
} }
} }
if (Arrays.equals(arguments, fTemplateArgs) && fieldOwner == fFieldOwner && nameOwner == fNameOwner) if (Arrays.equals(templateArgs, fTemplateArgs) && fieldOwner == fFieldOwner && nameOwner == fNameOwner)
return this; return this;
if (nameOwner == null) if (nameOwner == null && fieldOwner != null)
nameOwner = (IBinding) fFieldOwner.getTypeOrFunctionSet(point); nameOwner = (IBinding) fieldOwner.getTypeOrFunctionSet(point);
if (nameOwner instanceof ICompositeType) { 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? // 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 { try {
CPPSemantics.lookup(data, ownerType.getScope()); CPPSemantics.lookup(data, ownerType.getScope());
} catch (DOMException e) { } 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 @Override
public IValue getValue(IASTNode point) { 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 @Override
@ -97,7 +99,7 @@ public class EvalInitList extends CPPEvaluation {
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation(); args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation();
} }
return new EvalComma(args); return new EvalInitList(args);
} }
@Override @Override
@ -114,4 +116,13 @@ public class EvalInitList extends CPPEvaluation {
return this; return this;
return new EvalInitList(clauses); 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 @Override
public IValue getValue(IASTNode point) { 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 @Override
@ -324,4 +333,9 @@ public class EvalMemberAccess extends CPPEvaluation {
} }
return new EvalMemberAccess(ownerType, fOwnerValueCategory, member, fIsPointerDeref); 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.IType;
import org.eclipse.cdt.core.dom.ast.IValue; 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.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; 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.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
@ -73,7 +74,20 @@ public class EvalTypeId extends CPPEvaluation {
@Override @Override
public IValue getValue(IASTNode point) { 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 @Override
@ -144,4 +158,13 @@ public class EvalTypeId extends CPPEvaluation {
return this; return this;
return new EvalTypeId(type, args); 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 @Override
public IValue getValue(IASTNode point) { 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 @Override
@ -246,4 +256,9 @@ public class EvalUnary extends CPPEvaluation {
return this; return this;
return new EvalUnary(fOperator, argument); 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.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTNode; 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.IType;
import org.eclipse.cdt.core.dom.ast.IValue; 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.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.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; 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.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.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
@ -148,7 +152,56 @@ public class EvalUnaryTypeID extends CPPEvaluation {
@Override @Override
public IValue getValue(IASTNode point) { 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 @Override
@ -177,4 +230,9 @@ public class EvalUnaryTypeID extends CPPEvaluation {
return this; return this;
return new EvalUnaryTypeID(fOperator, type); 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) { public IValue getCompositeValue(IValue v) {
if (v == null) if (v == null)
return null; return null;
IBinding[] b= v.getUnknownBindings(); ICPPEvaluation eval = v.getEvaluation();
if (b.length == 0) if (eval == null)
return v; return v;
ICPPUnknownBinding[] b2= new ICPPUnknownBinding[b.length]; eval = getCompositeEvaluation(eval);
for (int i = 0; i < b2.length; i++) { return Value.fromInternalRepresentation(eval);
b2[i]= (ICPPUnknownBinding) getCompositeBinding((IIndexFragmentBinding) b[i]);
}
return Value.fromInternalRepresentation(v.getInternalExpression(), b2);
} }
private ICPPNamespace[] getNamespaces(IBinding rbinding) throws CoreException { private ICPPNamespace[] getNamespaces(IBinding rbinding) throws CoreException {