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 723979cc4d0..4e82a76857a 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 @@ -1526,11 +1526,11 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa ICPPTemplateInstance inst= (ICPPTemplateInstance) t1; final ICPPClassTemplate tmplDef = (ICPPClassTemplate) inst.getTemplateDefinition(); - IBinding inst2= CPPTemplates.instantiate(tmplDef, inst.getTemplateArguments()); + IBinding inst2= CPPTemplates.instantiate(tmplDef, inst.getTemplateArguments(), false); assertSame(inst, inst2); - IBinding charInst1= CPPTemplates.instantiate(tmplDef, new ICPPTemplateArgument[] {new CPPTemplateArgument(new CPPBasicType(Kind.eChar, 0))}); - IBinding charInst2= CPPTemplates.instantiate(tmplDef, new ICPPTemplateArgument[] {new CPPTemplateArgument(new CPPBasicType(Kind.eChar, 0))}); + IBinding charInst1= CPPTemplates.instantiate(tmplDef, new ICPPTemplateArgument[] {new CPPTemplateArgument(new CPPBasicType(Kind.eChar, 0))}, false); + IBinding charInst2= CPPTemplates.instantiate(tmplDef, new ICPPTemplateArgument[] {new CPPTemplateArgument(new CPPBasicType(Kind.eChar, 0))}, false); assertSame(charInst1, charInst2); } 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 ee716d09d8a..eef7eab9818 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 @@ -16,12 +16,16 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; 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.internal.core.dom.parser.cpp.semantics.CPPTemplates; +import org.eclipse.cdt.internal.core.index.IIndexType; /** * The result of instantiating a class template. @@ -59,4 +63,32 @@ public class CPPClassInstance extends CPPClassSpecialization implements ICPPTemp public boolean equals(Object obj) { return obj instanceof ICPPClassType && isSameType((ICPPClassType) obj); } + + @Override + public boolean isSameType(IType type) { + if (type == this) + return true; + if (type instanceof ITypedef || type instanceof IIndexType) + return type.isSameType(this); + + return isSameClassInstance(this, type); + } + + public static boolean isSameClassInstance(ICPPClassSpecialization classInstance, IType type) { + assert classInstance instanceof ICPPTemplateInstance; + + // require a class instance + if (!(type instanceof ICPPClassSpecialization) || !(type instanceof ICPPTemplateInstance) || + type instanceof IProblemBinding) { + return false; + } + + final ICPPClassSpecialization classSpec2 = (ICPPClassSpecialization) type; + final ICPPClassType orig1= classInstance.getSpecializedBinding(); + final ICPPClassType orig2= classSpec2.getSpecializedBinding(); + if (!orig1.isSameType(orig2)) + return false; + + return CPPTemplates.haveSameArguments((ICPPTemplateInstance) classInstance, (ICPPTemplateInstance) type); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java index b0480de4507..4bb256b3e4d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java @@ -22,6 +22,7 @@ import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IField; +import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; @@ -37,6 +38,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; +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.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.ObjectMap; @@ -277,11 +280,15 @@ public class CPPClassSpecialization extends CPPSpecialization /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IType#isSameType(org.eclipse.cdt.core.dom.ast.IType) */ - public final boolean isSameType(IType type) { - if( type == this ) + public boolean isSameType(IType type) { + if (type == this) return true; - if( type instanceof ITypedef || type instanceof IIndexType ) - return type.isSameType( this ); + if (type instanceof ITypedef || type instanceof IIndexType) + return type.isSameType(this); + + if (type instanceof ICPPClassSpecialization) { + return isSameClassSpecialization(this, (ICPPClassSpecialization) type); + } return false; } @@ -308,4 +315,34 @@ public class CPPClassSpecialization extends CPPSpecialization } return false; } + + + public static boolean isSameClassSpecialization(ICPPClassSpecialization t1, ICPPClassSpecialization t2) { + // exclude class template specialization or class instance + if (t2 instanceof ICPPTemplateInstance || t2 instanceof ICPPTemplateDefinition || + t2 instanceof IProblemBinding) + return false; + + try { + if (t1.getKey() != t2.getKey()) + return false; + + if (!CharArrayUtils.equals(t1.getNameCharArray(), t2.getNameCharArray())) + return false; + + // the argument map is not significant for comparing specializations, the map is + // determined by the owner of the specialization. This is different for instances, + // which have a separate implementation for isSameType(). + final IBinding owner1= t1.getOwner(); + final IBinding owner2= t2.getOwner(); + + // for a specialization that is not an instance the owner has to be a class-type + if (owner1 instanceof ICPPClassType == false || owner2 instanceof ICPPClassType == false) + return false; + + return ((ICPPClassType) owner1).isSameType((ICPPClassType) owner2); + } catch (DOMException e) { + return false; + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecialization.java index e21a655f802..af7ab84839f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecialization.java @@ -15,14 +15,17 @@ import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; 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.ITypedef; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; 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.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; +import org.eclipse.cdt.internal.core.index.IIndexType; /** * A partial class template specialization. @@ -86,4 +89,44 @@ public class CPPClassTemplatePartialSpecialization extends CPPClassTemplate public IType[] getArguments() throws DOMException { return CPPTemplates.getArguments(getTemplateArguments()); } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IType#isSameType(org.eclipse.cdt.core.dom.ast.IType) + */ + @Override + public boolean isSameType(IType type) { + if (type == this) + return true; + if (type instanceof ITypedef || type instanceof IIndexType) + return type.isSameType(this); + + if (type instanceof ICPPClassTemplatePartialSpecialization) { + return isSamePartialClassSpecialization(this, (ICPPClassTemplatePartialSpecialization) type); + } + return false; + } + + public static boolean isSamePartialClassSpecialization( + ICPPClassTemplatePartialSpecialization lhs, + ICPPClassTemplatePartialSpecialization rhs) { + try { + ICPPClassType ct1= lhs.getPrimaryClassTemplate(); + ICPPClassType ct2= rhs.getPrimaryClassTemplate(); + if(!ct1.isSameType(ct2)) + return false; + + ICPPTemplateArgument[] args1= lhs.getTemplateArguments(); + ICPPTemplateArgument[] args2= rhs.getTemplateArguments(); + if (args1.length != args2.length) + return false; + + for (int i = 0; i < args2.length; i++) { + if (args1[i].isSameValue(args2[i])) + return false; + } + } catch (DOMException e) { + return false; + } + return true; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScopeMapper.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScopeMapper.java index 5b9303b73c1..6ccecac7e23 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScopeMapper.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScopeMapper.java @@ -295,7 +295,7 @@ public class CPPScopeMapper { if (template instanceof IIndexBinding && template instanceof ICPPClassType) { IBinding mapped= mapToAST((ICPPClassType) template); if (mapped != template && mapped instanceof ICPPClassType) { - mapped= CPPTemplates.instantiate((ICPPClassTemplate) mapped, inst.getTemplateArguments()); + mapped= CPPTemplates.instantiate((ICPPClassTemplate) mapped, inst.getTemplateArguments(), false); if (mapped instanceof ICPPClassType) return (ICPPClassType) mapped; } 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 0b04ee9c13f..f9947db6dc9 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 @@ -367,7 +367,7 @@ public class CPPSemantics { if (data.tu != null) { ICPPASTTemplateId id = (ICPPASTTemplateId) data.astName; ICPPTemplateArgument[] args = CPPTemplates.createTemplateArgumentArray(id); - IBinding inst= CPPTemplates.instantiate((ICPPClassTemplate) cls, args); + IBinding inst= CPPTemplates.instantiate((ICPPClassTemplate) cls, args, false); if (inst instanceof ICPPClassType) { cls= (ICPPClassType) inst; } 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 46be86d7fd4..f9993145832 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 @@ -84,6 +84,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; +import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArraySet; import org.eclipse.cdt.core.parser.util.CharArrayUtils; @@ -149,7 +150,7 @@ public class CPPTemplates { /** * Instantiates a class template with the given arguments. May return null. */ - public static IBinding instantiate(ICPPClassTemplate template, ICPPTemplateArgument[] arguments) { + public static IBinding instantiate(ICPPClassTemplate template, ICPPTemplateArgument[] arguments, boolean isDef) { try { arguments= SemanticUtil.getSimplifiedArguments(arguments); if (template instanceof ICPPTemplateTemplateParameter || hasDependentArgument(arguments)) { @@ -157,7 +158,7 @@ public class CPPTemplates { } if (template instanceof ICPPClassTemplatePartialSpecialization) { - return instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) template, arguments); + return instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) template, arguments, isDef); } // check whether we need to use default arguments @@ -209,10 +210,10 @@ public class CPPTemplates { return tdef; if (tdef instanceof ICPPClassTemplatePartialSpecialization) { - return instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) tdef, completeArgs); + return instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) tdef, completeArgs, isDef); } - return instantiatePrimaryTemplate(template, completeArgs, map); + return instantiatePrimaryTemplate(template, completeArgs, map, isDef); } catch (DOMException e) { return e.getProblem(); } @@ -269,8 +270,8 @@ public class CPPTemplates { /** * Instantiates a partial class template specialization. */ - private static IBinding instantiatePartialSpecialization(ICPPClassTemplatePartialSpecialization partialSpec, ICPPTemplateArgument[] args) throws DOMException { - ICPPTemplateInstance instance= getInstance(partialSpec, args); + private static IBinding instantiatePartialSpecialization(ICPPClassTemplatePartialSpecialization partialSpec, ICPPTemplateArgument[] args, boolean isDef) throws DOMException { + ICPPTemplateInstance instance= getInstance(partialSpec, args, isDef); if (instance != null) return instance; @@ -296,10 +297,10 @@ public class CPPTemplates { * @param map */ private static IBinding instantiatePrimaryTemplate(ICPPClassTemplate template, ICPPTemplateArgument[] arguments, - CPPTemplateParameterMap map) throws DOMException { + CPPTemplateParameterMap map, boolean isDef) throws DOMException { assert !(template instanceof ICPPClassTemplatePartialSpecialization); - ICPPTemplateInstance instance= getInstance(template, arguments); + ICPPTemplateInstance instance= getInstance(template, arguments, isDef); if (instance != null) { return instance; } @@ -312,7 +313,7 @@ public class CPPTemplates { private static IBinding instantiateFunctionTemplate(ICPPFunctionTemplate template, ICPPTemplateArgument[] arguments) throws DOMException { - ICPPTemplateInstance instance= getInstance(template, arguments); + ICPPTemplateInstance instance= getInstance(template, arguments, false); if (instance != null) { return instance; } @@ -336,9 +337,12 @@ public class CPPTemplates { /** * Obtains a cached instance from the template. */ - private static ICPPTemplateInstance getInstance(ICPPTemplateDefinition template, ICPPTemplateArgument[] args) { + private static ICPPTemplateInstance getInstance(ICPPTemplateDefinition template, ICPPTemplateArgument[] args, boolean forDefinition) { if (template instanceof ICPPInstanceCache) { - return ((ICPPInstanceCache) template).getInstance(args); + ICPPTemplateInstance result = ((ICPPInstanceCache) template).getInstance(args); + if (forDefinition && result instanceof IIndexBinding) + return null; + return result; } return null; } @@ -353,7 +357,7 @@ public class CPPTemplates { } private static IBinding deferredInstance(ICPPClassTemplate template, ICPPTemplateArgument[] arguments) throws DOMException { - ICPPTemplateInstance instance= getInstance(template, arguments); + ICPPTemplateInstance instance= getInstance(template, arguments, false); if (instance != null) return instance; @@ -590,7 +594,7 @@ public class CPPTemplates { } } if (result == null) { - result= instantiate(classTemplate, args); + result= instantiate(classTemplate, args, isDef); if (result instanceof ICPPInternalBinding) { if (isDecl) { ASTInternal.addDeclaration(result, id); @@ -2211,7 +2215,7 @@ public class CPPTemplates { ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments( ((ICPPUnknownClassInstance) unknown).getArguments(), tpMap, within); if (result instanceof ICPPClassTemplate) { - result = instantiate((ICPPClassTemplate) result, newArgs); + result = instantiate((ICPPClassTemplate) result, newArgs, false); } } } @@ -2235,7 +2239,7 @@ public class CPPTemplates { } if (changed) { - IBinding inst= instantiate(classTemplate, newArgs); + IBinding inst= instantiate(classTemplate, newArgs, false); if (inst != null) return inst; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassInstance.java index 7738d584a2c..dc89417c4cf 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassInstance.java @@ -13,14 +13,13 @@ package org.eclipse.cdt.internal.core.pdom.dom.cpp; import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; 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.internal.core.dom.parser.cpp.CPPClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; @@ -90,19 +89,7 @@ class PDOMCPPClassInstance extends PDOMCPPClassSpecialization implements ICPPTem } } - // require a class instance - if (!(type instanceof ICPPClassSpecialization) || !(type instanceof ICPPTemplateInstance) || - type instanceof IProblemBinding) { - return false; - } - - final ICPPClassSpecialization classSpec2 = (ICPPClassSpecialization) type; - final ICPPClassType orig1= getSpecializedBinding(); - final ICPPClassType orig2= classSpec2.getSpecializedBinding(); - if (!orig1.isSameType(orig2)) - return false; - - return CPPTemplates.haveSameArguments(this, (ICPPTemplateInstance) type); + return CPPClassInstance.isSameClassInstance(this, type); } @Deprecated diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java index 05eec997dbe..201aa971f9c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java @@ -21,7 +21,6 @@ import org.eclipse.cdt.core.dom.IPDOMVisitor; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IField; -import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; @@ -33,10 +32,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; -import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.ObjectMap; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; @@ -310,35 +307,10 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements } // require a class specialization - if (type instanceof ICPPSpecialization == false || type instanceof IProblemBinding) + if (!(type instanceof ICPPClassSpecialization)) return false; - - // exclude class template specialization or class instance - if (type instanceof ICPPTemplateInstance || type instanceof ICPPTemplateDefinition) - return false; - - final ICPPClassSpecialization classSpec2 = (ICPPClassSpecialization) type; - try { - if (getKey() != classSpec2.getKey()) - return false; - - if (!CharArrayUtils.equals(getNameCharArray(), classSpec2.getNameCharArray())) - return false; - - // the argument map is not significant for comparing specializations, the map is - // determined by the owner of the specialization. This is different for instances, - // which have a separate implementation for isSameType(). - final IBinding owner1= getOwner(); - final IBinding owner2= classSpec2.getOwner(); - - // for a specialization that is not an instance the owner has to be a class-type - if (owner1 instanceof ICPPClassType == false || owner2 instanceof ICPPClassType == false) - return false; - return ((ICPPClassType) owner1).isSameType((ICPPClassType) owner2); - } catch (DOMException e) { - return false; - } + return CPPClassSpecialization.isSameClassSpecialization(this, (ICPPClassSpecialization) type); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecializationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecializationSpecialization.java index b27794abba0..95b6545c061 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecializationSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecializationSpecialization.java @@ -17,8 +17,8 @@ import org.eclipse.cdt.core.dom.ast.ITypedef; 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.ICPPClassTemplatePartialSpecializationSpecialization; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassTemplatePartialSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.pdom.db.Database; @@ -100,25 +100,7 @@ class PDOMCPPClassTemplatePartialSpecializationSpecialization extends PDOMCPPCla } final ICPPClassTemplatePartialSpecialization rhs = (ICPPClassTemplatePartialSpecialization)type; - try { - ICPPClassType ct1= getPrimaryClassTemplate(); - ICPPClassType ct2= rhs.getPrimaryClassTemplate(); - if(!ct1.isSameType(ct2)) - return false; - - ICPPTemplateArgument[] args1= getTemplateArguments(); - ICPPTemplateArgument[] args2= rhs.getTemplateArguments(); - if (args1.length != args2.length) - return false; - - for (int i = 0; i < args2.length; i++) { - if (args1[i].isSameValue(args2[i])) - return false; - } - } catch (DOMException e) { - return false; - } - return true; + return CPPClassTemplatePartialSpecialization.isSamePartialClassSpecialization(this, rhs); } public ICPPClassTemplate getPrimaryClassTemplate() { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java index e798c5260e1..d814c17b5d7 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java @@ -310,9 +310,23 @@ class OpenDeclarationsJob extends Job implements ASTRunnable { declNames.addAll(Arrays.asList(ast.getDefinitionsInAST(binding))); for (Iterator i = declNames.iterator(); i.hasNext();) { IASTName name= i.next(); - if (name.resolveBinding() instanceof ICPPUsingDeclaration) { + final IBinding b2 = name.resolveBinding(); + if (b2 instanceof ICPPUsingDeclaration) { i.remove(); } + if (binding != b2 && binding instanceof ICPPSpecialization) { + // make sure binding specializes b2 so that for instance we do not navigate from + // one partial specialization to another. + IBinding spec= binding; + while (spec instanceof ICPPSpecialization) { + spec= ((ICPPSpecialization) spec).getSpecializedBinding(); + if (spec == b2) + break; + } + if (!(spec instanceof ICPPSpecialization)) { + i.remove(); + } + } } if (!declNames.isEmpty()) { return declNames.toArray(new IASTName[declNames.size()]);