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 3f188e5fedc..d3ca3056055 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 @@ -1805,7 +1805,10 @@ public class AST2TemplateTests extends AST2BaseTest { ICPPClassType BI = (ICPPClassType) col.getName(19).resolveBinding(); assertTrue(BI instanceof ICPPTemplateInstance); - assertSame(((ICPPTemplateInstance)BI).getSpecializedBinding(), spec); + final IBinding partialSpecSpec = ((ICPPTemplateInstance)BI).getSpecializedBinding(); + assertTrue(partialSpecSpec instanceof ICPPSpecialization); + IBinding partialSpec= ((ICPPSpecialization) partialSpecSpec).getSpecializedBinding(); + assertSame(partialSpec, spec); } // template int f(T); // #1 @@ -3592,7 +3595,7 @@ public class AST2TemplateTests extends AST2BaseTest { // new A(&B::m); // } // }; - public void _testNestedTemplates_259872_2() throws Exception { + public void testNestedTemplates_259872_2() throws Exception { BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true); bh.assertNonProblem("A", 9, ICPPConstructor.class); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplatePartialSpecializationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplatePartialSpecializationSpecialization.java new file mode 100644 index 00000000000..964f542e6c3 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplatePartialSpecializationSpecialization.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2009 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.dom.ast.cpp; + +/** + * Interface for specializations of partial specializations. + * + * @since 5.1 + * @noextend This interface is not intended to be extended by clients. + * @noimplement This interface is not intended to be implemented by clients. + */ +public interface ICPPClassTemplatePartialSpecializationSpecialization extends + ICPPClassTemplatePartialSpecialization, ICPPClassSpecialization { + +} 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 28d9da07dad..b0480de4507 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 @@ -1,12 +1,12 @@ /******************************************************************************* - * Copyright (c) 2005, 2008 IBM Corporation and others. + * Copyright (c) 2005, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM - Initial API and implementation + * Andrew Niefer (IBM) - Initial API and implementation * Bryan Wilkinson (QNX) * Markus Schorn (Wind River Systems) *******************************************************************************/ @@ -44,8 +44,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.index.IIndexType; /** - * @author aniefer - * + * Specialization of a class. */ public class CPPClassSpecialization extends CPPSpecialization implements ICPPClassSpecialization, ICPPInternalClassTypeMixinHost { @@ -71,7 +70,7 @@ public class CPPClassSpecialization extends CPPSpecialization return result; } - IBinding result= CPPTemplates.createSpecialization(this, original, getTemplateParameterMap()); + IBinding result= CPPTemplates.createSpecialization(this, original); synchronized(this) { IBinding concurrent= (IBinding) specializationMap.get(original); if (concurrent != null) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecializationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecializationSpecialization.java new file mode 100644 index 00000000000..343dd9e949e --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecializationSpecialization.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright (c) 2009 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +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.cpp.ICPPClassSpecialization; +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.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; +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; + +/** + * Represents a specialization of a partial class-template specialization + */ +public class CPPClassTemplatePartialSpecializationSpecialization extends CPPClassSpecialization + implements ICPPClassTemplatePartialSpecializationSpecialization, ICPPInternalClassTemplate { + + private ObjectMap instances = null; + private ICPPDeferredClassInstance fDeferredInstance; + private ICPPClassTemplate fClassTemplate; + + public CPPClassTemplatePartialSpecializationSpecialization(ICPPClassTemplatePartialSpecialization orig, ICPPClassTemplate template, ICPPTemplateParameterMap argumentMap) throws DOMException { + super(orig, template.getOwner(), argumentMap); + fClassTemplate= template; + } + + public ICPPTemplateParameter[] getTemplateParameters() throws DOMException { + ICPPClassTemplatePartialSpecialization template = (ICPPClassTemplatePartialSpecialization) getSpecializedBinding(); + return template.getTemplateParameters(); + } + + public synchronized final void addInstance(ICPPTemplateArgument[] arguments, ICPPTemplateInstance instance) { + if (instances == null) + instances = new ObjectMap(2); + String key= ASTTypeUtil.getArgumentListString(arguments, true); + instances.put(key, instance); + } + + public synchronized final ICPPTemplateInstance getInstance(ICPPTemplateArgument[] arguments) { + if (instances != null) { + String key= ASTTypeUtil.getArgumentListString(arguments, true); + return (ICPPTemplateInstance) instances.get(key); + } + return null; + } + + public synchronized ICPPTemplateInstance[] getAllInstances() { + if (instances != null) { + ICPPTemplateInstance[] result= new ICPPTemplateInstance[instances.size()]; + for (int i=0; i < instances.size(); i++) { + result[i]= (ICPPTemplateInstance) instances.getAt(i); + } + return result; + } + return ICPPTemplateInstance.EMPTY_TEMPLATE_INSTANCE_ARRAY; + } + + public IBinding resolveTemplateParameter(ICPPTemplateParameter param) { + return param; + } + + public ICPPDeferredClassInstance asDeferredInstance() throws DOMException { + if (fDeferredInstance == null) { + ICPPTemplateArgument[] args = CPPTemplates.templateParametersAsArguments(getTemplateParameters()); + fDeferredInstance= new CPPDeferredClassInstance(this, args, getCompositeScope()); + } + return fDeferredInstance; + } + + public ICPPClassTemplate getPrimaryClassTemplate() { + return fClassTemplate; + } + + public ICPPTemplateArgument[] getTemplateArguments() throws DOMException { + ICPPTemplateArgument[] args = ((ICPPClassTemplatePartialSpecialization) getSpecializedBinding()).getTemplateArguments(); + final IBinding owner = getOwner(); + if (owner instanceof ICPPClassSpecialization) { + return CPPTemplates.instantiateArguments(args, getTemplateParameterMap(), (ICPPClassSpecialization) owner); + } + return CPPTemplates.instantiateArguments(args, getTemplateParameterMap(), null); + } + + public void addPartialSpecialization(ICPPClassTemplatePartialSpecialization spec) { + } + + public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() throws DOMException { + return ICPPClassTemplatePartialSpecialization.EMPTY_PARTIAL_SPECIALIZATION_ARRAY; + } + + @Override + public String toString() { + try { + return super.toString() + ASTTypeUtil.getArgumentListString(getTemplateArguments(), true); + } catch (DOMException e) { + return super.toString() + '<' + e.getProblem().toString() + '>'; + } + } + + @Override + @Deprecated + public ObjectMap getArgumentMap() { + return CPPTemplates.getArgumentMap(getPrimaryClassTemplate(), getTemplateParameterMap()); + } + + @Deprecated + public IType[] getArguments() throws DOMException { + return CPPTemplates.getArguments(getTemplateArguments()); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java index e94c8a3f07d..1c5500d1751 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2008 IBM Corporation and others. + * Copyright (c) 2005, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -33,22 +33,25 @@ public class CPPClassTemplateSpecialization extends CPPClassSpecialization private ObjectMap instances = null; private ICPPDeferredClassInstance fDeferredInstance; + private ICPPClassTemplatePartialSpecialization[] fPartialSpecs; public CPPClassTemplateSpecialization(ICPPClassTemplate orig, ICPPClassType owner, ICPPTemplateParameterMap argumentMap) { super(orig, owner, argumentMap); } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate#getPartialSpecializations() - */ public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() throws DOMException { - // mstodo the partial specializations need to be specialized - return ((ICPPClassTemplate) getSpecializedBinding()).getPartialSpecializations(); + if (fPartialSpecs == null) { + ICPPClassTemplate origTemplate= (ICPPClassTemplate) getSpecializedBinding(); + ICPPClassTemplatePartialSpecialization[] orig = origTemplate.getPartialSpecializations(); + ICPPClassTemplatePartialSpecialization[] spec = new ICPPClassTemplatePartialSpecialization[orig.length]; + for (int i = 0; i < orig.length; i++) { + spec[i]= (ICPPClassTemplatePartialSpecialization) specializeMember(orig[i]); + } + fPartialSpecs = spec; + } + return fPartialSpecs; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition#getTemplateParameters() - */ public ICPPTemplateParameter[] getTemplateParameters() throws DOMException { ICPPClassTemplate template = (ICPPClassTemplate) getSpecializedBinding(); return template.getTemplateParameters(); @@ -81,17 +84,6 @@ public class CPPClassTemplateSpecialization extends CPPClassSpecialization } public void addPartialSpecialization(ICPPClassTemplatePartialSpecialization spec) { - // mstodo partial specializations for class template specializations. - // this is legal code: - // template class CT { - // template class NT { - // }; - // }; - // // creates a partial spec for the specialization of CT::NT - // template<> template class CT::NT { - // public: - // int spec; - // }; } @Override 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 05bb1c0c04a..ac30f020862 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 @@ -97,6 +97,7 @@ 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; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassTemplatePartialSpecialization; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassTemplatePartialSpecializationSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassTemplateSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPConstructorInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPConstructorSpecialization; @@ -683,14 +684,17 @@ public class CPPTemplates { return instance; } - public static ICPPSpecialization createSpecialization(ICPPClassSpecialization owner, IBinding decl, ICPPTemplateParameterMap tpMap) { - - // mstodo specializations of partial specializations - if (decl instanceof ICPPClassTemplatePartialSpecialization) - return null; - + public static ICPPSpecialization createSpecialization(ICPPClassSpecialization owner, IBinding decl) { ICPPSpecialization spec = null; - if (decl instanceof ICPPClassTemplate) { + final ICPPTemplateParameterMap tpMap= owner.getTemplateParameterMap(); + if (decl instanceof ICPPClassTemplatePartialSpecialization) { + try { + ICPPClassTemplatePartialSpecialization pspec= (ICPPClassTemplatePartialSpecialization) decl; + ICPPClassTemplate template= (ICPPClassTemplate) owner.specializeMember(pspec.getPrimaryClassTemplate()); + spec= new CPPClassTemplatePartialSpecializationSpecialization(pspec, template, tpMap); + } catch (DOMException e) { + } + } else if (decl instanceof ICPPClassTemplate) { spec = new CPPClassTemplateSpecialization((ICPPClassTemplate) decl, owner, tpMap); } else if (decl instanceof ICPPClassType) { spec = new CPPClassSpecialization((ICPPClassType) decl, owner, tpMap); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexCPPBindingConstants.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexCPPBindingConstants.java index 761051150ed..c049efc3c72 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexCPPBindingConstants.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexCPPBindingConstants.java @@ -60,4 +60,5 @@ public interface IIndexCPPBindingConstants { int CPP_TEMPLATE_NON_TYPE_PARAMETER= IIndexBindingConstants.LAST_CONSTANT + 44; int CPP_FRIEND_DECLARATION = IIndexBindingConstants.LAST_CONSTANT + 45; int CPP_TEMPLATE_TEMPLATE_PARAMETER= IIndexBindingConstants.LAST_CONSTANT + 46; + int CPP_CLASS_TEMPLATE_PARTIAL_SPEC_SPEC = IIndexBindingConstants.LAST_CONSTANT + 47; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java index 3919caf0722..5c65ca71854 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java @@ -27,6 +27,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding; 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.ICPPClassTemplatePartialSpecializationSpecialization; 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; @@ -197,6 +198,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { } } else if (binding instanceof ICPPTemplateDefinition) { if (binding instanceof ICPPClassTemplatePartialSpecialization) { + if (binding instanceof ICPPClassTemplatePartialSpecializationSpecialization) + return new CompositeCPPClassTemplatePartialSpecializationSpecialization(this, (ICPPClassTemplatePartialSpecializationSpecialization) binding); return new CompositeCPPClassTemplatePartialSpecialization(this, (ICPPClassTemplatePartialSpecialization) findOneBinding(binding)); } else if (binding instanceof ICPPClassType) { return new CompositeCPPClassTemplateSpecialization(this, (ICPPClassType) binding); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java index 202fa8d5345..ea1d5e065db 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 Symbian Software Systems and others. + * Copyright (c) 2007, 2009 Symbian Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -101,7 +101,7 @@ public class CompositeCPPClassSpecialization extends CompositeCPPClassType imple if (result != null) return result; } - IBinding newSpec= CPPTemplates.createSpecialization(this, original, getTemplateParameterMap()); + IBinding newSpec= CPPTemplates.createSpecialization(this, original); synchronized (specializationMap) { IBinding oldSpec= (IBinding) specializationMap.put(original, newSpec); if (oldSpec != null) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplate.java index 60999e64da8..a294b9a8c63 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplate.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 Symbian Software Systems and others. + * Copyright (c) 2007, 2009 Symbian Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -33,19 +33,23 @@ public class CompositeCPPClassTemplate extends CompositeCPPClassType super(cf, ct); } - public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() - throws DOMException { + public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() throws DOMException { try { - IIndexFragmentBinding[] bindings= ((CIndex)((CPPCompositesFactory) cf).getContext()).findEquivalentBindings(rbinding); - IIndexFragmentBinding[][] preresult= new IIndexFragmentBinding[bindings.length][]; - - for (int i= 0; i < bindings.length; i++) { - ICPPClassTemplatePartialSpecialization[] ss= ((ICPPClassTemplate) bindings[i]).getPartialSpecializations(); - preresult[i]= new IIndexFragmentBinding[ss.length]; + final CIndex cIndex = (CIndex) ((CPPCompositesFactory) cf).getContext(); + IIndexFragmentBinding[] bindings = cIndex.findEquivalentBindings(rbinding); + IIndexFragmentBinding[][] preresult = new IIndexFragmentBinding[bindings.length][]; + + for (int i = 0; i < bindings.length; i++) { + final ICPPClassTemplate template = (ICPPClassTemplate) bindings[i]; + ICPPClassTemplatePartialSpecialization[] ss = template.getPartialSpecializations(); + preresult[i] = new IIndexFragmentBinding[ss.length]; System.arraycopy(ss, 0, preresult[i], 0, ss.length); } - - return (ICPPClassTemplatePartialSpecialization[]) ArrayUtil.addAll(ICPPClassTemplatePartialSpecialization.class, null, cf.getCompositeBindings(preresult)); + + return (ICPPClassTemplatePartialSpecialization[]) ArrayUtil.addAll( + ICPPClassTemplatePartialSpecialization.class, + ICPPClassTemplatePartialSpecialization.EMPTY_PARTIAL_SPECIALIZATION_ARRAY, cf + .getCompositeBindings(preresult)); } catch (CoreException ce) { CCorePlugin.log(ce); return ICPPClassTemplatePartialSpecialization.EMPTY_PARTIAL_SPECIALIZATION_ARRAY; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplatePartialSpecializationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplatePartialSpecializationSpecialization.java new file mode 100644 index 00000000000..4b26642bda8 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplatePartialSpecializationSpecialization.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2009 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.index.composite.cpp; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IType; +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.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache; +import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; +import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; + +public class CompositeCPPClassTemplatePartialSpecializationSpecialization extends + CompositeCPPClassSpecialization implements ICPPClassTemplatePartialSpecializationSpecialization, ICPPInstanceCache { + + public CompositeCPPClassTemplatePartialSpecializationSpecialization(ICompositesFactory cf, ICPPClassTemplatePartialSpecializationSpecialization rbinding) { + super(cf, rbinding); + } + + public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() { + return ICPPClassTemplatePartialSpecialization.EMPTY_PARTIAL_SPECIALIZATION_ARRAY; + } + + public ICPPTemplateParameter[] getTemplateParameters() throws DOMException { + return TemplateInstanceUtil.convert(cf, ((ICPPClassTemplate) rbinding).getTemplateParameters()); + } + + public ICPPTemplateInstance getInstance(ICPPTemplateArgument[] arguments) { + return CompositeInstanceCache.getCache(cf, rbinding).getInstance(arguments); + } + + public void addInstance(ICPPTemplateArgument[] arguments, ICPPTemplateInstance instance) { + CompositeInstanceCache.getCache(cf, rbinding).addInstance(arguments, instance); + } + + public ICPPTemplateInstance[] getAllInstances() { + return CompositeInstanceCache.getCache(cf, rbinding).getAllInstances(); + } + + public ICPPClassTemplate getPrimaryClassTemplate() throws DOMException { + return (ICPPClassTemplate) cf.getCompositeBinding((IIndexFragmentBinding) ((ICPPClassTemplatePartialSpecializationSpecialization) rbinding).getPrimaryClassTemplate()); + } + + public ICPPTemplateArgument[] getTemplateArguments() { + return TemplateInstanceUtil.getTemplateArguments(cf, (ICPPClassTemplatePartialSpecialization) rbinding); + } + + @Deprecated + public IType[] getArguments() { + return TemplateInstanceUtil.getArguments(cf, (ICPPClassTemplatePartialSpecialization) rbinding); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index 3a7dd496ed2..49618d74c89 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -169,11 +169,12 @@ public class PDOM extends PlatformObject implements IPDOM { * 77.0 - support for parameter annotations, bug 254520 * 78.0 - support for updating class templates, bug 254520 * 79.0 - instantiation of values, bug 245027 + * 80.0 - support for specializations of partial specializations, bug 259872 */ private static int version(int major, int minor) { return major << 16 + minor; } - public static final int MAJOR_VERSION = 79; + public static final int MAJOR_VERSION = 80; public static final int MINOR_VERSION = 0; // minor versions must be compatible public static final int CURRENT_VERSION= version(MAJOR_VERSION, MINOR_VERSION); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMPartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMPartialSpecialization.java new file mode 100644 index 00000000000..f1b8a3b1114 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMPartialSpecialization.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2009 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.internal.core.pdom.dom.IPDOMBinding; +import org.eclipse.core.runtime.CoreException; + +/** + * Interface for partial specializations in the pdom. + */ +interface IPDOMPartialSpecialization extends ICPPClassTemplatePartialSpecialization, IPDOMBinding { + + /** + * Allows for setting the arguments after the binding has been added to the pdom. + */ + void setArguments(ICPPTemplateArgument[] args) throws CoreException; +} 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 b36908887c9..8e06165a060 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 QNX Software Systems and others. + * Copyright (c) 2007, 2009 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -120,7 +120,7 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements if (result != null) return result; } - IBinding newSpec= CPPTemplates.createSpecialization(this, original, getTemplateParameterMap()); + IBinding newSpec= CPPTemplates.createSpecialization(this, original); synchronized (specializationMap) { IBinding oldSpec= (IBinding) specializationMap.put(original, newSpec); if (oldSpec != null) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecialization.java index 820ff06e749..f32770b0b50 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecialization.java @@ -40,7 +40,7 @@ import org.eclipse.core.runtime.CoreException; * Partial specialization of a class template for the index. */ class PDOMCPPClassTemplatePartialSpecialization extends PDOMCPPClassTemplate - implements ICPPClassTemplatePartialSpecialization, ICPPSpecialization, IPDOMOverloader { + implements IPDOMPartialSpecialization, ICPPSpecialization, IPDOMOverloader { private static final int ARGUMENTS = PDOMCPPClassTemplate.RECORD_SIZE + 0; private static final int SIGNATURE_HASH = PDOMCPPClassTemplate.RECORD_SIZE + 4; 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 new file mode 100644 index 00000000000..33c8ddd1057 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecializationSpecialization.java @@ -0,0 +1,160 @@ +/******************************************************************************* + * Copyright (c) 2009 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IType; +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.semantics.CPPTemplates; +import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; +import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.db.Database; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +/** + * A partial specialization further specialized in the context of a class specialization. + */ +class PDOMCPPClassTemplatePartialSpecializationSpecialization extends PDOMCPPClassTemplateSpecialization + implements IPDOMPartialSpecialization, ICPPClassTemplatePartialSpecializationSpecialization { + + private static final int PRIMARY_TEMPLATE = PDOMCPPClassTemplateSpecialization.RECORD_SIZE; + private static final int ARGUMENTS = PDOMCPPClassTemplateSpecialization.RECORD_SIZE+4; + private static final int NEXT_PARTIAL = PDOMCPPClassTemplateSpecialization.RECORD_SIZE+8; + @SuppressWarnings("hiding") + protected static final int RECORD_SIZE= PDOMCPPClassTemplateSpecialization.RECORD_SIZE+12; + + private ICPPClassTemplate fPrimaryTemplate; + + public PDOMCPPClassTemplatePartialSpecializationSpecialization(PDOM pdom, + PDOMCPPLinkage linkage, PDOMNode parent, PDOMBinding specialized, + ICPPClassTemplatePartialSpecialization partial, PDOMCPPClassTemplateSpecialization primary) throws CoreException { + super(pdom, parent, partial, specialized); + + pdom.getDB().putInt(record + PRIMARY_TEMPLATE, primary.getRecord()); + primary.addPartial(this); + + linkage.new ConfigurePartialSpecialization(this, partial); + + } + + public PDOMCPPClassTemplatePartialSpecializationSpecialization(PDOM pdom, int bindingRecord) { + super(pdom, bindingRecord); + } + + @Override + protected int getRecordSize() { + return RECORD_SIZE; + } + + @Override + public int getNodeType() { + return IIndexCPPBindingConstants.CPP_CLASS_TEMPLATE_PARTIAL_SPEC_SPEC; + } + + @Override + public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() throws DOMException { + return ICPPClassTemplatePartialSpecialization.EMPTY_PARTIAL_SPECIALIZATION_ARRAY; + } + + public PDOMCPPClassTemplatePartialSpecializationSpecialization getNextPartial() throws CoreException { + int value = pdom.getDB().getInt(record + NEXT_PARTIAL); + return value != 0 ? new PDOMCPPClassTemplatePartialSpecializationSpecialization(pdom, value) : null; + } + + public void setNextPartial(PDOMCPPClassTemplatePartialSpecializationSpecialization partial) throws CoreException { + int value = partial != null ? partial.getRecord() : 0; + pdom.getDB().putInt(record + NEXT_PARTIAL, value); + } + + @Override + public boolean isSameType(IType type) { + if (type instanceof ITypedef) { + return type.isSameType(this); + } + + if (type instanceof PDOMNode) { + PDOMNode node= (PDOMNode) type; + if (node.getPDOM() == getPDOM()) { + return node.getRecord() == getRecord(); + } + } + + if (!(type instanceof ICPPClassTemplatePartialSpecialization)) { + return false; + } + + 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; + } + + public ICPPClassTemplate getPrimaryClassTemplate() { + if (fPrimaryTemplate == null) { + try { + int specializedRec = pdom.getDB().getInt(record + PRIMARY_TEMPLATE); + fPrimaryTemplate= (ICPPClassTemplate) getLinkageImpl().getNode(specializedRec); + } catch (CoreException e) { + CCorePlugin.log(e); + } + } + return fPrimaryTemplate; + } + + public void setArguments(ICPPTemplateArgument[] templateArguments) throws CoreException { + final Database db = getPDOM().getDB(); + int oldRec = db.getInt(record+ARGUMENTS); + int rec= PDOMCPPArgumentList.putArguments(this, templateArguments); + db.putInt(record+ARGUMENTS, rec); + if (oldRec != 0) { + PDOMCPPArgumentList.clearArguments(this, oldRec); + } + } + + public ICPPTemplateArgument[] getTemplateArguments() { + try { + final int rec= getPDOM().getDB().getInt(record+ARGUMENTS); + return PDOMCPPArgumentList.getArguments(this, rec); + } catch (CoreException e) { + CCorePlugin.log(e); + return ICPPTemplateArgument.EMPTY_ARGUMENTS; + } + } + + @Deprecated + public IType[] getArguments() { + return CPPTemplates.getArguments(getTemplateArguments()); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplateSpecialization.java index b4327e8685e..d78b31614fd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplateSpecialization.java @@ -1,16 +1,19 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 QNX Software Systems and others. + * Copyright (c) 2007, 2009 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX - Initial API and implementation + * Bryan Wilkinson (QNX) - Initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.cpp; +import java.util.ArrayList; + +import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding; @@ -34,12 +37,15 @@ import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.core.runtime.CoreException; /** - * @author Bryan Wilkinson - * + * Specialization of a class template. */ class PDOMCPPClassTemplateSpecialization extends PDOMCPPClassSpecialization implements ICPPClassTemplate, ICPPInstanceCache { + private static final int FIRST_PARTIAL = PDOMCPPClassSpecialization.RECORD_SIZE; + @SuppressWarnings("hiding") + protected static final int RECORD_SIZE = PDOMCPPClassSpecialization.RECORD_SIZE+4; + public PDOMCPPClassTemplateSpecialization(PDOM pdom, PDOMNode parent, ICPPClassTemplate template, PDOMBinding specialized) throws CoreException { super(pdom, parent, template, specialized); @@ -59,10 +65,6 @@ class PDOMCPPClassTemplateSpecialization extends PDOMCPPClassSpecialization return IIndexCPPBindingConstants.CPP_CLASS_TEMPLATE_SPECIALIZATION; } - public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() throws DOMException { - return ((ICPPClassTemplate)getSpecializedBinding()).getPartialSpecializations(); - } - public ICPPTemplateParameter[] getTemplateParameters() throws DOMException { ICPPClassTemplate template = (ICPPClassTemplate) getSpecializedBinding(); return template.getTemplateParameters(); @@ -155,5 +157,32 @@ class PDOMCPPClassTemplateSpecialization extends PDOMCPPClassSpecialization return false; } } - + + private PDOMCPPClassTemplatePartialSpecializationSpecialization getFirstPartial() throws CoreException { + int value = pdom.getDB().getInt(record + FIRST_PARTIAL); + return value != 0 ? new PDOMCPPClassTemplatePartialSpecializationSpecialization(pdom, value) : null; + } + + public void addPartial(PDOMCPPClassTemplatePartialSpecializationSpecialization pspecspec) throws CoreException { + PDOMCPPClassTemplatePartialSpecializationSpecialization first = getFirstPartial(); + pspecspec.setNextPartial(first); + pdom.getDB().putInt(record + FIRST_PARTIAL, pspecspec.getRecord()); + } + + public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() throws DOMException { + try { + ArrayList partials = + new ArrayList(); + for (PDOMCPPClassTemplatePartialSpecializationSpecialization partial = getFirstPartial(); + partial != null; + partial = partial.getNextPartial()) { + partials.add(partial); + } + + return partials.toArray(new PDOMCPPClassTemplatePartialSpecializationSpecialization[partials.size()]); + } catch (CoreException e) { + CCorePlugin.log(e); + return new PDOMCPPClassTemplatePartialSpecializationSpecialization[0]; + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java index e9c36fd56f3..3d66440ac05 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java @@ -42,6 +42,7 @@ 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.ICPPClassTemplatePartialSpecializationSpecialization; 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; @@ -144,10 +145,10 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { } class ConfigurePartialSpecialization implements Runnable { - PDOMCPPClassTemplatePartialSpecialization partial; + IPDOMPartialSpecialization partial; ICPPClassTemplatePartialSpecialization binding; - public ConfigurePartialSpecialization(PDOMCPPClassTemplatePartialSpecialization partial, + public ConfigurePartialSpecialization(IPDOMPartialSpecialization partial, ICPPClassTemplatePartialSpecialization binding) { this.partial = partial; this.binding = binding; @@ -461,6 +462,8 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { return CPP_CLASS_INSTANCE; } } else if (binding instanceof ICPPClassTemplatePartialSpecialization) { + if (binding instanceof ICPPClassTemplatePartialSpecializationSpecialization) + return CPP_CLASS_TEMPLATE_PARTIAL_SPEC_SPEC; return CPP_CLASS_TEMPLATE_PARTIAL_SPEC; } else if (binding instanceof ICPPField) { return CPP_FIELD_SPECIALIZATION; @@ -766,6 +769,8 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { return new PDOMCPPClassTemplate(pdom, record); case CPP_CLASS_TEMPLATE_PARTIAL_SPEC: return new PDOMCPPClassTemplatePartialSpecialization(pdom, record); + case CPP_CLASS_TEMPLATE_PARTIAL_SPEC_SPEC: + return new PDOMCPPClassTemplatePartialSpecializationSpecialization(pdom, record); case CPP_FUNCTION_INSTANCE: return new PDOMCPPFunctionInstance(pdom, record); case CPP_METHOD_INSTANCE: