From 480e491e88dbd3d2f03fdc8a37cf4cc6fa87f7ca Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Tue, 16 Jul 2013 00:57:07 -0400 Subject: [PATCH] Bug 407497, Bug 399454 - Specialize template parameters when appropriate Change-Id: Iff52b04319234ca8e5fe0f9b23d5d1787cee4449 Signed-off-by: Nathan Ridge Reviewed-on: https://git.eclipse.org/r/14533 Reviewed-by: Sergey Prigogin IP-Clean: Sergey Prigogin Tested-by: Sergey Prigogin --- .../parser/tests/ast2/AST2TemplateTests.java | 28 ++ .../tests/IndexCPPTemplateResolutionTest.java | 42 +++ .../cpp/CPPClassTemplateSpecialization.java | 31 ++- .../CPPConstructorTemplateSpecialization.java | 4 +- .../cpp/CPPMethodTemplateSpecialization.java | 25 +- ...emplateNonTypeParameterSpecialization.java | 90 +++++++ .../CPPTemplateParameterSpecialization.java | 130 +++++++++ ...mplateTemplateParameterSpecialization.java | 169 ++++++++++++ ...PPTemplateTypeParameterSpecialization.java | 69 +++++ .../parser/cpp/semantics/CPPTemplates.java | 255 +++++++++++------- .../dom/parser/cpp/semantics/EvalTypeId.java | 2 + .../eclipse/cdt/internal/core/pdom/PDOM.java | 11 +- .../PDOMCPPClassTemplateSpecialization.java | 49 +++- ...MCPPConstructorTemplateSpecialization.java | 2 +- .../PDOMCPPMethodTemplateSpecialization.java | 57 +++- 15 files changed, 842 insertions(+), 122 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeParameterSpecialization.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateParameterSpecialization.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameterSpecialization.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeParameterSpecialization.java 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 e7810e8fb8e..a7b160f3252 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 @@ -6410,6 +6410,34 @@ public class AST2TemplateTests extends AST2TestBase { public void testPointerToMemberOfTemplateClass_402861() throws Exception { parseAndCheckBindings(); } + + // struct N { + // int node; + // }; + // + // template + // struct List { + // template + // struct Base {}; + // }; + // + // List::Base<&N::node> base; + public void testDependentTemplateParameterInNestedTemplate_407497() throws Exception { + parseAndCheckBindings(); + } + + // template + // struct enclosing { + // template + // struct nested { + // typedef U type; + // }; + // }; + // + // typedef enclosing::nested<>::type waldo; + public void testDependentTemplateParameterInNestedTemplate_399454() throws Exception { + parseAndCheckBindings(); + } // class Memory { }; // Memory memory; 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 8ea564117a0..57eab0e8d04 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 @@ -2322,4 +2322,46 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa public void testSpecializationRedefinition_409444() throws Exception { checkBindings(); } + + // struct N { + // int node; + // }; + // + // template + // struct List { + // template + // struct Base {}; + // }; + + // List::Base<&N::node> base; + public void testDependentTemplateParameterInNestedTemplate_407497() throws Exception { + checkBindings(); + } + + // template + // struct enclosing { + // template + // struct nested { + // typedef U type; + // }; + // }; + + // typedef enclosing::nested<>::type waldo; + public void testDependentTemplateParameterInNestedTemplate_399454() throws Exception { + checkBindings(); + } + + // void f(int); + // + // template + // struct A + // { + // template + // static R foo(); + // }; + + // typedef decltype(A::foo<>()) waldo; + public void testNPE_407497() throws Exception { + checkBindings(); + } } 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 85b9aba05cd..a3371a42ccd 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, 2011 IBM Corporation and others. + * Copyright (c) 2005, 2013 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 @@ -9,6 +9,7 @@ * IBM - Initial API and implementation * Bryan Wilkinson (QNX) * Markus Schorn (Wind River Systems) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -19,7 +20,6 @@ import org.eclipse.cdt.core.dom.ast.IBinding; 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.ICPPClassType; 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; @@ -36,19 +36,25 @@ public class CPPClassTemplateSpecialization extends CPPClassSpecialization private ObjectMap instances = null; private ICPPDeferredClassInstance fDeferredInstance; private ICPPClassTemplatePartialSpecialization[] fPartialSpecs; + private ICPPTemplateParameter[] fTemplateParameters; - public CPPClassTemplateSpecialization(ICPPClassTemplate orig, ICPPClassType owner, ICPPTemplateParameterMap argumentMap) { + public CPPClassTemplateSpecialization(ICPPClassTemplate orig, ICPPClassSpecialization owner, + ICPPTemplateParameterMap argumentMap) { super(orig, owner, argumentMap); } + + public void setTemplateParameters(ICPPTemplateParameter[] templateParameters) { + fTemplateParameters = templateParameters; + } @Override public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() { if (fPartialSpecs == null) { IASTNode point= null; // Instantiation of dependent expressions may not work. - ICPPClassTemplate origTemplate= (ICPPClassTemplate) getSpecializedBinding(); + ICPPClassTemplate origTemplate= getSpecializedBinding(); ICPPClassTemplatePartialSpecialization[] orig = origTemplate.getPartialSpecializations(); ICPPClassTemplatePartialSpecialization[] spec = new ICPPClassTemplatePartialSpecialization[orig.length]; - ICPPClassSpecialization owner = (ICPPClassSpecialization) getOwner(); + ICPPClassSpecialization owner = getOwner(); for (int i = 0; i < orig.length; i++) { spec[i]= (ICPPClassTemplatePartialSpecialization) owner.specializeMember(orig[i], point); } @@ -59,10 +65,7 @@ public class CPPClassTemplateSpecialization extends CPPClassSpecialization @Override public ICPPTemplateParameter[] getTemplateParameters() { - // mstodo if we specialize the template parameters (because of its default values), it will - // be less error prone to use the defaults. - ICPPClassTemplate template = (ICPPClassTemplate) getSpecializedBinding(); - return template.getTemplateParameters(); + return fTemplateParameters; } @Override @@ -120,4 +123,14 @@ public class CPPClassTemplateSpecialization extends CPPClassSpecialization public ICPPTemplateArgument getDefaultArgFromIndex(int paramPos) throws DOMException { return null; } + + @Override + public ICPPClassSpecialization getOwner() { + return (ICPPClassSpecialization) super.getOwner(); + } + + @Override + public ICPPClassTemplate getSpecializedBinding() { + return (ICPPClassTemplate) super.getSpecializedBinding(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorTemplateSpecialization.java index 030f0843401..69449e96373 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorTemplateSpecialization.java @@ -12,7 +12,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.IType; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; @@ -24,7 +24,7 @@ public class CPPConstructorTemplateSpecialization extends CPPMethodTemplateSpeci implements ICPPConstructor { public CPPConstructorTemplateSpecialization(ICPPConstructor original, - ICPPClassType owner, ICPPTemplateParameterMap tpmap, ICPPFunctionType type, IType[] exceptionSpecs) { + ICPPClassSpecialization owner, ICPPTemplateParameterMap tpmap, ICPPFunctionType type, IType[] exceptionSpecs) { super(original, owner, tpmap, type, exceptionSpecs); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodTemplateSpecialization.java index 83ae82cea0f..5506b986c5a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodTemplateSpecialization.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2012 IBM Corporation and others. + * Copyright (c) 2005, 2013 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 @@ -9,14 +9,17 @@ * Andrew Niefer (IBM) - Initial API and implementation * Markus Schorn (Wind River Systems) * Thomas Corbat (IFS) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; 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.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; /** @@ -24,11 +27,22 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; */ public class CPPMethodTemplateSpecialization extends CPPFunctionTemplateSpecialization implements ICPPMethod { + + private ICPPTemplateParameter[] fTemplateParameters; - public CPPMethodTemplateSpecialization(ICPPMethod specialized, ICPPClassType owner, + public CPPMethodTemplateSpecialization(ICPPMethod specialized, ICPPClassSpecialization owner, ICPPTemplateParameterMap ctmap, ICPPFunctionType type, IType[] exceptionSpecs) { super(specialized, owner, ctmap, type, exceptionSpecs); } + + public void setTemplateParameters(ICPPTemplateParameter[] templateParameters) { + fTemplateParameters = templateParameters; + } + + @Override + public ICPPTemplateParameter[] getTemplateParameters() { + return fTemplateParameters; + } @Override public boolean isVirtual() { @@ -48,7 +62,7 @@ public class CPPMethodTemplateSpecialization extends CPPFunctionTemplateSpeciali @Override public ICPPClassType getClassOwner() { - return (ICPPClassType) getOwner(); + return getOwner(); } @Override @@ -93,4 +107,9 @@ public class CPPMethodTemplateSpecialization extends CPPFunctionTemplateSpeciali public boolean isFinal() { return false; } + + @Override + public ICPPClassSpecialization getOwner() { + return (ICPPClassSpecialization) super.getOwner(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeParameterSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeParameterSpecialization.java new file mode 100644 index 00000000000..bd27da5335e --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeParameterSpecialization.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2013 Nathan Ridge. + * 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: + * Nathan Ridge + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IASTExpression; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; +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.ICPPTemplateNonTypeParameter; + +/** + * A specialization of a non-type template parameter. This is needed when a nested template + * has a non-type template parameter whose type or default value is dependent on a template + * parameter of an enclosing template. + * + * This class can represent a specialization of either an AST or a PDOM template parameter. + */ +public class CPPTemplateNonTypeParameterSpecialization extends CPPTemplateParameterSpecialization + implements ICPPTemplateNonTypeParameter { + + private final IType fType; + + public CPPTemplateNonTypeParameterSpecialization(ICPPSpecialization owner, ICPPScope scope, + ICPPTemplateNonTypeParameter specialized, ICPPTemplateArgument defaultValue, IType type) { + super(owner, scope, specialized, defaultValue); + + this.fType = type; + } + + @Override + public ICPPTemplateNonTypeParameter getSpecializedBinding() { + return (ICPPTemplateNonTypeParameter) super.getSpecializedBinding(); + } + + @Override + public boolean isMutable() { + return false; + } + + @Override + public boolean isExternC() { + return false; + } + + @Override + public boolean isStatic() { + return false; + } + + @Override + public boolean isExtern() { + return false; + } + + @Override + public boolean isRegister() { + return false; + } + + @Override + public boolean isAuto() { + return false; + } + + @Override + public IType getType() { + return fType; + } + + @Override + public IValue getInitialValue() { + return getDefaultValue().getNonTypeValue(); + } + + @Override + @Deprecated + public IASTExpression getDefault() { + return null; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateParameterSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateParameterSpecialization.java new file mode 100644 index 00000000000..d9992c4d7f6 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateParameterSpecialization.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * Copyright (c) 2013 Nathan Ridge. + * 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: + * Nathan Ridge + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ILinkage; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; +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.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.Linkage; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; +import org.eclipse.core.runtime.PlatformObject; + +/** + * A specialization of a template parameter. + * + * This class provides common implementation for CPPTemplateNonTypeParameterSpecialization, + * CPPTemplateTypeParameterSpecialization, and CPPTemplateTemplateParameterSpecialization. + */ +public abstract class CPPTemplateParameterSpecialization extends PlatformObject + implements ICPPTemplateParameter, ICPPSpecialization { + + private final ICPPSpecialization fOwner; + private final ICPPScope fScope; + private final ICPPTemplateParameter fSpecialized; + private final ICPPTemplateParameterMap fTemplateParameterMap; + private final ICPPTemplateArgument fDefaultValue; + + public CPPTemplateParameterSpecialization(ICPPSpecialization owner, ICPPScope scope, ICPPTemplateParameter specialized, + ICPPTemplateArgument defaultValue) { + fOwner = owner; + fScope = scope; + fSpecialized = specialized; + fTemplateParameterMap = owner.getTemplateParameterMap(); + fDefaultValue = defaultValue; + } + + @Override + public String[] getQualifiedName() throws DOMException { + return fSpecialized.getQualifiedName(); + } + + @Override + public char[][] getQualifiedNameCharArray() throws DOMException { + return fSpecialized.getQualifiedNameCharArray(); + } + + @Override + public boolean isGloballyQualified() throws DOMException { + return false; + } + + @Override + public String getName() { + return fSpecialized.getName(); + } + + @Override + public char[] getNameCharArray() { + return fSpecialized.getNameCharArray(); + } + + @Override + public ILinkage getLinkage() { + return Linkage.CPP_LINKAGE; + } + + @Override + public ICPPSpecialization getOwner() { + return fOwner; + } + + @Override + public ICPPScope getScope() throws DOMException { + return fScope; + } + + @Override + public ICPPTemplateParameter getSpecializedBinding() { + return fSpecialized; + } + + @Override + public ICPPTemplateParameterMap getTemplateParameterMap() { + return fTemplateParameterMap; + } + + @Override + @Deprecated + public ObjectMap getArgumentMap() { + return CPPTemplates.getArgumentMap(this, getTemplateParameterMap()); + } + + @Override + public short getParameterPosition() { + return fSpecialized.getParameterPosition(); + } + + @Override + public short getTemplateNestingLevel() { + return fSpecialized.getTemplateNestingLevel(); + } + + @Override + public int getParameterID() { + return fSpecialized.getParameterID(); + } + + @Override + public ICPPTemplateArgument getDefaultValue() { + return fDefaultValue; + } + + @Override + public boolean isParameterPack() { + return fSpecialized.isParameterPack(); + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameterSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameterSpecialization.java new file mode 100644 index 00000000000..37ab60f84e6 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameterSpecialization.java @@ -0,0 +1,169 @@ +/******************************************************************************* + * Copyright (c) 2013 Nathan Ridge. + * 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: + * Nathan Ridge + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +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.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; +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.ICPPTemplateInstance; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter; + +/** + * A specialization of a template template parameter. This is needed when a nested template + * has a template template parameter whose default value is dependent on a template + * parameter of an enclosing template. + * + * This class can represent a specialization of either an AST or a PDOM template parameter. + */ +public class CPPTemplateTemplateParameterSpecialization extends CPPTemplateParameterSpecialization + implements ICPPTemplateTemplateParameter { + + public CPPTemplateTemplateParameterSpecialization(ICPPSpecialization owner, ICPPScope scope, + ICPPTemplateTemplateParameter specialized, ICPPTemplateArgument defaultValue) { + super(owner, scope, specialized, defaultValue); + } + + @Override + public ICPPTemplateTemplateParameter getSpecializedBinding() { + return (ICPPTemplateTemplateParameter) super.getSpecializedBinding(); + } + + @Override + public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() { + return ICPPClassTemplatePartialSpecialization.EMPTY_PARTIAL_SPECIALIZATION_ARRAY; + } + + @Override + public ICPPTemplateInstance asDeferredInstance() { + return null; + } + + @Override + public ICPPBase[] getBases() { + return ICPPBase.EMPTY_BASE_ARRAY; + } + + @Override + public IField[] getFields() { + return IField.EMPTY_FIELD_ARRAY; + } + + @Override + public IField findField(String name) { + return null; + } + + @Override + public ICPPField[] getDeclaredFields() { + return ICPPField.EMPTY_CPPFIELD_ARRAY; + } + + @Override + public ICPPMethod[] getMethods() { + return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; + } + + @Override + public ICPPMethod[] getAllDeclaredMethods() { + return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; + } + + @Override + public ICPPMethod[] getDeclaredMethods() { + return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; + } + + @Override + public ICPPConstructor[] getConstructors() { + return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY; + } + + @Override + public IBinding[] getFriends() { + return IBinding.EMPTY_BINDING_ARRAY; + } + + @Override + public ICPPClassType[] getNestedClasses() { + return ICPPClassType.EMPTY_CLASS_ARRAY; + } + + @Override + public boolean isFinal() { + return false; + } + + @Override + public int getVisibility(IBinding member) { + return getSpecializedBinding().getVisibility(member); + } + + @Override + public int getKey() { + return 0; + } + + @Override + public boolean isAnonymous() { + return false; + } + + @Override + public IScope getCompositeScope() { + return null; + } + + @Override + public ICPPTemplateParameter[] getTemplateParameters() { + return getSpecializedBinding().getTemplateParameters(); + } + + @Override + public IType getDefault() throws DOMException { + return getDefaultValue().getTypeValue(); + } + + @Override + public boolean isSameType(IType type) { + if (type == this) + return true; + if (type instanceof ITypedef) + return type.isSameType(this); + if (!(type instanceof ICPPTemplateTemplateParameter)) + return false; + + return getParameterID() == ((ICPPTemplateParameter) type).getParameterID(); + } + + @Override + public Object clone() { + Object o = null; + try { + o = super.clone(); + } catch (CloneNotSupportedException e) { + //not going to happen + } + return o; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeParameterSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeParameterSpecialization.java new file mode 100644 index 00000000000..d2bfca32c3b --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeParameterSpecialization.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2013 Nathan Ridge. + * 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: + * Nathan Ridge + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +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.ICPPScope; +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.ICPPTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter; + +/** + * A specialization of a type template parameter. This is needed when a nested template + * has a type template parameter whose default value is dependent on a template + * parameter of an enclosing template. + * + * This class can represent a specialization of either an AST or a PDOM template parameter. + */ +public class CPPTemplateTypeParameterSpecialization extends CPPTemplateParameterSpecialization + implements ICPPTemplateTypeParameter { + + public CPPTemplateTypeParameterSpecialization(ICPPSpecialization owner, ICPPScope scope, + ICPPTemplateTypeParameter specialized, ICPPTemplateArgument defaultValue) { + super(owner, scope, specialized, defaultValue); + } + + @Override + public ICPPTemplateTypeParameter getSpecializedBinding() { + return (ICPPTemplateTypeParameter) super.getSpecializedBinding(); + } + + @Override + public IType getDefault() throws DOMException { + return getDefaultValue().getTypeValue(); + } + + @Override + public boolean isSameType(IType type) { + if (type == this) + return true; + if (type instanceof ITypedef) + return type.isSameType(this); + if (!(type instanceof ICPPTemplateTypeParameter)) + return false; + + return getParameterID() == ((ICPPTemplateParameter) type).getParameterID(); + } + + @Override + public Object clone() { + Object o = null; + try { + o = super.clone(); + } catch (CloneNotSupportedException e) { + //not going to happen + } + return o; + } +} 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 a844d5c4964..1627d77c99f 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 @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.DOMException; @@ -137,10 +138,13 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateDefinition; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeParameter; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeParameterSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTemplateParameter; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTemplateParameterSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeParameter; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeParameterSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedefSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownMemberClass; @@ -801,106 +805,120 @@ public class CPPTemplates { public static IBinding createSpecialization(ICPPClassSpecialization owner, IBinding decl, IASTNode point) { IBinding spec = null; final ICPPTemplateParameterMap tpMap= owner.getTemplateParameterMap(); - if (decl instanceof ICPPClassTemplatePartialSpecialization) { - try { - final ICPPClassSpecialization within = getSpecializationContext(owner); - ICPPClassTemplatePartialSpecialization pspec= (ICPPClassTemplatePartialSpecialization) decl; - ICPPClassTemplate template= pspec.getPrimaryClassTemplate(); - ICPPTemplateArgument[] args = pspec.getTemplateArguments(); - template= (ICPPClassTemplate) owner.specializeMember(template, point); - args= instantiateArguments(args, tpMap, -1, within, point, false); - spec= new CPPClassTemplatePartialSpecializationSpecialization(pspec, tpMap, template, args); - } catch (DOMException e) { - } - } else if (decl instanceof ICPPClassTemplate) { - spec = new CPPClassTemplateSpecialization((ICPPClassTemplate) decl, owner, tpMap); - } else if (decl instanceof ICPPClassType) { - IBinding oldOwner = decl.getOwner(); - if (oldOwner instanceof IType && owner.getSpecializedBinding().isSameType((IType) oldOwner)) { - spec = new CPPClassSpecialization((ICPPClassType) decl, owner, tpMap); - } else { - spec = new CPPClassSpecialization((ICPPClassType) decl, oldOwner, tpMap); - } - } else if (decl instanceof ICPPField) { - final ICPPClassSpecialization within = getSpecializationContext(owner); - ICPPField field= (ICPPField) decl; - IType type= instantiateType(field.getType(), tpMap, -1, within, point); - IValue value= instantiateValue(field.getInitialValue(), tpMap, -1, within, Value.MAX_RECURSION_DEPTH, point); - spec = new CPPFieldSpecialization(decl, owner, tpMap, type, value); - } else if (decl instanceof ICPPFunction) { - ICPPFunction func= (ICPPFunction) decl; - ICPPClassSpecialization within = getSpecializationContext(owner); - ICPPFunctionType type= (ICPPFunctionType) instantiateType(func.getType(), tpMap, -1, within, point); - IType[] exceptionSpecs= instantiateTypes(func.getExceptionSpecification(), tpMap, -1, within, point); - - if (decl instanceof ICPPFunctionTemplate) { - if (decl instanceof ICPPConstructor) { - spec = new CPPConstructorTemplateSpecialization((ICPPConstructor) decl, owner, tpMap, type, exceptionSpecs); - } else if (decl instanceof ICPPMethod) { - spec = new CPPMethodTemplateSpecialization((ICPPMethod) decl, owner, tpMap, type, exceptionSpecs); - } else { - IBinding oldOwner = decl.getOwner(); - spec = new CPPFunctionTemplateSpecialization((ICPPFunctionTemplate) decl, oldOwner, tpMap, type, exceptionSpecs); - } - } else if (decl instanceof ICPPConstructor) { - spec = new CPPConstructorSpecialization((ICPPConstructor) decl, owner, tpMap, type, exceptionSpecs); - } else if (decl instanceof ICPPMethod) { - spec = new CPPMethodSpecialization((ICPPMethod) decl, owner, tpMap, type, exceptionSpecs); - } else if (decl instanceof ICPPFunction) { - IBinding oldOwner = decl.getOwner(); - spec = new CPPFunctionSpecialization((ICPPFunction) decl, oldOwner, tpMap, type, exceptionSpecs); - } - } else if (decl instanceof ITypedef) { - IType type= instantiateType(((ITypedef) decl).getType(), tpMap, -1, getSpecializationContext(owner), point); - spec = new CPPTypedefSpecialization(decl, owner, tpMap, type); - } else if (decl instanceof ICPPAliasTemplate) { - ICPPAliasTemplate aliasTemplate = (ICPPAliasTemplate) decl; - IType type= instantiateType(aliasTemplate.getType(), tpMap, -1, getSpecializationContext(owner), point); - spec = new CPPAliasTemplateInstance(decl.getNameCharArray(), aliasTemplate, type); - } else if (decl instanceof ICPPEnumeration) { - ICPPClassSpecialization within = getSpecializationContext(owner); - ICPPEnumeration enumeration = (ICPPEnumeration) decl; - IType fixedType = instantiateType(enumeration.getFixedType(), tpMap, -1, within, point); - CPPEnumerationSpecialization specializedEnumeration = - new CPPEnumerationSpecialization(enumeration, owner, tpMap, fixedType); - IEnumerator[] enumerators = enumeration.getEnumerators(); - IEnumerator[] specializedEnumerators = new IEnumerator[enumerators.length]; - for (int i = 0; i < enumerators.length; ++i) { - IEnumerator enumerator = enumerators[i]; - IValue specializedValue = - instantiateValue(enumerator.getValue(), tpMap, -1, within, Value.MAX_RECURSION_DEPTH, point); - specializedEnumerators[i] = - new CPPEnumeratorSpecialization(enumerator, specializedEnumeration, tpMap, specializedValue); - } - specializedEnumeration.setEnumerators(specializedEnumerators); - spec = specializedEnumeration; - } else if (decl instanceof IEnumerator) { - IEnumerator enumerator = (IEnumerator) decl; - ICPPEnumeration enumeration = (ICPPEnumeration) enumerator.getOwner(); - ICPPEnumerationSpecialization enumSpec = - (ICPPEnumerationSpecialization) owner.specializeMember(enumeration, point); - spec = enumSpec.specializeEnumerator(enumerator); - } else if (decl instanceof ICPPUsingDeclaration) { - IBinding[] delegates= ((ICPPUsingDeclaration) decl).getDelegates(); - List result= new ArrayList(); - ICPPClassSpecialization within = getSpecializationContext(owner); - for (IBinding delegate : delegates) { + try { + if (decl instanceof ICPPClassTemplatePartialSpecialization) { try { - if (delegate instanceof ICPPUnknownBinding) { - delegate= resolveUnknown((ICPPUnknownBinding) delegate, tpMap, -1, within, point); - } - if (delegate instanceof CPPFunctionSet) { - for (IBinding b : ((CPPFunctionSet) delegate).getBindings()) { - result.add(b); - } - } else if (delegate != null) { - result.add(delegate); - } + final ICPPClassSpecialization within = getSpecializationContext(owner); + ICPPClassTemplatePartialSpecialization pspec= (ICPPClassTemplatePartialSpecialization) decl; + ICPPClassTemplate template= pspec.getPrimaryClassTemplate(); + ICPPTemplateArgument[] args = pspec.getTemplateArguments(); + template= (ICPPClassTemplate) owner.specializeMember(template, point); + args= instantiateArguments(args, tpMap, -1, within, point, false); + spec= new CPPClassTemplatePartialSpecializationSpecialization(pspec, tpMap, template, args); } catch (DOMException e) { } + } else if (decl instanceof ICPPClassTemplate) { + ICPPClassTemplate template = (ICPPClassTemplate) decl; + CPPClassTemplateSpecialization classTemplateSpec = new CPPClassTemplateSpecialization(template, owner, tpMap); + classTemplateSpec.setTemplateParameters(CPPTemplates.specializeTemplateParameters(classTemplateSpec, + (ICPPScope) classTemplateSpec.getScope(), template.getTemplateParameters(), owner, point)); + spec = classTemplateSpec; + } else if (decl instanceof ICPPClassType) { + IBinding oldOwner = decl.getOwner(); + if (oldOwner instanceof IType && owner.getSpecializedBinding().isSameType((IType) oldOwner)) { + spec = new CPPClassSpecialization((ICPPClassType) decl, owner, tpMap); + } else { + spec = new CPPClassSpecialization((ICPPClassType) decl, oldOwner, tpMap); + } + } else if (decl instanceof ICPPField) { + final ICPPClassSpecialization within = getSpecializationContext(owner); + ICPPField field= (ICPPField) decl; + IType type= instantiateType(field.getType(), tpMap, -1, within, point); + IValue value= instantiateValue(field.getInitialValue(), tpMap, -1, within, Value.MAX_RECURSION_DEPTH, point); + spec = new CPPFieldSpecialization(decl, owner, tpMap, type, value); + } else if (decl instanceof ICPPFunction) { + ICPPFunction func= (ICPPFunction) decl; + ICPPClassSpecialization within = getSpecializationContext(owner); + ICPPFunctionType type= (ICPPFunctionType) instantiateType(func.getType(), tpMap, -1, within, point); + IType[] exceptionSpecs= instantiateTypes(func.getExceptionSpecification(), tpMap, -1, within, point); + + if (decl instanceof ICPPFunctionTemplate) { + if (decl instanceof ICPPMethod) { + CPPMethodTemplateSpecialization methodSpec; + if (decl instanceof ICPPConstructor) { + methodSpec = new CPPConstructorTemplateSpecialization((ICPPConstructor) decl, owner, tpMap, type, exceptionSpecs); + } else { + methodSpec = new CPPMethodTemplateSpecialization((ICPPMethod) decl, owner, tpMap, type, exceptionSpecs); + } + methodSpec.setTemplateParameters(CPPTemplates.specializeTemplateParameters(methodSpec, + (ICPPScope) methodSpec.getScope(), ((ICPPFunctionTemplate) decl).getTemplateParameters(), owner, point)); + spec = methodSpec; + } else { + IBinding oldOwner = decl.getOwner(); + spec = new CPPFunctionTemplateSpecialization((ICPPFunctionTemplate) decl, oldOwner, tpMap, type, exceptionSpecs); + } + } else if (decl instanceof ICPPConstructor) { + spec = new CPPConstructorSpecialization((ICPPConstructor) decl, owner, tpMap, type, exceptionSpecs); + } else if (decl instanceof ICPPMethod) { + spec = new CPPMethodSpecialization((ICPPMethod) decl, owner, tpMap, type, exceptionSpecs); + } else if (decl instanceof ICPPFunction) { + IBinding oldOwner = decl.getOwner(); + spec = new CPPFunctionSpecialization((ICPPFunction) decl, oldOwner, tpMap, type, exceptionSpecs); + } + } else if (decl instanceof ITypedef) { + IType type= instantiateType(((ITypedef) decl).getType(), tpMap, -1, getSpecializationContext(owner), point); + spec = new CPPTypedefSpecialization(decl, owner, tpMap, type); + } else if (decl instanceof ICPPAliasTemplate) { + ICPPAliasTemplate aliasTemplate = (ICPPAliasTemplate) decl; + IType type= instantiateType(aliasTemplate.getType(), tpMap, -1, getSpecializationContext(owner), point); + spec = new CPPAliasTemplateInstance(decl.getNameCharArray(), aliasTemplate, type); + } else if (decl instanceof ICPPEnumeration) { + ICPPClassSpecialization within = getSpecializationContext(owner); + ICPPEnumeration enumeration = (ICPPEnumeration) decl; + IType fixedType = instantiateType(enumeration.getFixedType(), tpMap, -1, within, point); + CPPEnumerationSpecialization specializedEnumeration = + new CPPEnumerationSpecialization(enumeration, owner, tpMap, fixedType); + IEnumerator[] enumerators = enumeration.getEnumerators(); + IEnumerator[] specializedEnumerators = new IEnumerator[enumerators.length]; + for (int i = 0; i < enumerators.length; ++i) { + IEnumerator enumerator = enumerators[i]; + IValue specializedValue = + instantiateValue(enumerator.getValue(), tpMap, -1, within, Value.MAX_RECURSION_DEPTH, point); + specializedEnumerators[i] = + new CPPEnumeratorSpecialization(enumerator, specializedEnumeration, tpMap, specializedValue); + } + specializedEnumeration.setEnumerators(specializedEnumerators); + spec = specializedEnumeration; + } else if (decl instanceof IEnumerator) { + IEnumerator enumerator = (IEnumerator) decl; + ICPPEnumeration enumeration = (ICPPEnumeration) enumerator.getOwner(); + ICPPEnumerationSpecialization enumSpec = + (ICPPEnumerationSpecialization) owner.specializeMember(enumeration, point); + spec = enumSpec.specializeEnumerator(enumerator); + } else if (decl instanceof ICPPUsingDeclaration) { + IBinding[] delegates= ((ICPPUsingDeclaration) decl).getDelegates(); + List result= new ArrayList(); + ICPPClassSpecialization within = getSpecializationContext(owner); + for (IBinding delegate : delegates) { + try { + if (delegate instanceof ICPPUnknownBinding) { + delegate= resolveUnknown((ICPPUnknownBinding) delegate, tpMap, -1, within, point); + } + if (delegate instanceof CPPFunctionSet) { + for (IBinding b : ((CPPFunctionSet) delegate).getBindings()) { + result.add(b); + } + } else if (delegate != null) { + result.add(delegate); + } + } catch (DOMException e) { + } + } + delegates= result.toArray(new IBinding[result.size()]); + spec= new CPPUsingDeclarationSpecialization((ICPPUsingDeclaration) decl, owner, tpMap, delegates); } - delegates= result.toArray(new IBinding[result.size()]); - spec= new CPPUsingDeclarationSpecialization((ICPPUsingDeclaration) decl, owner, tpMap, delegates); + } catch (DOMException e) { + CCorePlugin.log(e); } return spec; } @@ -1332,6 +1350,51 @@ public class CPPTemplates { } } + /** + * Specialize a template parameter of a nested template by subtituting values for the template + * parameters of enclosing templates into the template parameter's default value and, in the + * case of a non-type template parameter, type. + * + * @param owner the specialization of the nested template. This will be the owner of the + * specialized template parameter. + * @param scope the scope of the nested template specialization + * @param specialized the template parameter to be specialized + * @param within the specialization of the enclosing class + * @param point the point of template instantiation + * @return the specialized template parameter + */ + public static ICPPTemplateParameter specializeTemplateParameter(ICPPSpecialization owner, ICPPScope scope, + ICPPTemplateParameter specialized, ICPPClassSpecialization within, IASTNode point) { + if (specialized == null) + return null; + ICPPTemplateParameterMap tpMap = owner.getTemplateParameterMap(); + ICPPTemplateArgument defaultValue = instantiateArgument(specialized.getDefaultValue(), tpMap, 0, within, point); + if (specialized instanceof ICPPTemplateNonTypeParameter) { + ICPPTemplateNonTypeParameter spec = (ICPPTemplateNonTypeParameter) specialized; + IType type = instantiateType(spec.getType(), tpMap, 0, within, point); + return new CPPTemplateNonTypeParameterSpecialization(owner, scope, spec, defaultValue, type); + } else if (specialized instanceof ICPPTemplateTypeParameter) { + return new CPPTemplateTypeParameterSpecialization(owner, scope, (ICPPTemplateTypeParameter) specialized, + defaultValue); + } else if (specialized instanceof ICPPTemplateTemplateParameter) { + return new CPPTemplateTemplateParameterSpecialization(owner, scope, (ICPPTemplateTemplateParameter) specialized, + defaultValue); + } + return null; + } + + /** + * Convenience method for specializing all template parameters in an array. + * See specializeTemplateParameter(). + */ + public static ICPPTemplateParameter[] specializeTemplateParameters(ICPPSpecialization owner, ICPPScope scope, + ICPPTemplateParameter[] specialized, ICPPClassSpecialization within, IASTNode point) { + ICPPTemplateParameter[] result = new ICPPTemplateParameter[specialized.length]; + for (int i = 0; i < specialized.length; ++i) + result[i] = specializeTemplateParameter(owner, scope, specialized[i], within, point); + return result; + } + public static IBinding instantiateBinding(IBinding binding, ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, int maxdepth, IASTNode point) throws DOMException { if (binding instanceof ICPPClassTemplate) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java index 59cccee4e1a..ca566539281 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java @@ -145,6 +145,8 @@ public class EvalTypeId extends CPPDependentEvaluation { for (int i = 0; i < args.length; i++) { args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation(); } + } else { + args = new ICPPEvaluation[0]; // arguments must not be null } IBinding templateDefinition= buffer.unmarshalBinding(); return new EvalTypeId(type, templateDefinition, args); 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 6ab47206add..4280ec5a4fd 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 @@ -238,11 +238,14 @@ public class PDOM extends PlatformObject implements IPDOM { * 144.0 - Add support for storing function sets with zero functions in EvalFunctionSet, bug 402498. * 145.0 - Changed marshalling of CPPBasicType to store the associated numerical value, bug 407808. * 146.0 - Added visibility support on class type level, bug 402878. - * 147.0 - Store whether function name is qualified in EvalFunctionSet, bug 408296. + * #147.0# - Store whether function name is qualified in EvalFunctionSet, bug 408296. + * + * CDT 8.3 development (versions not supported on the 8.2.x branch) + * 148.0 - Store specialized template parameters of class/function template specializations, bug 407497. */ - private static final int MIN_SUPPORTED_VERSION= version(147, 0); - private static final int MAX_SUPPORTED_VERSION= version(147, Short.MAX_VALUE); - private static final int DEFAULT_VERSION = version(147, 0); + private static final int MIN_SUPPORTED_VERSION= version(148, 0); + private static final int MAX_SUPPORTED_VERSION= version(148, Short.MAX_VALUE); + private static final int DEFAULT_VERSION = version(148, 0); private static int version(int major, int minor) { return (major << 16) + minor; 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 33a1d504d33..905af599cb3 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,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2011 QNX Software Systems and others. + * Copyright (c) 2007, 2013 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 @@ -8,9 +8,12 @@ * Contributors: * Bryan Wilkinson (QNX) - Initial API and implementation * Markus Schorn (Wind River Systems) + * Nathan Ridge *******************************************************************************/ 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.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding; @@ -30,6 +33,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache; 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; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; @@ -40,12 +44,22 @@ import org.eclipse.core.runtime.CoreException; */ class PDOMCPPClassTemplateSpecialization extends PDOMCPPClassSpecialization implements ICPPClassTemplate, ICPPInstanceCache { + + private static final int TEMPLATE_PARAMS = PDOMCPPClassSpecialization.RECORD_SIZE; + @SuppressWarnings("hiding") - protected static final int RECORD_SIZE = PDOMCPPClassSpecialization.RECORD_SIZE; + protected static final int RECORD_SIZE = TEMPLATE_PARAMS + Database.PTR_SIZE; + + private volatile IPDOMCPPTemplateParameter[] fTemplateParameters; - public PDOMCPPClassTemplateSpecialization(PDOMLinkage linkage, PDOMNode parent, ICPPClassTemplate template, PDOMBinding specialized) + public PDOMCPPClassTemplateSpecialization(PDOMCPPLinkage linkage, PDOMNode parent, ICPPClassTemplate template, PDOMBinding specialized) throws CoreException { super(linkage, parent, template, specialized); + computeTemplateParameters(template); // sets fTemplateParameters + final Database db = getDB(); + long rec = PDOMTemplateParameterArray.putArray(db, fTemplateParameters); + db.putRecPtr(record + TEMPLATE_PARAMS, rec); + linkage.new ConfigureTemplateParameters(template.getTemplateParameters(), fTemplateParameters); } public PDOMCPPClassTemplateSpecialization(PDOMLinkage linkage, long bindingRecord) { @@ -64,8 +78,20 @@ class PDOMCPPClassTemplateSpecialization extends PDOMCPPClassSpecialization @Override public ICPPTemplateParameter[] getTemplateParameters() { - ICPPClassTemplate template = (ICPPClassTemplate) getSpecializedBinding(); - return template.getTemplateParameters(); + if (fTemplateParameters == null) { + try { + long rec = getDB().getRecPtr(record + TEMPLATE_PARAMS); + if (rec == 0) { + fTemplateParameters = IPDOMCPPTemplateParameter.EMPTY_ARRAY; + } else { + fTemplateParameters = PDOMTemplateParameterArray.getArray(this, rec); + } + } catch (CoreException e) { + CCorePlugin.log(e); + fTemplateParameters = IPDOMCPPTemplateParameter.EMPTY_ARRAY; + } + } + return fTemplateParameters; } @Override @@ -180,4 +206,17 @@ class PDOMCPPClassTemplateSpecialization extends PDOMCPPClassSpecialization return dci; } } + + private void computeTemplateParameters(ICPPClassTemplate originalTemplate) { + try { + fTemplateParameters = PDOMTemplateParameterArray.createPDOMTemplateParameters(getLinkage(), this, + originalTemplate.getTemplateParameters()); + } catch (DOMException e) { + CCorePlugin.log(e); + fTemplateParameters = IPDOMCPPTemplateParameter.EMPTY_ARRAY; + } catch (CoreException e) { + CCorePlugin.log(e); + fTemplateParameters = IPDOMCPPTemplateParameter.EMPTY_ARRAY; + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPConstructorTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPConstructorTemplateSpecialization.java index 7e1c5d4f9c7..7d6837a29fa 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPConstructorTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPConstructorTemplateSpecialization.java @@ -28,7 +28,7 @@ class PDOMCPPConstructorTemplateSpecialization extends PDOMCPPMethodTemplateSpec @SuppressWarnings("hiding") protected static final int RECORD_SIZE = PDOMCPPFunctionSpecialization.RECORD_SIZE + 0; - public PDOMCPPConstructorTemplateSpecialization(PDOMLinkage linkage, PDOMNode parent, ICPPConstructor constructor, PDOMBinding specialized) + public PDOMCPPConstructorTemplateSpecialization(PDOMCPPLinkage linkage, PDOMNode parent, ICPPConstructor constructor, PDOMBinding specialized) throws CoreException { super(linkage, parent, constructor, specialized); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethodTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethodTemplateSpecialization.java index c8ced8f22d4..fb22b1e581a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethodTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethodTemplateSpecialization.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2012 QNX Software Systems and others. + * Copyright (c) 2007, 2013 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 @@ -9,14 +9,19 @@ * QNX - Initial API and implementation * Markus Schorn (Wind River Systems) * Thomas Corbat (IFS) + * Nathan Ridge *******************************************************************************/ 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.IBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; +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.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; @@ -29,15 +34,50 @@ import org.eclipse.core.runtime.CoreException; class PDOMCPPMethodTemplateSpecialization extends PDOMCPPFunctionTemplateSpecialization implements ICPPMethod { - public PDOMCPPMethodTemplateSpecialization(PDOMLinkage linkage, PDOMNode parent, ICPPMethod method, PDOMBinding specialized) + private static final int TEMPLATE_PARAMS = PDOMCPPFunctionTemplateSpecialization.RECORD_SIZE; + + @SuppressWarnings("hiding") + protected static final int RECORD_SIZE = TEMPLATE_PARAMS + Database.PTR_SIZE; + + private volatile IPDOMCPPTemplateParameter[] fTemplateParameters; + + public PDOMCPPMethodTemplateSpecialization(PDOMCPPLinkage linkage, PDOMNode parent, ICPPMethod method, PDOMBinding specialized) throws CoreException { super(linkage, parent, (ICPPFunctionTemplate) method, specialized); + computeTemplateParameters((ICPPFunctionTemplate) method); // sets fTemplateParameters + final Database db = getDB(); + long rec = PDOMTemplateParameterArray.putArray(db, fTemplateParameters); + db.putRecPtr(record + TEMPLATE_PARAMS, rec); + linkage.new ConfigureTemplateParameters(((ICPPFunctionTemplate) method).getTemplateParameters(), fTemplateParameters); } public PDOMCPPMethodTemplateSpecialization(PDOMLinkage linkage, long bindingRecord) { super(linkage, bindingRecord); } + @Override + protected int getRecordSize() { + return RECORD_SIZE; + } + + @Override + public ICPPTemplateParameter[] getTemplateParameters() { + if (fTemplateParameters == null) { + try { + long rec = getDB().getRecPtr(record + TEMPLATE_PARAMS); + if (rec == 0) { + fTemplateParameters = IPDOMCPPTemplateParameter.EMPTY_ARRAY; + } else { + fTemplateParameters = PDOMTemplateParameterArray.getArray(this, rec); + } + } catch (CoreException e) { + CCorePlugin.log(e); + fTemplateParameters = IPDOMCPPTemplateParameter.EMPTY_ARRAY; + } + } + return fTemplateParameters; + } + @Override public int getNodeType() { return IIndexCPPBindingConstants.CPP_METHOD_TEMPLATE_SPECIALIZATION; @@ -112,4 +152,17 @@ class PDOMCPPMethodTemplateSpecialization extends public boolean isFinal() { return false; } + + private void computeTemplateParameters(ICPPFunctionTemplate originalMethodTemplate) { + try { + fTemplateParameters = PDOMTemplateParameterArray.createPDOMTemplateParameters(getLinkage(), this, + originalMethodTemplate.getTemplateParameters()); + } catch (DOMException e) { + CCorePlugin.log(e); + fTemplateParameters = IPDOMCPPTemplateParameter.EMPTY_ARRAY; + } catch (CoreException e) { + CCorePlugin.log(e); + fTemplateParameters = IPDOMCPPTemplateParameter.EMPTY_ARRAY; + } + } }