mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 22:52:11 +02:00
Bug 497875 - Avoid evaluating isConstantExpression multiple times
Change-Id: I54d6b533f5b21294a92319ea1d45d4f18962a460
This commit is contained in:
parent
f2af760266
commit
b7ecc46eca
9 changed files with 108 additions and 18 deletions
|
@ -81,6 +81,8 @@ public class EvalBinary extends CPPDependentEvaluation {
|
|||
|
||||
private ICPPFunction fOverload= CPPFunction.UNINITIALIZED_FUNCTION;
|
||||
private IType fType;
|
||||
private boolean fCheckedIsConstantExpression;
|
||||
private boolean fIsConstantExpression;
|
||||
|
||||
public EvalBinary(int operator, ICPPEvaluation arg1, ICPPEvaluation arg2, IASTNode pointOfDefinition) {
|
||||
this(operator, arg1, arg2, findEnclosingTemplate(pointOfDefinition));
|
||||
|
@ -201,9 +203,17 @@ public class EvalBinary extends CPPDependentEvaluation {
|
|||
public boolean isValueDependent() {
|
||||
return fArg1.isValueDependent() || fArg2.isValueDependent();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isConstantExpression(IASTNode point) {
|
||||
if (!fCheckedIsConstantExpression) {
|
||||
fCheckedIsConstantExpression = true;
|
||||
fIsConstantExpression = computeIsConstantExpression(point);
|
||||
}
|
||||
return fIsConstantExpression;
|
||||
}
|
||||
|
||||
private boolean computeIsConstantExpression(IASTNode point) {
|
||||
return fArg1.isConstantExpression(point)
|
||||
&& fArg2.isConstantExpression(point)
|
||||
&& isNullOrConstexprFunc(getOverload(point));
|
||||
|
@ -262,7 +272,7 @@ public class EvalBinary extends CPPDependentEvaluation {
|
|||
IType type = fArg1.getType(point);
|
||||
type= SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE);
|
||||
if (type instanceof ICPPClassType) {
|
||||
return CPPSemantics.findOverloadedBinaryOperator(point, getTemplateDefinitionScope(),
|
||||
return CPPSemantics.findOverloadedBinaryOperator(point, getTemplateDefinitionScope(),
|
||||
OverloadableOperator.BRACKET, fArg1, fArg2);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -36,9 +36,11 @@ public class EvalComma extends CPPDependentEvaluation {
|
|||
private ICPPFunction[] fOverloads;
|
||||
|
||||
private IType fType;
|
||||
private boolean fCheckedIsConstantExpression;
|
||||
private boolean fIsConstantExpression;
|
||||
|
||||
public EvalComma(ICPPEvaluation[] evals, IASTNode pointOfDefinition) {
|
||||
this(evals, findEnclosingTemplate(pointOfDefinition));
|
||||
this(evals, findEnclosingTemplate(pointOfDefinition));
|
||||
}
|
||||
|
||||
public EvalComma(ICPPEvaluation[] evals, IBinding templateDefinition) {
|
||||
|
@ -72,9 +74,17 @@ public class EvalComma extends CPPDependentEvaluation {
|
|||
public boolean isValueDependent() {
|
||||
return containsDependentValue(fArguments);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isConstantExpression(IASTNode point) {
|
||||
if (!fCheckedIsConstantExpression) {
|
||||
fCheckedIsConstantExpression = true;
|
||||
fIsConstantExpression = computeIsConstantExpression(point);
|
||||
}
|
||||
return fIsConstantExpression;
|
||||
}
|
||||
|
||||
private boolean computeIsConstantExpression(IASTNode point) {
|
||||
if (!areAllConstantExpressions(fArguments, point)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -55,6 +55,8 @@ public class EvalConditional extends CPPDependentEvaluation {
|
|||
private ValueCategory fValueCategory;
|
||||
private IType fType;
|
||||
private ICPPFunction fOverload;
|
||||
private boolean fCheckedIsConstantExpression;
|
||||
private boolean fIsConstantExpression;
|
||||
|
||||
public EvalConditional(ICPPEvaluation condition, ICPPEvaluation positive, ICPPEvaluation negative,
|
||||
boolean positiveThrows, boolean negativeThrows, IASTNode pointOfDefinition) {
|
||||
|
@ -149,6 +151,14 @@ public class EvalConditional extends CPPDependentEvaluation {
|
|||
|
||||
@Override
|
||||
public boolean isConstantExpression(IASTNode point) {
|
||||
if (!fCheckedIsConstantExpression) {
|
||||
fCheckedIsConstantExpression = true;
|
||||
fIsConstantExpression = computeIsConstantExpression(point);
|
||||
}
|
||||
return fIsConstantExpression;
|
||||
}
|
||||
|
||||
private boolean computeIsConstantExpression(IASTNode point) {
|
||||
return fCondition.isConstantExpression(point)
|
||||
&& (fPositive == null || fPositive.isConstantExpression(point))
|
||||
&& fNegative.isConstantExpression(point);
|
||||
|
@ -243,7 +253,7 @@ public class EvalConditional extends CPPDependentEvaluation {
|
|||
|
||||
// 5.16-5: At least one class type but no conversion
|
||||
if (isClassType2 || isClassType3) {
|
||||
fOverload = CPPSemantics.findOverloadedConditionalOperator(point, getTemplateDefinitionScope(), positive, fNegative);
|
||||
fOverload = CPPSemantics.findOverloadedConditionalOperator(point, getTemplateDefinitionScope(), positive, fNegative);
|
||||
if (fOverload != null) {
|
||||
fType= ExpressionTypes.typeFromFunctionCall(fOverload);
|
||||
} else {
|
||||
|
|
|
@ -45,6 +45,8 @@ public class EvalFixed extends CPPEvaluation {
|
|||
private boolean fCheckedIsTypeDependent;
|
||||
private boolean fIsValueDependent;
|
||||
private boolean fCheckedIsValueDependent;
|
||||
private boolean fCheckedIsConstantExpression;
|
||||
private boolean fIsConstantExpression;
|
||||
|
||||
public EvalFixed(IType type, ValueCategory cat, IValue value) {
|
||||
// Avoid nesting EvalFixed's as nesting causes the signature to be different.
|
||||
|
@ -54,7 +56,7 @@ public class EvalFixed extends CPPEvaluation {
|
|||
cat = inner.fValueCategory;
|
||||
value = inner.fValue;
|
||||
}
|
||||
|
||||
|
||||
if (type instanceof CPPBasicType) {
|
||||
Long num = value.numericalValue();
|
||||
if (num != null) {
|
||||
|
@ -67,7 +69,7 @@ public class EvalFixed extends CPPEvaluation {
|
|||
fValueCategory= cat;
|
||||
fValue= value;
|
||||
}
|
||||
|
||||
|
||||
public IType getType() {
|
||||
return fType;
|
||||
}
|
||||
|
@ -107,9 +109,17 @@ public class EvalFixed extends CPPEvaluation {
|
|||
}
|
||||
return fIsValueDependent;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isConstantExpression(IASTNode point) {
|
||||
if (!fCheckedIsConstantExpression) {
|
||||
fCheckedIsConstantExpression = true;
|
||||
fIsConstantExpression = computeIsConstantExpression(point);
|
||||
}
|
||||
return fIsConstantExpression;
|
||||
}
|
||||
|
||||
private boolean computeIsConstantExpression(IASTNode point) {
|
||||
return (fType instanceof ICPPClassType && TypeTraits.isEmpty(fType, point))
|
||||
|| isConstexprValue(fValue, point);
|
||||
}
|
||||
|
@ -180,11 +190,11 @@ public class EvalFixed extends CPPEvaluation {
|
|||
IValue value = CPPTemplates.instantiateValue(fValue, context, maxDepth);
|
||||
if (type == fType && value == fValue)
|
||||
return this;
|
||||
// If an error occurred while instantiating the value (such as a substitution failure),
|
||||
// If an error occurred while instantiating the value (such as a substitution failure),
|
||||
// propagate that error.
|
||||
if (value == Value.ERROR)
|
||||
return EvalFixed.INCOMPLETE;
|
||||
// Resolve the parameter pack type to the underlying type if the instantiated value is not dependent.
|
||||
// Resolve the parameter pack type to the underlying type if the instantiated value is not dependent.
|
||||
if (type instanceof ICPPParameterPackType && value.numericalValue() != null)
|
||||
type = ((ICPPParameterPackType) type).getType();
|
||||
return new EvalFixed(type, fValueCategory, value);
|
||||
|
|
|
@ -45,6 +45,8 @@ public class EvalFunctionCall extends CPPDependentEvaluation {
|
|||
private final ICPPEvaluation[] fArguments;
|
||||
private ICPPFunction fOverload= CPPFunction.UNINITIALIZED_FUNCTION;
|
||||
private IType fType;
|
||||
private boolean fCheckedIsConstantExpression;
|
||||
private boolean fIsConstantExpression;
|
||||
|
||||
public EvalFunctionCall(ICPPEvaluation[] args, IASTNode pointOfDefinition) {
|
||||
this(args, findEnclosingTemplate(pointOfDefinition));
|
||||
|
@ -85,6 +87,14 @@ public class EvalFunctionCall extends CPPDependentEvaluation {
|
|||
|
||||
@Override
|
||||
public boolean isConstantExpression(IASTNode point) {
|
||||
if (!fCheckedIsConstantExpression) {
|
||||
fCheckedIsConstantExpression = true;
|
||||
fIsConstantExpression = computeIsConstantExpression(point);
|
||||
}
|
||||
return fIsConstantExpression;
|
||||
}
|
||||
|
||||
private boolean computeIsConstantExpression(IASTNode point) {
|
||||
return areAllConstantExpressions(fArguments, point) && isNullOrConstexprFunc(getOverload(point));
|
||||
}
|
||||
|
||||
|
@ -101,7 +111,7 @@ public class EvalFunctionCall extends CPPDependentEvaluation {
|
|||
|
||||
IType t= SemanticUtil.getNestedType(fArguments[0].getType(point), TDEF | REF | CVTYPE);
|
||||
if (t instanceof ICPPClassType) {
|
||||
return CPPSemantics.findOverloadedOperator(point, getTemplateDefinitionScope(), fArguments, t,
|
||||
return CPPSemantics.findOverloadedOperator(point, getTemplateDefinitionScope(), fArguments, t,
|
||||
OverloadableOperator.PAREN, LookupMode.NO_GLOBALS);
|
||||
}
|
||||
return null;
|
||||
|
@ -121,7 +131,7 @@ public class EvalFunctionCall extends CPPDependentEvaluation {
|
|||
ICPPFunction overload = getOverload(point);
|
||||
if (overload != null)
|
||||
return ExpressionTypes.typeFromFunctionCall(overload);
|
||||
|
||||
|
||||
ICPPEvaluation function = fArguments[0];
|
||||
IType result = ExpressionTypes.typeFromFunctionCall(function.getType(point));
|
||||
if (function instanceof EvalMemberAccess) {
|
||||
|
@ -135,7 +145,7 @@ public class EvalFunctionCall extends CPPDependentEvaluation {
|
|||
ICPPEvaluation eval = computeForFunctionCall(new ConstexprEvaluationContext(point));
|
||||
if (eval == this) {
|
||||
return Value.create(eval);
|
||||
}
|
||||
}
|
||||
return eval.getValue(point);
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,8 @@ public class EvalFunctionSet extends CPPDependentEvaluation {
|
|||
// by asking the first function in the set for its name.)
|
||||
// Exactly one of fFunctionSet and fName should be non-null.
|
||||
private final char[] fName;
|
||||
private boolean fCheckedIsConstantExpression;
|
||||
private boolean fIsConstantExpression;
|
||||
|
||||
public EvalFunctionSet(CPPFunctionSet set, boolean qualified, boolean addressOf, IType impliedObjectType,
|
||||
IASTNode pointOfDefinition) {
|
||||
|
@ -140,6 +142,14 @@ public class EvalFunctionSet extends CPPDependentEvaluation {
|
|||
|
||||
@Override
|
||||
public boolean isConstantExpression(IASTNode point) {
|
||||
if (!fCheckedIsConstantExpression) {
|
||||
fCheckedIsConstantExpression = true;
|
||||
fIsConstantExpression = computeIsConstantExpression(point);
|
||||
}
|
||||
return fIsConstantExpression;
|
||||
}
|
||||
|
||||
private boolean computeIsConstantExpression(IASTNode point) {
|
||||
if (fFunctionSet == null)
|
||||
return false;
|
||||
for (ICPPFunction f : fFunctionSet.getBindings()) {
|
||||
|
|
|
@ -31,6 +31,8 @@ import org.eclipse.core.runtime.CoreException;
|
|||
*/
|
||||
public class EvalInitList extends CPPDependentEvaluation {
|
||||
private final ICPPEvaluation[] fClauses;
|
||||
private boolean fCheckedIsConstantExpression;
|
||||
private boolean fIsConstantExpression;
|
||||
|
||||
public EvalInitList(ICPPEvaluation[] clauses, IASTNode pointOfDefinition) {
|
||||
this(clauses, findEnclosingTemplate(pointOfDefinition));
|
||||
|
@ -64,9 +66,17 @@ public class EvalInitList extends CPPDependentEvaluation {
|
|||
public boolean isValueDependent() {
|
||||
return containsDependentValue(fClauses);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isConstantExpression(IASTNode point) {
|
||||
if (!fCheckedIsConstantExpression) {
|
||||
fCheckedIsConstantExpression = true;
|
||||
fIsConstantExpression = computeIsConstantExpression(point);
|
||||
}
|
||||
return fIsConstantExpression;
|
||||
}
|
||||
|
||||
private boolean computeIsConstantExpression(IASTNode point) {
|
||||
return areAllConstantExpressions(fClauses, point);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,8 @@ public class EvalTypeId extends CPPDependentEvaluation {
|
|||
private ICPPFunction fConstructor = CPPFunction.UNINITIALIZED_FUNCTION;
|
||||
private boolean fCheckedIsTypeDependent;
|
||||
private boolean fIsTypeDependent;
|
||||
private boolean fCheckedIsConstantExpression;
|
||||
private boolean fIsConstantExpression;
|
||||
|
||||
public EvalTypeId(IType type, IASTNode pointOfDefinition, ICPPEvaluation... arguments) {
|
||||
this(type, findEnclosingTemplate(pointOfDefinition), false, arguments);
|
||||
|
@ -151,6 +153,14 @@ public class EvalTypeId extends CPPDependentEvaluation {
|
|||
|
||||
@Override
|
||||
public boolean isConstantExpression(IASTNode point) {
|
||||
if (!fCheckedIsConstantExpression) {
|
||||
fCheckedIsConstantExpression = true;
|
||||
fIsConstantExpression = computeIsConstantExpression(point);
|
||||
}
|
||||
return fIsConstantExpression;
|
||||
}
|
||||
|
||||
private boolean computeIsConstantExpression(IASTNode point) {
|
||||
return !fRepresentsNewExpression
|
||||
&& areAllConstantExpressions(fArguments, point)
|
||||
&& isNullOrConstexprFunc(getConstructor(point));
|
||||
|
@ -298,7 +308,7 @@ public class EvalTypeId extends CPPDependentEvaluation {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
||||
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
||||
ConstexprEvaluationContext context) {
|
||||
ICPPEvaluation[] args = fArguments;
|
||||
for (int i = 0; i < fArguments.length; i++) {
|
||||
|
|
|
@ -79,6 +79,8 @@ public class EvalUnary extends CPPDependentEvaluation {
|
|||
private final IBinding fAddressOfQualifiedNameBinding;
|
||||
private ICPPFunction fOverload= CPPFunction.UNINITIALIZED_FUNCTION;
|
||||
private IType fType;
|
||||
private boolean fCheckedIsConstantExpression;
|
||||
private boolean fIsConstantExpression;
|
||||
|
||||
public EvalUnary(int operator, ICPPEvaluation operand, IBinding addressOfQualifiedNameBinding,
|
||||
IASTNode pointOfDefinition) {
|
||||
|
@ -149,9 +151,17 @@ public class EvalUnary extends CPPDependentEvaluation {
|
|||
return fArgument.isValueDependent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isConstantExpression(IASTNode point) {
|
||||
if (!fCheckedIsConstantExpression) {
|
||||
fCheckedIsConstantExpression = true;
|
||||
fIsConstantExpression = computeIsConstantExpression(point);
|
||||
}
|
||||
return fIsConstantExpression;
|
||||
}
|
||||
|
||||
private boolean computeIsConstantExpression(IASTNode point) {
|
||||
return fArgument.isConstantExpression(point)
|
||||
&& isNullOrConstexprFunc(getOverload(point));
|
||||
}
|
||||
|
@ -287,7 +297,7 @@ public class EvalUnary extends CPPDependentEvaluation {
|
|||
return Value.ERROR;
|
||||
IType targetType = parameterTypes[0];
|
||||
arg = maybeApplyConversion(arg, targetType, point);
|
||||
|
||||
|
||||
if (!(overload instanceof CPPImplicitFunction)) {
|
||||
if (!overload.isConstexpr())
|
||||
return Value.ERROR;
|
||||
|
@ -381,7 +391,7 @@ public class EvalUnary extends CPPDependentEvaluation {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
||||
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
||||
ConstexprEvaluationContext context) {
|
||||
ICPPEvaluation argument = fArgument.computeForFunctionCall(parameterMap, context.recordStep());
|
||||
if (argument == fArgument)
|
||||
|
|
Loading…
Add table
Reference in a new issue