mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 09:25:31 +02:00
Use default arguments before selecting partial specializations, bug 257169.
This commit is contained in:
parent
efc84f0131
commit
4145150968
9 changed files with 240 additions and 102 deletions
|
@ -3385,4 +3385,33 @@ public class AST2TemplateTests extends AST2BaseTest {
|
|||
assertSame(mt1, mt2);
|
||||
assertInstance(mt1, ICPPFunctionTemplate.class);
|
||||
}
|
||||
|
||||
// template <typename T, typename U=T> class XT {};
|
||||
// template <typename T> class XT<T,T> {public: int partial;};
|
||||
// void test() {
|
||||
// XT<int> xt;
|
||||
// xt.partial;
|
||||
// }
|
||||
public void testDefaultArgsWithPartialSpecialization() throws Exception {
|
||||
final String code = getAboveComment();
|
||||
parseAndCheckBindings(code, ParserLanguage.CPP);
|
||||
}
|
||||
|
||||
// template <typename T> class XT {
|
||||
// public:
|
||||
// int a;
|
||||
// void m() {
|
||||
// this->a= 1;
|
||||
// }
|
||||
// };
|
||||
public void _testFieldReference_Bug234321() throws Exception {
|
||||
final String code = getAboveComment();
|
||||
parseAndCheckBindings(code, ParserLanguage.CPP);
|
||||
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
||||
|
||||
IBinding a1= bh.assertNonProblem("a;", 1);
|
||||
IBinding a2= bh.assertNonProblem("a=", 1);
|
||||
assertInstance(a1, ICPPField.class);
|
||||
assertSame(a1, a2);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1482,7 +1482,7 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
|
|||
assertInstance(t1, ICPPTemplateInstance.class);
|
||||
|
||||
ICPPTemplateInstance inst= (ICPPTemplateInstance) t1;
|
||||
final ICPPTemplateDefinition tmplDef = inst.getTemplateDefinition();
|
||||
final ICPPClassTemplate tmplDef = (ICPPClassTemplate) inst.getTemplateDefinition();
|
||||
IBinding inst2= CPPTemplates.instantiate(tmplDef, inst.getTemplateArguments());
|
||||
assertSame(inst, inst2);
|
||||
|
||||
|
|
|
@ -96,9 +96,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
|||
ICPPClassType clsType = (ICPPClassType) binding;
|
||||
if (clsType instanceof ICPPClassTemplate) {
|
||||
try {
|
||||
IBinding within = CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) clsType);
|
||||
if (within instanceof ICPPClassType)
|
||||
clsType = (ICPPClassType)within;
|
||||
clsType= CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) clsType);
|
||||
} catch (DOMException e) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,8 +15,10 @@ import org.eclipse.cdt.core.dom.ast.DOMException;
|
|||
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.ICPPClassSpecialization;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
|
||||
|
||||
/**
|
||||
* Binding for a specialization of a parameter.
|
||||
|
@ -41,6 +43,18 @@ public class CPPParameterSpecialization extends CPPSpecialization implements ICP
|
|||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType specializeType(IType type) throws DOMException {
|
||||
IBinding owner= getOwner();
|
||||
if (owner != null) {
|
||||
owner= owner.getOwner();
|
||||
if (owner instanceof ICPPClassSpecialization) {
|
||||
return CPPTemplates.instantiateType(type, getTemplateParameterMap(), (ICPPClassSpecialization) owner);
|
||||
}
|
||||
}
|
||||
return CPPTemplates.instantiateType(type, getTemplateParameterMap(), null);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IVariable#isStatic()
|
||||
|
|
|
@ -272,8 +272,11 @@ public abstract class CPPTemplateDefinition extends PlatformObject implements IC
|
|||
}
|
||||
|
||||
final protected void updateTemplateParameterBindings(IASTName name) {
|
||||
ICPPASTTemplateParameter[] updateParams = CPPTemplates.getTemplateDeclaration(name).getTemplateParameters();
|
||||
|
||||
final ICPPASTTemplateDeclaration templateDeclaration = CPPTemplates.getTemplateDeclaration(name);
|
||||
if (templateDeclaration == null)
|
||||
return;
|
||||
|
||||
ICPPASTTemplateParameter[] updateParams = templateDeclaration.getTemplateParameters();
|
||||
int k= 0;
|
||||
int tdeclLen= declarations == null ? 0 : declarations.length;
|
||||
for (int i= -1; i < tdeclLen && k < updateParams.length; i++) {
|
||||
|
|
|
@ -23,7 +23,6 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.cdt.core.dom.IName;
|
||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
|
||||
|
@ -89,6 +88,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
|
||||
|
@ -253,53 +253,31 @@ public class CPPSemantics {
|
|||
}
|
||||
}
|
||||
|
||||
/* 14.6.1-1: Class template name without argument list is equivalent to the injected-class-name followed by
|
||||
* the template-parameters of the class template enclosed in <> */
|
||||
if (binding instanceof ICPPClassTemplate) {
|
||||
ICPPClassTemplate ct= (ICPPClassTemplate) binding;
|
||||
/* 14.6.1-1:
|
||||
* Within the scope of a class template, when the name of the template is neither qualified nor
|
||||
* followed by <, it is equivalent to the name followed by the template parameters enclosed in <>.
|
||||
*/
|
||||
if (binding instanceof ICPPClassTemplate && !(binding instanceof ICPPClassSpecialization) &&
|
||||
!(data.astName instanceof ICPPASTTemplateId)) {
|
||||
ASTNodeProperty prop = data.astName.getPropertyInParent();
|
||||
if (prop != ICPPASTQualifiedName.SEGMENT_NAME && prop != ICPPASTTemplateId.TEMPLATE_NAME &&
|
||||
binding instanceof ICPPInternalBinding) {
|
||||
try {
|
||||
IScope scope= CPPVisitor.getContainingScope(data.astName);
|
||||
while (scope instanceof IASTInternalScope) {
|
||||
final IASTInternalScope internalScope = (IASTInternalScope) scope;
|
||||
if (scope instanceof ICPPClassScope) {
|
||||
final IName scopeName = internalScope.getScopeName();
|
||||
if (scopeName instanceof IASTName) {
|
||||
IBinding b= ((IASTName) scopeName).resolveBinding();
|
||||
if (binding == b) {
|
||||
binding= CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) binding);
|
||||
break;
|
||||
}
|
||||
if (b instanceof ICPPClassTemplatePartialSpecialization) {
|
||||
ICPPClassTemplatePartialSpecialization pspec= (ICPPClassTemplatePartialSpecialization) b;
|
||||
if (ct.isSameType(pspec.getPrimaryClassTemplate())) {
|
||||
binding= CPPTemplates.instantiateWithinClassTemplate(pspec);
|
||||
break;
|
||||
}
|
||||
} else if (b instanceof ICPPClassSpecialization) {
|
||||
ICPPClassSpecialization specialization= (ICPPClassSpecialization) b;
|
||||
if (ct.isSameType(specialization.getSpecializedBinding())) {
|
||||
binding= specialization;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (prop != ICPPASTTemplateId.TEMPLATE_NAME && prop != ICPPASTQualifiedName.SEGMENT_NAME) {
|
||||
// You cannot use a class template name outside of the class template scope,
|
||||
// mark it as a problem.
|
||||
IBinding replacement= CPPTemplates.isUsedInClassTemplateScope((ICPPClassTemplate) binding, data.astName);
|
||||
if (replacement != null) {
|
||||
binding= replacement;
|
||||
} else {
|
||||
boolean ok= false;
|
||||
IASTNode node= data.astName.getParent();
|
||||
while (node != null && !ok) {
|
||||
if (node instanceof ICPPASTTemplateId ||
|
||||
node instanceof ICPPASTTemplatedTypeTemplateParameter) {
|
||||
ok= true; // can be argument or default-value for template template parameter
|
||||
break;
|
||||
}
|
||||
scope= CPPVisitor.getContainingScope(internalScope.getPhysicalNode());
|
||||
node= node.getParent();
|
||||
}
|
||||
} catch (DOMException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/* If the class template name is used as a type name in a simple declaration,
|
||||
* outside of the class template scope, mark it as a problem.
|
||||
*/
|
||||
if (binding instanceof ICPPClassTemplate) {
|
||||
IASTNode parent= data.astName.getParent();
|
||||
if (parent instanceof IASTNamedTypeSpecifier) {
|
||||
if (parent.getParent() instanceof IASTSimpleDeclaration) {
|
||||
if (!ok) {
|
||||
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_INVALID_TYPE, data.name());
|
||||
}
|
||||
}
|
||||
|
@ -843,20 +821,16 @@ public class CPPSemantics {
|
|||
inherited = null;
|
||||
|
||||
final ICPPClassType cls = (ICPPClassType) b;
|
||||
final ICPPScope parent = (ICPPScope) cls.getCompositeScope();
|
||||
|
||||
if (parent == null)
|
||||
continue;
|
||||
if (parent instanceof CPPUnknownScope) {
|
||||
if (data.unknownBinding == null && classType instanceof ICPPClassTemplate && data.astName != null) {
|
||||
ICPPClassTemplate template= ((ICPPClassTemplate) classType);
|
||||
IBinding thisType= CPPTemplates.instantiateWithinClassTemplate(template);
|
||||
if (thisType instanceof ICPPUnknownBinding) {
|
||||
data.unknownBinding= ((ICPPUnknownBinding) thisType).getUnknownScope().getBinding(data.astName, true);
|
||||
}
|
||||
if (cls instanceof ICPPUnknownBinding) {
|
||||
if (data.unknownBinding == null) {
|
||||
data.unknownBinding= cls;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
final ICPPScope parent = (ICPPScope) cls.getCompositeScope();
|
||||
if (parent == null || parent instanceof CPPUnknownScope)
|
||||
continue;
|
||||
|
||||
if (!base.isVirtual() || !data.visited.containsKey(parent)) {
|
||||
if (base.isVirtual()) {
|
||||
|
@ -1970,9 +1944,7 @@ public class CPPSemantics {
|
|||
System.arraycopy(ptypes, 0, result, 1, ptypes.length);
|
||||
ICPPClassType owner= ((ICPPMethod) fn).getClassOwner();
|
||||
if (owner instanceof ICPPClassTemplate) {
|
||||
IBinding within= CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) owner);
|
||||
if (within instanceof ICPPClassType)
|
||||
owner = (ICPPClassType)within;
|
||||
owner= CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) owner);
|
||||
}
|
||||
IType implicitType= owner;
|
||||
if (ftype.isConst() || ftype.isVolatile()) {
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.dom.IName;
|
||||
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
|
@ -57,6 +58,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
|
||||
|
@ -86,9 +88,11 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
|||
import org.eclipse.cdt.core.parser.util.ObjectMap;
|
||||
import org.eclipse.cdt.core.parser.util.ObjectSet;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.Value;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassInstance;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassSpecialization;
|
||||
|
@ -130,7 +134,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalClassTemplate;
|
|||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownClassInstance;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownClassType;
|
||||
import org.eclipse.core.runtime.Assert;
|
||||
|
||||
/**
|
||||
* Collection of static methods to perform template instantiation, member specialization and
|
||||
|
@ -139,33 +142,122 @@ import org.eclipse.core.runtime.Assert;
|
|||
public class CPPTemplates {
|
||||
|
||||
/**
|
||||
* Instantiates a template with the given arguments. May return <code>null</code>.
|
||||
* Instantiates a class template with the given arguments. May return <code>null</code>.
|
||||
*/
|
||||
public static IBinding instantiate(ICPPTemplateDefinition template, ICPPTemplateArgument[] arguments) {
|
||||
public static IBinding instantiate(ICPPClassTemplate template, ICPPTemplateArgument[] arguments) {
|
||||
try {
|
||||
arguments= SemanticUtil.getSimplifiedArguments(arguments);
|
||||
if (template instanceof ICPPTemplateTemplateParameter || hasDependentArgument(arguments)) {
|
||||
return deferredInstance(template, arguments);
|
||||
}
|
||||
|
||||
if (template instanceof ICPPClassTemplate) {
|
||||
template= CPPTemplates.selectSpecialization((ICPPClassTemplate) template, arguments);
|
||||
if (template == null || template instanceof IProblemBinding)
|
||||
return template;
|
||||
|
||||
if (template instanceof ICPPClassTemplatePartialSpecialization) {
|
||||
final ICPPClassTemplatePartialSpecialization partialSpec = (ICPPClassTemplatePartialSpecialization) template;
|
||||
return instantiatePartialSpecialization(partialSpec, arguments);
|
||||
}
|
||||
|
||||
return instantiateSelectedTemplate(template, arguments);
|
||||
|
||||
if (template instanceof ICPPClassTemplatePartialSpecialization) {
|
||||
return instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) template, arguments);
|
||||
}
|
||||
return instantiateSelectedTemplate(template, arguments);
|
||||
|
||||
// check whether we need to use default arguments
|
||||
final ICPPTemplateParameter[] parameters= template.getTemplateParameters();
|
||||
final int numArgs = arguments.length;
|
||||
final int numParams= parameters.length;
|
||||
if (numParams == 0 || numParams < numArgs)
|
||||
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_USING);
|
||||
|
||||
ICPPTemplateArgument[] completeArgs= new ICPPTemplateArgument[numParams];
|
||||
CPPTemplateParameterMap map= new CPPTemplateParameterMap(numParams);
|
||||
|
||||
boolean hasDependentDefaultArg= false;
|
||||
for (int i = 0; i < numParams; i++) {
|
||||
ICPPTemplateArgument arg;
|
||||
ICPPTemplateParameter param= parameters[i];
|
||||
if (i < numArgs) {
|
||||
arg= arguments[i];
|
||||
} else {
|
||||
ICPPTemplateArgument defaultArg= param.getDefaultValue();
|
||||
if (defaultArg == null) {
|
||||
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_USING);
|
||||
}
|
||||
arg= instantiateArgument(defaultArg, map, null);
|
||||
arg= SemanticUtil.getSimplifiedArgument(arg);
|
||||
hasDependentDefaultArg |= isDependentArgument(arg);
|
||||
}
|
||||
|
||||
if (!hasDependentDefaultArg) {
|
||||
arg= CPPTemplates.matchTemplateParameterAndArgument(param, arg, map);
|
||||
if (arg == null)
|
||||
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_USING);
|
||||
}
|
||||
|
||||
map.put(param, arg);
|
||||
completeArgs[i]= arg;
|
||||
}
|
||||
|
||||
if (hasDependentDefaultArg)
|
||||
return deferredInstance(template, completeArgs);
|
||||
|
||||
|
||||
ICPPTemplateDefinition tdef = CPPTemplates.selectSpecialization(template, completeArgs);
|
||||
if (tdef == null || tdef instanceof IProblemBinding)
|
||||
return tdef;
|
||||
|
||||
if (tdef instanceof ICPPClassTemplatePartialSpecialization) {
|
||||
return instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) tdef, completeArgs);
|
||||
}
|
||||
|
||||
return instantiatePrimaryTemplate(template, completeArgs, map);
|
||||
} catch (DOMException e) {
|
||||
return e.getProblem();
|
||||
}
|
||||
}
|
||||
|
||||
private static IBinding createProblem(ICPPClassTemplate template, int id) {
|
||||
IASTNode node= null;
|
||||
if (template instanceof ICPPInternalBinding) {
|
||||
ICPPInternalBinding internal= (ICPPInternalBinding) template;
|
||||
node= internal.getDefinition();
|
||||
if (node == null) {
|
||||
IASTNode[] decls= internal.getDeclarations();
|
||||
if (decls != null && decls.length > 0)
|
||||
node= decls[0];
|
||||
}
|
||||
}
|
||||
if (node == null) {
|
||||
node= new CPPASTName(template.getNameCharArray());
|
||||
}
|
||||
return new ProblemBinding(node, id, template.getNameCharArray());
|
||||
}
|
||||
|
||||
static IBinding isUsedInClassTemplateScope(ICPPClassTemplate ct, IASTName name) {
|
||||
try {
|
||||
IScope scope= CPPVisitor.getContainingScope(name);
|
||||
while (scope instanceof IASTInternalScope) {
|
||||
final IASTInternalScope internalScope = (IASTInternalScope) scope;
|
||||
if (scope instanceof ICPPClassScope) {
|
||||
final IName scopeName = internalScope.getScopeName();
|
||||
if (scopeName instanceof IASTName) {
|
||||
IBinding b= ((IASTName) scopeName).resolveBinding();
|
||||
if (b instanceof IType && ct.isSameType((IType) b)) {
|
||||
return CPPTemplates.instantiateWithinClassTemplate(ct);
|
||||
}
|
||||
if (b instanceof ICPPClassTemplatePartialSpecialization) {
|
||||
ICPPClassTemplatePartialSpecialization pspec= (ICPPClassTemplatePartialSpecialization) b;
|
||||
if (ct.isSameType(pspec.getPrimaryClassTemplate())) {
|
||||
return CPPTemplates.instantiateWithinClassTemplate(pspec);
|
||||
}
|
||||
} else if (b instanceof ICPPClassSpecialization) {
|
||||
ICPPClassSpecialization specialization= (ICPPClassSpecialization) b;
|
||||
if (ct.isSameType(specialization.getSpecializedBinding())) {
|
||||
return specialization;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scope= CPPVisitor.getContainingScope(internalScope.getPhysicalNode());
|
||||
}
|
||||
} catch (DOMException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a partial class template specialization.
|
||||
*/
|
||||
|
@ -193,11 +285,25 @@ public class CPPTemplates {
|
|||
|
||||
/**
|
||||
* Instantiates the selected template, without looking for specializations. May return <code>null</code>.
|
||||
* @param map
|
||||
*/
|
||||
private static IBinding instantiateSelectedTemplate(ICPPTemplateDefinition template, ICPPTemplateArgument[] arguments)
|
||||
throws DOMException {
|
||||
Assert.isTrue(!(template instanceof ICPPClassTemplatePartialSpecialization));
|
||||
private static IBinding instantiatePrimaryTemplate(ICPPClassTemplate template, ICPPTemplateArgument[] arguments,
|
||||
CPPTemplateParameterMap map) throws DOMException {
|
||||
|
||||
assert !(template instanceof ICPPClassTemplatePartialSpecialization);
|
||||
ICPPTemplateInstance instance= getInstance(template, arguments);
|
||||
if (instance != null) {
|
||||
return instance;
|
||||
}
|
||||
|
||||
IBinding owner= template.getOwner();
|
||||
instance = CPPTemplates.createInstance(owner, template, map, arguments);
|
||||
addInstance(template, arguments, instance);
|
||||
return instance;
|
||||
}
|
||||
|
||||
private static IBinding instantiateFunctionTemplate(ICPPFunctionTemplate template, ICPPTemplateArgument[] arguments)
|
||||
throws DOMException {
|
||||
ICPPTemplateParameter[] parameters= template.getTemplateParameters();
|
||||
if (parameters == null || parameters.length == 0)
|
||||
return null;
|
||||
|
@ -228,7 +334,7 @@ public class CPPTemplates {
|
|||
arg= CPPTemplates.matchTemplateParameterAndArgument(param, arg, map);
|
||||
if (arg == null)
|
||||
return null;
|
||||
|
||||
|
||||
if (!argIsParameter(arg, param)) {
|
||||
map.put(param, arg);
|
||||
}
|
||||
|
@ -304,7 +410,7 @@ public class CPPTemplates {
|
|||
/**
|
||||
* Instantiates the template for usage within its own body. May return <code>null</code>.
|
||||
*/
|
||||
public static IBinding instantiateWithinClassTemplate(ICPPClassTemplate template) throws DOMException {
|
||||
public static ICPPClassType instantiateWithinClassTemplate(ICPPClassTemplate template) throws DOMException {
|
||||
ICPPTemplateArgument[] args;
|
||||
if (template instanceof ICPPClassTemplatePartialSpecialization) {
|
||||
args= ((ICPPClassTemplatePartialSpecialization) template).getTemplateArguments();
|
||||
|
@ -323,7 +429,11 @@ public class CPPTemplates {
|
|||
}
|
||||
}
|
||||
}
|
||||
return deferredInstance(template, args);
|
||||
IBinding result = deferredInstance(template, args);
|
||||
if (result instanceof ICPPClassType)
|
||||
return (ICPPClassType) result;
|
||||
|
||||
return template;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1311,7 +1421,7 @@ public class CPPTemplates {
|
|||
try {
|
||||
ICPPTemplateArgument[] args= deduceTemplateFunctionArguments(template, templateArguments, fnArgs, map);
|
||||
if (args != null) {
|
||||
IBinding temp= instantiate(template, args);
|
||||
IBinding temp= instantiateFunctionTemplate(template, args);
|
||||
if (temp instanceof IFunction) {
|
||||
instances = (IFunction[]) ArrayUtil.append(IFunction.class, instances, temp);
|
||||
}
|
||||
|
@ -1587,13 +1697,13 @@ public class CPPTemplates {
|
|||
CPPTemplateParameterMap m2= new CPPTemplateParameterMap(2);
|
||||
|
||||
ICPPTemplateArgument[] args = createArgsForFunctionTemplateOrdering(f1);
|
||||
IBinding function = instantiate(f1, args);
|
||||
IBinding function = instantiateFunctionTemplate(f1, args);
|
||||
if (function instanceof ICPPFunction)
|
||||
if (!deduceTemplateParameterMapFromFunctionParameters(f2, ((ICPPFunction) function).getType().getParameterTypes(), m1))
|
||||
m1= null;
|
||||
|
||||
args = createArgsForFunctionTemplateOrdering(f2);
|
||||
function = instantiate(f2, args);
|
||||
function = instantiateFunctionTemplate(f2, args);
|
||||
if (function instanceof ICPPFunction)
|
||||
if (!deduceTemplateParameterMapFromFunctionParameters(f1, ((ICPPFunction) function).getType().getParameterTypes(), m2))
|
||||
m2= null;
|
||||
|
@ -1754,7 +1864,8 @@ public class CPPTemplates {
|
|||
static private ICPPFunctionTemplate classTemplateSpecializationToFunctionTemplate(ICPPClassTemplatePartialSpecialization specialization) {
|
||||
try {
|
||||
// ICPPTemplateArgument[] args= specialization.getTemplateArguments();
|
||||
IBinding paramType = instantiateWithinClassTemplate(specialization);
|
||||
ICPPTemplateArgument[] args= (specialization).getTemplateArguments();
|
||||
IBinding paramType = deferredInstance(specialization, args);
|
||||
if (!(paramType instanceof IType))
|
||||
return null;
|
||||
|
||||
|
@ -1881,10 +1992,14 @@ public class CPPTemplates {
|
|||
ICPPTemplateParameter par= pars[i];
|
||||
ICPPTemplateArgument arg = args[i];
|
||||
if (par instanceof IType) {
|
||||
if (arg.isNonTypeValue())
|
||||
return false;
|
||||
IType argType= arg.getTypeValue();
|
||||
if (argType == null || !argType.isSameType((IType) par))
|
||||
return false;
|
||||
} else {
|
||||
if (arg.isTypeValue())
|
||||
return false;
|
||||
int parpos= Value.isTemplateParameter(arg.getNonTypeValue());
|
||||
if (parpos != par.getParameterID())
|
||||
return false;
|
||||
|
@ -1998,7 +2113,11 @@ public class CPPTemplates {
|
|||
}
|
||||
if (unknown instanceof ICPPUnknownClassInstance && result instanceof ICPPTemplateDefinition) {
|
||||
ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments(((ICPPUnknownClassInstance) unknown).getArguments(), tpMap, within);
|
||||
result = instantiate((ICPPTemplateDefinition) result, newArgs);
|
||||
if (result instanceof ICPPClassTemplate)
|
||||
result = instantiate((ICPPClassTemplate) result, newArgs);
|
||||
else if (result instanceof ICPPFunctionTemplate) {
|
||||
result= instantiateFunctionTemplate((ICPPFunctionTemplate) result, newArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1802,9 +1802,7 @@ public class CPPVisitor extends ASTQueries {
|
|||
ICPPClassScope cScope = (ICPPClassScope) s;
|
||||
IType type = cScope.getClassType();
|
||||
if (type instanceof ICPPClassTemplate) {
|
||||
IBinding within = CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) type);
|
||||
if (within instanceof ICPPClassType)
|
||||
type = (ICPPClassType)within;
|
||||
type= CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) type);
|
||||
}
|
||||
if (dtor.isConst() || dtor.isVolatile())
|
||||
type = new CPPQualifierType(type, dtor.isConst(), dtor.isVolatile());
|
||||
|
|
|
@ -304,13 +304,7 @@ public class SemanticUtil {
|
|||
final ICPPTemplateArgument arg= args[i];
|
||||
ICPPTemplateArgument newArg= arg;
|
||||
if (arg != null) {
|
||||
if (arg.isTypeValue()) {
|
||||
final IType type= arg.getTypeValue();
|
||||
final IType newType= getSimplifiedType(type);
|
||||
if (newType != type) {
|
||||
newArg= new CPPTemplateArgument(newType);
|
||||
}
|
||||
}
|
||||
newArg = getSimplifiedArgument(arg);
|
||||
if (result != args) {
|
||||
result[i]= newArg;
|
||||
} else if (arg != newArg) {
|
||||
|
@ -325,6 +319,17 @@ public class SemanticUtil {
|
|||
return result;
|
||||
}
|
||||
|
||||
public static ICPPTemplateArgument getSimplifiedArgument(final ICPPTemplateArgument arg) {
|
||||
if (arg.isTypeValue()) {
|
||||
final IType type= arg.getTypeValue();
|
||||
final IType newType= getSimplifiedType(type);
|
||||
if (newType != type) {
|
||||
return new CPPTemplateArgument(newType);
|
||||
}
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the parameter type according to 8.3.5-3:
|
||||
* cv-qualifiers are deleted, arrays and function types are converted to pointers.
|
||||
|
|
Loading…
Add table
Reference in a new issue