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()]);