/*******************************************************************************
* Copyright (c) 2012, 2014 Google, Inc and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sergey Prigogin (Google) - initial API and implementation
* Nathan Ridge
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
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.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
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.ICPPTemplateArgument;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext;
import org.eclipse.core.runtime.CoreException;
public abstract class CPPEvaluation implements ICPPEvaluation {
CPPEvaluation() {
}
@Override
public IBinding getTemplateDefinition() {
return null;
}
@Override
public char[] getSignature() {
SignatureBuilder buf = new SignatureBuilder();
try {
marshal(buf, true);
} catch (CoreException e) {
CCorePlugin.log(e);
return new char[] { '?' };
}
return buf.getSignature();
}
protected static IBinding resolveUnknown(ICPPUnknownBinding unknown, InstantiationContext context) {
try {
return CPPTemplates.resolveUnknown(unknown, context);
} catch (DOMException e) {
CCorePlugin.log(e);
}
return unknown;
}
protected static ICPPTemplateArgument[] instantiateArguments(ICPPTemplateArgument[] args,
InstantiationContext context, boolean strict) {
try {
return CPPTemplates.instantiateArguments(args, context, strict);
} catch (DOMException e) {
CCorePlugin.log(e);
}
return args;
}
protected static IBinding instantiateBinding(IBinding binding, InstantiationContext context, int maxDepth) {
try {
return CPPTemplates.instantiateBinding(binding, context, maxDepth);
} catch (DOMException e) {
CCorePlugin.log(e);
}
return binding;
}
protected static boolean containsDependentType(ICPPEvaluation[] evaluations) {
for (ICPPEvaluation eval : evaluations) {
if (eval.isTypeDependent())
return true;
}
return false;
}
protected static boolean containsDependentValue(ICPPEvaluation[] evaluations) {
for (ICPPEvaluation eval : evaluations) {
if (eval.isValueDependent())
return true;
}
return false;
}
/**
* Checks if all evaluations contained in the given array are constant expressions.
*
* @param evaluations the evaluations to check
* @param point the point of instantiation
*/
protected static boolean areAllConstantExpressions(ICPPEvaluation[] evaluations, IASTNode point) {
return areAllConstantExpressions(evaluations, 0, evaluations.length, point);
}
/**
* Checks if all evaluations contained in a range of the given array are constant expressions.
*
* @param evaluations the evaluations to check
* @param from the initial index of the range to be checked, inclusive
* @param to the final index of the range to be checked, exclusive
* @param point the point of instantiation
*/
protected static boolean areAllConstantExpressions(ICPPEvaluation[] evaluations, int from, int to,
IASTNode point) {
for (int i = from; i < to; i++) {
if (!evaluations[i].isConstantExpression(point)) {
return false;
}
}
return true;
}
protected static boolean isConstexprValue(IValue value, IASTNode point) {
if (value == null) {
return false;
}
ICPPEvaluation innerEval = value.getEvaluation();
if (innerEval == null) {
if (value instanceof IntegralValue) {
return value.numberValue() != null;
} else {
return true;
}
}
return innerEval.isConstantExpression(point);
}
protected static boolean isNullOrConstexprFunc(ICPPFunction function) {
return function == null || function.isConstexpr();
}
/**
* If a user-defined conversion is required to convert 'argument' to type 'targetType',
* returns 'argument' wrapped in an evaluation representing the conversion.
* Otherwise, returns 'argument' unmodified.
*
* @param argument the evaluation to convert
* @param targetType the type to convert to
* @param point point of instantiation for name lookups
*/
protected static ICPPEvaluation maybeApplyConversion(ICPPEvaluation argument, IType targetType,
IASTNode point) {
IType type = argument.getType(point);
ValueCategory valueCategory = argument.getValueCategory(point);
ICPPFunction conversion = null;
if (type instanceof ICPPClassType) {
try {
Cost cost = Conversions.initializationByConversion(valueCategory, type, (ICPPClassType) type,
targetType, false, point);
conversion = cost.getUserDefinedConversion();
} catch (DOMException e) {
CCorePlugin.log(e);
}
}
if (conversion != null) {
if (!conversion.isConstexpr()) {
return EvalFixed.INCOMPLETE;
}
ICPPEvaluation eval = new EvalBinding(conversion, null, (IBinding) null);
argument = new EvalFunctionCall(new ICPPEvaluation[] {eval, argument}, null, (IBinding) null);
}
return argument;
}
}