1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 09:46:02 +02:00

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
This commit is contained in:
Nathan Ridge 2017-05-10 03:37:46 -04:00
parent 8d6cab41e7
commit e374b4b08e
9 changed files with 149 additions and 42 deletions

View file

@ -20,9 +20,10 @@ import org.eclipse.cdt.core.dom.ast.ITypedef;
* @noextend This interface is not intended to be extended by clients. * @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented 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. * Returns the alias template specialized by this instance.
*/ */
@Override
public ICPPAliasTemplate getTemplateDefinition(); public ICPPAliasTemplate getTemplateDefinition();
} }

View file

@ -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.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplate; 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.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.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.Linkage; 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.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.core.runtime.PlatformObject;
public class CPPAliasTemplateInstance extends PlatformObject public class CPPAliasTemplateInstance extends CPPSpecialization implements ICPPAliasTemplateInstance,
implements ICPPAliasTemplateInstance, ITypeContainer, ICPPInternalBinding { ITypeContainer {
private final char[] name;
private final ICPPAliasTemplate aliasTemplate;
private IType aliasedType; private IType aliasedType;
private ICPPTemplateArgument[] fArguments;
public CPPAliasTemplateInstance(char[] name, ICPPAliasTemplate aliasTemplate, IType aliasedType) { public CPPAliasTemplateInstance(ICPPAliasTemplate aliasTemplate, IType aliasedType, IBinding owner,
this.name = name; ICPPTemplateParameterMap argumentMap, ICPPTemplateArgument[] arguments) {
this.aliasTemplate = aliasTemplate; super(aliasTemplate, owner, argumentMap);
this.aliasedType = aliasedType; this.aliasedType = aliasedType;
this.fArguments = arguments;
} }
@Override @Override
public ICPPAliasTemplate getTemplateDefinition() { public ICPPAliasTemplate getTemplateDefinition() {
return aliasTemplate; return (ICPPAliasTemplate) super.getSpecializedBinding();
} }
@Override @Override
@ -80,6 +81,7 @@ public class CPPAliasTemplateInstance extends PlatformObject
@Override @Override
public char[] getNameCharArray() { public char[] getNameCharArray() {
char[] name = getTemplateDefinition().getNameCharArray();
if (name != null) { if (name != null) {
return name; return name;
} }
@ -93,16 +95,16 @@ public class CPPAliasTemplateInstance extends PlatformObject
@Override @Override
public IBinding getOwner() { public IBinding getOwner() {
if (aliasTemplate != null) { if (getTemplateDefinition() != null) {
return aliasTemplate.getOwner(); return getTemplateDefinition().getOwner();
} }
return null; return null;
} }
@Override @Override
public IScope getScope() throws DOMException { public IScope getScope() throws DOMException {
if (aliasTemplate != null) { if (getTemplateDefinition() != null) {
return aliasTemplate.getScope(); return getTemplateDefinition().getScope();
} }
return null; return null;
} }
@ -119,13 +121,13 @@ public class CPPAliasTemplateInstance extends PlatformObject
@Override @Override
public boolean isGloballyQualified() throws DOMException { public boolean isGloballyQualified() throws DOMException {
return aliasTemplate.isGloballyQualified(); return getTemplateDefinition().isGloballyQualified();
} }
@Override @Override
public IASTNode getDefinition() { public IASTNode getDefinition() {
if (aliasTemplate instanceof ICPPInternalBinding) { if (getTemplateDefinition() instanceof ICPPInternalBinding) {
return ((ICPPInternalBinding) aliasTemplate).getDefinition(); return ((ICPPInternalBinding) getTemplateDefinition()).getDefinition();
} }
return null; return null;
} }
@ -150,4 +152,15 @@ public class CPPAliasTemplateInstance extends PlatformObject
public String toString() { public String toString() {
return ASTTypeUtil.getQualifiedName(this) + " -> " + ASTTypeUtil.getType(aliasedType, true); //$NON-NLS-1$ 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;
}
} }

View file

@ -852,7 +852,7 @@ public class CPPTemplates {
IBinding owner, IASTNode point) { IBinding owner, IASTNode point) {
InstantiationContext context = createInstantiationContext(parameterMap, owner, point); InstantiationContext context = createInstantiationContext(parameterMap, owner, point);
IType instantiatedType = instantiateType(aliasedType, context); 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) { static boolean isClassTemplate(ICPPASTTemplateId id) {

View file

@ -10,8 +10,11 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.index; 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.ICPPAliasTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplateInstance; 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. * 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); return new CPPAliasTemplateInstanceClone(this);
} }
private ICPPAliasTemplateInstance getDelegate() {
return (ICPPAliasTemplateInstance) delegate;
}
@Override @Override
public ICPPAliasTemplate getTemplateDefinition() { 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();
} }
} }

View file

@ -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.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; 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.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.ICPPTemplateTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUnaryTypeTransformation; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUnaryTypeTransformation;
@ -237,7 +238,12 @@ public class CPPCompositesFactory extends AbstractCompositeFactory {
if (aliasTemplate instanceof IIndexFragmentBinding) if (aliasTemplate instanceof IIndexFragmentBinding)
aliasTemplate = (ICPPAliasTemplate) getCompositeBinding((IIndexFragmentBinding) aliasTemplate); aliasTemplate = (ICPPAliasTemplate) getCompositeBinding((IIndexFragmentBinding) aliasTemplate);
IType aliasedType = getCompositeType(instance.getType()); 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) { if (rtype instanceof TypeOfDependentExpression) {
TypeOfDependentExpression type= (TypeOfDependentExpression) rtype; TypeOfDependentExpression type= (TypeOfDependentExpression) rtype;
@ -580,6 +586,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory {
return new CompositeCPPFieldInstance(this, (ICPPVariableInstance) binding); return new CompositeCPPFieldInstance(this, (ICPPVariableInstance) binding);
} else if (binding instanceof ICPPVariable) { } else if (binding instanceof ICPPVariable) {
return new CompositeCPPVariableInstance(this, (ICPPVariableInstance) binding); return new CompositeCPPVariableInstance(this, (ICPPVariableInstance) binding);
} else if (binding instanceof ICPPAliasTemplateInstance) {
return new CompositeCPPAliasTemplateInstance(this, (ICPPAliasTemplateInstance) binding);
} else { } else {
throw new CompositingNotImplementedError("Composite binding unavailable for " + binding + " " + binding.getClass()); //$NON-NLS-1$ //$NON-NLS-2$ throw new CompositingNotImplementedError("Composite binding unavailable for " + binding + " " + binding.getClass()); //$NON-NLS-1$ //$NON-NLS-2$
} }

View file

@ -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.ICPPAliasTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplateInstance; 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.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.CPPAliasTemplateInstanceClone;
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; 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) { public CompositeCPPAliasTemplateInstance(ICompositesFactory cf, ICPPBinding delegate) {
super(cf, delegate); super(cf, delegate);
} }
@ -32,4 +34,14 @@ class CompositeCPPAliasTemplateInstance extends CompositeCPPTypedef implements I
public Object clone() { public Object clone() {
return new CPPAliasTemplateInstanceClone(this); return new CPPAliasTemplateInstanceClone(this);
} }
@Override
public ICPPTemplateArgument[] getTemplateArguments() {
return TemplateInstanceUtil.getTemplateArguments(cf, (ICPPTemplateInstance) rbinding);
}
@Override
public boolean isExplicitSpecialization() {
return false;
}
} }

View file

@ -288,10 +288,11 @@ public class PDOM extends PlatformObject implements IPDOM {
* 208.0 - Trigger index rebuild to rebuild corrupted binding reference lists, bug 399147. * 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. * 209.0 - Alias templates and their instances take up more space than required, bug 516385.
* 210.0 - Return type deduction, bug 408470. * 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 MIN_SUPPORTED_VERSION= version(211, 0);
private static final int MAX_SUPPORTED_VERSION= version(210, Short.MAX_VALUE); private static final int MAX_SUPPORTED_VERSION= version(211, Short.MAX_VALUE);
private static final int DEFAULT_VERSION = version(210, 0); private static final int DEFAULT_VERSION = version(211, 0);
private static int version(int major, int minor) { private static int version(int major, int minor) {
return (major << 16) + minor; return (major << 16) + minor;

View file

@ -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.DOMException;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplate; 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.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.CPPAliasTemplateInstanceClone;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.pdom.db.Database; 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. * PDOM binding for alias template instance.
*/ */
class PDOMCPPAliasTemplateInstance extends PDOMCPPTypedef implements ICPPAliasTemplateInstance { class PDOMCPPAliasTemplateInstance extends PDOMCPPTypedefSpecialization implements ICPPAliasTemplateInstance {
private static final int TEMPLATE_DEFINITION_OFFSET = PDOMCPPTypedef.RECORD_SIZE; private static final int TEMPLATE_ARGUMENTS = PDOMCPPTypedefSpecialization.RECORD_SIZE; // Database.PTR_SIZE
@SuppressWarnings("hiding") @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; private volatile ICPPTemplateArgument[] fTemplateArguments;
public PDOMCPPAliasTemplateInstance(PDOMCPPLinkage linkage, PDOMNode parent, PDOMBinding templateDefinition, public PDOMCPPAliasTemplateInstance(PDOMCPPLinkage linkage, PDOMNode parent,
ICPPAliasTemplateInstance binding) throws CoreException, DOMException { PDOMBinding aliasTemplate, ICPPAliasTemplateInstance astInstance)
super(linkage, parent, binding); throws CoreException, DOMException {
getDB().putRecPtr(record + TEMPLATE_DEFINITION_OFFSET, templateDefinition.getRecord()); super(linkage, parent, astInstance, aliasTemplate);
fTemplateArguments = astInstance.getTemplateArguments();
linkage.new ConfigureAliasTemplateInstance(this);
} }
public PDOMCPPAliasTemplateInstance(PDOMCPPLinkage linkage, long record) { public PDOMCPPAliasTemplateInstance(PDOMCPPLinkage linkage, long record) {
@ -49,15 +52,7 @@ class PDOMCPPAliasTemplateInstance extends PDOMCPPTypedef implements ICPPAliasTe
@Override @Override
public ICPPAliasTemplate getTemplateDefinition() { public ICPPAliasTemplate getTemplateDefinition() {
if (fTemplateDefinition == null) { return (ICPPAliasTemplate) getSpecializedBinding();
try {
long templateRec = getDB().getRecPtr(record + TEMPLATE_DEFINITION_OFFSET);
fTemplateDefinition = (ICPPAliasTemplate) PDOMNode.load(getPDOM(), templateRec);
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
return fTemplateDefinition;
} }
@Override @Override
@ -69,4 +64,38 @@ class PDOMCPPAliasTemplateInstance extends PDOMCPPTypedef implements ICPPAliasTe
public Object clone() { public Object clone() {
return new CPPAliasTemplateInstanceClone(this); 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;
}
} }

View file

@ -541,6 +541,20 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
} }
} }
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 { class ConfigureInstance implements Runnable {
PDOMCPPSpecialization fInstance; PDOMCPPSpecialization fInstance;
@ -930,6 +944,8 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
result = new PDOMCPPFieldInstance(this, parent, (ICPPVariableInstance) special, orig); result = new PDOMCPPFieldInstance(this, parent, (ICPPVariableInstance) special, orig);
} else if (special instanceof ICPPVariable && orig instanceof ICPPVariable) { } else if (special instanceof ICPPVariable && orig instanceof ICPPVariable) {
result= new PDOMCPPVariableInstance(this, parent, (ICPPVariableInstance) special, orig); 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) { } else if (special instanceof ICPPField) {
result= new PDOMCPPFieldSpecialization(this, parent, (ICPPField) special, orig); result= new PDOMCPPFieldSpecialization(this, parent, (ICPPField) special, orig);