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 fba3c3ef9f8..2a6c0fbb9a6 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 @@ -1285,8 +1285,7 @@ public class AST2TemplateTests extends AST2BaseTest { IBinding U2 = col.getName(10).resolveBinding(); assertSame(U, U2); - assertTrue(f2 instanceof ICPPSpecialization); - assertSame(((ICPPSpecialization)f2).getSpecializedBinding(), f1); + assertSame(f1, f2); } // template @@ -1792,9 +1791,10 @@ public class AST2TemplateTests extends AST2BaseTest { ICPPClassTemplate B = (ICPPClassTemplate) col.getName(4).resolveBinding(); assertSame(T, col.getName(5).resolveBinding()); - assertSame(T2, col.getName(6).resolveBinding()); + final IBinding T2ofPartialSpec = col.getName(6).resolveBinding(); + assertNotSame(T2, T2ofPartialSpec); // partial spec has its own template params assertSame(T, col.getName(10).resolveBinding()); - assertSame(T2, col.getName(14).resolveBinding()); + assertSame(T2ofPartialSpec, col.getName(14).resolveBinding()); ICPPClassTemplatePartialSpecialization spec = (ICPPClassTemplatePartialSpecialization) col.getName(12).resolveBinding(); assertSame(spec.getPrimaryClassTemplate(), B); @@ -3234,7 +3234,7 @@ public class AST2TemplateTests extends AST2BaseTest { @Override public void run() { try { - parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP); + parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP); } catch (Throwable e) { th[0]= e; } @@ -3247,4 +3247,50 @@ public class AST2TemplateTests extends AST2BaseTest { if (th[0] != null) throw th[0]; } + + // template class A {}; + // template class A { + // void foo(T t); + // }; + // template void A::foo(T t) {} + public void testBug177418() throws Exception { + IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP, true, true ); + + CPPNameCollector col = new CPPNameCollector(); + tu.accept( col ); + + ICPPTemplateParameter T1 = (ICPPTemplateParameter) col.getName(0).resolveBinding(); + ICPPTemplateParameter U = (ICPPTemplateParameter) col.getName(1).resolveBinding(); + ICPPClassTemplate A = (ICPPClassTemplate) col.getName(2).resolveBinding(); + + ICPPTemplateParameter T2 = (ICPPTemplateParameter) col.getName(3).resolveBinding(); + assertNotSame(T1, T2); + + ICPPClassTemplatePartialSpecialization A2 = (ICPPClassTemplatePartialSpecialization) col.getName(4).resolveBinding(); + assertSame(A2.getPrimaryClassTemplate(), A); + assertSame(A, col.getName(5).resolveBinding()); + assertSame(T2, col.getName(6).resolveBinding()); + + ICPPMethod foo = (ICPPMethod) col.getName(7).resolveBinding(); + assertSame(T2, col.getName(8).resolveBinding()); + assertSame(T2, col.getName(10).resolveBinding()); + ICPPParameter t = (ICPPParameter) col.getName(9).resolveBinding(); + + assertSame(A2, col.getName(12).resolveBinding()); + assertSame(A, col.getName(13).resolveBinding()); + assertSame(T2, col.getName(14).resolveBinding()); + assertSame(foo, col.getName(15).resolveBinding()); + assertSame(T2, col.getName(16).resolveBinding()); + assertSame(t, col.getName(17).resolveBinding()); + } + + // template class CT { + // T* instance(void); + // }; + // template T * CT::instance (void) { + // return new CT; + // } + public void testNewOfThisTemplate() throws Exception { + parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/PreprocessorBugsTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/PreprocessorBugsTests.java index 2d65dcbea7e..6acd173081a 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/PreprocessorBugsTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/PreprocessorBugsTests.java @@ -187,4 +187,24 @@ public class PreprocessorBugsTests extends PreprocessorTestsBase { validateProblem(0, IProblem.PREPROCESSOR_MISSING_RPAREN_PARMLIST, null); } + // #ifdef 0 + // /**/ #else + // OK1 + // #endif + // #ifdef 0 + // a /* + // */ #else + // OK2 + // #endif + // #ifdef 0 + // a /**/ #else + // NOTOK + // #endif + public void testCommentBeforeDirective_Bug255318() throws Exception { + initializeScanner(); + validateIdentifier("OK1"); + validateIdentifier("OK2"); + validateEOF(); + validateProblemCount(0); + } } 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 d60a4ebad78..080ebeb2c45 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 @@ -31,6 +31,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; 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.ICPPField; @@ -1490,7 +1491,6 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa assertSame(charInst1, charInst2); } - // template class XT { // public: void method() {}; // }; @@ -1508,4 +1508,16 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa assertEquals(1, ms.length); assertEquals(m, ms[0]); } + + // template class A {}; + // template class A { + // void foo(T t); + // }; + + // template void A::foo(T t) {} + public void testBug177418() throws Exception { + ICPPMethod m= getBindingFromASTName("foo", 3, ICPPMethod.class); + ICPPClassType owner= m.getClassOwner(); + assertInstance(owner, ICPPClassTemplatePartialSpecialization.class); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java index 9c98bea135e..da53dbe5695 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java @@ -122,14 +122,11 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition super.addDeclaration(node); } - /** - * @param name - */ - private void updateFunctionParameterBindings(IASTName paramName) { + private void updateFunctionParameterBindings(IASTName declName) { IASTName defName = definition != null ? definition : declarations[0]; - ICPPASTFunctionDeclarator orig = (ICPPASTFunctionDeclarator) defName.getParent(); + ICPPASTFunctionDeclarator orig = getDeclaratorByName(defName); IASTParameterDeclaration[] ops = orig.getParameters(); - IASTParameterDeclaration[] nps = ((ICPPASTFunctionDeclarator)paramName.getParent()).getParameters(); + IASTParameterDeclaration[] nps = getDeclaratorByName(declName).getParameters(); CPPParameter temp = null; for(int i = 0; i < nps.length; i++) { temp = (CPPParameter) CPPVisitor.findInnermostDeclarator(ops[i].getDeclarator()).getName().getBinding(); 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 942d226eb25..9f338f8db29 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 @@ -67,7 +67,6 @@ import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; -import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler; @@ -132,7 +131,6 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope; 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.CPPASTFieldReference; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName; @@ -220,12 +218,6 @@ public class CPPSemantics { return postResolution(binding, data); } - /** - * @param binding - * @param data - * @param name - * @return - */ private static IBinding postResolution(IBinding binding, LookupData data) { if (data.checkAssociatedScopes()) { //3.4.2 argument dependent name lookup, aka Koenig lookup @@ -321,58 +313,23 @@ public class CPPSemantics { } } - // mstodo this looks like a hack? - // in template declarations the template-ids get instantiated to deferred instances, revert that. - IASTName name = data.astName; - if (name instanceof ICPPASTTemplateId) { - if (binding instanceof ICPPDeferredTemplateInstance && CPPTemplates.getTemplateDeclaration(name) != null ) { - ICPPDeferredTemplateInstance deferred= (ICPPDeferredTemplateInstance) binding; - IBinding spec= deferred.getSpecializedBinding(); - if (spec instanceof ICPPTemplateDefinition) { - try { - ICPPTemplateArgument[] args= deferred.getTemplateArguments(); - ICPPTemplateParameter[] pars= ((ICPPTemplateDefinition) spec).getTemplateParameters(); - if (args.length == pars.length) { - boolean useOriginal= true; - for (int i = 0; useOriginal && i < pars.length; i++) { - ICPPTemplateParameter par= pars[i]; - if (par instanceof ICPPTemplateNonTypeParameter) { - IValue val= args[i].getNonTypeValue(); - if (val == null || par.getParameterPosition() != Value.isTemplateParameter(val)) { - useOriginal= false; - } - } else { - IType other= args[i].getTypeValue(); - if (!(other instanceof ICPPTemplateParameter)) { - useOriginal= false; - } else if (par.getParameterPosition() != ((ICPPTemplateParameter) other).getParameterPosition()) { - useOriginal= false; - } - } - } - if (useOriginal) { - binding= spec; - } - } - } catch (DOMException e) { - } - } - } - } - if (name.getParent() instanceof ICPPASTTemplateId) { + IASTName name= data.astName; + IASTNode nameParent= name.getParent(); + if (nameParent instanceof ICPPASTTemplateId) { if (binding instanceof ICPPTemplateInstance) { - IBinding b = binding; - binding = ((ICPPTemplateInstance)binding).getSpecializedBinding(); + final ICPPTemplateInstance instance = (ICPPTemplateInstance)binding; + binding = instance.getSpecializedBinding(); name.setBinding(binding); - name = (IASTName) name.getParent(); - name.setBinding(b); - } else { - name = (IASTName) name.getParent(); - } + ((ICPPASTTemplateId) nameParent).setBinding(instance); + } + name= (ICPPASTTemplateId) nameParent; + nameParent= name.getParent(); } - if (name.getParent() instanceof ICPPASTQualifiedName) { - if (name == ((ICPPASTQualifiedName)name.getParent()).getLastName()) - name = (IASTName) name.getParent(); + if (nameParent instanceof ICPPASTQualifiedName) { + if (name == ((ICPPASTQualifiedName) nameParent).getLastName()) { + name= (IASTName) nameParent; + nameParent= name.getParent(); + } } // if the lookup in base-classes ran into a deferred instance, use the computed unknown binding. @@ -1585,6 +1542,11 @@ public class CPPSemantics { if (candidate instanceof ICPPClassTemplatePartialSpecialization) return null; + // specialization is selected during instantiation + // mstodo why not? +// if (candidate instanceof ICPPTemplateInstance && candidate instanceof IType) +// candidate= ((ICPPTemplateInstance) candidate).getSpecializedBinding(); + return candidate; } } @@ -1737,9 +1699,16 @@ public class CPPSemantics { } else { continue; } + + // specialization is selected during instantiation + // mstodo why not? +// if (temp instanceof ICPPTemplateInstance && temp instanceof IType) +// temp= ((ICPPTemplateInstance) temp).getSpecializedBinding(); + // select among those bindings that have been created without problems. - if (temp instanceof IProblemBinding) + if (temp instanceof IProblemBinding) continue; + if (!(temp instanceof ICPPMember) && !declaredBefore) continue; if (temp instanceof ICPPUsingDeclaration) { 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 e10e2982784..67fb0f1d0ef 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 @@ -381,7 +381,7 @@ public class CPPTemplates { if (element instanceof ICPPASTTemplateId) { ++i; if (i == idx) { - binding = ((ICPPASTTemplateId) element).getTemplateName().resolveBinding(); + binding = ((ICPPASTTemplateId) element).resolveBinding(); break; } } @@ -426,10 +426,9 @@ public class CPPTemplates { public static IBinding createBinding(ICPPASTTemplateId id) { IASTNode parent = id.getParent(); - int segment = -1; + boolean isLastName= true; if (parent instanceof ICPPASTQualifiedName) { - IASTName[] ns = ((ICPPASTQualifiedName) parent).getNames(); - segment = (ns[ns.length - 1] == id) ? 1 : 0; + isLastName= ((ICPPASTQualifiedName) parent).getLastName() == id; parent = parent.getParent(); } @@ -443,50 +442,65 @@ public class CPPTemplates { } try { - if (decl instanceof ICPPASTExplicitTemplateInstantiation && - parent instanceof ICPPASTElaboratedTypeSpecifier && segment != 0) { - return createExplicitClassInstantiation((ICPPASTElaboratedTypeSpecifier) parent); - } else if (((parent instanceof ICPPASTElaboratedTypeSpecifier && - decl instanceof ICPPASTTemplateDeclaration) || - parent instanceof ICPPASTCompositeTypeSpecifier) && - segment != 0) { - return createExplicitClassSpecialization((ICPPASTDeclSpecifier) parent); - } else if (parent instanceof ICPPASTFunctionDeclarator && segment != 0) { - return createFunctionSpecialization(id); - } + final boolean isClassDecl= parent instanceof ICPPASTElaboratedTypeSpecifier; + final boolean isClassDef = parent instanceof ICPPASTCompositeTypeSpecifier; + + if (isLastName) { + if (isClassDecl && decl instanceof ICPPASTExplicitTemplateInstantiation) + return createExplicitClassInstantiation((ICPPASTElaboratedTypeSpecifier) parent); + + if (isClassDef || (isClassDecl && decl instanceof ICPPASTTemplateDeclaration)) + return createExplicitClassSpecialization((ICPPASTDeclSpecifier) parent); - //a reference: class or function template? - IBinding template = null; - if (parent instanceof ICPPASTNamedTypeSpecifier || - parent instanceof ICPPASTElaboratedTypeSpecifier || - parent instanceof ICPPASTBaseSpecifier || - segment == 0) { - //class template + if (parent instanceof ICPPASTFunctionDeclarator) + return createFunctionSpecialization(id); + } + + if (!isLastName || isClassDecl || parent instanceof ICPPASTNamedTypeSpecifier || + parent instanceof ICPPASTBaseSpecifier) { + // class template instance IASTName templateName = id.getTemplateName(); - template = templateName.resolveBinding(); - if (template instanceof ICPPClassTemplatePartialSpecialization) { - //specializations are selected during the instantiation, start with the primary template - try { - template = ((ICPPClassTemplatePartialSpecialization) template).getPrimaryClassTemplate(); - } catch (DOMException e) { - return e.getProblem(); - } - } else if (template instanceof ICPPSpecialization && !(template instanceof ICPPTemplateDefinition)) { - template = ((ICPPSpecialization) template).getSpecializedBinding(); + IBinding template = templateName.resolveBinding(); + if (template instanceof ICPPUnknownClassInstance) { + // mstodo we should not get here, rather than that an unknown class + // should be made to an unknown class instance here + return template; + } + if (template instanceof ICPPConstructor) { + template= template.getOwner(); } - if (template instanceof ICPPTemplateDefinition) { - ICPPTemplateArgument[] args= CPPTemplates.createTemplateArgumentArray(id); - IBinding instance= instantiate((ICPPTemplateDefinition) template, args); - return CPPSemantics.postResolution(instance, id); - } - } else { - //functions are instantiated as part of the resolution process - template = CPPVisitor.createBinding(id); - if (template instanceof ICPPTemplateInstance) { - IASTName templateName = id.getTemplateName(); - templateName.setBinding(((ICPPTemplateInstance) template).getTemplateDefinition()); + if (!(template instanceof ICPPClassTemplate) || template instanceof ICPPClassTemplatePartialSpecialization) + return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TYPE, templateName.toCharArray()); + + final ICPPClassTemplate classTemplate = (ICPPClassTemplate) template; + ICPPTemplateArgument[] args= createTemplateArgumentArray(id); + ICPPASTTemplateDeclaration tdecl= getTemplateDeclaration(id); + if (tdecl != null) { + if (hasDependentArgument(args)) { + IBinding result= null; + if (argsAreTrivial(classTemplate.getTemplateParameters(), args)) { + result= classTemplate; + } else { + ICPPClassTemplatePartialSpecialization partialSpec= findPartialSpecialization(classTemplate, args); + if (partialSpec == null) + return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TYPE, templateName.toCharArray()); + result= partialSpec; + } + if (isClassDecl && result instanceof ICPPInternalBinding) + ((ICPPInternalBinding) result).addDeclaration(id); + return result; + } } + IBinding instance= instantiate(classTemplate, args); + return CPPSemantics.postResolution(instance, id); + } + + //functions are instantiated as part of the resolution process + IBinding template = CPPVisitor.createBinding(id); + if (template instanceof ICPPTemplateInstance) { + IASTName templateName = id.getTemplateName(); + templateName.setBinding(((ICPPTemplateInstance) template).getTemplateDefinition()); } return template; } catch (DOMException e) { @@ -571,22 +585,10 @@ public class CPPTemplates { } return inst; } - //else partial specialization - //CPPClassTemplate template = (CPPClassTemplate) binding; - ICPPClassTemplatePartialSpecialization spec= null; - try { - ICPPClassTemplatePartialSpecialization[] specs = template.getPartialSpecializations(); - if (specs != null) { - for (ICPPClassTemplatePartialSpecialization specialization : specs) { - if (isSameTemplate(specialization, id)) { - spec = specialization; - break; - } - } - } - } catch (DOMException e) { - } - + + // we have a partial specialization + ICPPTemplateArgument[] args= createTemplateArgumentArray(id); + ICPPClassTemplatePartialSpecialization spec= findPartialSpecialization(template, args); if (spec != null) { if (spec instanceof ICPPInternalBinding) ((ICPPInternalBinding) spec).addDefinition(id); @@ -594,6 +596,7 @@ public class CPPTemplates { } spec = new CPPClassTemplatePartialSpecialization(id); + // mstodo how to add partial specialization to class template from index? if (template instanceof ICPPInternalClassTemplate) ((ICPPInternalClassTemplate) template).addPartialSpecialization(spec); return spec; @@ -609,7 +612,7 @@ public class CPPTemplates { } CPPSemantics.lookup(data, scope); - ICPPFunctionTemplate function = resolveTemplateFunctions((Object[]) data.foundItems, name); + ICPPFunctionTemplate function= resolveTemplateFunctions((Object[]) data.foundItems, name); if (function == null) return new ProblemBinding(name, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, name.toCharArray()); if (function instanceof IProblemBinding) @@ -628,22 +631,33 @@ public class CPPTemplates { if (args == null) return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_TYPE, name.toCharArray()); + IBinding result= null; + if (hasDependentArgument(args)) { + // we are looking at a definition for a function-template. + final ICPPTemplateParameter[] pars= function.getTemplateParameters(); + if (!argsAreTrivial(pars, args)) { + return new ProblemBinding(name, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, name.toCharArray()); + } + result= function; + } else { + result= getInstance(function, args); + if (result == null) { + IBinding owner= function.getOwner(); + ICPPTemplateInstance instance= createInstance(owner, function, tpMap, args); + addInstance(function, args, instance); + result= instance; + } + } while (!(parent instanceof IASTDeclaration)) parent = parent.getParent(); - IBinding owner= function.getOwner(); - ICPPTemplateInstance instance= getInstance(function, args); - if (instance == null) { - instance = createInstance(owner, function, tpMap, args); - addInstance(function, args, instance); - } - if (instance instanceof ICPPInternalBinding) { + if (result instanceof ICPPInternalBinding) { if (parent instanceof IASTSimpleDeclaration) - ((ICPPInternalBinding) instance).addDeclaration(name); + ((ICPPInternalBinding) result).addDeclaration(name); else if (parent instanceof IASTFunctionDefinition) - ((ICPPInternalBinding) instance).addDefinition(name); + ((ICPPInternalBinding) result).addDefinition(name); } - return instance; + return result; } catch (DOMException e) { return e.getProblem(); } @@ -1642,6 +1656,22 @@ public class CPPTemplates { return d1 - d2; } + private static ICPPClassTemplatePartialSpecialization findPartialSpecialization(ICPPClassTemplate ct, ICPPTemplateArgument[] args) throws DOMException { + ICPPClassTemplatePartialSpecialization[] pspecs = ct.getPartialSpecializations(); + if (pspecs != null && pspecs.length > 0) { + final String argStr= ASTTypeUtil.getArgumentListString(args, true); + for (ICPPClassTemplatePartialSpecialization pspec : pspecs) { + try { + if (argStr.equals(ASTTypeUtil.getArgumentListString(pspec.getTemplateArguments(), true))) + return pspec; + } catch (DOMException e) { + // ignore partial specializations with problems + } + } + } + return null; + } + static public ICPPTemplateDefinition selectSpecialization(ICPPClassTemplate template, ICPPTemplateArgument[] args) throws DOMException { if (template == null) { @@ -1874,12 +1904,41 @@ public class CPPTemplates { return cost != null && cost.rank != Cost.NO_MATCH_RANK; } + private static boolean argsAreTrivial(ICPPTemplateParameter[] pars, ICPPTemplateArgument[] args) { + if (pars.length != args.length) { + return false; + } + for (int i = 0; i < args.length; i++) { + ICPPTemplateParameter par= pars[i]; + ICPPTemplateArgument arg = args[i]; + if (par instanceof IType) { + IType argType= arg.getTypeValue(); + if (argType == null || !argType.isSameType((IType) par)) + return false; + } else { + int parpos= Value.isTemplateParameter(arg.getNonTypeValue()); + if (parpos != par.getParameterPosition()) + return false; + } + } + return true; + } + + public static boolean hasDependentArgument(ICPPTemplateArgument[] args) { + for (ICPPTemplateArgument arg : args) { + if (isDependentArgument(arg)) + return true; + } + return false; + } + public static boolean isDependentArgument(ICPPTemplateArgument arg) { if (arg.isTypeValue()) return isDependentType(arg.getTypeValue()); return Value.isDependentValue(arg.getNonTypeValue()); } + public static boolean isDependentType(IType t) { // mstodo needs to be extended if (t instanceof ICPPTemplateParameter)