/******************************************************************************* * Copyright (c) 2012, 2014 Wind River Systems, 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: * Markus Schorn - initial API and implementation * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; 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.ICPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.CompositeValue; import org.eclipse.cdt.internal.core.dom.parser.DependentValue; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; 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.InstantiationContext; import org.eclipse.core.runtime.CoreException; /** * Performs evaluation of an expression. */ public class EvalInitList extends CPPDependentEvaluation { private final ICPPEvaluation[] fClauses; private boolean fCheckedIsValueDependent; private boolean fIsValueDependent; private boolean fCheckedIsConstantExpression; private boolean fIsConstantExpression; public EvalInitList(ICPPEvaluation[] clauses, IASTNode pointOfDefinition) { this(clauses, findEnclosingTemplate(pointOfDefinition)); } public EvalInitList(ICPPEvaluation[] clauses, IBinding templateDefinition) { super(templateDefinition); fClauses= clauses; } public ICPPEvaluation[] getClauses() { return fClauses; } @Override public boolean isInitializerList() { return true; } @Override public boolean isFunctionSet() { return false; } @Override public boolean isTypeDependent() { return containsDependentType(fClauses); } @Override public boolean isValueDependent() { if (!fCheckedIsValueDependent) { fCheckedIsValueDependent = true; fIsValueDependent = containsDependentValue(fClauses); } return fIsValueDependent; } @Override public boolean isConstantExpression(IASTNode point) { if (!fCheckedIsConstantExpression) { fCheckedIsConstantExpression = true; fIsConstantExpression = computeIsConstantExpression(point); } return fIsConstantExpression; } private boolean computeIsConstantExpression(IASTNode point) { return areAllConstantExpressions(fClauses, point); } @Override public IType getType(IASTNode point) { return new InitializerListType(this); } @Override public IValue getValue(IASTNode point) { if (isValueDependent()) { return DependentValue.create(this); } if (getClauses().length >= 1) { return CompositeValue.create(this); } else { return IntegralValue.UNKNOWN; } } @Override public ValueCategory getValueCategory(IASTNode point) { return PRVALUE; } @Override public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException { buffer.putShort(ITypeMarshalBuffer.EVAL_INIT_LIST); buffer.putInt(fClauses.length); for (ICPPEvaluation arg : fClauses) { buffer.marshalEvaluation(arg, includeValue); } marshalTemplateDefinition(buffer); } public static ICPPEvaluation unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException { int len= buffer.getInt(); ICPPEvaluation[] args = new ICPPEvaluation[len]; for (int i = 0; i < args.length; i++) { args[i]= buffer.unmarshalEvaluation(); } IBinding templateDefinition= buffer.unmarshalBinding(); return new EvalInitList(args, templateDefinition); } @Override public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) { ICPPEvaluation[] clauses = instantiateCommaSeparatedSubexpressions(fClauses, context, maxDepth); if (clauses == fClauses) return this; return new EvalInitList(clauses, getTemplateDefinition()); } @Override public ICPPEvaluation computeForFunctionCall(ActivationRecord record, ConstexprEvaluationContext context) { ICPPEvaluation[] clauses = fClauses; for (int i = 0; i < fClauses.length; i++) { ICPPEvaluation clause = fClauses[i].computeForFunctionCall(record, context.recordStep()); if (clause != fClauses[i]) { if (clauses == fClauses) { clauses = new ICPPEvaluation[fClauses.length]; System.arraycopy(fClauses, 0, clauses, 0, fClauses.length); } clauses[i] = clause; } } if (clauses == fClauses) { return this; } return new EvalInitList(clauses, this.getTemplateDefinition()); } @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; } @Override public boolean referencesTemplateParameter() { for (ICPPEvaluation clause : fClauses) { if (clause.referencesTemplateParameter()) return true; } return false; } }