/*******************************************************************************
* Copyright (c) 2008, 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)
* Nathan Ridge
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
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.ICPPDeferredFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableType;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.core.runtime.CoreException;
/**
* Represents a reference to a (member) function (instance), which cannot be resolved because
* an argument depends on a template parameter. A compiler would resolve it during instantiation.
*/
public class CPPDeferredFunction extends CPPUnknownBinding implements ICPPDeferredFunction,
ICPPComputableFunction, ISerializableType {
private static final ICPPFunctionType FUNCTION_TYPE=
new CPPFunctionType(ProblemType.UNKNOWN_FOR_EXPRESSION, IType.EMPTY_TYPE_ARRAY);
/**
* Creates a CPPDeferredFunction given a set of overloaded functions
* (some of which may be templates) that the function might resolve to.
* At least one candidate must be provided.
*
* @param candidates a set of overloaded functions, some of which may be templates
* @return the constructed CPPDeferredFunction
*/
public static ICPPFunction createForCandidates(ICPPFunction... candidates) {
if (candidates[0] instanceof ICPPConstructor)
return new CPPDeferredConstructor(((ICPPConstructor) candidates[0]).getClassOwner(), candidates);
final IBinding owner = candidates[0].getOwner();
return new CPPDeferredFunction(owner, candidates[0].getNameCharArray(), candidates);
}
/**
* Creates a CPPDeferredFunction given a name. This is for cases where there
* are no candidates that could be passed to {@link #createForCandidates}.
*
* @param name the name of the function
* @return the constructed CPPDeferredFunction
*/
public static ICPPFunction createForName(char[] name) {
return new CPPDeferredFunction(null, name, null);
}
private final IBinding fOwner;
private final ICPPFunction[] fCandidates;
public CPPDeferredFunction(IBinding owner, char[] name, ICPPFunction[] candidates) {
super(name);
fOwner= owner;
fCandidates = candidates;
}
@Override
public ICPPFunction[] getCandidates() {
return fCandidates;
}
@Override
public IType[] getExceptionSpecification() {
return null;
}
@Override
public boolean isDeleted() {
return false;
}
@Override
public boolean isExternC() {
return false;
}
@Override
public boolean isInline() {
return false;
}
@Override
public boolean isMutable() {
return false;
}
@Override
public boolean isConstexpr() {
return false;
}
@Override
public IScope getFunctionScope() {
return asScope();
}
@Override
public ICPPParameter[] getParameters() {
return ICPPParameter.EMPTY_CPPPARAMETER_ARRAY;
}
@Override
public ICPPFunctionType getType() {
return FUNCTION_TYPE;
}
@Override
public boolean isAuto() {
return false;
}
@Override
public boolean isExtern() {
return false;
}
@Override
public boolean isRegister() {
return false;
}
@Override
public boolean isStatic() {
return false;
}
@Override
public boolean takesVarArgs() {
return false;
}
@Override
public boolean isNoReturn() {
return false;
}
@Override
public int getRequiredArgumentCount() {
return 0;
}
@Override
public boolean hasParameterPack() {
return false;
}
@Override
public IBinding getOwner() {
return fOwner;
}
@Override
public ICPPExecution getFunctionBodyExecution(IASTNode point) {
return null;
}
@Override
public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
short firstBytes = ITypeMarshalBuffer.DEFERRED_FUNCTION;
if (this instanceof CPPDeferredConstructor) {
firstBytes |= ITypeMarshalBuffer.FLAG1;
}
buffer.putShort(firstBytes);
buffer.putCharArray(getNameCharArray());
buffer.marshalBinding(getOwner());
if (getCandidates() != null) {
buffer.putInt(getCandidates().length);
for (ICPPFunction candidate : getCandidates()) {
buffer.marshalBinding(candidate);
}
} else {
buffer.putInt(0);
}
}
public static IBinding unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException {
char[] name = buffer.getCharArray();
IBinding owner = buffer.unmarshalBinding();
int length = buffer.getInt();
ICPPFunction[] candidates = null;
if (length > 0) {
candidates = new ICPPFunction[length];
for (int i = 0; i < candidates.length; ++i) {
candidates[i] = (ICPPFunction) buffer.unmarshalBinding();
}
}
if ((firstBytes & ITypeMarshalBuffer.FLAG1) != 0 && (owner instanceof ICPPClassType)) {
return new CPPDeferredConstructor((ICPPClassType) owner, candidates);
}
return new CPPDeferredFunction(owner, name, candidates);
}
}