diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index 37e08cb62d7..8ff1943ace6 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -3385,4 +3385,33 @@ public class AST2TemplateTests extends AST2BaseTest { assertSame(mt1, mt2); assertInstance(mt1, ICPPFunctionTemplate.class); } + + // template class XT {}; + // template class XT {public: int partial;}; + // void test() { + // XT xt; + // xt.partial; + // } + public void testDefaultArgsWithPartialSpecialization() throws Exception { + final String code = getAboveComment(); + parseAndCheckBindings(code, ParserLanguage.CPP); + } + + // template 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); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java index 286d56c405e..38d54991672 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java @@ -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); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java index fe7bbeb11d5..3044a109ce9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java @@ -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) { } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterSpecialization.java index 465952ee57b..f04a8e8ca4c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterSpecialization.java @@ -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() diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java index fb1d6c8cc52..396279b1612 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java @@ -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++) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index 508584b79c7..daa8125adf0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -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()) { 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 733c1b7215d..8676581df87 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 @@ -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 null. + * Instantiates a class template with the given arguments. May return null. */ - 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 null. + * @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 null. */ - 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); + } } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index dfcb7d04a86..b2a29f3b3e7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -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()); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java index 04c13f66568..1b3d5ad3dad 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java @@ -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.