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

Bug 299911. Fixed AST2TemplateTests.testDependentExpressions test.

This commit is contained in:
Sergey Prigogin 2012-08-01 19:01:51 -07:00
parent 3400d21110
commit a2201b07ae
10 changed files with 193 additions and 87 deletions

View file

@ -5631,7 +5631,7 @@ public class AST2TemplateTests extends AST2BaseTest {
// ns::C<IsAorB<int>::value> a; // ns::C<IsAorB<int>::value> a;
// f(a); // f(a);
// }; // };
public void _testDependentExpressions() throws Exception { public void testDependentExpressions() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }

View file

@ -22,6 +22,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IPointerType;
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;
@ -109,7 +110,9 @@ public class SizeofCalculator {
*/ */
public SizeAndAlignment sizeAndAlignment(IType type) { public SizeAndAlignment sizeAndAlignment(IType type) {
type = SemanticUtil.getNestedType(type, SemanticUtil.CVTYPE | SemanticUtil.TDEF); type = SemanticUtil.getNestedType(type, SemanticUtil.CVTYPE | SemanticUtil.TDEF);
if (type instanceof IFunctionType) {
return sizeAndAlignment(((IFunctionType) type).getReturnType());
}
if (type instanceof IBasicType) { if (type instanceof IBasicType) {
return sizeAndAlignment((IBasicType) type); return sizeAndAlignment((IBasicType) type);
} }

View file

@ -12,12 +12,16 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTNode;
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.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
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.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.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;
@ -25,6 +29,7 @@ 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.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
public abstract class CPPEvaluation implements ICPPEvaluation { public abstract class CPPEvaluation implements ICPPEvaluation {
@ -219,4 +224,24 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
} }
return buf.getSignature(); return buf.getSignature();
} }
protected static IBinding resolveUnknown(ICPPUnknownBinding unknown, ICPPTemplateParameterMap tpMap,
int packOffset, ICPPClassSpecialization within, IASTNode point) {
try {
return CPPTemplates.resolveUnknown(unknown, tpMap, packOffset, within, point);
} catch (DOMException e) {
CCorePlugin.log(e);
}
return unknown;
}
protected static ICPPTemplateArgument[] instantiateArguments(ICPPTemplateArgument[] args,
ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, IASTNode point) {
try {
return CPPTemplates.instantiateArguments(args, tpMap, packOffset, within, point);
} catch (DOMException e) {
CCorePlugin.log(e);
}
return args;
}
} }

View file

@ -11,6 +11,30 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_assign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_binaryAnd;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_binaryAndAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_binaryOrAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_binaryXorAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_divideAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_equals;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_greaterEqual;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_greaterThan;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_lessEqual;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_lessThan;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_logicalAnd;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_logicalOr;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_minus;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_minusAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_moduloAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_multiplyAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_notequals;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_plus;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_plusAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_pmarrow;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_pmdot;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_shiftLeftAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_shiftRightAssign;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType;
@ -21,14 +45,12 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
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.IPointerType; import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem; 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.ICPPASTBinaryExpression;
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.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
@ -114,13 +136,18 @@ public class EvalBinary extends CPPEvaluation {
} }
IValue v1 = fArg1.getValue(point); IValue v1 = fArg1.getValue(point);
if (v1 == Value.UNKNOWN)
return Value.UNKNOWN;
IValue v2 = fArg2.getValue(point); IValue v2 = fArg2.getValue(point);
if (v2 == Value.UNKNOWN)
return Value.UNKNOWN;
switch (fOperator) { switch (fOperator) {
case IASTBinaryExpression.op_equals: case op_equals:
if (v1.equals(v2)) if (v1.equals(v2))
return Value.create(1); return Value.create(1);
break; break;
case IASTBinaryExpression.op_notequals: case op_notequals:
if (v1.equals(v2)) if (v1.equals(v2))
return Value.create(0); return Value.create(0);
break; break;
@ -128,6 +155,12 @@ public class EvalBinary extends CPPEvaluation {
Long num1 = v1.numericalValue(); Long num1 = v1.numericalValue();
if (num1 != null) { if (num1 != null) {
if (num1 == 0) {
if (fOperator == op_binaryAnd || fOperator == op_logicalAnd)
return v1;
} else if (fOperator == op_logicalOr) {
return v1;
}
Long num2 = v2.numericalValue(); Long num2 = v2.numericalValue();
if (num2 != null) { if (num2 != null) {
return Value.evaluateBinaryExpression(fOperator, num1, num2); return Value.evaluateBinaryExpression(fOperator, num1, num2);
@ -160,25 +193,25 @@ public class EvalBinary extends CPPEvaluation {
switch (fOperator) { switch (fOperator) {
case op_arrayAccess: case op_arrayAccess:
case IASTBinaryExpression.op_assign: case op_assign:
case IASTBinaryExpression.op_binaryAndAssign: case op_binaryAndAssign:
case IASTBinaryExpression.op_binaryOrAssign: case op_binaryOrAssign:
case IASTBinaryExpression.op_binaryXorAssign: case op_binaryXorAssign:
case IASTBinaryExpression.op_divideAssign: case op_divideAssign:
case IASTBinaryExpression.op_minusAssign: case op_minusAssign:
case IASTBinaryExpression.op_moduloAssign: case op_moduloAssign:
case IASTBinaryExpression.op_multiplyAssign: case op_multiplyAssign:
case IASTBinaryExpression.op_plusAssign: case op_plusAssign:
case IASTBinaryExpression.op_shiftLeftAssign: case op_shiftLeftAssign:
case IASTBinaryExpression.op_shiftRightAssign: case op_shiftRightAssign:
return LVALUE; return LVALUE;
case IASTBinaryExpression.op_pmdot: case op_pmdot:
if (!(getTypeOrFunctionSet(point) instanceof ICPPFunctionType)) if (!(getTypeOrFunctionSet(point) instanceof ICPPFunctionType))
return fArg1.getValueCategory(point); return fArg1.getValueCategory(point);
break; break;
case IASTBinaryExpression.op_pmarrow: case op_pmarrow:
if (!(getTypeOrFunctionSet(point) instanceof ICPPFunctionType)) if (!(getTypeOrFunctionSet(point) instanceof ICPPFunctionType))
return LVALUE; return LVALUE;
break; break;
@ -246,17 +279,17 @@ public class EvalBinary extends CPPEvaluation {
} }
return ProblemType.UNKNOWN_FOR_EXPRESSION; return ProblemType.UNKNOWN_FOR_EXPRESSION;
case IASTBinaryExpression.op_lessEqual: case op_lessEqual:
case IASTBinaryExpression.op_lessThan: case op_lessThan:
case IASTBinaryExpression.op_greaterEqual: case op_greaterEqual:
case IASTBinaryExpression.op_greaterThan: case op_greaterThan:
case IASTBinaryExpression.op_logicalAnd: case op_logicalAnd:
case IASTBinaryExpression.op_logicalOr: case op_logicalOr:
case IASTBinaryExpression.op_equals: case op_equals:
case IASTBinaryExpression.op_notequals: case op_notequals:
return CPPBasicType.BOOLEAN; return CPPBasicType.BOOLEAN;
case IASTBinaryExpression.op_plus: case op_plus:
if (type1 instanceof IPointerType) { if (type1 instanceof IPointerType) {
return ExpressionTypes.restoreTypedefs(type1, originalType1); return ExpressionTypes.restoreTypedefs(type1, originalType1);
} }
@ -265,7 +298,7 @@ public class EvalBinary extends CPPEvaluation {
} }
break; break;
case IASTBinaryExpression.op_minus: case op_minus:
if (type1 instanceof IPointerType) { if (type1 instanceof IPointerType) {
if (type2 instanceof IPointerType) { if (type2 instanceof IPointerType) {
return CPPVisitor.getPointerDiffType(point); return CPPVisitor.getPointerDiffType(point);
@ -274,13 +307,13 @@ public class EvalBinary extends CPPEvaluation {
} }
break; break;
case ICPPASTBinaryExpression.op_pmarrow: case op_pmarrow:
case ICPPASTBinaryExpression.op_pmdot: case op_pmdot:
if (type2 instanceof ICPPPointerToMemberType) { if (type2 instanceof ICPPPointerToMemberType) {
IType t= ((ICPPPointerToMemberType) type2).getType(); IType t= ((ICPPPointerToMemberType) type2).getType();
if (t instanceof ICPPFunctionType) if (t instanceof ICPPFunctionType)
return t; return t;
if (fOperator == ICPPASTBinaryExpression.op_pmdot && fArg1.getValueCategory(point) == PRVALUE) { if (fOperator == op_pmdot && fArg1.getValueCategory(point) == PRVALUE) {
return prvalueType(t); return prvalueType(t);
} }
return glvalueType(t); return glvalueType(t);

View file

@ -14,8 +14,6 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
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.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
@ -26,6 +24,8 @@ 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.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; 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.ICPPTemplateDefinition;
@ -86,7 +86,6 @@ public class EvalBinding extends CPPEvaluation {
private boolean computeIsTypeDependent() { private boolean computeIsTypeDependent() {
IType t= null; IType t= null;
// mstodo: Please review this change.
if (fFixedType) { if (fFixedType) {
t = fType; t = fType;
} else if (fBinding instanceof IEnumerator) { } else if (fBinding instanceof IEnumerator) {
@ -230,11 +229,16 @@ public class EvalBinding extends CPPEvaluation {
} }
// TODO(sprigogin): Do we need something similar for pack expansion? // TODO(sprigogin): Do we need something similar for pack expansion?
} else if (fBinding instanceof ICPPUnknownBinding) { } else if (fBinding instanceof ICPPUnknownBinding) {
try { binding = resolveUnknown((ICPPUnknownBinding) fBinding, tpMap, packOffset, within, point);
binding = CPPTemplates.resolveUnknown((ICPPUnknownBinding) fBinding, tpMap, } else if (fBinding instanceof ICPPMethod) {
packOffset, within, point); IBinding owner = fBinding.getOwner();
} catch (DOMException e) { if (owner instanceof ICPPClassTemplate) {
CCorePlugin.log(e); owner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) owner),
tpMap, packOffset, within, point);
}
if (owner instanceof ICPPClassSpecialization) {
binding = CPPTemplates.createSpecialization((ICPPClassSpecialization) owner,
fBinding, point);
} }
} }
if (binding == fBinding) if (binding == fBinding)

View file

@ -18,8 +18,13 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import java.util.Arrays;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
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.IBinding;
import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
@ -48,6 +53,10 @@ public class EvalFunctionCall extends CPPEvaluation {
fArguments= args; fArguments= args;
} }
/**
* Returns arguments of the function call. The first argument is the function name, the rest
* are arguments passed to the function.
*/
public ICPPEvaluation[] getArguments() { public ICPPEvaluation[] getArguments() {
return fArguments; return fArguments;
} }
@ -135,10 +144,8 @@ public class EvalFunctionCall extends CPPEvaluation {
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue(IASTNode point) {
if (isValueDependent()) // TODO(sprigogin): Simulate execution of a function call if the value is not dependent.
return Value.create(this); return Value.create(this);
// TODO(sprigogin): Simulate execution of a function call.
return Value.UNKNOWN;
} }
@Override @Override
@ -188,6 +195,21 @@ public class EvalFunctionCall extends CPPEvaluation {
} }
if (!changed) if (!changed)
return this; return this;
if (args[0] instanceof EvalFunctionSet) {
CPPFunctionSet functionSet = ((EvalFunctionSet) args[0]).getFunctionSet();
ICPPFunction[] functions = functionSet.getBindings();
LookupData data = new LookupData(functions[0].getNameCharArray(),
functionSet.getTemplateArguments(), point);
data.setFunctionArguments(false, Arrays.copyOfRange(args, 1, args.length));
try {
IBinding binding = CPPSemantics.resolveFunction(data, functions, true);
if (binding instanceof ICPPFunction)
return new EvalBinding(binding, null);
} catch (DOMException e) {
CCorePlugin.log(e);
}
}
return new EvalFunctionCall(args); return new EvalFunctionCall(args);
} }

View file

@ -15,8 +15,6 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import java.util.Arrays; import java.util.Arrays;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
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.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
@ -115,7 +113,10 @@ public class EvalFunctionSet extends CPPEvaluation {
buffer.marshalBinding(binding); buffer.marshalBinding(binding);
} }
if (args != null) { if (args != null) {
// mstodo marshall arguments buffer.putShort((short) args.length);
for (ICPPTemplateArgument arg : args) {
buffer.marshalTemplateArgument(arg);
}
} }
} }
@ -128,7 +129,11 @@ public class EvalFunctionSet extends CPPEvaluation {
} }
ICPPTemplateArgument[] args= null; ICPPTemplateArgument[] args= null;
if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0) { if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0) {
// mstodo marshall arguments int len= buffer.getShort();
args = new ICPPTemplateArgument[len];
for (int i = 0; i < args.length; i++) {
args[i]= buffer.unmarshalTemplateArgument();
}
} }
return new EvalFunctionSet(new CPPFunctionSet(bindings, args, null), addressOf); return new EvalFunctionSet(new CPPFunctionSet(bindings, args, null), addressOf);
} }
@ -138,21 +143,12 @@ public class EvalFunctionSet extends CPPEvaluation {
ICPPClassSpecialization within, int maxdepth, IASTNode point) { ICPPClassSpecialization within, int maxdepth, IASTNode point) {
ICPPTemplateArgument[] originalArguments = fFunctionSet.getTemplateArguments(); ICPPTemplateArgument[] originalArguments = fFunctionSet.getTemplateArguments();
ICPPTemplateArgument[] arguments = originalArguments; ICPPTemplateArgument[] arguments = originalArguments;
try { arguments = instantiateArguments(originalArguments, tpMap, packOffset, within, point);
arguments = CPPTemplates.instantiateArguments(originalArguments, tpMap, packOffset, within, point);
} catch (DOMException e) {
CCorePlugin.log(e);
}
IBinding originalOwner = fFunctionSet.getOwner(); IBinding originalOwner = fFunctionSet.getOwner();
IBinding owner = originalOwner; IBinding owner = originalOwner;
if (originalOwner instanceof ICPPUnknownBinding) { if (originalOwner instanceof ICPPUnknownBinding) {
try { owner = resolveUnknown((ICPPUnknownBinding) owner, tpMap, packOffset, within, point);
owner = CPPTemplates.resolveUnknown((ICPPUnknownBinding) owner, tpMap,
packOffset, within, point);
} catch (DOMException e) {
CCorePlugin.log(e); // TODO(sprigogin): Is this exception safe to ignore?
}
} else if (owner instanceof IType) { } else if (owner instanceof IType) {
IType type = CPPTemplates.instantiateType((IType) owner, tpMap, packOffset, within, point); IType type = CPPTemplates.instantiateType((IType) owner, tpMap, packOffset, within, point);
if (type instanceof IBinding) if (type instanceof IBinding)

View file

@ -16,7 +16,6 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import java.util.Arrays; import java.util.Arrays;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
@ -40,6 +39,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
@ -132,6 +132,7 @@ public class EvalID extends CPPEvaluation {
if (nameOwner == null && fFieldOwner != null) if (nameOwner == null && fFieldOwner != null)
nameOwner = (IBinding) fFieldOwner.getTypeOrFunctionSet(point); nameOwner = (IBinding) fFieldOwner.getTypeOrFunctionSet(point);
// TODO(sprigogin): Verify that name resolution is required here.
if (nameOwner instanceof ICPPClassType) { if (nameOwner instanceof ICPPClassType) {
ICPPEvaluation eval = resolveName((ICPPClassType) nameOwner, fTemplateArgs, point); ICPPEvaluation eval = resolveName((ICPPClassType) nameOwner, fTemplateArgs, point);
if (eval != null) if (eval != null)
@ -281,11 +282,7 @@ public class EvalID extends CPPEvaluation {
ICPPClassSpecialization within, int maxdepth, IASTNode point) { ICPPClassSpecialization within, int maxdepth, IASTNode point) {
ICPPTemplateArgument[] templateArgs = fTemplateArgs; ICPPTemplateArgument[] templateArgs = fTemplateArgs;
if (templateArgs != null) { if (templateArgs != null) {
try { templateArgs = instantiateArguments(templateArgs, tpMap, packOffset, within, point);
templateArgs = CPPTemplates.instantiateArguments(templateArgs, tpMap, packOffset, within, point);
} catch (DOMException e) {
CCorePlugin.log(e);
}
} }
ICPPEvaluation fieldOwner = fFieldOwner; ICPPEvaluation fieldOwner = fFieldOwner;
@ -302,7 +299,7 @@ public class EvalID extends CPPEvaluation {
nameOwner = (IBinding) type; nameOwner = (IBinding) type;
} }
} else if (nameOwner instanceof ICPPUnknownBinding) { } else if (nameOwner instanceof ICPPUnknownBinding) {
nameOwner = resolveUnknown(nameOwner, tpMap, packOffset, within, point); nameOwner = resolveUnknown((ICPPUnknownBinding) nameOwner, tpMap, packOffset, within, point);
} else if (nameOwner instanceof ICPPClassTemplate) { } else if (nameOwner instanceof ICPPClassTemplate) {
nameOwner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) nameOwner), nameOwner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) nameOwner),
tpMap, packOffset, within, point); tpMap, packOffset, within, point);
@ -310,23 +307,13 @@ public class EvalID extends CPPEvaluation {
if (Arrays.equals(templateArgs, fTemplateArgs) && fieldOwner == fFieldOwner && nameOwner == fNameOwner) if (Arrays.equals(templateArgs, fTemplateArgs) && fieldOwner == fFieldOwner && nameOwner == fNameOwner)
return this; return this;
// We don't do name lookup here since it is going to happen anyway when the getValue method ICPPEvaluation eval = resolveName((ICPPClassType) nameOwner, fTemplateArgs, point);
// is called. if (eval != null)
return eval;
return new EvalID(fieldOwner, nameOwner, fName, fAddressOf, fQualified, templateArgs); return new EvalID(fieldOwner, nameOwner, fName, fAddressOf, fQualified, templateArgs);
} }
IBinding resolveUnknown(IBinding binding, ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, IASTNode point) {
try {
binding = CPPTemplates.resolveUnknown((ICPPUnknownBinding) binding, tpMap,
packOffset, within, point);
} catch (DOMException e) {
CCorePlugin.log(e);
}
return binding;
}
private ICPPEvaluation resolveName(ICPPClassType nameOwner, ICPPTemplateArgument[] templateArgs, private ICPPEvaluation resolveName(ICPPClassType nameOwner, ICPPTemplateArgument[] templateArgs,
IASTNode point) { IASTNode point) {
LookupData data = new LookupData(fName, templateArgs, point); LookupData data = new LookupData(fName, templateArgs, point);
@ -336,6 +323,11 @@ public class EvalID extends CPPEvaluation {
} catch (DOMException e) { } catch (DOMException e) {
} }
IBinding[] bindings = data.getFoundBindings(); IBinding[] bindings = data.getFoundBindings();
if (bindings.length > 1 && bindings[0] instanceof ICPPFunction) {
ICPPFunction[] functions = new ICPPFunction[bindings.length];
System.arraycopy(bindings, 0, functions, 0, bindings.length);
return new EvalFunctionSet(new CPPFunctionSet(functions, fTemplateArgs, null), fAddressOf);
}
IBinding binding = bindings.length == 1 ? bindings[0] : null; IBinding binding = bindings.length == 1 ? bindings[0] : null;
if (binding instanceof IEnumerator) { if (binding instanceof IEnumerator) {
return new EvalBinding(binding, null); return new EvalBinding(binding, null);

View file

@ -38,7 +38,6 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti
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.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
@ -49,6 +48,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.CPPArithmeticConversion; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArithmeticConversion;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
@ -144,7 +145,7 @@ public class EvalUnary extends CPPEvaluation {
return null; return null;
ICPPEvaluation[] args; ICPPEvaluation[] args;
if (fOperator == IASTUnaryExpression.op_postFixDecr || fOperator == IASTUnaryExpression.op_postFixIncr) { if (fOperator == op_postFixDecr || fOperator == op_postFixIncr) {
args = new ICPPEvaluation[] { fArgument, ZERO_EVAL }; args = new ICPPEvaluation[] { fArgument, ZERO_EVAL };
} else { } else {
args = new ICPPEvaluation[] { fArgument }; args = new ICPPEvaluation[] { fArgument };
@ -205,11 +206,31 @@ public class EvalUnary extends CPPEvaluation {
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue(IASTNode point) {
if (isValueDependent())
return Value.create(this);
if (getOverload(point) != null) { if (getOverload(point) != null) {
// TODO(sprigogin): Simulate execution of a function call. // TODO(sprigogin): Simulate execution of a function call.
return Value.create(this); return Value.create(this);
} }
switch (fOperator) {
case op_sizeof: {
SizeAndAlignment info = getSizeAndAlignment(point);
return info == null ? Value.UNKNOWN : Value.create(info.size);
}
case op_alignOf: {
SizeAndAlignment info = getSizeAndAlignment(point);
return info == null ? Value.UNKNOWN : Value.create(info.alignment);
}
case op_sizeofParameterPack:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_typeid:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_throw:
return Value.UNKNOWN; // TODO(sprigogin): Implement
}
IValue val = fArgument.getValue(point); IValue val = fArgument.getValue(point);
Long num = val.numericalValue(); Long num = val.numericalValue();
if (num != null) { if (num != null) {
@ -218,6 +239,14 @@ public class EvalUnary extends CPPEvaluation {
return Value.create(this); return Value.create(this);
} }
private SizeAndAlignment getSizeAndAlignment(IASTNode point) {
if (point == null)
return null;
IType type = fArgument.getTypeOrFunctionSet(point);
return new SizeofCalculator(point.getTranslationUnit()).sizeAndAlignment(type);
}
@Override @Override
public ValueCategory getValueCategory(IASTNode point) { public ValueCategory getValueCategory(IASTNode point) {
ICPPFunction overload = getOverload(point); ICPPFunction overload = getOverload(point);

View file

@ -157,15 +157,11 @@ public class EvalUnaryTypeID extends CPPEvaluation {
switch (fOperator) { switch (fOperator) {
case op_sizeof: { case op_sizeof: {
if (point == null) SizeAndAlignment info = getSizeAndAlignment(point);
return Value.UNKNOWN;
SizeAndAlignment info = new SizeofCalculator(point.getTranslationUnit()).sizeAndAlignment(fOrigType);
return info == null ? Value.UNKNOWN : Value.create(info.size); return info == null ? Value.UNKNOWN : Value.create(info.size);
} }
case op_alignof: { case op_alignof: {
if (point == null) SizeAndAlignment info = getSizeAndAlignment(point);
return Value.UNKNOWN;
SizeAndAlignment info = new SizeofCalculator(point.getTranslationUnit()).sizeAndAlignment(fOrigType);
return info == null ? Value.UNKNOWN : Value.create(info.alignment); return info == null ? Value.UNKNOWN : Value.create(info.alignment);
} }
case op_typeid: case op_typeid:
@ -204,6 +200,12 @@ public class EvalUnaryTypeID extends CPPEvaluation {
return Value.create(this); return Value.create(this);
} }
private SizeAndAlignment getSizeAndAlignment(IASTNode point) {
if (point == null)
return null;
return new SizeofCalculator(point.getTranslationUnit()).sizeAndAlignment(fOrigType);
}
@Override @Override
public ValueCategory getValueCategory(IASTNode point) { public ValueCategory getValueCategory(IASTNode point) {
return fOperator == op_typeid ? LVALUE : PRVALUE; return fOperator == op_typeid ? LVALUE : PRVALUE;