diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index c7e8539f991..10d8d03ec8d 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -5631,7 +5631,7 @@ public class AST2TemplateTests extends AST2BaseTest { // ns::C::value> a; // f(a); // }; - public void _testDependentExpressions() throws Exception { + public void testDependentExpressions() throws Exception { parseAndCheckBindings(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/SizeofCalculator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/SizeofCalculator.java index 52863030731..aa3ed3d9321 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/SizeofCalculator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/SizeofCalculator.java @@ -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.IEnumeration; 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.IType; import org.eclipse.cdt.core.dom.ast.IValue; @@ -109,7 +110,9 @@ public class SizeofCalculator { */ public SizeAndAlignment sizeAndAlignment(IType type) { type = SemanticUtil.getNestedType(type, SemanticUtil.CVTYPE | SemanticUtil.TDEF); - + if (type instanceof IFunctionType) { + return sizeAndAlignment(((IFunctionType) type).getReturnType()); + } if (type instanceof IBasicType) { return sizeAndAlignment((IBasicType) type); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java index 57623407455..3faa3341be6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java @@ -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.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.IType; 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.ICPPClassSpecialization; 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.ICPPTemplateParameterMap; 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; @@ -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.cpp.CPPTemplateNonTypeArgument; 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; public abstract class CPPEvaluation implements ICPPEvaluation { @@ -219,4 +224,24 @@ public abstract class CPPEvaluation implements ICPPEvaluation { } 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; + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java index 911c8cc1062..625fe770542 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java @@ -11,6 +11,30 @@ *******************************************************************************/ 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.PRVALUE; 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.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.IASTNode; import org.eclipse.cdt.core.dom.ast.IPointerType; 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.ICPPASTBinaryExpression; 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.ICPPFunction; @@ -114,13 +136,18 @@ public class EvalBinary extends CPPEvaluation { } IValue v1 = fArg1.getValue(point); + if (v1 == Value.UNKNOWN) + return Value.UNKNOWN; IValue v2 = fArg2.getValue(point); + if (v2 == Value.UNKNOWN) + return Value.UNKNOWN; + switch (fOperator) { - case IASTBinaryExpression.op_equals: + case op_equals: if (v1.equals(v2)) return Value.create(1); break; - case IASTBinaryExpression.op_notequals: + case op_notequals: if (v1.equals(v2)) return Value.create(0); break; @@ -128,6 +155,12 @@ public class EvalBinary extends CPPEvaluation { Long num1 = v1.numericalValue(); 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(); if (num2 != null) { return Value.evaluateBinaryExpression(fOperator, num1, num2); @@ -160,25 +193,25 @@ public class EvalBinary extends CPPEvaluation { switch (fOperator) { case op_arrayAccess: - case IASTBinaryExpression.op_assign: - case IASTBinaryExpression.op_binaryAndAssign: - case IASTBinaryExpression.op_binaryOrAssign: - case IASTBinaryExpression.op_binaryXorAssign: - case IASTBinaryExpression.op_divideAssign: - case IASTBinaryExpression.op_minusAssign: - case IASTBinaryExpression.op_moduloAssign: - case IASTBinaryExpression.op_multiplyAssign: - case IASTBinaryExpression.op_plusAssign: - case IASTBinaryExpression.op_shiftLeftAssign: - case IASTBinaryExpression.op_shiftRightAssign: + case op_assign: + case op_binaryAndAssign: + case op_binaryOrAssign: + case op_binaryXorAssign: + case op_divideAssign: + case op_minusAssign: + case op_moduloAssign: + case op_multiplyAssign: + case op_plusAssign: + case op_shiftLeftAssign: + case op_shiftRightAssign: return LVALUE; - case IASTBinaryExpression.op_pmdot: + case op_pmdot: if (!(getTypeOrFunctionSet(point) instanceof ICPPFunctionType)) return fArg1.getValueCategory(point); break; - case IASTBinaryExpression.op_pmarrow: + case op_pmarrow: if (!(getTypeOrFunctionSet(point) instanceof ICPPFunctionType)) return LVALUE; break; @@ -246,17 +279,17 @@ public class EvalBinary extends CPPEvaluation { } return ProblemType.UNKNOWN_FOR_EXPRESSION; - case IASTBinaryExpression.op_lessEqual: - case IASTBinaryExpression.op_lessThan: - case IASTBinaryExpression.op_greaterEqual: - case IASTBinaryExpression.op_greaterThan: - case IASTBinaryExpression.op_logicalAnd: - case IASTBinaryExpression.op_logicalOr: - case IASTBinaryExpression.op_equals: - case IASTBinaryExpression.op_notequals: + case op_lessEqual: + case op_lessThan: + case op_greaterEqual: + case op_greaterThan: + case op_logicalAnd: + case op_logicalOr: + case op_equals: + case op_notequals: return CPPBasicType.BOOLEAN; - case IASTBinaryExpression.op_plus: + case op_plus: if (type1 instanceof IPointerType) { return ExpressionTypes.restoreTypedefs(type1, originalType1); } @@ -265,7 +298,7 @@ public class EvalBinary extends CPPEvaluation { } break; - case IASTBinaryExpression.op_minus: + case op_minus: if (type1 instanceof IPointerType) { if (type2 instanceof IPointerType) { return CPPVisitor.getPointerDiffType(point); @@ -274,13 +307,13 @@ public class EvalBinary extends CPPEvaluation { } break; - case ICPPASTBinaryExpression.op_pmarrow: - case ICPPASTBinaryExpression.op_pmdot: + case op_pmarrow: + case op_pmdot: if (type2 instanceof ICPPPointerToMemberType) { IType t= ((ICPPPointerToMemberType) type2).getType(); if (t instanceof ICPPFunctionType) return t; - if (fOperator == ICPPASTBinaryExpression.op_pmdot && fArg1.getValueCategory(point) == PRVALUE) { + if (fOperator == op_pmdot && fArg1.getValueCategory(point) == PRVALUE) { return prvalueType(t); } return glvalueType(t); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java index ee5b09c13c0..74788246143 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java @@ -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.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.IASTNode; 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.IVariable; 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.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; @@ -86,7 +86,6 @@ public class EvalBinding extends CPPEvaluation { private boolean computeIsTypeDependent() { IType t= null; - // mstodo: Please review this change. if (fFixedType) { t = fType; } else if (fBinding instanceof IEnumerator) { @@ -230,11 +229,16 @@ public class EvalBinding extends CPPEvaluation { } // TODO(sprigogin): Do we need something similar for pack expansion? } else if (fBinding instanceof ICPPUnknownBinding) { - try { - binding = CPPTemplates.resolveUnknown((ICPPUnknownBinding) fBinding, tpMap, - packOffset, within, point); - } catch (DOMException e) { - CCorePlugin.log(e); + binding = resolveUnknown((ICPPUnknownBinding) fBinding, tpMap, packOffset, within, point); + } else if (fBinding instanceof ICPPMethod) { + IBinding owner = fBinding.getOwner(); + if (owner instanceof ICPPClassTemplate) { + owner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) owner), + tpMap, packOffset, within, point); + } + if (owner instanceof ICPPClassSpecialization) { + binding = CPPTemplates.createSpecialization((ICPPClassSpecialization) owner, + fBinding, point); } } if (binding == fBinding) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java index f574db24ece..d7737ffc9e4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java @@ -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.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.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.ISemanticProblem; @@ -48,6 +53,10 @@ public class EvalFunctionCall extends CPPEvaluation { 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() { return fArguments; } @@ -135,10 +144,8 @@ public class EvalFunctionCall extends CPPEvaluation { @Override public IValue getValue(IASTNode point) { - if (isValueDependent()) - return Value.create(this); - // TODO(sprigogin): Simulate execution of a function call. - return Value.UNKNOWN; + // TODO(sprigogin): Simulate execution of a function call if the value is not dependent. + return Value.create(this); } @Override @@ -188,6 +195,21 @@ public class EvalFunctionCall extends CPPEvaluation { } if (!changed) 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); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java index d645aa6032b..47fc4b8a99e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java @@ -15,8 +15,6 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; 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.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; @@ -115,7 +113,10 @@ public class EvalFunctionSet extends CPPEvaluation { buffer.marshalBinding(binding); } 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; 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); } @@ -138,21 +143,12 @@ public class EvalFunctionSet extends CPPEvaluation { ICPPClassSpecialization within, int maxdepth, IASTNode point) { ICPPTemplateArgument[] originalArguments = fFunctionSet.getTemplateArguments(); ICPPTemplateArgument[] arguments = originalArguments; - try { - arguments = CPPTemplates.instantiateArguments(originalArguments, tpMap, packOffset, within, point); - } catch (DOMException e) { - CCorePlugin.log(e); - } + arguments = instantiateArguments(originalArguments, tpMap, packOffset, within, point); IBinding originalOwner = fFunctionSet.getOwner(); IBinding owner = originalOwner; if (originalOwner instanceof ICPPUnknownBinding) { - try { - owner = CPPTemplates.resolveUnknown((ICPPUnknownBinding) owner, tpMap, - packOffset, within, point); - } catch (DOMException e) { - CCorePlugin.log(e); // TODO(sprigogin): Is this exception safe to ignore? - } + owner = resolveUnknown((ICPPUnknownBinding) owner, tpMap, packOffset, within, point); } else if (owner instanceof IType) { IType type = CPPTemplates.instantiateType((IType) owner, tpMap, packOffset, within, point); if (type instanceof IBinding) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java index 3e5971d1a9c..206047da2f3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java @@ -16,7 +16,6 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; 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; 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.ICPPConstructor; 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.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; @@ -132,6 +132,7 @@ public class EvalID extends CPPEvaluation { if (nameOwner == null && fFieldOwner != null) nameOwner = (IBinding) fFieldOwner.getTypeOrFunctionSet(point); + // TODO(sprigogin): Verify that name resolution is required here. if (nameOwner instanceof ICPPClassType) { ICPPEvaluation eval = resolveName((ICPPClassType) nameOwner, fTemplateArgs, point); if (eval != null) @@ -281,11 +282,7 @@ public class EvalID extends CPPEvaluation { ICPPClassSpecialization within, int maxdepth, IASTNode point) { ICPPTemplateArgument[] templateArgs = fTemplateArgs; if (templateArgs != null) { - try { - templateArgs = CPPTemplates.instantiateArguments(templateArgs, tpMap, packOffset, within, point); - } catch (DOMException e) { - CCorePlugin.log(e); - } + templateArgs = instantiateArguments(templateArgs, tpMap, packOffset, within, point); } ICPPEvaluation fieldOwner = fFieldOwner; @@ -302,7 +299,7 @@ public class EvalID extends CPPEvaluation { nameOwner = (IBinding) type; } } 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) { nameOwner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) nameOwner), tpMap, packOffset, within, point); @@ -310,23 +307,13 @@ public class EvalID extends CPPEvaluation { if (Arrays.equals(templateArgs, fTemplateArgs) && fieldOwner == fFieldOwner && nameOwner == fNameOwner) return this; - // We don't do name lookup here since it is going to happen anyway when the getValue method - // is called. + ICPPEvaluation eval = resolveName((ICPPClassType) nameOwner, fTemplateArgs, point); + if (eval != null) + return eval; 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, IASTNode point) { LookupData data = new LookupData(fName, templateArgs, point); @@ -336,6 +323,11 @@ public class EvalID extends CPPEvaluation { } catch (DOMException e) { } 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; if (binding instanceof IEnumerator) { return new EvalBinding(binding, null); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java index ab728bf6462..17017f2770a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java @@ -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.IASTNode; -import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.ISemanticProblem; 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.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.CPPArithmeticConversion; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; @@ -144,7 +145,7 @@ public class EvalUnary extends CPPEvaluation { return null; ICPPEvaluation[] args; - if (fOperator == IASTUnaryExpression.op_postFixDecr || fOperator == IASTUnaryExpression.op_postFixIncr) { + if (fOperator == op_postFixDecr || fOperator == op_postFixIncr) { args = new ICPPEvaluation[] { fArgument, ZERO_EVAL }; } else { args = new ICPPEvaluation[] { fArgument }; @@ -205,11 +206,31 @@ public class EvalUnary extends CPPEvaluation { @Override public IValue getValue(IASTNode point) { + if (isValueDependent()) + return Value.create(this); + if (getOverload(point) != null) { // TODO(sprigogin): Simulate execution of a function call. 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); Long num = val.numericalValue(); if (num != null) { @@ -218,6 +239,14 @@ public class EvalUnary extends CPPEvaluation { 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 public ValueCategory getValueCategory(IASTNode point) { ICPPFunction overload = getOverload(point); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java index 993b032ded9..e7e97cc5c12 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java @@ -157,15 +157,11 @@ public class EvalUnaryTypeID extends CPPEvaluation { switch (fOperator) { case op_sizeof: { - if (point == null) - return Value.UNKNOWN; - SizeAndAlignment info = new SizeofCalculator(point.getTranslationUnit()).sizeAndAlignment(fOrigType); + SizeAndAlignment info = getSizeAndAlignment(point); 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); + SizeAndAlignment info = getSizeAndAlignment(point); return info == null ? Value.UNKNOWN : Value.create(info.alignment); } case op_typeid: @@ -204,6 +200,12 @@ public class EvalUnaryTypeID extends CPPEvaluation { return Value.create(this); } + private SizeAndAlignment getSizeAndAlignment(IASTNode point) { + if (point == null) + return null; + return new SizeofCalculator(point.getTranslationUnit()).sizeAndAlignment(fOrigType); + } + @Override public ValueCategory getValueCategory(IASTNode point) { return fOperator == op_typeid ? LVALUE : PRVALUE;