From e374b4b08e7323b8d33ef1f2826b761f74c9b54f Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Wed, 10 May 2017 03:37:46 -0400 Subject: [PATCH] Bug 516338 - Have ICPPAliasTemplateInstance implement ICPPTemplateInstance This allows querying alias template instances for their arguments (for e.g. instantiating dependent arguments later). Change-Id: I7cc3dfcef75fe0faf104dc7bfe11e2acd90a4748 --- .../ast/cpp/ICPPAliasTemplateInstance.java | 3 +- .../parser/cpp/CPPAliasTemplateInstance.java | 45 ++++++++----- .../parser/cpp/semantics/CPPTemplates.java | 2 +- .../index/CPPAliasTemplateInstanceClone.java | 29 ++++++++- .../composite/cpp/CPPCompositesFactory.java | 10 ++- .../CompositeCPPAliasTemplateInstance.java | 14 +++- .../eclipse/cdt/internal/core/pdom/PDOM.java | 7 +- .../dom/cpp/PDOMCPPAliasTemplateInstance.java | 65 ++++++++++++++----- .../core/pdom/dom/cpp/PDOMCPPLinkage.java | 16 +++++ 9 files changed, 149 insertions(+), 42 deletions(-) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPAliasTemplateInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPAliasTemplateInstance.java index f176a8e8e1c..294295319b0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPAliasTemplateInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPAliasTemplateInstance.java @@ -20,9 +20,10 @@ import org.eclipse.cdt.core.dom.ast.ITypedef; * @noextend This interface is not intended to be extended by clients. * @noimplement This interface is not intended to be implemented by clients. */ -public interface ICPPAliasTemplateInstance extends ITypedef, ICPPBinding { +public interface ICPPAliasTemplateInstance extends ITypedef, ICPPTemplateInstance { /** * Returns the alias template specialized by this instance. */ + @Override public ICPPAliasTemplate getTemplateDefinition(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPAliasTemplateInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPAliasTemplateInstance.java index 74669f24076..0f595659952 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPAliasTemplateInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPAliasTemplateInstance.java @@ -21,27 +21,28 @@ import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplateInstance; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; -import org.eclipse.core.runtime.PlatformObject; -public class CPPAliasTemplateInstance extends PlatformObject - implements ICPPAliasTemplateInstance, ITypeContainer, ICPPInternalBinding { - private final char[] name; - private final ICPPAliasTemplate aliasTemplate; +public class CPPAliasTemplateInstance extends CPPSpecialization implements ICPPAliasTemplateInstance, + ITypeContainer { private IType aliasedType; + private ICPPTemplateArgument[] fArguments; - public CPPAliasTemplateInstance(char[] name, ICPPAliasTemplate aliasTemplate, IType aliasedType) { - this.name = name; - this.aliasTemplate = aliasTemplate; + public CPPAliasTemplateInstance(ICPPAliasTemplate aliasTemplate, IType aliasedType, IBinding owner, + ICPPTemplateParameterMap argumentMap, ICPPTemplateArgument[] arguments) { + super(aliasTemplate, owner, argumentMap); this.aliasedType = aliasedType; + this.fArguments = arguments; } @Override public ICPPAliasTemplate getTemplateDefinition() { - return aliasTemplate; + return (ICPPAliasTemplate) super.getSpecializedBinding(); } @Override @@ -80,6 +81,7 @@ public class CPPAliasTemplateInstance extends PlatformObject @Override public char[] getNameCharArray() { + char[] name = getTemplateDefinition().getNameCharArray(); if (name != null) { return name; } @@ -93,16 +95,16 @@ public class CPPAliasTemplateInstance extends PlatformObject @Override public IBinding getOwner() { - if (aliasTemplate != null) { - return aliasTemplate.getOwner(); + if (getTemplateDefinition() != null) { + return getTemplateDefinition().getOwner(); } return null; } @Override public IScope getScope() throws DOMException { - if (aliasTemplate != null) { - return aliasTemplate.getScope(); + if (getTemplateDefinition() != null) { + return getTemplateDefinition().getScope(); } return null; } @@ -119,13 +121,13 @@ public class CPPAliasTemplateInstance extends PlatformObject @Override public boolean isGloballyQualified() throws DOMException { - return aliasTemplate.isGloballyQualified(); + return getTemplateDefinition().isGloballyQualified(); } @Override public IASTNode getDefinition() { - if (aliasTemplate instanceof ICPPInternalBinding) { - return ((ICPPInternalBinding) aliasTemplate).getDefinition(); + if (getTemplateDefinition() instanceof ICPPInternalBinding) { + return ((ICPPInternalBinding) getTemplateDefinition()).getDefinition(); } return null; } @@ -150,4 +152,15 @@ public class CPPAliasTemplateInstance extends PlatformObject public String toString() { return ASTTypeUtil.getQualifiedName(this) + " -> " + ASTTypeUtil.getType(aliasedType, true); //$NON-NLS-1$ } + + @Override + public ICPPTemplateArgument[] getTemplateArguments() { + return fArguments; + } + + @Override + public boolean isExplicitSpecialization() { + // Alias templates cannot have explicit specializations. + return false; + } } 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 0c9591ddbec..c21ff48da66 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 @@ -852,7 +852,7 @@ public class CPPTemplates { IBinding owner, IASTNode point) { InstantiationContext context = createInstantiationContext(parameterMap, owner, point); IType instantiatedType = instantiateType(aliasedType, context); - return new CPPAliasTemplateInstance(aliasTemplate.getNameCharArray(), aliasTemplate, instantiatedType); + return new CPPAliasTemplateInstance(aliasTemplate, instantiatedType, owner, parameterMap, args); } static boolean isClassTemplate(ICPPASTTemplateId id) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CPPAliasTemplateInstanceClone.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CPPAliasTemplateInstanceClone.java index b9a9ae2782b..f656e9d4ace 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CPPAliasTemplateInstanceClone.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/CPPAliasTemplateInstanceClone.java @@ -10,8 +10,11 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.index; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplateInstance; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; /** * Delegating clone implementation for index classes implementing {@link ICPPAliasTemplateInstance} interface. @@ -26,8 +29,32 @@ public class CPPAliasTemplateInstanceClone extends CPPTypedefClone implements IC return new CPPAliasTemplateInstanceClone(this); } + private ICPPAliasTemplateInstance getDelegate() { + return (ICPPAliasTemplateInstance) delegate; + } + @Override public ICPPAliasTemplate getTemplateDefinition() { - return ((ICPPAliasTemplateInstance) delegate).getTemplateDefinition(); + return getDelegate().getTemplateDefinition(); + } + + @Override + public ICPPTemplateArgument[] getTemplateArguments() { + return getDelegate().getTemplateArguments(); + } + + @Override + public boolean isExplicitSpecialization() { + return false; + } + + @Override + public IBinding getSpecializedBinding() { + return getDelegate().getSpecializedBinding(); + } + + @Override + public ICPPTemplateParameterMap getTemplateParameterMap() { + return getDelegate().getTemplateParameterMap(); } } 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 a90d9393397..e3e15eb6d05 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 @@ -54,6 +54,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUnaryTypeTransformation; @@ -237,7 +238,12 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { if (aliasTemplate instanceof IIndexFragmentBinding) aliasTemplate = (ICPPAliasTemplate) getCompositeBinding((IIndexFragmentBinding) aliasTemplate); IType aliasedType = getCompositeType(instance.getType()); - return new CPPAliasTemplateInstance(instance.getNameCharArray(), aliasTemplate, aliasedType); + IBinding owner = instance.getOwner(); + if (owner instanceof IIndexFragmentBinding) + owner = getCompositeBinding((IIndexFragmentBinding) owner); + ICPPTemplateArgument[] args = TemplateInstanceUtil.convert(this, instance.getTemplateArguments()); + ICPPTemplateParameterMap map = TemplateInstanceUtil.getTemplateParameterMap(this, instance); + return new CPPAliasTemplateInstance(aliasTemplate, aliasedType, owner, map, args); } if (rtype instanceof TypeOfDependentExpression) { TypeOfDependentExpression type= (TypeOfDependentExpression) rtype; @@ -580,6 +586,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { return new CompositeCPPFieldInstance(this, (ICPPVariableInstance) binding); } else if (binding instanceof ICPPVariable) { return new CompositeCPPVariableInstance(this, (ICPPVariableInstance) binding); + } else if (binding instanceof ICPPAliasTemplateInstance) { + return new CompositeCPPAliasTemplateInstance(this, (ICPPAliasTemplateInstance) binding); } else { throw new CompositingNotImplementedError("Composite binding unavailable for " + binding + " " + binding.getClass()); //$NON-NLS-1$ //$NON-NLS-2$ } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPAliasTemplateInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPAliasTemplateInstance.java index 11920d5b7ed..9c07ff8aa83 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPAliasTemplateInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPAliasTemplateInstance.java @@ -13,11 +13,13 @@ package org.eclipse.cdt.internal.core.index.composite.cpp; import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.internal.core.index.CPPAliasTemplateInstanceClone; import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; -class CompositeCPPAliasTemplateInstance extends CompositeCPPTypedef implements ICPPAliasTemplateInstance { +class CompositeCPPAliasTemplateInstance extends CompositeCPPTypedefSpecialization implements ICPPAliasTemplateInstance { public CompositeCPPAliasTemplateInstance(ICompositesFactory cf, ICPPBinding delegate) { super(cf, delegate); } @@ -32,4 +34,14 @@ class CompositeCPPAliasTemplateInstance extends CompositeCPPTypedef implements I public Object clone() { return new CPPAliasTemplateInstanceClone(this); } + + @Override + public ICPPTemplateArgument[] getTemplateArguments() { + return TemplateInstanceUtil.getTemplateArguments(cf, (ICPPTemplateInstance) rbinding); + } + + @Override + public boolean isExplicitSpecialization() { + return false; + } } 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 bb8b5d8a065..d2b3b725c68 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 @@ -288,10 +288,11 @@ public class PDOM extends PlatformObject implements IPDOM { * 208.0 - Trigger index rebuild to rebuild corrupted binding reference lists, bug 399147. * 209.0 - Alias templates and their instances take up more space than required, bug 516385. * 210.0 - Return type deduction, bug 408470. + * 211.0 - Change representation of alias template instances, bug 516338. */ - private static final int MIN_SUPPORTED_VERSION= version(210, 0); - private static final int MAX_SUPPORTED_VERSION= version(210, Short.MAX_VALUE); - private static final int DEFAULT_VERSION = version(210, 0); + private static final int MIN_SUPPORTED_VERSION= version(211, 0); + private static final int MAX_SUPPORTED_VERSION= version(211, Short.MAX_VALUE); + private static final int DEFAULT_VERSION = version(211, 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/PDOMCPPAliasTemplateInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPAliasTemplateInstance.java index a92c3b2f287..b3f498d4828 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPAliasTemplateInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPAliasTemplateInstance.java @@ -14,6 +14,7 @@ import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplateInstance; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.internal.core.index.CPPAliasTemplateInstanceClone; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.pdom.db.Database; @@ -24,18 +25,20 @@ import org.eclipse.core.runtime.CoreException; /** * PDOM binding for alias template instance. */ -class PDOMCPPAliasTemplateInstance extends PDOMCPPTypedef implements ICPPAliasTemplateInstance { - private static final int TEMPLATE_DEFINITION_OFFSET = PDOMCPPTypedef.RECORD_SIZE; +class PDOMCPPAliasTemplateInstance extends PDOMCPPTypedefSpecialization implements ICPPAliasTemplateInstance { + private static final int TEMPLATE_ARGUMENTS = PDOMCPPTypedefSpecialization.RECORD_SIZE; // Database.PTR_SIZE @SuppressWarnings("hiding") - protected static final int RECORD_SIZE = TEMPLATE_DEFINITION_OFFSET + Database.PTR_SIZE; + protected static final int RECORD_SIZE = TEMPLATE_ARGUMENTS + Database.PTR_SIZE; - private volatile ICPPAliasTemplate fTemplateDefinition; - - public PDOMCPPAliasTemplateInstance(PDOMCPPLinkage linkage, PDOMNode parent, PDOMBinding templateDefinition, - ICPPAliasTemplateInstance binding) throws CoreException, DOMException { - super(linkage, parent, binding); - getDB().putRecPtr(record + TEMPLATE_DEFINITION_OFFSET, templateDefinition.getRecord()); + private volatile ICPPTemplateArgument[] fTemplateArguments; + + public PDOMCPPAliasTemplateInstance(PDOMCPPLinkage linkage, PDOMNode parent, + PDOMBinding aliasTemplate, ICPPAliasTemplateInstance astInstance) + throws CoreException, DOMException { + super(linkage, parent, astInstance, aliasTemplate); + fTemplateArguments = astInstance.getTemplateArguments(); + linkage.new ConfigureAliasTemplateInstance(this); } public PDOMCPPAliasTemplateInstance(PDOMCPPLinkage linkage, long record) { @@ -49,15 +52,7 @@ class PDOMCPPAliasTemplateInstance extends PDOMCPPTypedef implements ICPPAliasTe @Override public ICPPAliasTemplate getTemplateDefinition() { - if (fTemplateDefinition == null) { - try { - long templateRec = getDB().getRecPtr(record + TEMPLATE_DEFINITION_OFFSET); - fTemplateDefinition = (ICPPAliasTemplate) PDOMNode.load(getPDOM(), templateRec); - } catch (CoreException e) { - CCorePlugin.log(e); - } - } - return fTemplateDefinition; + return (ICPPAliasTemplate) getSpecializedBinding(); } @Override @@ -69,4 +64,38 @@ class PDOMCPPAliasTemplateInstance extends PDOMCPPTypedef implements ICPPAliasTe public Object clone() { return new CPPAliasTemplateInstanceClone(this); } + + @Override + public ICPPTemplateArgument[] getTemplateArguments() { + if (fTemplateArguments == null) { + try { + final long rec= getPDOM().getDB().getRecPtr(record + TEMPLATE_ARGUMENTS); + fTemplateArguments = PDOMCPPArgumentList.getArguments(this, rec); + } catch (CoreException e) { + CCorePlugin.log(e); + fTemplateArguments = ICPPTemplateArgument.EMPTY_ARGUMENTS; + } + } + return fTemplateArguments; + } + + public void storeTemplateArguments() { + try { + // fTemplateArguments here are the temporarily stored, possibly non-PDOM arguments stored + // by the constructor. Construct the PDOM arguments and store them. + final long argListRec = PDOMCPPArgumentList.putArguments(this, fTemplateArguments); + getDB().putRecPtr(record + TEMPLATE_ARGUMENTS, argListRec); + + // Read the stored arguments next time getTemplateArguments() is called. + fTemplateArguments = null; + } catch (CoreException e) { + CCorePlugin.log(e); + } + } + + @Override + public boolean isExplicitSpecialization() { + // Alias templates cannot be explicitly specialized. + return false; + } } \ No newline at end of file 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 8ced0892f45..3b22799aa91 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 @@ -540,6 +540,20 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { fTemplate.initData(fOriginalAliasedType); } } + + class ConfigureAliasTemplateInstance implements Runnable { + PDOMCPPAliasTemplateInstance fAliasInstance; + + public ConfigureAliasTemplateInstance(PDOMCPPAliasTemplateInstance aliasInstance) { + fAliasInstance = aliasInstance; + postProcesses.add(this); + } + + @Override + public void run() { + fAliasInstance.storeTemplateArguments(); + } + } class ConfigureInstance implements Runnable { PDOMCPPSpecialization fInstance; @@ -930,6 +944,8 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { result = new PDOMCPPFieldInstance(this, parent, (ICPPVariableInstance) special, orig); } else if (special instanceof ICPPVariable && orig instanceof ICPPVariable) { result= new PDOMCPPVariableInstance(this, parent, (ICPPVariableInstance) special, orig); + } else if (special instanceof ICPPAliasTemplateInstance && orig instanceof ICPPAliasTemplate) { + result = new PDOMCPPAliasTemplateInstance(this, parent, orig, (ICPPAliasTemplateInstance) special); } } else if (special instanceof ICPPField) { result= new PDOMCPPFieldSpecialization(this, parent, (ICPPField) special, orig);