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 7c43c703e56..d16f4b96b4d 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 @@ -2684,4 +2684,32 @@ public class AST2TemplateTests extends AST2BaseTest { ICPPTemplateTypeParameter T3b= ba.assertNonProblem("T3)", 2, ICPPTemplateTypeParameter.class); ICPPClassType b= ba.assertNonProblem("B<>", 3, ICPPClassType.class, ICPPTemplateInstance.class); } + + // template class A {public: class X {};}; + // template class A {public: class Y {};}; + // template class A {public: class Z {};}; + // + // class B {}; + // + // A::X x; + // A::Y y; + // A::Z z; + public void testNonTypeArgumentDisambiguation_233460() throws Exception { + BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true); + ICPPClassType b2= ba.assertNonProblem("A", 7, ICPPClassType.class, ICPPTemplateInstance.class); + ICPPClassType b3= ba.assertNonProblem("A", 7, ICPPClassType.class, ICPPTemplateInstance.class); + ICPPClassType b4= ba.assertNonProblem("A", 7, ICPPClassType.class, ICPPTemplateInstance.class); + + assertTrue(!b2.isSameType(b3)); + assertTrue(!b3.isSameType(b4)); + assertTrue(!b4.isSameType(b2)); + + ICPPClassType X= ba.assertNonProblem("X x", 1, ICPPClassType.class); + ICPPClassType Y= ba.assertNonProblem("Y y", 1, ICPPClassType.class); + ICPPClassType Z= ba.assertNonProblem("Z z", 1, ICPPClassType.class); + + assertTrue(!X.isSameType(Y)); + assertTrue(!Y.isSameType(Z)); + assertTrue(!Z.isSameType(X)); + } } 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 2870f1c315c..5263a338a41 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 @@ -57,6 +57,7 @@ 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.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; @@ -1056,23 +1057,22 @@ public class CPPTemplates { if (definition instanceof ICPPClassTemplatePartialSpecialization) { ICPPClassTemplatePartialSpecialization spec = (ICPPClassTemplatePartialSpecialization) definition; IASTNode[] args = ((ICPPASTTemplateId) name).getTemplateArguments(); - IType[] specArgs = null; try { - specArgs = spec.getArguments(); + IType[] specArgs = spec.getArguments(); + if (args.length == specArgs.length) { + int i = 0; + for (; i < args.length; i++) { + IType t1 = specArgs[i]; + IType t2 = CPPVisitor.createType(args[i]); + if (isSameTemplateArgument(t1, t2)) + continue; + break; + } + result = (i == args.length); + } } catch (DOMException e) { result = false; } - if (specArgs != null && args.length == specArgs.length) { - int i = 0; - for (; i < args.length; i++) { - IType t1 = specArgs[i]; - IType t2 = CPPVisitor.createType(args[i]); - if (t1 != null && t2 != null && t1.isSameType(t2)) - continue; - break; - } - result = (i == args.length); - } } } else { result = CharArrayUtils.equals(definition.getNameCharArray(), name.toCharArray()); @@ -1087,6 +1087,27 @@ public class CPPTemplates { return result; } + /** + * @param argA + * @param argB + * @return whether the two specified template arguments are the same + * @throws DOMException + */ + private static final boolean isSameTemplateArgument(IType argA, IType argB) throws DOMException { + // special case treatment for non-type integral parameters + if(argA instanceof ICPPBasicType && argB instanceof ICPPBasicType) { + IASTExpression eA= ((ICPPBasicType) argA).getValue(); + IASTExpression eB= ((ICPPBasicType) argB).getValue(); + if(eA != null && eB != null) { + return expressionsEquivalent(eA, eB); + } else if(eA == null ^ eB == null) { + return false; + } + } + + return argA != null && argB != null && argA.isSameType(argB); + } + static public IType[] createTypeArray(Object[] params) { if (params == null) return IType.EMPTY_TYPE_ARRAY;