1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 18:26:01 +02:00

Bug 407497, Bug 399454 - Specialize template parameters when appropriate

Change-Id: Iff52b04319234ca8e5fe0f9b23d5d1787cee4449
Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
Reviewed-on: https://git.eclipse.org/r/14533
Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
IP-Clean: Sergey Prigogin <eclipse.sprigogin@gmail.com>
Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
Nathan Ridge 2013-07-16 00:57:07 -04:00 committed by Sergey Prigogin
parent e18ad3974c
commit 480e491e88
15 changed files with 842 additions and 122 deletions

View file

@ -6411,6 +6411,34 @@ public class AST2TemplateTests extends AST2TestBase {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// struct N {
// int node;
// };
//
// template <typename T>
// struct List {
// template <int T::*>
// struct Base {};
// };
//
// List<N>::Base<&N::node> base;
public void testDependentTemplateParameterInNestedTemplate_407497() throws Exception {
parseAndCheckBindings();
}
// template <typename T>
// struct enclosing {
// template <typename U = T>
// struct nested {
// typedef U type;
// };
// };
//
// typedef enclosing<int>::nested<>::type waldo;
public void testDependentTemplateParameterInNestedTemplate_399454() throws Exception {
parseAndCheckBindings();
}
// class Memory { }; // class Memory { };
// Memory memory; // Memory memory;
// template<Memory* m> struct Container { // template<Memory* m> struct Container {

View file

@ -2322,4 +2322,46 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
public void testSpecializationRedefinition_409444() throws Exception { public void testSpecializationRedefinition_409444() throws Exception {
checkBindings(); checkBindings();
} }
// struct N {
// int node;
// };
//
// template <typename T>
// struct List {
// template <int T::*>
// struct Base {};
// };
// List<N>::Base<&N::node> base;
public void testDependentTemplateParameterInNestedTemplate_407497() throws Exception {
checkBindings();
}
// template <typename T>
// struct enclosing {
// template <typename U = T>
// struct nested {
// typedef U type;
// };
// };
// typedef enclosing<int>::nested<>::type waldo;
public void testDependentTemplateParameterInNestedTemplate_399454() throws Exception {
checkBindings();
}
// void f(int);
//
// template <typename... Args>
// struct A
// {
// template <typename R = decltype(f(Args()...))>
// static R foo();
// };
// typedef decltype(A<int>::foo<>()) waldo;
public void testNPE_407497() throws Exception {
checkBindings();
}
} }

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -9,6 +9,7 @@
* IBM - Initial API and implementation * IBM - Initial API and implementation
* Bryan Wilkinson (QNX) * Bryan Wilkinson (QNX)
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Nathan Ridge
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; 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.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; 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.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.ICPPTemplateArgument;
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.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
@ -36,19 +36,25 @@ public class CPPClassTemplateSpecialization extends CPPClassSpecialization
private ObjectMap instances = null; private ObjectMap instances = null;
private ICPPDeferredClassInstance fDeferredInstance; private ICPPDeferredClassInstance fDeferredInstance;
private ICPPClassTemplatePartialSpecialization[] fPartialSpecs; 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); super(orig, owner, argumentMap);
} }
public void setTemplateParameters(ICPPTemplateParameter[] templateParameters) {
fTemplateParameters = templateParameters;
}
@Override @Override
public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() { public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() {
if (fPartialSpecs == null) { if (fPartialSpecs == null) {
IASTNode point= null; // Instantiation of dependent expressions may not work. IASTNode point= null; // Instantiation of dependent expressions may not work.
ICPPClassTemplate origTemplate= (ICPPClassTemplate) getSpecializedBinding(); ICPPClassTemplate origTemplate= getSpecializedBinding();
ICPPClassTemplatePartialSpecialization[] orig = origTemplate.getPartialSpecializations(); ICPPClassTemplatePartialSpecialization[] orig = origTemplate.getPartialSpecializations();
ICPPClassTemplatePartialSpecialization[] spec = new ICPPClassTemplatePartialSpecialization[orig.length]; ICPPClassTemplatePartialSpecialization[] spec = new ICPPClassTemplatePartialSpecialization[orig.length];
ICPPClassSpecialization owner = (ICPPClassSpecialization) getOwner(); ICPPClassSpecialization owner = getOwner();
for (int i = 0; i < orig.length; i++) { for (int i = 0; i < orig.length; i++) {
spec[i]= (ICPPClassTemplatePartialSpecialization) owner.specializeMember(orig[i], point); spec[i]= (ICPPClassTemplatePartialSpecialization) owner.specializeMember(orig[i], point);
} }
@ -59,10 +65,7 @@ public class CPPClassTemplateSpecialization extends CPPClassSpecialization
@Override @Override
public ICPPTemplateParameter[] getTemplateParameters() { public ICPPTemplateParameter[] getTemplateParameters() {
// mstodo if we specialize the template parameters (because of its default values), it will return fTemplateParameters;
// be less error prone to use the defaults.
ICPPClassTemplate template = (ICPPClassTemplate) getSpecializedBinding();
return template.getTemplateParameters();
} }
@Override @Override
@ -120,4 +123,14 @@ public class CPPClassTemplateSpecialization extends CPPClassSpecialization
public ICPPTemplateArgument getDefaultArgFromIndex(int paramPos) throws DOMException { public ICPPTemplateArgument getDefaultArgFromIndex(int paramPos) throws DOMException {
return null; return null;
} }
@Override
public ICPPClassSpecialization getOwner() {
return (ICPPClassSpecialization) super.getOwner();
}
@Override
public ICPPClassTemplate getSpecializedBinding() {
return (ICPPClassTemplate) super.getSpecializedBinding();
}
} }

View file

@ -12,7 +12,7 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IType; 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.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
@ -24,7 +24,7 @@ public class CPPConstructorTemplateSpecialization extends CPPMethodTemplateSpeci
implements ICPPConstructor { implements ICPPConstructor {
public CPPConstructorTemplateSpecialization(ICPPConstructor original, 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); super(original, owner, tpmap, type, exceptionSpecs);
} }
} }

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -9,14 +9,17 @@
* Andrew Niefer (IBM) - Initial API and implementation * Andrew Niefer (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Thomas Corbat (IFS) * Thomas Corbat (IFS)
* Nathan Ridge
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType; 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.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; 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.ICPPMethod;
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.ICPPTemplateParameterMap;
/** /**
@ -25,11 +28,22 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
public class CPPMethodTemplateSpecialization extends CPPFunctionTemplateSpecialization public class CPPMethodTemplateSpecialization extends CPPFunctionTemplateSpecialization
implements ICPPMethod { implements ICPPMethod {
public CPPMethodTemplateSpecialization(ICPPMethod specialized, ICPPClassType owner, private ICPPTemplateParameter[] fTemplateParameters;
public CPPMethodTemplateSpecialization(ICPPMethod specialized, ICPPClassSpecialization owner,
ICPPTemplateParameterMap ctmap, ICPPFunctionType type, IType[] exceptionSpecs) { ICPPTemplateParameterMap ctmap, ICPPFunctionType type, IType[] exceptionSpecs) {
super(specialized, owner, ctmap, type, exceptionSpecs); super(specialized, owner, ctmap, type, exceptionSpecs);
} }
public void setTemplateParameters(ICPPTemplateParameter[] templateParameters) {
fTemplateParameters = templateParameters;
}
@Override
public ICPPTemplateParameter[] getTemplateParameters() {
return fTemplateParameters;
}
@Override @Override
public boolean isVirtual() { public boolean isVirtual() {
IBinding m = getSpecializedBinding(); IBinding m = getSpecializedBinding();
@ -48,7 +62,7 @@ public class CPPMethodTemplateSpecialization extends CPPFunctionTemplateSpeciali
@Override @Override
public ICPPClassType getClassOwner() { public ICPPClassType getClassOwner() {
return (ICPPClassType) getOwner(); return getOwner();
} }
@Override @Override
@ -93,4 +107,9 @@ public class CPPMethodTemplateSpecialization extends CPPFunctionTemplateSpeciali
public boolean isFinal() { public boolean isFinal() {
return false; return false;
} }
@Override
public ICPPClassSpecialization getOwner() {
return (ICPPClassSpecialization) super.getOwner();
}
} }

View file

@ -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;
}
}

View file

@ -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();
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -24,6 +24,7 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; 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.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException; 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.CPPTemplateDefinition;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeArgument; 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.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.CPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTemplateParameter; 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.CPPTemplateTypeArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeParameter; 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.CPPTypedefSpecialization;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownMemberClass; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownMemberClass;
@ -801,6 +805,7 @@ public class CPPTemplates {
public static IBinding createSpecialization(ICPPClassSpecialization owner, IBinding decl, IASTNode point) { public static IBinding createSpecialization(ICPPClassSpecialization owner, IBinding decl, IASTNode point) {
IBinding spec = null; IBinding spec = null;
final ICPPTemplateParameterMap tpMap= owner.getTemplateParameterMap(); final ICPPTemplateParameterMap tpMap= owner.getTemplateParameterMap();
try {
if (decl instanceof ICPPClassTemplatePartialSpecialization) { if (decl instanceof ICPPClassTemplatePartialSpecialization) {
try { try {
final ICPPClassSpecialization within = getSpecializationContext(owner); final ICPPClassSpecialization within = getSpecializationContext(owner);
@ -813,7 +818,11 @@ public class CPPTemplates {
} catch (DOMException e) { } catch (DOMException e) {
} }
} else if (decl instanceof ICPPClassTemplate) { } else if (decl instanceof ICPPClassTemplate) {
spec = new CPPClassTemplateSpecialization((ICPPClassTemplate) decl, owner, tpMap); 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) { } else if (decl instanceof ICPPClassType) {
IBinding oldOwner = decl.getOwner(); IBinding oldOwner = decl.getOwner();
if (oldOwner instanceof IType && owner.getSpecializedBinding().isSameType((IType) oldOwner)) { if (oldOwner instanceof IType && owner.getSpecializedBinding().isSameType((IType) oldOwner)) {
@ -834,10 +843,16 @@ public class CPPTemplates {
IType[] exceptionSpecs= instantiateTypes(func.getExceptionSpecification(), tpMap, -1, within, point); IType[] exceptionSpecs= instantiateTypes(func.getExceptionSpecification(), tpMap, -1, within, point);
if (decl instanceof ICPPFunctionTemplate) { if (decl instanceof ICPPFunctionTemplate) {
if (decl instanceof ICPPMethod) {
CPPMethodTemplateSpecialization methodSpec;
if (decl instanceof ICPPConstructor) { if (decl instanceof ICPPConstructor) {
spec = new CPPConstructorTemplateSpecialization((ICPPConstructor) decl, owner, tpMap, type, exceptionSpecs); methodSpec = new CPPConstructorTemplateSpecialization((ICPPConstructor) decl, owner, tpMap, type, exceptionSpecs);
} else if (decl instanceof ICPPMethod) { } else {
spec = new CPPMethodTemplateSpecialization((ICPPMethod) decl, owner, tpMap, type, exceptionSpecs); 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 { } else {
IBinding oldOwner = decl.getOwner(); IBinding oldOwner = decl.getOwner();
spec = new CPPFunctionTemplateSpecialization((ICPPFunctionTemplate) decl, oldOwner, tpMap, type, exceptionSpecs); spec = new CPPFunctionTemplateSpecialization((ICPPFunctionTemplate) decl, oldOwner, tpMap, type, exceptionSpecs);
@ -902,6 +917,9 @@ public class CPPTemplates {
delegates= result.toArray(new IBinding[result.size()]); delegates= result.toArray(new IBinding[result.size()]);
spec= new CPPUsingDeclarationSpecialization((ICPPUsingDeclaration) decl, owner, tpMap, delegates); spec= new CPPUsingDeclarationSpecialization((ICPPUsingDeclaration) decl, owner, tpMap, delegates);
} }
} catch (DOMException e) {
CCorePlugin.log(e);
}
return spec; 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, public static IBinding instantiateBinding(IBinding binding, ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point) throws DOMException { ICPPClassSpecialization within, int maxdepth, IASTNode point) throws DOMException {
if (binding instanceof ICPPClassTemplate) { if (binding instanceof ICPPClassTemplate) {

View file

@ -145,6 +145,8 @@ public class EvalTypeId extends CPPDependentEvaluation {
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation(); args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation();
} }
} else {
args = new ICPPEvaluation[0]; // arguments must not be null
} }
IBinding templateDefinition= buffer.unmarshalBinding(); IBinding templateDefinition= buffer.unmarshalBinding();
return new EvalTypeId(type, templateDefinition, args); return new EvalTypeId(type, templateDefinition, args);

View file

@ -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. * 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. * 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. * 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 MIN_SUPPORTED_VERSION= version(148, 0);
private static final int MAX_SUPPORTED_VERSION= version(147, Short.MAX_VALUE); private static final int MAX_SUPPORTED_VERSION= version(148, Short.MAX_VALUE);
private static final int DEFAULT_VERSION = version(147, 0); private static final int DEFAULT_VERSION = version(148, 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

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -8,9 +8,12 @@
* Contributors: * Contributors:
* Bryan Wilkinson (QNX) - Initial API and implementation * Bryan Wilkinson (QNX) - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Nathan Ridge
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp; 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.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; 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.ICPPInstanceCache;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; 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.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.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
@ -40,12 +44,22 @@ import org.eclipse.core.runtime.CoreException;
*/ */
class PDOMCPPClassTemplateSpecialization extends PDOMCPPClassSpecialization class PDOMCPPClassTemplateSpecialization extends PDOMCPPClassSpecialization
implements ICPPClassTemplate, ICPPInstanceCache { implements ICPPClassTemplate, ICPPInstanceCache {
@SuppressWarnings("hiding")
protected static final int RECORD_SIZE = PDOMCPPClassSpecialization.RECORD_SIZE;
public PDOMCPPClassTemplateSpecialization(PDOMLinkage linkage, PDOMNode parent, ICPPClassTemplate template, PDOMBinding specialized) private static final int TEMPLATE_PARAMS = PDOMCPPClassSpecialization.RECORD_SIZE;
@SuppressWarnings("hiding")
protected static final int RECORD_SIZE = TEMPLATE_PARAMS + Database.PTR_SIZE;
private volatile IPDOMCPPTemplateParameter[] fTemplateParameters;
public PDOMCPPClassTemplateSpecialization(PDOMCPPLinkage linkage, PDOMNode parent, ICPPClassTemplate template, PDOMBinding specialized)
throws CoreException { throws CoreException {
super(linkage, parent, template, specialized); 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) { public PDOMCPPClassTemplateSpecialization(PDOMLinkage linkage, long bindingRecord) {
@ -64,8 +78,20 @@ class PDOMCPPClassTemplateSpecialization extends PDOMCPPClassSpecialization
@Override @Override
public ICPPTemplateParameter[] getTemplateParameters() { public ICPPTemplateParameter[] getTemplateParameters() {
ICPPClassTemplate template = (ICPPClassTemplate) getSpecializedBinding(); if (fTemplateParameters == null) {
return template.getTemplateParameters(); 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 @Override
@ -180,4 +206,17 @@ class PDOMCPPClassTemplateSpecialization extends PDOMCPPClassSpecialization
return dci; 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;
}
}
} }

View file

@ -28,7 +28,7 @@ class PDOMCPPConstructorTemplateSpecialization extends PDOMCPPMethodTemplateSpec
@SuppressWarnings("hiding") @SuppressWarnings("hiding")
protected static final int RECORD_SIZE = PDOMCPPFunctionSpecialization.RECORD_SIZE + 0; 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 { throws CoreException {
super(linkage, parent, constructor, specialized); super(linkage, parent, constructor, specialized);
} }

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -9,14 +9,19 @@
* QNX - Initial API and implementation * QNX - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Thomas Corbat (IFS) * Thomas Corbat (IFS)
* Nathan Ridge
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp; 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.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; 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.ICPPFunctionTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; 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.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.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
@ -29,15 +34,50 @@ import org.eclipse.core.runtime.CoreException;
class PDOMCPPMethodTemplateSpecialization extends class PDOMCPPMethodTemplateSpecialization extends
PDOMCPPFunctionTemplateSpecialization implements ICPPMethod { 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 { throws CoreException {
super(linkage, parent, (ICPPFunctionTemplate) method, specialized); 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) { public PDOMCPPMethodTemplateSpecialization(PDOMLinkage linkage, long bindingRecord) {
super(linkage, 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 @Override
public int getNodeType() { public int getNodeType() {
return IIndexCPPBindingConstants.CPP_METHOD_TEMPLATE_SPECIALIZATION; return IIndexCPPBindingConstants.CPP_METHOD_TEMPLATE_SPECIALIZATION;
@ -112,4 +152,17 @@ class PDOMCPPMethodTemplateSpecialization extends
public boolean isFinal() { public boolean isFinal() {
return false; 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;
}
}
} }