1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 17:05:26 +02:00

Bug 486971 - Introduced InstantiationContext class

No semantic changes yet.

Change-Id: I834a2f3882d8f9897798c4b1047ca2d8e5b585b1
This commit is contained in:
Sergey Prigogin 2016-02-10 16:18:00 -08:00
parent 11eefb48b1
commit bab94bb9d0
29 changed files with 548 additions and 356 deletions

View file

@ -169,7 +169,7 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
IBinding origClass = base.getBaseClass();
if (origClass instanceof ICPPTemplateParameter && ((ICPPTemplateParameter) origClass).isParameterPack()) {
IType[] specClasses= CPPTemplates.instantiateTypes(new IType[] { new CPPParameterPackType((IType) origClass) },
tpmap, -1, specialClass, point);
new InstantiationContext(tpmap, specialClass, point));
if (specClasses.length == 1 && specClasses[0] instanceof ICPPParameterPackType) {
result= ArrayUtil.append(result, base);
} else {
@ -191,7 +191,8 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
if (owner instanceof ICPPClassSpecialization) {
specializationContext = (ICPPClassSpecialization) owner;
}
IType specClass= CPPTemplates.instantiateType((IType) origClass, tpmap, -1, specializationContext, point);
IType specClass= CPPTemplates.instantiateType((IType) origClass,
new InstantiationContext(tpmap, specializationContext, point));
specClass = SemanticUtil.getUltimateType(specClass, false);
if (specClass instanceof IBinding && !(specClass instanceof IProblemBinding)) {
specBase.setBaseClass((IBinding) specClass);

View file

@ -25,6 +25,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
/**
@ -33,7 +34,8 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
public class CPPClassInstance extends CPPClassSpecialization implements ICPPTemplateInstance {
private final ICPPTemplateArgument[] arguments;
public CPPClassInstance(ICPPClassType orig, IBinding owner, CPPTemplateParameterMap argMap, ICPPTemplateArgument[] args) {
public CPPClassInstance(ICPPClassType orig, IBinding owner, ICPPTemplateParameterMap argMap,
ICPPTemplateArgument[] args) {
super(orig, owner, argMap);
this.arguments= args;
}

View file

@ -16,14 +16,15 @@ 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.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
/**
* Instantiation of a constructor template
*/
public class CPPConstructorInstance extends CPPMethodInstance implements ICPPConstructor {
public CPPConstructorInstance(ICPPConstructor orig, ICPPClassType owner,
CPPTemplateParameterMap tpmap, ICPPTemplateArgument[] args, ICPPFunctionType type, IType[] exceptionSpec) {
public CPPConstructorInstance(ICPPConstructor orig, ICPPClassType owner, ICPPTemplateParameterMap tpmap,
ICPPTemplateArgument[] args, ICPPFunctionType type, IType[] exceptionSpec) {
super(orig, owner, tpmap, args, type, exceptionSpec);
}
}

View file

@ -40,10 +40,12 @@ public class CPPEnumerationSpecialization extends CPPSpecialization implements I
public static IBinding createInstance(ICPPEnumeration enumeration,
ICPPClassSpecialization owner, ICPPTemplateParameterMap tpMap, IASTNode point) {
ICPPClassSpecialization within = CPPTemplates.getSpecializationContext(owner);
IType fixedType = enumeration.getFixedType();
if (fixedType != null)
fixedType = CPPTemplates.instantiateType(fixedType, tpMap, -1, within, point);
if (fixedType != null) {
ICPPClassSpecialization within = CPPTemplates.getSpecializationContext(owner);
InstantiationContext context = new InstantiationContext(tpMap, within, point);
fixedType = CPPTemplates.instantiateType(fixedType, context);
}
CPPEnumerationSpecialization specializedEnumeration =
new CPPEnumerationSpecialization(enumeration, owner, tpMap, fixedType);
specializedEnumeration.initialize(point);
@ -63,13 +65,14 @@ public class CPPEnumerationSpecialization extends CPPSpecialization implements I
IType previousInternalType = CPPBasicType.INT;
for (int i = 0; i < enumerators.length; ++i) {
IEnumerator enumerator = enumerators[i];
IValue specializedValue = CPPTemplates.instantiateValue(enumerator.getValue(), tpMap, -1,
this, Value.MAX_RECURSION_DEPTH, point);
InstantiationContext context = new InstantiationContext(tpMap, this, point);
IValue specializedValue =
CPPTemplates.instantiateValue(enumerator.getValue(), context, Value.MAX_RECURSION_DEPTH);
IType internalType = null;
if (fFixedType == null && enumerator instanceof ICPPInternalEnumerator) {
internalType = ((ICPPInternalEnumerator) enumerator).getInternalType();
if (internalType != null) {
internalType = CPPTemplates.instantiateType(internalType, tpMap, -1, this, point);
internalType = CPPTemplates.instantiateType(internalType, context);
} else if (previousInternalType instanceof IBasicType) {
internalType = ASTEnumerator.getTypeOfIncrementedValue(
(IBasicType) previousInternalType, specializedValue);

View file

@ -22,6 +22,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
/**
@ -30,7 +31,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
public class CPPFunctionInstance extends CPPFunctionSpecialization implements ICPPFunctionInstance {
private final ICPPTemplateArgument[] fArguments;
public CPPFunctionInstance(ICPPFunction orig, IBinding owner, CPPTemplateParameterMap argMap,
public CPPFunctionInstance(ICPPFunction orig, IBinding owner, ICPPTemplateParameterMap argMap,
ICPPTemplateArgument[] args, ICPPFunctionType type, IType[] exceptionSpecs) {
super(orig, owner, argMap, type, exceptionSpecs);
fArguments = args;

View file

@ -28,6 +28,7 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
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;
@ -334,8 +335,10 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP
if (f instanceof ICPPComputableFunction) {
ICPPEvaluation eval = ((ICPPComputableFunction) f).getReturnExpression(point);
if (eval != null) {
eval = eval.instantiate(getTemplateParameterMap(), -1,
CPPTemplates.getSpecializationContext(getOwner()), Value.MAX_RECURSION_DEPTH, point);
ICPPClassSpecialization within = CPPTemplates.getSpecializationContext(getOwner());
InstantiationContext context =
new InstantiationContext(getTemplateParameterMap(), within, point);
eval = eval.instantiate(context, Value.MAX_RECURSION_DEPTH);
}
return eval;
}

View file

@ -17,13 +17,14 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
/**
* The result of instantiating a method template.
*/
public class CPPMethodInstance extends CPPFunctionInstance implements ICPPMethod {
public CPPMethodInstance(ICPPMethod orig, ICPPClassType owner, CPPTemplateParameterMap tpmap,
public CPPMethodInstance(ICPPMethod orig, ICPPClassType owner, ICPPTemplateParameterMap tpmap,
ICPPTemplateArgument[] args, ICPPFunctionType type, IType[] exceptionSpecs) {
super(orig, owner, tpmap, args, type, exceptionSpecs);
}

View file

@ -18,7 +18,6 @@ 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.core.dom.ast.cpp.ICPPTypeSpecialization;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPFunctionParameterMap;
@ -81,10 +80,10 @@ public interface ICPPEvaluation extends ISerializableEvaluation {
/**
* Instantiates the evaluation with the provided template parameter map and pack offset.
* The context is used to replace templates with their specialization, where appropriate.
*
* @return a fully or partially instantiated evaluation, or the original evaluation
*/
ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPTypeSpecialization within, int maxdepth, IASTNode point);
ICPPEvaluation instantiate(InstantiationContext context, int maxDepth);
/**
* Keeps track of state during a constexpr evaluation.

View file

@ -0,0 +1,175 @@
/*******************************************************************************
* Copyright (c) 2016 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
*******************************************************************************/
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.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumerationSpecialization;
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.dom.ast.cpp.ICPPTypeSpecialization;
/**
* Represents parameters and state of template instantiation.
*/
public class InstantiationContext {
private CPPTemplateParameterMap parameterMap;
private int packOffset;
private final ICPPTypeSpecialization contextTypeSpecialization;
private final IASTNode point;
/**
* @param parameterMap mapping of template parameters to arguments, may be {@code null}.
* @param packOffset parameter pack offset, or -1 if expansion of a parameter pack is not desired
* pack.
* @param contextTypeSpecialization the type specialization if instantiation happens inside a specialized
* type, otherwise {@code null}.
* @param point the point of instantiation
*/
public InstantiationContext(ICPPTemplateParameterMap parameterMap, int packOffset,
ICPPTypeSpecialization contextTypeSpecialization, IASTNode point) {
this.parameterMap = (CPPTemplateParameterMap) parameterMap;
this.packOffset = packOffset;
this.contextTypeSpecialization = contextTypeSpecialization;
this.point = point;
}
/**
* @param parameterMap mapping of template parameters to arguments, may be {@code null}.
* @param contextTypeSpecialization the type specialization if instantiation happens inside a specialized
* type, otherwise {@code null}.
* @param point the point of instantiation
*/
public InstantiationContext(ICPPTemplateParameterMap parameterMap,
ICPPTypeSpecialization contextTypeSpecialization, IASTNode point) {
this(parameterMap, -1, contextTypeSpecialization, point);
}
/**
* @param parameterMap mapping of template parameters to arguments, may be {@code null}.
* @param packOffset parameter pack offset, or -1 if not known
* @param point the point of instantiation
*/
public InstantiationContext(ICPPTemplateParameterMap parameterMap, int packOffset, IASTNode point) {
this(parameterMap, packOffset, null, point);
}
/**
* @param parameterMap mapping of template parameters to arguments, may be {@code null}.
* @param point the point of instantiation
*/
public InstantiationContext(ICPPTemplateParameterMap parameterMap, IASTNode point) {
this(parameterMap, -1, null, point);
}
/**
* Returns the mapping of template parameters to arguments, possibly {@code null} if the context doesn't
* contain it.
*/
public final ICPPTemplateParameterMap getParameterMap() {
return parameterMap;
}
/**
* Adds a parameter mapping.
*/
public final void addToParameterMap(ICPPTemplateParameter par, ICPPTemplateArgument arg) {
if (parameterMap == null) {
parameterMap = new CPPTemplateParameterMap(1);
}
parameterMap.put(par, arg);
}
/**
* Adds a parameter mapping.
*/
public final void addToParameterMap(ICPPTemplateParameter par, ICPPTemplateArgument[] args) {
if (parameterMap == null) {
parameterMap = new CPPTemplateParameterMap(1);
}
parameterMap.put(par, args);
}
/**
* Puts all mappings from the supplied map into the parameter map of the context.
*/
public final void addToParameterMap(ICPPTemplateParameterMap toAdd) {
if (parameterMap == null) {
parameterMap = new CPPTemplateParameterMap((CPPTemplateParameterMap) toAdd);
} else {
parameterMap.putAll(toAdd);
}
}
/**
* Returns the type specialization if instantiation happens inside a specialized type, otherwise
* {@code null}.
*/
public final ICPPTypeSpecialization getContextTypeSpecialization() {
return contextTypeSpecialization;
}
/**
* Returns the class specialization if instantiation happens inside a specialized class, otherwise
* {@code null}.
*/
public ICPPClassSpecialization getContextClassSpecialization() {
return getContextClassSpecialization(contextTypeSpecialization);
}
/**
* Returns the point of instantiation
*/
public final IASTNode getPoint() {
return point;
}
/**
* Returns true if the pack offset is specified.
*/
public final boolean hasPackOffset() {
return packOffset != -1;
}
/**
* Returns the pack offset if specified, otherwise -1.
*/
public final int getPackOffset() {
return packOffset;
}
/**
* Sets the pack offset.
*/
public void setPackOffset(int packOffset) {
this.packOffset = packOffset;
}
/**
* @see ICPPTemplateParameterMap#getArgument(ICPPTemplateParameter, int)
*/
public ICPPTemplateArgument getArgument(ICPPTemplateParameter param) {
return parameterMap.getArgument(param, packOffset);
}
/**
* Returns the class specialization that the given binding is or is owned by, otherwise {@code null}.
*/
public static ICPPClassSpecialization getContextClassSpecialization(IBinding owner) {
if (owner instanceof ICPPEnumerationSpecialization)
owner = owner.getOwner();
if (owner instanceof ICPPClassSpecialization)
return (ICPPClassSpecialization) owner;
return null;
}
}

View file

@ -18,10 +18,9 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
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;
import org.eclipse.core.runtime.PlatformObject;
@ -34,13 +33,13 @@ import org.eclipse.core.runtime.PlatformObject;
public abstract class CPPDependentEvaluation extends CPPEvaluation {
private IBinding fTemplateDefinition;
private IScope fTemplateDefinitionScope;
CPPDependentEvaluation(IBinding templateDefinition) {
fTemplateDefinition = templateDefinition;
}
@Override
public IBinding getTemplateDefinition() {
public IBinding getTemplateDefinition() {
if (fTemplateDefinition instanceof DeferredResolutionBinding) {
IBinding toResolve = fTemplateDefinition;
// While resolve() is called, set fTemplateDefinition to null to avoid
@ -51,7 +50,7 @@ public abstract class CPPDependentEvaluation extends CPPEvaluation {
}
return fTemplateDefinition;
}
protected IScope getTemplateDefinitionScope() {
if (fTemplateDefinitionScope == null) {
IBinding templateDefinition = getTemplateDefinition();
@ -62,15 +61,15 @@ public abstract class CPPDependentEvaluation extends CPPEvaluation {
try {
fTemplateDefinitionScope = templateDefinition.getScope();
} catch (DOMException e) {
}
}
}
}
return fTemplateDefinitionScope;
}
/**
* If the given node is contained in some template declaration,
* returns the binding for that template. Otherwise returns null.
* returns the binding for that template. Otherwise returns null.
*/
protected static IBinding findEnclosingTemplate(IASTNode node) {
while (node != null) {
@ -85,7 +84,7 @@ public abstract class CPPDependentEvaluation extends CPPEvaluation {
}
return null;
}
protected void marshalTemplateDefinition(ITypeMarshalBuffer buffer) throws CoreException {
// Don't marshal the template definition when building a signature.
// While the template definition needs to be stored in the index, it does not
@ -95,20 +94,19 @@ public abstract class CPPDependentEvaluation extends CPPEvaluation {
if (!(buffer instanceof SignatureBuilder))
buffer.marshalBinding(getTemplateDefinition());
}
/**
* Instantiate evaluations that represent subexpressions separated by commas.
* If a subexpression is a pack expansion expression, and the template parameter map
* contains a mapping for the parameter pack(s) that occur in its expansion pattern,
* the expansion pattern is instantiated once for each mapped template argument,
* and the resulting evaluations are returned in place of the pack expansion.
*
* and the resulting evaluations are returned in place of the pack expansion.
*
* This code is similar to CPPTemplates.instantiateArguments(), but applies to evaluations
* rather than template arguments.
* rather than template arguments.
*/
protected static ICPPEvaluation[] instantiateCommaSeparatedSubexpressions(
ICPPEvaluation[] subexpressions, ICPPTemplateParameterMap tpMap, int packOffset,
ICPPTypeSpecialization within, int maxdepth, IASTNode point) {
ICPPEvaluation[] subexpressions, InstantiationContext context, int maxDepth) {
ICPPEvaluation[] result = subexpressions;
int resultShift = 0;
for (int i = 0; i < subexpressions.length; i++) {
@ -119,7 +117,7 @@ public abstract class CPPDependentEvaluation extends CPPEvaluation {
if (pattern == null) {
newEval = EvalFixed.INCOMPLETE;
} else {
int packSize = pattern.determinePackSize(tpMap);
int packSize = pattern.determinePackSize(context.getParameterMap());
if (packSize == CPPTemplates.PACK_SIZE_FAIL || packSize == CPPTemplates.PACK_SIZE_NOT_FOUND) {
newEval = EvalFixed.INCOMPLETE;
} else if (packSize == CPPTemplates.PACK_SIZE_DEFER) {
@ -128,19 +126,22 @@ public abstract class CPPDependentEvaluation extends CPPEvaluation {
int shift = packSize - 1;
ICPPEvaluation[] newResult = new ICPPEvaluation[subexpressions.length + resultShift + shift];
System.arraycopy(result, 0, newResult, 0, i + resultShift);
int oldPackOffset = context.getPackOffset();
for (int j = 0; j < packSize; ++j) {
newEval = pattern.instantiate(tpMap, j, within, maxdepth, point);
context.setPackOffset(j);
newEval = pattern.instantiate(context, maxDepth);
newResult[i + resultShift + j] = newEval;
}
context.setPackOffset(oldPackOffset);
result = newResult;
resultShift += shift;
continue;
}
}
} else {
newEval = origEval.instantiate(tpMap, packOffset, within, maxdepth, point);
newEval = origEval.instantiate(context, maxDepth);
}
if (result != subexpressions) {
result[i + resultShift] = newEval;
} else if (newEval != origEval) {
@ -152,22 +153,22 @@ public abstract class CPPDependentEvaluation extends CPPEvaluation {
}
return result;
}
/**
* Used to defer the resolution of a template definition until it is needed,
* Used to defer the resolution of a template definition until it is needed,
* to avoid recursion. The only valid operation on this binding is resolve().
*/
private static class DeferredResolutionBinding extends PlatformObject implements IBinding {
private final IASTName fName;
public DeferredResolutionBinding(IASTName name) {
fName = name;
}
public IBinding resolve() {
return fName.resolveBinding();
}
@Override
public String getName() {
throw new UnsupportedOperationException();

View file

@ -21,10 +21,9 @@ 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.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization;
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 {
@ -49,10 +48,9 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
return buf.getSignature();
}
protected static IBinding resolveUnknown(ICPPUnknownBinding unknown, ICPPTemplateParameterMap tpMap,
int packOffset, ICPPTypeSpecialization within, IASTNode point) {
protected static IBinding resolveUnknown(ICPPUnknownBinding unknown, InstantiationContext context) {
try {
return CPPTemplates.resolveUnknown(unknown, tpMap, packOffset, within, point);
return CPPTemplates.resolveUnknown(unknown, context);
} catch (DOMException e) {
CCorePlugin.log(e);
}
@ -60,19 +58,18 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
}
protected static ICPPTemplateArgument[] instantiateArguments(ICPPTemplateArgument[] args,
ICPPTemplateParameterMap tpMap, int packOffset, ICPPTypeSpecialization within, IASTNode point) {
InstantiationContext context) {
try {
return CPPTemplates.instantiateArguments(args, tpMap, packOffset, within, point, false);
return CPPTemplates.instantiateArguments(args, context, false);
} catch (DOMException e) {
CCorePlugin.log(e);
}
return args;
}
protected static IBinding instantiateBinding(IBinding binding, ICPPTemplateParameterMap tpMap,
int packOffset, ICPPTypeSpecialization within, int maxdepth, IASTNode point) {
protected static IBinding instantiateBinding(IBinding binding, InstantiationContext context, int maxDepth) {
try {
return CPPTemplates.instantiateBinding(binding, tpMap, packOffset, within, maxdepth, point);
return CPPTemplates.instantiateBinding(binding, context, maxDepth);
} catch (DOMException e) {
CCorePlugin.log(e);
}

View file

@ -16,6 +16,7 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext.getContextClassSpecialization;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
@ -182,6 +183,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownMember;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownMemberClass;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownMemberClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.Context;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMode;
import org.eclipse.cdt.internal.core.index.IIndexType;
@ -209,13 +211,13 @@ public class CPPTemplates {
static final int PACK_SIZE_NOT_FOUND = Integer.MAX_VALUE;
static enum TypeSelection { PARAMETERS, RETURN_TYPE, PARAMETERS_AND_RETURN_TYPE }
// Infrastructure to protect against rogue template metaprograms that don't terminate.
private static final int TEMPLATE_INSTANTIATION_DEPTH_LIMIT = 256;
private static final ThreadLocal<Integer> fTemplateInstantiationDepth = new ThreadLocal<Integer>() {
@Override
protected Integer initialValue() {
return 0;
protected Integer initialValue() {
return 0;
}
};
@ -243,7 +245,8 @@ public class CPPTemplates {
}
if (template instanceof ICPPClassTemplatePartialSpecialization) {
return instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) template, arguments, isDefinition, null, point);
return instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) template,
arguments, isDefinition, null, point);
}
if (arguments == args) {
@ -264,7 +267,8 @@ public class CPPTemplates {
return result;
}
return instantiatePrimaryTemplate(template, arguments, map, isDefinition, point);
return instantiatePrimaryTemplate(template, arguments, new InstantiationContext(map, point),
isDefinition);
} catch (DOMException e) {
return e.getProblem();
}
@ -289,7 +293,7 @@ public class CPPTemplates {
// a recursion as 'name' is currently being resolved. Since an out-of-line method
// definition cannot be inside a template scope, we can accurately return null
// in this case.
if (functionName.getParent() instanceof ICPPASTQualifiedName
if (functionName.getParent() instanceof ICPPASTQualifiedName
&& ASTQueries.isAncestorOf(functionName.getParent(), name)) {
return null;
}
@ -343,14 +347,14 @@ public class CPPTemplates {
}
private static IBinding instantiateFunctionTemplate(ICPPFunctionTemplate template,
ICPPTemplateArgument[] arguments, CPPTemplateParameterMap map, IASTNode point) throws DOMException {
ICPPTemplateArgument[] arguments, CPPTemplateParameterMap tpMap, IASTNode point) throws DOMException {
ICPPTemplateInstance instance= getInstance(template, arguments, false);
if (instance != null) {
return instance;
}
IBinding owner= template.getOwner();
instance = createInstance(owner, template, map, arguments, point);
instance = createInstance(owner, template, tpMap, arguments, point);
if (instance instanceof ICPPFunction && SemanticUtil.isValidType(((ICPPFunction) instance).getType())) {
addInstance(template, arguments, instance);
}
@ -360,9 +364,9 @@ public class CPPTemplates {
/**
* Instantiates a partial class template specialization.
*/
private static IBinding instantiatePartialSpecialization(
ICPPPartialSpecialization partialSpec, ICPPTemplateArgument[] args, boolean isDef,
CPPTemplateParameterMap tpMap, IASTNode point) throws DOMException {
private static IBinding instantiatePartialSpecialization(ICPPPartialSpecialization partialSpec,
ICPPTemplateArgument[] args, boolean isDef, CPPTemplateParameterMap tpMap, IASTNode point)
throws DOMException {
ICPPTemplateInstance instance= getInstance(partialSpec, args, isDef);
if (instance != null)
return instance;
@ -370,8 +374,9 @@ public class CPPTemplates {
if (tpMap == null) {
tpMap = new CPPTemplateParameterMap(args.length);
if (!TemplateArgumentDeduction.fromTemplateArguments(partialSpec.getTemplateParameters(),
partialSpec.getTemplateArguments(), args, tpMap, point))
partialSpec.getTemplateArguments(), args, tpMap, point)) {
return null;
}
}
instance= createInstance(partialSpec.getOwner(), partialSpec, tpMap, args, point);
@ -383,8 +388,8 @@ public class CPPTemplates {
* Instantiates the selected template, without looking for specializations.
* May return {@code null}.
*/
private static IBinding instantiatePrimaryTemplate(ICPPPartiallySpecializable template, ICPPTemplateArgument[] arguments,
CPPTemplateParameterMap map, boolean isDef, IASTNode point) throws DOMException {
private static IBinding instantiatePrimaryTemplate(ICPPPartiallySpecializable template,
ICPPTemplateArgument[] arguments, InstantiationContext context, boolean isDef) throws DOMException {
assert !(template instanceof ICPPClassTemplatePartialSpecialization);
ICPPTemplateInstance instance= getInstance(template, arguments, isDef);
if (instance != null) {
@ -392,7 +397,7 @@ public class CPPTemplates {
}
IBinding owner= template.getOwner();
instance = createInstance(owner, template, map, arguments, point);
instance = createInstance(owner, template, context.getParameterMap(), arguments, context.getPoint());
addInstance(template, arguments, instance);
return instance;
}
@ -408,12 +413,12 @@ public class CPPTemplates {
return null;
if (result != null) {
// Don't use the cached instance if its argument is an index type and the requested
// argument is an AST type. Despite identical signatures the types may be different.
// argument is an AST type. Despite identical signatures the types may be different.
ICPPTemplateArgument[] instanceArgs = result.getTemplateArguments();
for (int i = 0; i < args.length; i++) {
if (!(args[i].getTypeValue() instanceof IIndexType) &&
(instanceArgs[i].getTypeValue() instanceof IIndexType)) {
return null;
return null;
}
}
}
@ -492,6 +497,7 @@ public class CPPTemplates {
ICPPTemplateArgument[] completeArgs= new ICPPTemplateArgument[tparCount];
CPPTemplateParameterMap map= new CPPTemplateParameterMap(tparCount);
InstantiationContext context = new InstantiationContext(map, point);
for (int i = 0; i < tparCount; i++) {
final ICPPTemplateParameter tpar = tpars[i];
if (tpar.isParameterPack()) {
@ -510,13 +516,13 @@ public class CPPTemplates {
}
if (defaultArg == null)
return null;
arg= instantiateArgument(defaultArg, map, -1, null, point);
arg= instantiateArgument(defaultArg, context);
arg= SemanticUtil.getSimplifiedArgument(arg);
if (!isValidArgument(arg)) {
return null;
}
}
map.put(tpar, arg);
context.addToParameterMap(tpar, arg);
completeArgs[i]= arg;
}
return completeArgs;
@ -715,7 +721,7 @@ public class CPPTemplates {
if (args == null) {
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, templateName.toCharArray());
}
ICPPTemplateParameterMap parameterMap = createParameterMap(aliasTemplate, args, id);
CPPTemplateParameterMap parameterMap = createParameterMap(aliasTemplate, args, id);
if (parameterMap == null) {
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, templateName.toCharArray());
}
@ -733,7 +739,7 @@ public class CPPTemplates {
if (args == null) {
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, templateName.toCharArray());
}
ICPPTemplateParameterMap parameterMap = createParameterMap(aliasTemplate, args, id);
CPPTemplateParameterMap parameterMap = createParameterMap(aliasTemplate, args, id);
if (parameterMap == null) {
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, templateName.toCharArray());
}
@ -813,12 +819,12 @@ public class CPPTemplates {
}
private static IBinding createAliasTemplaceInstance(ICPPAliasTemplate aliasTemplate,
ICPPTemplateArgument[] args, ICPPTemplateParameterMap parameterMap, IType aliasedType,
IBinding owner, ICPPASTTemplateId id) {
ICPPClassSpecialization within = getSpecializationContext(owner);
IType instantiatedType = instantiateType(aliasedType, parameterMap, -1, within, id);
ICPPTemplateArgument[] args, CPPTemplateParameterMap parameterMap, IType aliasedType,
IBinding owner, IASTNode point) {
InstantiationContext context = createInstantiationContext(parameterMap, owner, point);
IType instantiatedType = instantiateType(aliasedType, context);
StringBuilder buf= new StringBuilder();
buf.append(id.getSimpleID()).append(ASTTypeUtil.getArgumentListString(args, false));
buf.append(aliasTemplate.getName()).append(ASTTypeUtil.getArgumentListString(args, false));
char[] name = new char[buf.length()];
buf.getChars(0, buf.length(), name, 0);
return new CPPAliasTemplateInstance(name, aliasTemplate, instantiatedType);
@ -848,11 +854,11 @@ public class CPPTemplates {
}
public static ICPPTemplateInstance createInstance(IBinding owner, ICPPTemplateDefinition template,
CPPTemplateParameterMap tpMap, ICPPTemplateArgument[] args, IASTNode point) {
ICPPTemplateParameterMap tpMap, ICPPTemplateArgument[] args, IASTNode point) {
if (owner instanceof ICPPSpecialization) {
ICPPTemplateParameterMap map= ((ICPPSpecialization) owner).getTemplateParameterMap();
if (map != null) {
tpMap.putAll(map);
((CPPTemplateParameterMap) tpMap).putAll(map);
}
}
@ -861,33 +867,36 @@ public class CPPTemplates {
instance = new CPPClassInstance((ICPPClassType) template, owner, tpMap, args);
} else if (template instanceof ICPPFunction) {
ICPPFunction func= (ICPPFunction) template;
ICPPClassSpecialization within = getSpecializationContext(owner);
ICPPFunctionType type= (ICPPFunctionType) instantiateType(func.getType(), tpMap, -1, within, point);
IType[] exceptionSpecs= instantiateTypes(func.getExceptionSpecification(), tpMap, -1, within, point);
InstantiationContext context = createInstantiationContext(tpMap, owner, point);
ICPPFunctionType type= (ICPPFunctionType) instantiateType(func.getType(), context);
IType[] exceptionSpecs= instantiateTypes(func.getExceptionSpecification(), context);
CPPFunctionSpecialization spec;
if (owner instanceof ICPPClassType && template instanceof ICPPMethod) {
if (template instanceof ICPPConstructor) {
spec = new CPPConstructorInstance((ICPPConstructor) template, (ICPPClassType) owner, tpMap, args, type, exceptionSpecs);
spec = new CPPConstructorInstance((ICPPConstructor) template, (ICPPClassType) owner,
context.getParameterMap(), args, type, exceptionSpecs);
} else {
spec = new CPPMethodInstance((ICPPMethod) template, (ICPPClassType) owner, tpMap, args, type, exceptionSpecs);
spec = new CPPMethodInstance((ICPPMethod) template, (ICPPClassType) owner,
context.getParameterMap(), args, type, exceptionSpecs);
}
} else {
spec = new CPPFunctionInstance((ICPPFunction) template, owner, tpMap, args, type, exceptionSpecs);
spec = new CPPFunctionInstance((ICPPFunction) template, owner, tpMap, args, type, exceptionSpecs);
}
spec.setParameters(specializeParameters(func.getParameters(), spec, tpMap, -1, within, Value.MAX_RECURSION_DEPTH, point));
spec.setParameters(specializeParameters(func.getParameters(), spec, context, Value.MAX_RECURSION_DEPTH));
instance = (ICPPTemplateInstance) spec;
} else if (template instanceof ICPPVariable) {
ICPPVariable var = (ICPPVariable) template;
ICPPClassSpecialization within = getSpecializationContext(owner);
IType type = instantiateType(var.getType(), tpMap, -1, within, point);
InstantiationContext context = createInstantiationContext(tpMap, owner, point);
IType type = instantiateType(var.getType(), context);
IValue value;
ICPPASTDeclarator decl = ASTQueries.findAncestorWithType(point, ICPPASTDeclarator.class);
if (((IASTName) point).getRoleOfName(false) == IASTNameOwner.r_definition && decl != null && decl.getInitializer() != null) {
if (((IASTName) point).getRoleOfName(false) == IASTNameOwner.r_definition
&& decl != null && decl.getInitializer() != null) {
// Explicit specialization.
value = SemanticUtil.getValueOfInitializer(decl.getInitializer(), type);
} else {
value = instantiateValue(var.getInitialValue(), tpMap, -1, within, Value.MAX_RECURSION_DEPTH, point);
value = instantiateValue(var.getInitialValue(), context, Value.MAX_RECURSION_DEPTH);
}
if (template instanceof ICPPField) {
@ -898,14 +907,13 @@ public class CPPTemplates {
}
return instance;
}
public static ICPPParameter[] specializeParameters(ICPPParameter[] parameters, ICPPFunction functionSpec,
ICPPTemplateParameterMap tpMap, int packOffset, ICPPTypeSpecialization within, int maxdepth,
IASTNode point) {
public static ICPPParameter[] specializeParameters(ICPPParameter[] parameters, ICPPFunction functionSpec,
InstantiationContext context, int maxdepth) {
if (parameters.length == 0) {
return parameters;
}
}
// Because of parameter packs there can be more or less parameters in the specialization
IType[] specializedParameterTypes = functionSpec.getType().getParameterTypes();
final int length = specializedParameterTypes.length;
@ -917,10 +925,9 @@ public class CPPTemplates {
} // else reuse last parameter (which should be a pack)
@SuppressWarnings("null")
IValue defaultValue = par.getDefaultValue();
IValue specializedValue = CPPTemplates.instantiateValue(defaultValue, tpMap,
packOffset, within, maxdepth, point);
result[i] = new CPPParameterSpecialization(par, functionSpec, specializedParameterTypes[i],
specializedValue, tpMap);
IValue specializedValue = CPPTemplates.instantiateValue(defaultValue, context, maxdepth);
result[i] = new CPPParameterSpecialization(par, functionSpec, specializedParameterTypes[i],
specializedValue, context.getParameterMap());
}
return result;
}
@ -938,12 +945,12 @@ public class CPPTemplates {
try {
if (decl instanceof ICPPClassTemplatePartialSpecialization) {
try {
final ICPPClassSpecialization within = getSpecializationContext(owner);
ICPPClassTemplatePartialSpecialization pspec= (ICPPClassTemplatePartialSpecialization) decl;
ICPPClassTemplate template= pspec.getPrimaryClassTemplate();
ICPPTemplateArgument[] args = pspec.getTemplateArguments();
template= (ICPPClassTemplate) owner.specializeMember(template, point);
args= instantiateArguments(args, tpMap, -1, within, point, false);
InstantiationContext context = createInstantiationContext(tpMap, owner, point);
args= instantiateArguments(args, context, false);
spec= new CPPClassTemplatePartialSpecializationSpecialization(pspec, tpMap, template, args);
} catch (DOMException e) {
}
@ -961,10 +968,10 @@ public class CPPTemplates {
spec = new CPPClassSpecialization((ICPPClassType) decl, oldOwner, tpMap);
}
} else if (decl instanceof ICPPField) {
final ICPPClassSpecialization within = getSpecializationContext(owner);
ICPPField field= (ICPPField) decl;
IType type= instantiateType(field.getType(), tpMap, -1, within, point);
IValue value= instantiateValue(field.getInitialValue(), tpMap, -1, within, Value.MAX_RECURSION_DEPTH, point);
InstantiationContext context = createInstantiationContext(tpMap, owner, point);
IType type= instantiateType(field.getType(), context);
IValue value= instantiateValue(field.getInitialValue(), context, Value.MAX_RECURSION_DEPTH);
if (decl instanceof ICPPFieldTemplate) {
CPPFieldTemplateSpecialization fieldTempSpec = new CPPFieldTemplateSpecialization(decl,
owner, tpMap, type, value);
@ -978,25 +985,29 @@ public class CPPTemplates {
}
} else if (decl instanceof ICPPFunction) {
ICPPFunction func= (ICPPFunction) decl;
ICPPClassSpecialization within = getSpecializationContext(owner);
ICPPFunctionType type= (ICPPFunctionType) instantiateType(func.getType(), tpMap, -1, within, point);
IType[] exceptionSpecs= instantiateTypes(func.getExceptionSpecification(), tpMap, -1, within, point);
InstantiationContext context = createInstantiationContext(tpMap, owner, point);
ICPPFunctionType type= (ICPPFunctionType) instantiateType(func.getType(), context);
IType[] exceptionSpecs= instantiateTypes(func.getExceptionSpecification(), context);
CPPFunctionSpecialization functionSpec = null;
if (decl instanceof ICPPFunctionTemplate) {
if (decl instanceof ICPPMethod) {
CPPMethodTemplateSpecialization methodSpec;
if (decl instanceof ICPPConstructor) {
methodSpec = new CPPConstructorTemplateSpecialization((ICPPConstructor) decl, owner, tpMap, type, exceptionSpecs);
methodSpec = new CPPConstructorTemplateSpecialization((ICPPConstructor) decl,
owner, tpMap, type, exceptionSpecs);
} else {
methodSpec = new CPPMethodTemplateSpecialization((ICPPMethod) decl, owner, tpMap, type, exceptionSpecs);
methodSpec = new CPPMethodTemplateSpecialization((ICPPMethod) decl, owner, tpMap,
type, exceptionSpecs);
}
methodSpec.setTemplateParameters(CPPTemplates.specializeTemplateParameters(methodSpec,
(ICPPScope) methodSpec.getScope(), ((ICPPFunctionTemplate) decl).getTemplateParameters(), owner, point));
(ICPPScope) methodSpec.getScope(),
((ICPPFunctionTemplate) decl).getTemplateParameters(), owner, point));
functionSpec = methodSpec;
} else {
IBinding oldOwner = decl.getOwner();
functionSpec = new CPPFunctionTemplateSpecialization((ICPPFunctionTemplate) decl, oldOwner, tpMap, type, exceptionSpecs);
functionSpec = new CPPFunctionTemplateSpecialization((ICPPFunctionTemplate) decl,
oldOwner, tpMap, type, exceptionSpecs);
}
} else if (decl instanceof ICPPConstructor) {
functionSpec = new CPPConstructorSpecialization((ICPPConstructor) decl, owner, tpMap, type, exceptionSpecs);
@ -1007,17 +1018,18 @@ public class CPPTemplates {
functionSpec = new CPPFunctionSpecialization((ICPPFunction) decl, oldOwner, tpMap, type, exceptionSpecs);
}
if (functionSpec != null) {
functionSpec.setParameters(specializeParameters(func.getParameters(), functionSpec, tpMap, -1, within,
Value.MAX_RECURSION_DEPTH, point));
functionSpec.setParameters(specializeParameters(func.getParameters(), functionSpec, context,
Value.MAX_RECURSION_DEPTH));
}
spec = functionSpec;
} else if (decl instanceof ITypedef) {
IType type= instantiateType(((ITypedef) decl).getType(), tpMap, -1, getSpecializationContext(owner), point);
InstantiationContext context = createInstantiationContext(tpMap, owner, point);
IType type= instantiateType(((ITypedef) decl).getType(), context);
spec = new CPPTypedefSpecialization(decl, owner, tpMap, type);
} else if (decl instanceof ICPPAliasTemplate) {
ICPPAliasTemplate aliasTemplate = (ICPPAliasTemplate) decl;
IType type= instantiateType(aliasTemplate.getType(), tpMap, -1, getSpecializationContext(owner), point);
InstantiationContext context = createInstantiationContext(tpMap, owner, point);
IType type= instantiateType(aliasTemplate.getType(), context);
spec = new CPPAliasTemplateInstance(decl.getNameCharArray(), aliasTemplate, type);
} else if (decl instanceof ICPPEnumeration) {
spec = CPPEnumerationSpecialization.createInstance((ICPPEnumeration) decl, owner, tpMap, point);
@ -1030,11 +1042,11 @@ public class CPPTemplates {
} else if (decl instanceof ICPPUsingDeclaration) {
IBinding[] delegates= ((ICPPUsingDeclaration) decl).getDelegates();
List<IBinding> result= new ArrayList<>();
ICPPClassSpecialization within = getSpecializationContext(owner);
InstantiationContext context = createInstantiationContext(tpMap, owner, point);
for (IBinding delegate : delegates) {
try {
if (delegate instanceof ICPPUnknownBinding) {
delegate= resolveUnknown((ICPPUnknownBinding) delegate, tpMap, -1, within, point);
delegate= resolveUnknown((ICPPUnknownBinding) delegate, context);
}
if (delegate instanceof CPPFunctionSet) {
for (IBinding b : ((CPPFunctionSet) delegate).getBindings()) {
@ -1058,6 +1070,11 @@ public class CPPTemplates {
return spec;
}
private static InstantiationContext createInstantiationContext(ICPPTemplateParameterMap tpMap,
IBinding owner, IASTNode point) {
return new InstantiationContext(tpMap, getSpecializationContext(owner), point);
}
public static ICPPClassSpecialization getSpecializationContext(IBinding owner) {
ICPPClassSpecialization within = getContextClassSpecialization(owner);
if (within == null)
@ -1076,25 +1093,16 @@ public class CPPTemplates {
}
}
protected static ICPPClassSpecialization getContextClassSpecialization(IBinding owner) {
if (owner instanceof ICPPEnumerationSpecialization)
owner = owner.getOwner();
if (owner instanceof ICPPClassSpecialization)
return (ICPPClassSpecialization) owner;
return null;
}
public static IValue instantiateValue(IValue value, ICPPTemplateParameterMap tpMap, int packOffset,
ICPPTypeSpecialization within, int maxdepth, IASTNode point) {
public static IValue instantiateValue(IValue value, InstantiationContext context, int maxDepth) {
if (value == null)
return null;
ICPPEvaluation evaluation = value.getEvaluation();
if (evaluation == null)
return value;
ICPPEvaluation instantiated = evaluation.instantiate(tpMap, packOffset, within, maxdepth, point);
ICPPEvaluation instantiated = evaluation.instantiate(context, maxDepth);
if (instantiated == evaluation)
return value;
return instantiated.getValue(point);
return instantiated.getValue(context.getPoint());
}
public static boolean containsParameterPack(IType type) {
@ -1120,7 +1128,7 @@ public class CPPTemplates {
if (type instanceof ICPPTemplateParameter) {
return determinePackSize((ICPPTemplateParameter) type, tpMap);
}
if (type instanceof TypeOfDependentExpression) {
return ((TypeOfDependentExpression) type).getEvaluation().determinePackSize(tpMap);
}
@ -1202,12 +1210,12 @@ public class CPPTemplates {
/**
* Instantiates types contained in an array.
*
* @param types an array of types
* @param tpMap template argument map
* @param context the template instantiation context
* @return an array containing instantiated types.
*/
public static IType[] instantiateTypes(IType[] types, ICPPTemplateParameterMap tpMap,
int packOffset, ICPPTypeSpecialization within, IASTNode point) {
public static IType[] instantiateTypes(IType[] types, InstantiationContext context) {
if (types == null)
return null;
@ -1219,9 +1227,9 @@ public class CPPTemplates {
IType newType;
if (origType instanceof ICPPParameterPackType) {
IType innerType= ((ICPPParameterPackType) origType).getType();
int packSize= determinePackSize(innerType, tpMap);
int packSize= determinePackSize(innerType, context.getParameterMap());
if (packSize == PACK_SIZE_FAIL || packSize == PACK_SIZE_NOT_FOUND) {
newType= new ProblemBinding(point, IProblemBinding.SEMANTIC_INVALID_TYPE,
newType= new ProblemBinding(context.getPoint(), IProblemBinding.SEMANTIC_INVALID_TYPE,
types[i] instanceof IBinding ? ((IBinding) types[i]).getNameCharArray() : null);
} else if (packSize == PACK_SIZE_DEFER) {
newType= origType;
@ -1229,13 +1237,16 @@ public class CPPTemplates {
IType[] newResult= new IType[result.length + packSize - 1];
System.arraycopy(result, 0, newResult, 0, j);
result= newResult;
int oldPackOffset = context.getPackOffset();
for (int k= 0; k < packSize; k++) {
result[j++]= instantiateType(innerType, tpMap, k, within, point);
context.setPackOffset(k);
result[j++]= instantiateType(innerType, context);
}
context.setPackOffset(oldPackOffset);
continue;
}
} else {
newType = instantiateType(origType, tpMap, packOffset, within, point);
newType = instantiateType(origType, context);
}
if (result != types) {
result[j++]= newType;
@ -1259,9 +1270,7 @@ public class CPPTemplates {
* arguments.
*/
public static ICPPTemplateArgument[] instantiateArguments(ICPPTemplateArgument[] args,
ICPPTemplateParameterMap tpMap, int packOffset, ICPPTypeSpecialization within,
IASTNode point, boolean strict)
throws DOMException {
InstantiationContext context, boolean strict) throws DOMException {
// Don't create a new array until it's really needed.
ICPPTemplateArgument[] result = args;
int resultShift= 0;
@ -1270,17 +1279,20 @@ public class CPPTemplates {
ICPPTemplateArgument newArg;
if (origArg.isPackExpansion()) {
ICPPTemplateArgument pattern= origArg.getExpansionPattern();
int packSize= determinePackSize(pattern, tpMap);
int packSize= determinePackSize(pattern, context.getParameterMap());
if (packSize == PACK_SIZE_FAIL || packSize == PACK_SIZE_NOT_FOUND) {
throw new DOMException(new ProblemBinding(point, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, null));
throw new DOMException(new ProblemBinding(context.getPoint(),
IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, null));
} else if (packSize == PACK_SIZE_DEFER) {
newArg= origArg;
} else {
int shift = packSize - 1;
ICPPTemplateArgument[] newResult= new ICPPTemplateArgument[args.length + resultShift + shift];
System.arraycopy(result, 0, newResult, 0, i + resultShift);
int oldPackOffset = context.getPackOffset();
for (int j= 0; j < packSize; j++) {
newArg = instantiateArgument(pattern, tpMap, j, within, point);
context.setPackOffset(j);
newArg = instantiateArgument(pattern, context);
if (!isValidArgument(newArg)) {
if (strict)
return null;
@ -1291,12 +1303,13 @@ public class CPPTemplates {
}
newResult[i + resultShift + j]= newArg;
}
context.setPackOffset(oldPackOffset);
result= newResult;
resultShift += shift;
continue;
}
} else {
newArg = instantiateArgument(origArg, tpMap, packOffset, within, point);
newArg = instantiateArgument(origArg, context);
if (!isValidArgument(newArg)) {
if (strict)
return null;
@ -1319,35 +1332,34 @@ public class CPPTemplates {
}
/**
* Instantiates an argument
* Instantiates a template argument.
*/
static ICPPTemplateArgument instantiateArgument(ICPPTemplateArgument arg,
ICPPTemplateParameterMap tpMap, int packOffset, ICPPTypeSpecialization within, IASTNode point) {
static ICPPTemplateArgument instantiateArgument(ICPPTemplateArgument arg, InstantiationContext context) {
if (arg == null)
return null;
if (arg.isNonTypeValue()) {
final ICPPEvaluation eval = arg.getNonTypeEvaluation();
final ICPPEvaluation newEval= eval.instantiate(tpMap, packOffset, within, Value.MAX_RECURSION_DEPTH, point);
final ICPPEvaluation newEval= eval.instantiate(context, Value.MAX_RECURSION_DEPTH);
if (eval == newEval)
return arg;
return new CPPTemplateNonTypeArgument(newEval, point);
return new CPPTemplateNonTypeArgument(newEval, context.getPoint());
}
final IType orig= arg.getTypeValue();
final IType inst= instantiateType(orig, tpMap, packOffset, within, point);
final IType inst= instantiateType(orig, context);
if (orig == inst)
return arg;
return new CPPTemplateTypeArgument(inst);
}
private static CPPTemplateParameterMap instantiateArgumentMap(ICPPTemplateParameterMap orig, ICPPTemplateParameterMap tpMap,
int packOffset, ICPPTypeSpecialization within, IASTNode point) {
private static CPPTemplateParameterMap instantiateArgumentMap(ICPPTemplateParameterMap orig,
InstantiationContext context) {
final Integer[] positions = orig.getAllParameterPositions();
CPPTemplateParameterMap newMap= new CPPTemplateParameterMap(positions.length);
for (Integer key : positions) {
ICPPTemplateArgument arg = orig.getArgument(key);
if (arg != null) {
ICPPTemplateArgument newArg = instantiateArgument(arg, tpMap, packOffset, within, point);
ICPPTemplateArgument newArg = instantiateArgument(arg, context);
if (!isValidArgument(newArg))
newArg = arg;
newMap.put(key, newArg);
@ -1355,7 +1367,7 @@ public class CPPTemplates {
ICPPTemplateArgument[] args = orig.getPackExpansion(key);
if (args != null) {
try {
newMap.put(key, instantiateArguments(args, tpMap, packOffset, within, point, false));
newMap.put(key, instantiateArguments(args, context, false));
} catch (DOMException e) {
newMap.put(key, args);
}
@ -1369,10 +1381,9 @@ public class CPPTemplates {
* Instantiates the given type with the provided map and packОffset.
* The context is used to replace templates with their specialization, where appropriate.
*/
public static IType instantiateType(IType type, ICPPTemplateParameterMap tpMap, int packOffset,
ICPPTypeSpecialization within, IASTNode point) {
public static IType instantiateType(IType type, InstantiationContext context) {
try {
if (tpMap == null)
if (context.getParameterMap() == null)
return type;
if (type instanceof ICPPFunctionType) {
@ -1380,9 +1391,9 @@ public class CPPTemplates {
IType ret = null;
IType[] params = null;
final IType r = ft.getReturnType();
ret = instantiateType(r, tpMap, packOffset, within, point);
ret = instantiateType(r, context);
IType[] ps = ft.getParameterTypes();
params = instantiateTypes(ps, tpMap, packOffset, within, point);
params = instantiateTypes(ps, context);
if (ret == r && params == ps) {
return type;
}
@ -1398,28 +1409,26 @@ public class CPPTemplates {
}
if (type instanceof ICPPTemplateParameter) {
return resolveTemplateTypeParameter((ICPPTemplateParameter) type, tpMap, packOffset, point);
return resolveTemplateTypeParameter((ICPPTemplateParameter) type, context);
}
if (type instanceof ICPPUnknownBinding) {
if (type instanceof TypeOfDependentExpression) {
ICPPEvaluation eval = ((TypeOfDependentExpression) type).getEvaluation();
ICPPEvaluation instantiated = eval.instantiate(tpMap, packOffset, within,
Value.MAX_RECURSION_DEPTH, point);
ICPPEvaluation instantiated = eval.instantiate(context, Value.MAX_RECURSION_DEPTH);
if (instantiated != eval)
return instantiated.getType(point);
return instantiated.getType(context.getPoint());
} else {
IBinding binding= resolveUnknown((ICPPUnknownBinding) type, tpMap, packOffset,
within, point);
IBinding binding= resolveUnknown((ICPPUnknownBinding) type, context);
if (binding instanceof IType)
return (IType) binding;
return type;
}
}
if (type instanceof TypeOfUnknownMember) {
IBinding binding = resolveUnknown(((TypeOfUnknownMember) type).getUnknownMember(), tpMap, packOffset, within, point);
IBinding binding = resolveUnknown(((TypeOfUnknownMember) type).getUnknownMember(), context);
if (binding instanceof IType) {
return (IType) binding;
} else if (binding instanceof IVariable) {
@ -1430,9 +1439,9 @@ public class CPPTemplates {
return type;
}
if (within != null && type instanceof IBinding) {
if (context.getContextTypeSpecialization() != null && type instanceof IBinding) {
IType unwound= getNestedType(type, TDEF);
ICPPClassSpecialization withinClass = getContextClassSpecialization(within);
ICPPClassSpecialization withinClass = context.getContextClassSpecialization();
if (unwound instanceof ICPPClassType && unwound.isSameType(withinClass.getSpecializedBinding())) {
// Convert (partial) class-templates (specializations) to the more specialized
// version.
@ -1449,11 +1458,11 @@ public class CPPTemplates {
// owner of another binding, to the more specialized version.
newOwner= withinClass;
} else {
newOwner= instantiateType(ownerAsType, tpMap, packOffset, within, point);
newOwner= instantiateType(ownerAsType, context);
}
if (newOwner != owner && newOwner instanceof ICPPClassSpecialization) {
return (IType) ((ICPPClassSpecialization) newOwner).specializeMember(typeAsBinding, point);
return (IType) ((ICPPClassSpecialization) newOwner).specializeMember(typeAsBinding, context.getPoint());
}
}
@ -1463,11 +1472,10 @@ public class CPPTemplates {
final IBinding origClass = classInstance.getSpecializedBinding();
if (origClass instanceof ICPPClassType) {
ICPPTemplateArgument[] args = classInstance.getTemplateArguments();
ICPPTemplateArgument[] newArgs = instantiateArguments(args, tpMap, packOffset,
within, point, false);
ICPPTemplateArgument[] newArgs = instantiateArguments(args, context, false);
if (newArgs != args) {
CPPTemplateParameterMap tparMap = instantiateArgumentMap(classInstance.getTemplateParameterMap(),
tpMap, packOffset, within, point);
CPPTemplateParameterMap tparMap =
instantiateArgumentMap(classInstance.getTemplateParameterMap(), context);
return new CPPClassInstance((ICPPClassType) origClass, classInstance.getOwner(), tparMap, args);
}
}
@ -1477,11 +1485,11 @@ public class CPPTemplates {
if (type instanceof ITypeContainer) {
final ITypeContainer typeContainer = (ITypeContainer) type;
IType nestedType = typeContainer.getType();
IType newNestedType = instantiateType(nestedType, tpMap, packOffset, within, point);
IType newNestedType = instantiateType(nestedType, context);
if (typeContainer instanceof ICPPPointerToMemberType) {
ICPPPointerToMemberType ptm = (ICPPPointerToMemberType) typeContainer;
IType memberOfClass = ptm.getMemberOfClass();
IType newMemberOfClass = instantiateType(memberOfClass, tpMap, packOffset, within, point);
IType newMemberOfClass = instantiateType(memberOfClass, context);
IType classType = SemanticUtil.getNestedType(newMemberOfClass, CVTYPE | TDEF);
if (!(classType instanceof ICPPClassType || classType instanceof UniqueType
|| classType instanceof ICPPUnknownBinding)) {
@ -1497,7 +1505,7 @@ public class CPPTemplates {
IArrayType at= (IArrayType) typeContainer;
IValue asize= at.getSize();
if (asize != null) {
IValue newSize= instantiateValue(asize, tpMap, packOffset, within, Value.MAX_RECURSION_DEPTH, point);
IValue newSize= instantiateValue(asize, context, Value.MAX_RECURSION_DEPTH);
if (newSize != asize) {
return new CPPArrayType(newNestedType, newSize);
}
@ -1510,8 +1518,8 @@ public class CPPTemplates {
}
if (type instanceof ICPPUnaryTypeTransformation) {
ICPPUnaryTypeTransformation typeTransformation = (ICPPUnaryTypeTransformation) type;
IType operand = instantiateType(typeTransformation.getOperand(), tpMap, packOffset, within, point);
ICPPUnaryTypeTransformation typeTransformation = (ICPPUnaryTypeTransformation) type;
IType operand = instantiateType(typeTransformation.getOperand(), context);
switch (typeTransformation.getOperator()) {
case underlying_type: return TypeTraits.underlyingType(operand);
default: return null; // shouldn't happen
@ -1525,9 +1533,9 @@ public class CPPTemplates {
}
/**
* Specialize a template parameter of a nested template by subtituting values for the template
* parameters of enclosing templates into the template parameter's default value and, in the
* case of a non-type template parameter, type.
* Specialize a template parameter of a nested template by substituting values for the template
* parameters of enclosing templates into the template parameter's default value and, in the case
* of a non-type template parameter, type.
*
* @param owner the specialization of the nested template. This will be the owner of the
* specialized template parameter.
@ -1542,17 +1550,18 @@ public class CPPTemplates {
if (specialized == null)
return null;
ICPPTemplateParameterMap tpMap = owner.getTemplateParameterMap();
ICPPTemplateArgument defaultValue = instantiateArgument(specialized.getDefaultValue(), tpMap, 0, within, point);
InstantiationContext context = new InstantiationContext(tpMap, 0, within, point);
ICPPTemplateArgument defaultValue = instantiateArgument(specialized.getDefaultValue(), context);
if (specialized instanceof ICPPTemplateNonTypeParameter) {
ICPPTemplateNonTypeParameter spec = (ICPPTemplateNonTypeParameter) specialized;
IType type = instantiateType(spec.getType(), tpMap, 0, within, point);
IType type = instantiateType(spec.getType(), context);
return new CPPTemplateNonTypeParameterSpecialization(owner, scope, spec, defaultValue, type);
} else if (specialized instanceof ICPPTemplateTypeParameter) {
return new CPPTemplateTypeParameterSpecialization(owner, scope, (ICPPTemplateTypeParameter) specialized,
defaultValue);
return new CPPTemplateTypeParameterSpecialization(owner, scope,
(ICPPTemplateTypeParameter) specialized, defaultValue);
} else if (specialized instanceof ICPPTemplateTemplateParameter) {
return new CPPTemplateTemplateParameterSpecialization(owner, scope, (ICPPTemplateTemplateParameter) specialized,
defaultValue);
return new CPPTemplateTemplateParameterSpecialization(owner, scope,
(ICPPTemplateTemplateParameter) specialized, defaultValue);
}
return null;
}
@ -1569,31 +1578,32 @@ public class CPPTemplates {
return result;
}
public static IBinding instantiateBinding(IBinding binding, ICPPTemplateParameterMap tpMap, int packOffset,
ICPPTypeSpecialization within, int maxdepth, IASTNode point) throws DOMException {
public static IBinding instantiateBinding(IBinding binding, InstantiationContext context, int maxDepth)
throws DOMException {
if (binding instanceof ICPPClassTemplate) {
binding = createDeferredInstance((ICPPClassTemplate) binding);
}
if (binding instanceof ICPPUnknownBinding) {
return resolveUnknown((ICPPUnknownBinding) binding, tpMap, packOffset, within, point);
return resolveUnknown((ICPPUnknownBinding) binding, context);
} else if (binding instanceof ICPPMethod
|| binding instanceof ICPPField
|| binding instanceof ICPPEnumeration
|| binding instanceof ICPPClassType) {
IBinding owner = binding.getOwner();
if (!(owner instanceof ICPPSpecialization)) {
owner = instantiateBinding(owner, tpMap, packOffset, within, maxdepth, point);
owner = instantiateBinding(owner, context, maxDepth);
}
if (owner instanceof ICPPClassSpecialization) {
return ((ICPPClassSpecialization) owner).specializeMember(binding, point);
return ((ICPPClassSpecialization) owner).specializeMember(binding, context.getPoint());
}
} else if (binding instanceof IEnumerator) {
IBinding owner = binding.getOwner();
ICPPTypeSpecialization within = context.getContextTypeSpecialization();
if (within instanceof ICPPEnumerationSpecialization && within.getSpecializedBinding().equals(owner)) {
owner = within;
} else if (!(owner instanceof ICPPSpecialization)) {
owner = instantiateBinding(owner, tpMap, packOffset, within, maxdepth, point);
owner = instantiateBinding(owner, context, maxDepth);
}
if (owner instanceof ICPPEnumerationSpecialization) {
return ((ICPPEnumerationSpecialization) owner).specializeEnumerator((IEnumerator) binding);
@ -1605,17 +1615,15 @@ public class CPPTemplates {
// return that when appropriate?
ICPPFunctionInstance origInstance = (ICPPFunctionInstance) binding;
ICPPTemplateArgument[] origArgs = origInstance.getTemplateArguments();
ICPPTemplateArgument[] newArgs = instantiateArguments(origArgs, tpMap, packOffset, within, point, false);
ICPPTemplateArgument[] newArgs = instantiateArguments(origArgs, context, false);
if (origArgs != newArgs) {
CPPTemplateParameterMap newMap = instantiateArgumentMap(origInstance.getTemplateParameterMap(),
tpMap, packOffset, within, point);
IType newType = instantiateType(origInstance.getType(), tpMap, packOffset, within, point);
IType[] newExceptionSpecs = instantiateTypes(origInstance.getExceptionSpecification(),
tpMap, packOffset, within, point);
CPPFunctionInstance result = new CPPFunctionInstance((ICPPFunction) origInstance.getTemplateDefinition(),
CPPTemplateParameterMap newMap =
instantiateArgumentMap(origInstance.getTemplateParameterMap(), context);
IType newType = instantiateType(origInstance.getType(), context);
IType[] newExceptionSpecs = instantiateTypes(origInstance.getExceptionSpecification(), context);
CPPFunctionInstance result = new CPPFunctionInstance((ICPPFunction) origInstance.getTemplateDefinition(),
origInstance.getOwner(), newMap, newArgs, (ICPPFunctionType) newType, newExceptionSpecs);
result.setParameters(specializeParameters(origInstance.getParameters(), result, tpMap, packOffset,
within, maxdepth, point));
result.setParameters(specializeParameters(origInstance.getParameters(), result, context, maxDepth));
return result;
}
}
@ -1623,21 +1631,21 @@ public class CPPTemplates {
}
public static IType resolveTemplateTypeParameter(final ICPPTemplateParameter tpar,
ICPPTemplateParameterMap tpMap, int packOffset, IASTNode point) {
InstantiationContext context) {
ICPPTemplateArgument arg= null;
if (tpar.isParameterPack()) {
if (packOffset >= 0) {
ICPPTemplateArgument[] args = tpMap.getPackExpansion(tpar);
if (context.hasPackOffset()) {
ICPPTemplateArgument[] args = context.getParameterMap().getPackExpansion(tpar);
if (args != null) {
if (packOffset >= args.length) {
return new ProblemBinding(point, IProblemBinding.SEMANTIC_INVALID_TYPE,
if (context.getPackOffset() >= args.length) {
return new ProblemBinding(context.getPoint(), IProblemBinding.SEMANTIC_INVALID_TYPE,
tpar.getNameCharArray());
}
arg= args[packOffset];
arg= args[context.getPackOffset()];
}
}
} else {
arg= tpMap.getArgument(tpar);
arg= context.getParameterMap().getArgument(tpar);
}
if (arg != null) {
@ -2138,7 +2146,7 @@ public class CPPTemplates {
// the process of instantiation can increase the required argument
// count by expanding parameter packs. If arguments are provided
// for a parameter pack explicitly, it's possible for deduction to
// succeed without having enough function arguments to match a
// succeed without having enough function arguments to match a
// corresponding function parameter pack - so we check again.
if (fnArgs.size() >= f.getRequiredArgumentCount())
return f;
@ -2441,7 +2449,7 @@ public class CPPTemplates {
private static boolean checkInstantiationOfArguments(ICPPTemplateArgument[] args,
CPPTemplateParameterMap tpMap, IASTNode point) throws DOMException {
return instantiateArguments(args, tpMap, -1, null, point, true) != null;
return instantiateArguments(args, new InstantiationContext(tpMap, point), true) != null;
}
/**
@ -2501,7 +2509,8 @@ public class CPPTemplates {
transferMap.put(param, arg);
}
}
final ICPPTemplateArgument[] transferredArgs1 = instantiateArguments(targs1, transferMap, -1, null, point, false);
final ICPPTemplateArgument[] transferredArgs1 =
instantiateArguments(targs1, new InstantiationContext(transferMap, point), false);
// Deduce arguments for specialization 2
final CPPTemplateParameterMap deductionMap= new CPPTemplateParameterMap(2);
@ -2560,7 +2569,7 @@ public class CPPTemplates {
pType= ((ICPPParameterPackType) pType).getType();
}
if (map != null && pType != null) {
pType= instantiateType(pType, map, -1, null, point);
pType= instantiateType(pType, new InstantiationContext(map, point));
}
if (argType instanceof ICPPParameterPackType) {
@ -2789,43 +2798,42 @@ public class CPPTemplates {
/**
* Attempts to (partially) resolve an unknown binding with the given arguments.
*/
public static IBinding resolveUnknown(ICPPUnknownBinding unknown, ICPPTemplateParameterMap tpMap,
int packOffset, ICPPTypeSpecialization within, IASTNode point) throws DOMException {
public static IBinding resolveUnknown(ICPPUnknownBinding unknown, InstantiationContext context)
throws DOMException {
if (unknown instanceof ICPPDeferredClassInstance) {
return resolveDeferredClassInstance((ICPPDeferredClassInstance) unknown, tpMap, packOffset,
within, point);
return resolveDeferredClassInstance((ICPPDeferredClassInstance) unknown, context);
}
if (unknown instanceof ICPPUnknownMember) {
return resolveUnknownMember((ICPPUnknownMember) unknown, tpMap, packOffset, within, point);
return resolveUnknownMember((ICPPUnknownMember) unknown, context);
}
if (unknown instanceof ICPPTemplateParameter && unknown instanceof IType) {
IType type= resolveTemplateTypeParameter((ICPPTemplateParameter) unknown, tpMap, packOffset, point);
IType type= resolveTemplateTypeParameter((ICPPTemplateParameter) unknown, context);
if (type instanceof IBinding)
return (IBinding) type;
}
if (unknown instanceof TypeOfDependentExpression) {
IType type= instantiateType((IType) unknown, tpMap, packOffset, within, point);
IType type= instantiateType((IType) unknown, context);
if (type instanceof IBinding)
return (IBinding) type;
}
return unknown;
}
private static IBinding resolveUnknownMember(ICPPUnknownMember unknown, ICPPTemplateParameterMap tpMap,
int packOffset, ICPPTypeSpecialization within, IASTNode point) throws DOMException {
private static IBinding resolveUnknownMember(ICPPUnknownMember unknown, InstantiationContext context)
throws DOMException {
final IType ot0= unknown.getOwnerType();
if (ot0 == null)
return unknown;
IBinding result = unknown;
IType ot1 = instantiateType(ot0, tpMap, packOffset, within, point);
IType ot1 = instantiateType(ot0, context);
if (ot1 != null) {
ot1 = SemanticUtil.getUltimateType(ot1, false);
if (ot1 instanceof ICPPUnknownType) {
if (unknown instanceof ICPPUnknownMemberClassInstance) {
ICPPUnknownMemberClassInstance ucli= (ICPPUnknownMemberClassInstance) unknown;
ICPPTemplateArgument[] args0 = ucli.getArguments();
ICPPTemplateArgument[] args1 = instantiateArguments(args0, tpMap, packOffset, within, point, false);
ICPPTemplateArgument[] args1 = instantiateArguments(args0, context, false);
if (args0 != args1 || !ot1.isSameType(ot0)) {
args1= SemanticUtil.getSimplifiedArguments(args1);
result= new CPPUnknownClassInstance(ot1, ucli.getNameCharArray(), args1);
@ -2840,19 +2848,21 @@ public class CPPTemplates {
} else if (ot1 instanceof ICPPClassType) {
IScope s = ((ICPPClassType) ot1).getCompositeScope();
if (s != null) {
result= CPPSemantics.resolveUnknownName(s, unknown, point);
result= CPPSemantics.resolveUnknownName(s, unknown, context.getPoint());
if (unknown instanceof ICPPUnknownMemberClassInstance && result instanceof ICPPTemplateDefinition) {
ICPPTemplateArgument[] args1 = instantiateArguments(
((ICPPUnknownMemberClassInstance) unknown).getArguments(), tpMap, packOffset, within, point, false);
((ICPPUnknownMemberClassInstance) unknown).getArguments(), context, false);
if (result instanceof ICPPClassTemplate) {
result = instantiate((ICPPClassTemplate) result, args1, point);
result = instantiate((ICPPClassTemplate) result, args1, context.getPoint());
} else if (result instanceof ICPPAliasTemplate) {
result = createSpecialization(getSpecializationContext(within), result, point);
result = createSpecialization(context.getContextClassSpecialization(), result,
context.getPoint());
}
}
}
} else if (ot1 != ot0) {
return new ProblemBinding(new CPPASTName(unknown.getNameCharArray()), point, IProblemBinding.SEMANTIC_BAD_SCOPE);
return new ProblemBinding(new CPPASTName(unknown.getNameCharArray()), context.getPoint(),
IProblemBinding.SEMANTIC_BAD_SCOPE);
}
}
@ -2860,27 +2870,27 @@ public class CPPTemplates {
}
private static IBinding resolveDeferredClassInstance(ICPPDeferredClassInstance dci,
ICPPTemplateParameterMap tpMap, int packOffset, ICPPTypeSpecialization within, IASTNode point) {
InstantiationContext context) {
ICPPClassTemplate classTemplate = dci.getClassTemplate();
ICPPTemplateArgument[] arguments = dci.getTemplateArguments();
ICPPTemplateArgument[] newArgs;
try {
newArgs = instantiateArguments(arguments, tpMap, packOffset, within, point, true);
newArgs = instantiateArguments(arguments, context, true);
} catch (DOMException e) {
return e.getProblem();
}
if (newArgs == null)
return createProblem(classTemplate, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, point);
return createProblem(classTemplate, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, context.getPoint());
boolean changed= arguments != newArgs;
IType classTemplateSpecialization= instantiateType(classTemplate, tpMap, packOffset, within, point);
IType classTemplateSpecialization= instantiateType(classTemplate, context);
if (classTemplateSpecialization != classTemplate && classTemplateSpecialization instanceof ICPPClassTemplate) {
classTemplate= (ICPPClassTemplate) classTemplateSpecialization;
changed= true;
}
if (changed) {
IBinding inst= instantiate(classTemplate, newArgs, point);
IBinding inst= instantiate(classTemplate, newArgs, context.getPoint());
if (inst != null)
return inst;
}
@ -2906,7 +2916,7 @@ public class CPPTemplates {
*
* @param template the template definition
* @param arguments the template arguments; arguments may be modified by this method due to type
* conversion performed for non-type arguments
* conversion performed for non-type arguments
* @param point the point of instantiation
* @return the created template parameter map, or {@code null} if the arguments are invalid
*/

View file

@ -56,7 +56,6 @@ 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.ICPPPointerToMemberType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization;
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;
@ -65,6 +64,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArithmeticConversion;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext;
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
import org.eclipse.core.runtime.CoreException;
@ -355,10 +355,9 @@ public class EvalBinary extends CPPDependentEvaluation {
}
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPTypeSpecialization within, int maxdepth, IASTNode point) {
ICPPEvaluation arg1 = fArg1.instantiate(tpMap, packOffset, within, maxdepth, point);
ICPPEvaluation arg2 = fArg2.instantiate(tpMap, packOffset, within, maxdepth, point);
public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) {
ICPPEvaluation arg1 = fArg1.instantiate(context, maxDepth);
ICPPEvaluation arg2 = fArg2.instantiate(context, maxDepth);
if (arg1 == fArg1 && arg2 == fArg2)
return this;
return new EvalBinary(fOperator, arg1, arg2, getTemplateDefinition());

View file

@ -20,13 +20,13 @@ 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.core.dom.ast.cpp.ICPPTypeSpecialization;
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.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
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;
/**
@ -132,10 +132,9 @@ public class EvalBinaryTypeId extends CPPDependentEvaluation {
}
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPTypeSpecialization within, int maxdepth, IASTNode point) {
IType type1 = CPPTemplates.instantiateType(fType1, tpMap, packOffset, within, point);
IType type2 = CPPTemplates.instantiateType(fType2, tpMap, packOffset, within, point);
public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) {
IType type1 = CPPTemplates.instantiateType(fType1, context);
IType type2 = CPPTemplates.instantiateType(fType2, context);
if (type1 == fType1 && type2 == fType2)
return this;
return new EvalBinaryTypeId(fOperator, type1, type2, getTemplateDefinition());

View file

@ -37,7 +37,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
@ -47,6 +46,7 @@ import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPParameter;
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 class EvalBinding extends CPPDependentEvaluation {
@ -384,12 +384,11 @@ public class EvalBinding extends CPPDependentEvaluation {
}
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPTypeSpecialization within, int maxdepth, IASTNode point) {
public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) {
IBinding origBinding = getBinding();
if (origBinding instanceof ICPPTemplateNonTypeParameter) {
if (tpMap != null) {
ICPPTemplateArgument argument = tpMap.getArgument((ICPPTemplateNonTypeParameter) origBinding, packOffset);
if (context != null) {
ICPPTemplateArgument argument = context.getArgument((ICPPTemplateNonTypeParameter) origBinding);
if (argument != null && argument.isNonTypeValue()) {
return argument.getNonTypeEvaluation();
}
@ -397,15 +396,15 @@ public class EvalBinding extends CPPDependentEvaluation {
} else if (origBinding instanceof ICPPParameter) {
ICPPParameter parameter = (ICPPParameter) origBinding;
IType origType = parameter.getType();
if (origType instanceof ICPPParameterPackType && packOffset != -1) {
if (origType instanceof ICPPParameterPackType && context.hasPackOffset()) {
origType = ((ICPPParameterPackType) origType).getType();
}
IType instantiatedType = CPPTemplates.instantiateType(origType, tpMap, packOffset, within, point);
IType instantiatedType = CPPTemplates.instantiateType(origType, context);
if (origType != instantiatedType) {
return new EvalFixed(instantiatedType, ValueCategory.LVALUE, Value.create(this));
}
} else {
IBinding instantiatedBinding = instantiateBinding(origBinding, tpMap, packOffset, within, maxdepth, point);
IBinding instantiatedBinding = instantiateBinding(origBinding, context, maxDepth);
if (instantiatedBinding != origBinding)
return new EvalBinding(instantiatedBinding, null, getTemplateDefinition());
}

View file

@ -22,11 +22,11 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization;
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.Value;
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;
public class EvalComma extends CPPDependentEvaluation {
@ -184,11 +184,10 @@ public class EvalComma extends CPPDependentEvaluation {
}
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPTypeSpecialization within, int maxdepth, IASTNode point) {
public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) {
ICPPEvaluation[] args = fArguments;
for (int i = 0; i < fArguments.length; i++) {
ICPPEvaluation arg = fArguments[i].instantiate(tpMap, packOffset, within, maxdepth, point);
ICPPEvaluation arg = fArguments[i].instantiate(context, maxDepth);
if (arg != fArguments[i]) {
if (args == fArguments) {
args = new ICPPEvaluation[fArguments.length];

View file

@ -19,10 +19,10 @@ 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.core.dom.ast.cpp.ICPPTypeSpecialization;
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.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext;
import org.eclipse.core.runtime.CoreException;
/**
@ -99,9 +99,8 @@ public class EvalCompound extends CPPDependentEvaluation {
}
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPTypeSpecialization within, int maxdepth, IASTNode point) {
ICPPEvaluation delegate = fDelegate.instantiate(tpMap, packOffset, within, maxdepth, point);
public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) {
ICPPEvaluation delegate = fDelegate.instantiate(context, maxDepth);
if (delegate == fDelegate)
return this;
return new EvalCompound(delegate, getTemplateDefinition());

View file

@ -31,7 +31,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
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.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization;
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;
@ -40,6 +39,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArithmeticConversion;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.Context;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank;
@ -341,12 +341,11 @@ public class EvalConditional extends CPPDependentEvaluation {
}
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPTypeSpecialization within, int maxdepth, IASTNode point) {
ICPPEvaluation condition = fCondition.instantiate(tpMap, packOffset, within, maxdepth, point);
public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) {
ICPPEvaluation condition = fCondition.instantiate(context, maxDepth);
ICPPEvaluation positive = fPositive == null ?
null : fPositive.instantiate(tpMap, packOffset, within, maxdepth, point);
ICPPEvaluation negative = fNegative.instantiate(tpMap, packOffset, within, maxdepth, point);
null : fPositive.instantiate(context, maxDepth);
ICPPEvaluation negative = fNegative.instantiate(context, maxDepth);
if (condition == fCondition && positive == fPositive && negative == fNegative)
return this;
return new EvalConditional(condition, positive, negative, fPositiveThrows, fNegativeThrows, getTemplateDefinition());

View file

@ -21,13 +21,13 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization;
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.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
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;
/**
@ -173,10 +173,9 @@ public class EvalFixed extends CPPEvaluation {
}
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPTypeSpecialization within, int maxdepth, IASTNode point) {
IType type = CPPTemplates.instantiateType(fType, tpMap, packOffset, within, point);
IValue value = CPPTemplates.instantiateValue(fValue, tpMap, packOffset, within, maxdepth, point);
public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) {
IType type = CPPTemplates.instantiateType(fType, context);
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),

View file

@ -32,13 +32,13 @@ 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.ICPPParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization;
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.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext;
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics.LookupMode;
import org.eclipse.core.runtime.CoreException;
@ -190,16 +190,14 @@ public class EvalFunctionCall extends CPPDependentEvaluation {
}
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPTypeSpecialization within, int maxdepth, IASTNode point) {
ICPPEvaluation[] args = instantiateCommaSeparatedSubexpressions(fArguments, tpMap,
packOffset, within, maxdepth, point);
public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) {
ICPPEvaluation[] args = instantiateCommaSeparatedSubexpressions(fArguments, context, maxDepth);
if (args == fArguments)
return this;
if (args[0] instanceof EvalFunctionSet && getOverload(point) == null) {
if (args[0] instanceof EvalFunctionSet && getOverload(context.getPoint()) == null) {
// Resolve the function using the parameters of the function call.
args[0] = ((EvalFunctionSet) args[0]).resolveFunction(Arrays.copyOfRange(args, 1, args.length), point);
args[0] = ((EvalFunctionSet) args[0]).resolveFunction(Arrays.copyOfRange(args, 1, args.length), context.getPoint());
}
return new EvalFunctionCall(args, getTemplateDefinition());
}

View file

@ -29,7 +29,6 @@ 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.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
@ -37,6 +36,7 @@ import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
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;
/**
@ -232,25 +232,23 @@ public class EvalFunctionSet extends CPPDependentEvaluation {
}
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPTypeSpecialization within, int maxdepth, IASTNode point) {
public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) {
if (fFunctionSet == null)
return this;
ICPPTemplateArgument[] originalArguments = fFunctionSet.getTemplateArguments();
ICPPTemplateArgument[] arguments = originalArguments;
if (originalArguments != null)
arguments = instantiateArguments(originalArguments, tpMap, packOffset, within, point);
arguments = instantiateArguments(originalArguments, context);
IBinding originalOwner = fFunctionSet.getOwner();
IBinding owner = originalOwner;
if (owner instanceof ICPPUnknownBinding) {
owner = resolveUnknown((ICPPUnknownBinding) owner, tpMap, packOffset, within, point);
owner = resolveUnknown((ICPPUnknownBinding) owner, context);
} else if (owner instanceof ICPPClassTemplate) {
owner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) owner),
tpMap, packOffset, within, point);
owner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) owner), context);
} else if (owner instanceof IType) {
IType type = CPPTemplates.instantiateType((IType) owner, tpMap, packOffset, within, point);
IType type = CPPTemplates.instantiateType((IType) owner, context);
if (type instanceof IBinding)
owner = (IBinding) type;
}
@ -260,7 +258,7 @@ public class EvalFunctionSet extends CPPDependentEvaluation {
functions = new ICPPFunction[originalFunctions.length];
for (int i = 0; i < originalFunctions.length; i++) {
functions[i] = (ICPPFunction) CPPTemplates.createSpecialization((ICPPClassSpecialization) owner,
originalFunctions[i], point);
originalFunctions[i], context.getPoint());
}
}
// No need to instantiate the implied object type. An EvalFunctioNSet should only be created

View file

@ -49,15 +49,16 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
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.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalEnumerator;
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 class EvalID extends CPPDependentEvaluation {
@ -339,24 +340,23 @@ public class EvalID extends CPPDependentEvaluation {
}
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPTypeSpecialization within, int maxdepth, IASTNode point) {
public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) {
ICPPTemplateArgument[] templateArgs = fTemplateArgs;
if (templateArgs != null) {
templateArgs = instantiateArguments(templateArgs, tpMap, packOffset, within, point);
templateArgs = instantiateArguments(templateArgs, context);
}
ICPPEvaluation fieldOwner = fFieldOwner;
if (fieldOwner != null) {
fieldOwner = fieldOwner.instantiate(tpMap, packOffset, within, maxdepth, point);
fieldOwner = fieldOwner.instantiate(context, maxDepth);
}
IBinding nameOwner = fNameOwner;
if (nameOwner instanceof ICPPClassTemplate) {
nameOwner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) nameOwner),
tpMap, packOffset, within, point);
ICPPDeferredClassInstance deferred = CPPTemplates.createDeferredInstance((ICPPClassTemplate) nameOwner);
nameOwner = resolveUnknown(deferred, context);
} else if (nameOwner instanceof IType) {
IType type = CPPTemplates.instantiateType((IType) nameOwner, tpMap, packOffset, within, point);
IType type = CPPTemplates.instantiateType((IType) nameOwner, context);
type = getNestedType(type, TDEF | REF | CVTYPE);
if (!(type instanceof IBinding))
return EvalFixed.INCOMPLETE;
@ -370,7 +370,7 @@ public class EvalID extends CPPDependentEvaluation {
return this;
if (nameOwner instanceof ICPPClassType) {
ICPPEvaluation eval = resolveName((ICPPClassType) nameOwner, templateArgs, null, point);
ICPPEvaluation eval = resolveName((ICPPClassType) nameOwner, templateArgs, null, context.getPoint());
if (eval != null)
return eval;
if (!CPPTemplates.isDependentType((ICPPClassType) nameOwner))
@ -378,7 +378,7 @@ public class EvalID extends CPPDependentEvaluation {
}
if (fieldOwner != null && !fieldOwner.isTypeDependent()) {
IType fieldOwnerType = fieldOwner.getType(point);
IType fieldOwnerType = fieldOwner.getType(context.getPoint());
if (fIsPointerDeref) {
fieldOwnerType = SemanticUtil.getSimplifiedType(fieldOwnerType);
if (fieldOwnerType instanceof IPointerType) {
@ -390,7 +390,8 @@ public class EvalID extends CPPDependentEvaluation {
IType fieldOwnerClassTypeCV = SemanticUtil.getNestedType(fieldOwnerType, TDEF | REF);
IType fieldOwnerClassType = SemanticUtil.getNestedType(fieldOwnerClassTypeCV, CVTYPE);
if (fieldOwnerClassType instanceof ICPPClassType) {
ICPPEvaluation eval = resolveName((ICPPClassType) fieldOwnerClassType, templateArgs, fieldOwnerClassTypeCV, point);
ICPPEvaluation eval = resolveName((ICPPClassType) fieldOwnerClassType, templateArgs,
fieldOwnerClassTypeCV, context.getPoint());
if (eval != null)
return eval;
}

View file

@ -19,11 +19,11 @@ 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.core.dom.ast.cpp.ICPPTypeSpecialization;
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.Value;
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;
/**
@ -108,10 +108,8 @@ public class EvalInitList extends CPPDependentEvaluation {
}
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPTypeSpecialization within, int maxdepth, IASTNode point) {
ICPPEvaluation[] clauses = instantiateCommaSeparatedSubexpressions(fClauses, tpMap,
packOffset, within, maxdepth, point);
public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) {
ICPPEvaluation[] clauses = instantiateCommaSeparatedSubexpressions(fClauses, context, maxDepth);
if (clauses == fClauses)
return this;
return new EvalInitList(clauses, getTemplateDefinition());

View file

@ -42,7 +42,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization;
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;
@ -50,6 +49,7 @@ import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknownScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext;
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics.LookupMode;
import org.eclipse.core.runtime.CoreException;
@ -342,16 +342,15 @@ public class EvalMemberAccess extends CPPDependentEvaluation {
}
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPTypeSpecialization within, int maxdepth, IASTNode point) {
IType ownerType = CPPTemplates.instantiateType(fOwnerType, tpMap, packOffset, within, point);
public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) {
IType ownerType = CPPTemplates.instantiateType(fOwnerType, context);
if (ownerType == fOwnerType)
return this;
IBinding member = fMember;
IType ownerClass = SemanticUtil.getNestedType(ownerType, ALLCVQ);
if (ownerClass instanceof ICPPClassSpecialization) {
member = CPPTemplates.createSpecialization((ICPPClassSpecialization) ownerClass, fMember, point);
member = CPPTemplates.createSpecialization((ICPPClassSpecialization) ownerClass, fMember, context.getPoint());
}
return new EvalMemberAccess(ownerType, fOwnerValueCategory, member, fIsPointerDeref, getTemplateDefinition());
}

View file

@ -16,13 +16,13 @@ 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.core.dom.ast.cpp.ICPPTypeSpecialization;
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.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPParameterPackType;
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;
/**
@ -94,10 +94,8 @@ public class EvalParameterPack extends CPPDependentEvaluation {
}
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPTypeSpecialization within, int maxdepth, IASTNode point) {
ICPPEvaluation expansionPattern = fExpansionPattern.instantiate(tpMap, packOffset, within,
maxdepth, point);
public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) {
ICPPEvaluation expansionPattern = fExpansionPattern.instantiate(context, maxDepth);
if (expansionPattern == fExpansionPattern)
return this;
return new EvalParameterPack(expansionPattern, getTemplateDefinition());

View file

@ -26,7 +26,6 @@ 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.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization;
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.Value;
@ -34,6 +33,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
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;
/**
@ -216,10 +216,9 @@ public class EvalTypeId extends CPPDependentEvaluation {
}
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPTypeSpecialization within, int maxdepth, IASTNode point) {
ICPPEvaluation[] args= instantiateCommaSeparatedSubexpressions(fArguments, tpMap, packOffset, within, maxdepth, point);
IType type = CPPTemplates.instantiateType(fInputType, tpMap, packOffset, within, point);
public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) {
ICPPEvaluation[] args= instantiateCommaSeparatedSubexpressions(fArguments, context, maxDepth);
IType type = CPPTemplates.instantiateType(fInputType, context);
if (args == fArguments && type == fInputType)
return this;
@ -230,7 +229,7 @@ public class EvalTypeId extends CPPDependentEvaluation {
if (simplifiedType instanceof ICPPClassType) {
// Check the constructor call and return EvalFixed.INCOMPLETE to indicate a substitution
// failure if the call cannot be resolved.
ICPPFunction constructor = result.getConstructor(point);
ICPPFunction constructor = result.getConstructor(context.getPoint());
if (constructor == null || constructor instanceof IProblemBinding || constructor.isDeleted()) {
return EvalFixed.INCOMPLETE;
}

View file

@ -51,7 +51,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
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.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization;
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;
@ -67,6 +66,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
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.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics.LookupMode;
import org.eclipse.core.runtime.CoreException;
@ -362,14 +362,12 @@ public class EvalUnary extends CPPDependentEvaluation {
}
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPTypeSpecialization within, int maxdepth, IASTNode point) {
ICPPEvaluation argument = fArgument.instantiate(tpMap, packOffset, within, maxdepth, point);
public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) {
ICPPEvaluation argument = fArgument.instantiate(context, maxDepth);
IBinding binding = fAddressOfQualifiedNameBinding;
if (binding instanceof ICPPUnknownBinding) {
try {
binding= CPPTemplates.resolveUnknown((ICPPUnknownBinding) binding, tpMap, packOffset,
within, point);
binding= CPPTemplates.resolveUnknown((ICPPUnknownBinding) binding, context);
} catch (DOMException e) {
}
}

View file

@ -44,13 +44,13 @@ 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.core.dom.ast.cpp.ICPPTypeSpecialization;
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.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
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;
public class EvalUnaryTypeID extends CPPDependentEvaluation {
@ -205,17 +205,17 @@ public class EvalUnaryTypeID extends CPPDependentEvaluation {
}
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPTypeSpecialization within, int maxdepth, IASTNode point) {
public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) {
if (fOperator == op_sizeofParameterPack) {
int packSize = determinePackSize(tpMap);
int packSize = determinePackSize(context.getParameterMap());
if (packSize == CPPTemplates.PACK_SIZE_FAIL || packSize == CPPTemplates.PACK_SIZE_NOT_FOUND) {
return EvalFixed.INCOMPLETE;
} else if (packSize != CPPTemplates.PACK_SIZE_DEFER) {
IASTNode point = context.getPoint();
return new EvalFixed(getType(point), getValueCategory(point), Value.create(packSize));
}
}
IType type = CPPTemplates.instantiateType(fOrigType, tpMap, packOffset, within, point);
IType type = CPPTemplates.instantiateType(fOrigType, context);
if (type == fOrigType)
return this;
return new EvalUnaryTypeID(fOperator, type, getTemplateDefinition());

View file

@ -72,6 +72,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
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.ICPPUnknownMember;
import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext;
/**
* Algorithms for deducing template arguments in various contexts.
@ -133,7 +134,7 @@ public class TemplateArgumentDeduction {
break;
}
par= CPPTemplates.instantiateType(par, map, -1, null, point);
par= CPPTemplates.instantiateType(par, new InstantiationContext(map, point));
if (!SemanticUtil.isValidType(par))
return false;
@ -202,7 +203,7 @@ public class TemplateArgumentDeduction {
ICPPTemplateArgument arg = deduct.fDeducedArgs.getArgument(tpar);
if (arg != null) {
IType type1 = ((ICPPTemplateNonTypeParameter) tpar).getType();
type1= CPPTemplates.instantiateType(type1, map, -1, null, point);
type1= CPPTemplates.instantiateType(type1, new InstantiationContext(map, point));
IType type2= arg.getTypeOfNonTypeValue();
// Template-argument deduced from an array bound may be of any integral
// type.
@ -319,13 +320,15 @@ public class TemplateArgumentDeduction {
* @throws DOMException
*/
static ICPPTemplateArgument[] deduceForAddressOf(ICPPFunctionTemplate template,
ICPPTemplateArgument[] tmplArgs, IFunctionType arg, CPPTemplateParameterMap map, IASTNode point) throws DOMException {
ICPPTemplateArgument[] tmplArgs, IFunctionType arg, CPPTemplateParameterMap map, IASTNode point)
throws DOMException {
final ICPPTemplateParameter[] tmplParams = template.getTemplateParameters();
if (!addExplicitArguments(template, tmplParams, tmplArgs, map, point))
return null;
IType par= template.getType();
par= CPPTemplates.instantiateType(par, map, -1, null, point);
InstantiationContext context = new InstantiationContext(map, point);
par= CPPTemplates.instantiateType(par, context);
if (!SemanticUtil.isValidType(par))
return null;
@ -344,7 +347,7 @@ public class TemplateArgumentDeduction {
return null;
if (isDependentPar)
par= CPPTemplates.instantiateType(par, map, -1, null, point);
par= CPPTemplates.instantiateType(par, context);
if (arg == null || arg.isSameType(par)) {
return createArguments(map, tmplParams);
@ -371,12 +374,13 @@ public class TemplateArgumentDeduction {
return null;
}
InstantiationContext context = new InstantiationContext(map, point);
for (int i = 0; i < length; i++) {
if (result[i] == null) {
final ICPPTemplateParameter tpar = tmplParams[i];
ICPPTemplateArgument deducedArg= map.getArgument(tpar);
if (deducedArg == null) {
deducedArg= CPPTemplates.instantiateArgument(tpar.getDefaultValue(), map, -1, null, point);
deducedArg= CPPTemplates.instantiateArgument(tpar.getDefaultValue(), context);
if (!CPPTemplates.isValidArgument(deducedArg))
return null;
}
@ -391,14 +395,16 @@ public class TemplateArgumentDeduction {
* 14.8.2.6
*/
static ICPPTemplateArgument[] deduceForDeclaration(ICPPFunctionTemplate template,
ICPPTemplateArgument[] args, ICPPFunctionType ftype, CPPTemplateParameterMap map, IASTNode point) throws DOMException {
ICPPTemplateArgument[] args, ICPPFunctionType ftype, CPPTemplateParameterMap map, IASTNode point)
throws DOMException {
final ICPPTemplateParameter[] tmplParams = template.getTemplateParameters();
if (!addExplicitArguments(template, tmplParams, args, map, point))
return null;
IType a= SemanticUtil.getSimplifiedType(ftype);
IType p= CPPTemplates.instantiateType(template.getType(), map, -1, null, point);
InstantiationContext context = new InstantiationContext(map, point);
IType p= CPPTemplates.instantiateType(template.getType(), context);
if (!SemanticUtil.isValidType(p))
return null;
@ -414,7 +420,7 @@ public class TemplateArgumentDeduction {
if (!verifyDeduction(tmplParams, map, true, point))
return null;
IType type= CPPTemplates.instantiateType(p, map, -1, null, point);
IType type= CPPTemplates.instantiateType(p, context);
if (!ftype.isSameType(type))
return null;
@ -726,12 +732,14 @@ public class TemplateArgumentDeduction {
return verifyDeduction(pars, map, false, point);
}
private static boolean verifyDeduction(ICPPTemplateParameter[] pars, CPPTemplateParameterMap tpMap, boolean useDefaults, IASTNode point) {
private static boolean verifyDeduction(ICPPTemplateParameter[] pars, CPPTemplateParameterMap tpMap,
boolean useDefaults, IASTNode point) {
InstantiationContext context = new InstantiationContext(tpMap, point);
for (ICPPTemplateParameter tpar : pars) {
if (tpar.isParameterPack()) {
ICPPTemplateArgument[] deducedArgs= tpMap.getPackExpansion(tpar);
if (deducedArgs == null) {
tpMap.put(tpar, ICPPTemplateArgument.EMPTY_ARGUMENTS);
context.addToParameterMap(tpar, ICPPTemplateArgument.EMPTY_ARGUMENTS);
} else {
for (ICPPTemplateArgument arg : deducedArgs) {
if (arg == null)
@ -743,9 +751,9 @@ public class TemplateArgumentDeduction {
if (deducedArg == null && useDefaults) {
deducedArg= tpar.getDefaultValue();
if (deducedArg != null) {
deducedArg= CPPTemplates.instantiateArgument(deducedArg, tpMap, -1, null, point);
deducedArg= CPPTemplates.instantiateArgument(deducedArg, context);
if (CPPTemplates.isValidArgument(deducedArg)) {
tpMap.put(tpar, deducedArg);
context.addToParameterMap(tpar, deducedArg);
}
}
}
@ -995,7 +1003,9 @@ public class TemplateArgumentDeduction {
if (expansionPattern != null) {
p= expansionPattern;
deduct.incPackOffset();
p= CPPTemplates.instantiateArgument(p, fExplicitArgs, deduct.fPackOffset, null, point);
InstantiationContext context =
new InstantiationContext(fExplicitArgs, deduct.fPackOffset, point);
p= CPPTemplates.instantiateArgument(p, context);
if (!CPPTemplates.isValidArgument(p))
return false;
} else {
@ -1003,7 +1013,9 @@ public class TemplateArgumentDeduction {
if (p.isPackExpansion()) {
p= expansionPattern= p.getExpansionPattern();
deduct= new TemplateArgumentDeduction(this, aArgs.length - i);
p= CPPTemplates.instantiateArgument(p, fExplicitArgs, deduct.fPackOffset, null, point);
InstantiationContext context =
new InstantiationContext(fExplicitArgs, deduct.fPackOffset, point);
p= CPPTemplates.instantiateArgument(p, context);
if (!CPPTemplates.isValidArgument(p))
return false;
}
@ -1045,7 +1057,9 @@ public class TemplateArgumentDeduction {
if (parameterPack != null) {
p= parameterPack;
deduct.incPackOffset();
p= CPPTemplates.instantiateType(p, fExplicitArgs, deduct.fPackOffset, null, point);
InstantiationContext context =
new InstantiationContext(fExplicitArgs, deduct.fPackOffset, point);
p= CPPTemplates.instantiateType(p, context);
if (!SemanticUtil.isValidType(p))
return false;
} else {
@ -1053,7 +1067,9 @@ public class TemplateArgumentDeduction {
if (p instanceof ICPPParameterPackType) {
p= parameterPack= ((ICPPParameterPackType) p).getType();
deduct= new TemplateArgumentDeduction(this, aParams.length - i);
p= CPPTemplates.instantiateType(p, fExplicitArgs, deduct.fPackOffset, null, point);
InstantiationContext context =
new InstantiationContext(fExplicitArgs, deduct.fPackOffset, point);
p= CPPTemplates.instantiateType(p, context);
if (!SemanticUtil.isValidType(p))
return false;
}