diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPClassSpecializationScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPClassSpecializationScope.java index 7197e4b0c8c..2883f00a275 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPClassSpecializationScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPClassSpecializationScope.java @@ -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); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java index 55f635cb4fd..8d083e857c9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java @@ -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; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorInstance.java index 3c3263b0612..5b6c59f5337 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorInstance.java @@ -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); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java index 9cd15ba7552..3836ef8e9f7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java @@ -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); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java index a2aa8fb8047..2df9862315c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java index 1a6b89896eb..a586fe1d0c6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java @@ -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; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodInstance.java index 0da586a55e3..8b00d0484c2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodInstance.java @@ -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); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java index 89e677b4092..a0e3ac3e9be 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java @@ -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. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/InstantiationContext.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/InstantiationContext.java new file mode 100644 index 00000000000..906b86ca2cb --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/InstantiationContext.java @@ -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; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPDependentEvaluation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPDependentEvaluation.java index 61cf1a23542..2b8adc6ede9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPDependentEvaluation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPDependentEvaluation.java @@ -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(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java index ab71e4fc924..07d65582dd9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java @@ -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); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index c0b0ea90bf1..7e937964ed0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -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 fTemplateInstantiationDepth = new ThreadLocal() { @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 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 */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java index e2a33b6f189..8720512c3df 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java @@ -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()); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java index a9465f4683c..b26810f697f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java @@ -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()); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java index 1a013751952..736f1c4727a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java @@ -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()); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java index b0c3079339f..8bb0a524d57 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java @@ -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]; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalCompound.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalCompound.java index 824144329e5..a8ec95d066b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalCompound.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalCompound.java @@ -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()); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java index 463a2ef9b5f..ba6ee7b7a63 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java @@ -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()); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFixed.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFixed.java index 4e3a36a47ba..726e304d3c1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFixed.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFixed.java @@ -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), diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java index 0c3a16c4eea..5d080ebd114 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java @@ -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()); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java index d104f896903..bbfc0dac549 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java @@ -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 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java index 76c832eb8a2..62a10a4da78 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java @@ -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; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java index 61f31925a9b..9c39e504d42 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java @@ -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()); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalMemberAccess.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalMemberAccess.java index 5ef96bd254a..9388af02786 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalMemberAccess.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalMemberAccess.java @@ -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()); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalParameterPack.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalParameterPack.java index e65543f2a9f..e1ef75f1450 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalParameterPack.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalParameterPack.java @@ -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()); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java index f05bcfcb78c..2af37523de7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java @@ -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; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java index 891fbec5814..1fdbc79bf35 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java @@ -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) { } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java index fd82f12e539..202ae0e255c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java @@ -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()); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java index 72729d73980..d113fa2fa15 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java @@ -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; }