mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-09-10 03:53:21 +02:00
Use default arguments before selecting partial specializations, bug 257169.
This commit is contained in:
parent
efc84f0131
commit
4145150968
9 changed files with 240 additions and 102 deletions
|
@ -3385,4 +3385,33 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
assertSame(mt1, mt2);
|
assertSame(mt1, mt2);
|
||||||
assertInstance(mt1, ICPPFunctionTemplate.class);
|
assertInstance(mt1, ICPPFunctionTemplate.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template <typename T, typename U=T> class XT {};
|
||||||
|
// template <typename T> class XT<T,T> {public: int partial;};
|
||||||
|
// void test() {
|
||||||
|
// XT<int> xt;
|
||||||
|
// xt.partial;
|
||||||
|
// }
|
||||||
|
public void testDefaultArgsWithPartialSpecialization() throws Exception {
|
||||||
|
final String code = getAboveComment();
|
||||||
|
parseAndCheckBindings(code, ParserLanguage.CPP);
|
||||||
|
}
|
||||||
|
|
||||||
|
// template <typename T> class XT {
|
||||||
|
// public:
|
||||||
|
// int a;
|
||||||
|
// void m() {
|
||||||
|
// this->a= 1;
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
public void _testFieldReference_Bug234321() throws Exception {
|
||||||
|
final String code = getAboveComment();
|
||||||
|
parseAndCheckBindings(code, ParserLanguage.CPP);
|
||||||
|
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
||||||
|
|
||||||
|
IBinding a1= bh.assertNonProblem("a;", 1);
|
||||||
|
IBinding a2= bh.assertNonProblem("a=", 1);
|
||||||
|
assertInstance(a1, ICPPField.class);
|
||||||
|
assertSame(a1, a2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1482,7 +1482,7 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
|
||||||
assertInstance(t1, ICPPTemplateInstance.class);
|
assertInstance(t1, ICPPTemplateInstance.class);
|
||||||
|
|
||||||
ICPPTemplateInstance inst= (ICPPTemplateInstance) t1;
|
ICPPTemplateInstance inst= (ICPPTemplateInstance) t1;
|
||||||
final ICPPTemplateDefinition tmplDef = inst.getTemplateDefinition();
|
final ICPPClassTemplate tmplDef = (ICPPClassTemplate) inst.getTemplateDefinition();
|
||||||
IBinding inst2= CPPTemplates.instantiate(tmplDef, inst.getTemplateArguments());
|
IBinding inst2= CPPTemplates.instantiate(tmplDef, inst.getTemplateArguments());
|
||||||
assertSame(inst, inst2);
|
assertSame(inst, inst2);
|
||||||
|
|
||||||
|
|
|
@ -96,9 +96,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
||||||
ICPPClassType clsType = (ICPPClassType) binding;
|
ICPPClassType clsType = (ICPPClassType) binding;
|
||||||
if (clsType instanceof ICPPClassTemplate) {
|
if (clsType instanceof ICPPClassTemplate) {
|
||||||
try {
|
try {
|
||||||
IBinding within = CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) clsType);
|
clsType= CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) clsType);
|
||||||
if (within instanceof ICPPClassType)
|
|
||||||
clsType = (ICPPClassType)within;
|
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,10 @@ 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.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IValue;
|
import org.eclipse.cdt.core.dom.ast.IValue;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Binding for a specialization of a parameter.
|
* Binding for a specialization of a parameter.
|
||||||
|
@ -41,6 +43,18 @@ public class CPPParameterSpecialization extends CPPSpecialization implements ICP
|
||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IType specializeType(IType type) throws DOMException {
|
||||||
|
IBinding owner= getOwner();
|
||||||
|
if (owner != null) {
|
||||||
|
owner= owner.getOwner();
|
||||||
|
if (owner instanceof ICPPClassSpecialization) {
|
||||||
|
return CPPTemplates.instantiateType(type, getTemplateParameterMap(), (ICPPClassSpecialization) owner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CPPTemplates.instantiateType(type, getTemplateParameterMap(), null);
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.core.dom.ast.IVariable#isStatic()
|
* @see org.eclipse.cdt.core.dom.ast.IVariable#isStatic()
|
||||||
|
|
|
@ -272,8 +272,11 @@ public abstract class CPPTemplateDefinition extends PlatformObject implements IC
|
||||||
}
|
}
|
||||||
|
|
||||||
final protected void updateTemplateParameterBindings(IASTName name) {
|
final protected void updateTemplateParameterBindings(IASTName name) {
|
||||||
ICPPASTTemplateParameter[] updateParams = CPPTemplates.getTemplateDeclaration(name).getTemplateParameters();
|
final ICPPASTTemplateDeclaration templateDeclaration = CPPTemplates.getTemplateDeclaration(name);
|
||||||
|
if (templateDeclaration == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ICPPASTTemplateParameter[] updateParams = templateDeclaration.getTemplateParameters();
|
||||||
int k= 0;
|
int k= 0;
|
||||||
int tdeclLen= declarations == null ? 0 : declarations.length;
|
int tdeclLen= declarations == null ? 0 : declarations.length;
|
||||||
for (int i= -1; i < tdeclLen && k < updateParams.length; i++) {
|
for (int i= -1; i < tdeclLen && k < updateParams.length; i++) {
|
||||||
|
|
|
@ -23,7 +23,6 @@ import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.IName;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
|
||||||
|
@ -89,6 +88,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
|
||||||
|
@ -253,53 +253,31 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 14.6.1-1: Class template name without argument list is equivalent to the injected-class-name followed by
|
/* 14.6.1-1:
|
||||||
* the template-parameters of the class template enclosed in <> */
|
* Within the scope of a class template, when the name of the template is neither qualified nor
|
||||||
if (binding instanceof ICPPClassTemplate) {
|
* followed by <, it is equivalent to the name followed by the template parameters enclosed in <>.
|
||||||
ICPPClassTemplate ct= (ICPPClassTemplate) binding;
|
*/
|
||||||
|
if (binding instanceof ICPPClassTemplate && !(binding instanceof ICPPClassSpecialization) &&
|
||||||
|
!(data.astName instanceof ICPPASTTemplateId)) {
|
||||||
ASTNodeProperty prop = data.astName.getPropertyInParent();
|
ASTNodeProperty prop = data.astName.getPropertyInParent();
|
||||||
if (prop != ICPPASTQualifiedName.SEGMENT_NAME && prop != ICPPASTTemplateId.TEMPLATE_NAME &&
|
if (prop != ICPPASTTemplateId.TEMPLATE_NAME && prop != ICPPASTQualifiedName.SEGMENT_NAME) {
|
||||||
binding instanceof ICPPInternalBinding) {
|
// You cannot use a class template name outside of the class template scope,
|
||||||
try {
|
// mark it as a problem.
|
||||||
IScope scope= CPPVisitor.getContainingScope(data.astName);
|
IBinding replacement= CPPTemplates.isUsedInClassTemplateScope((ICPPClassTemplate) binding, data.astName);
|
||||||
while (scope instanceof IASTInternalScope) {
|
if (replacement != null) {
|
||||||
final IASTInternalScope internalScope = (IASTInternalScope) scope;
|
binding= replacement;
|
||||||
if (scope instanceof ICPPClassScope) {
|
} else {
|
||||||
final IName scopeName = internalScope.getScopeName();
|
boolean ok= false;
|
||||||
if (scopeName instanceof IASTName) {
|
IASTNode node= data.astName.getParent();
|
||||||
IBinding b= ((IASTName) scopeName).resolveBinding();
|
while (node != null && !ok) {
|
||||||
if (binding == b) {
|
if (node instanceof ICPPASTTemplateId ||
|
||||||
binding= CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) binding);
|
node instanceof ICPPASTTemplatedTypeTemplateParameter) {
|
||||||
break;
|
ok= true; // can be argument or default-value for template template parameter
|
||||||
}
|
break;
|
||||||
if (b instanceof ICPPClassTemplatePartialSpecialization) {
|
|
||||||
ICPPClassTemplatePartialSpecialization pspec= (ICPPClassTemplatePartialSpecialization) b;
|
|
||||||
if (ct.isSameType(pspec.getPrimaryClassTemplate())) {
|
|
||||||
binding= CPPTemplates.instantiateWithinClassTemplate(pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (b instanceof ICPPClassSpecialization) {
|
|
||||||
ICPPClassSpecialization specialization= (ICPPClassSpecialization) b;
|
|
||||||
if (ct.isSameType(specialization.getSpecializedBinding())) {
|
|
||||||
binding= specialization;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
scope= CPPVisitor.getContainingScope(internalScope.getPhysicalNode());
|
node= node.getParent();
|
||||||
}
|
}
|
||||||
} catch (DOMException e) {
|
if (!ok) {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the class template name is used as a type name in a simple declaration,
|
|
||||||
* outside of the class template scope, mark it as a problem.
|
|
||||||
*/
|
|
||||||
if (binding instanceof ICPPClassTemplate) {
|
|
||||||
IASTNode parent= data.astName.getParent();
|
|
||||||
if (parent instanceof IASTNamedTypeSpecifier) {
|
|
||||||
if (parent.getParent() instanceof IASTSimpleDeclaration) {
|
|
||||||
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_INVALID_TYPE, data.name());
|
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_INVALID_TYPE, data.name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -843,20 +821,16 @@ public class CPPSemantics {
|
||||||
inherited = null;
|
inherited = null;
|
||||||
|
|
||||||
final ICPPClassType cls = (ICPPClassType) b;
|
final ICPPClassType cls = (ICPPClassType) b;
|
||||||
final ICPPScope parent = (ICPPScope) cls.getCompositeScope();
|
if (cls instanceof ICPPUnknownBinding) {
|
||||||
|
if (data.unknownBinding == null) {
|
||||||
if (parent == null)
|
data.unknownBinding= cls;
|
||||||
continue;
|
|
||||||
if (parent instanceof CPPUnknownScope) {
|
|
||||||
if (data.unknownBinding == null && classType instanceof ICPPClassTemplate && data.astName != null) {
|
|
||||||
ICPPClassTemplate template= ((ICPPClassTemplate) classType);
|
|
||||||
IBinding thisType= CPPTemplates.instantiateWithinClassTemplate(template);
|
|
||||||
if (thisType instanceof ICPPUnknownBinding) {
|
|
||||||
data.unknownBinding= ((ICPPUnknownBinding) thisType).getUnknownScope().getBinding(data.astName, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final ICPPScope parent = (ICPPScope) cls.getCompositeScope();
|
||||||
|
if (parent == null || parent instanceof CPPUnknownScope)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!base.isVirtual() || !data.visited.containsKey(parent)) {
|
if (!base.isVirtual() || !data.visited.containsKey(parent)) {
|
||||||
if (base.isVirtual()) {
|
if (base.isVirtual()) {
|
||||||
|
@ -1970,9 +1944,7 @@ public class CPPSemantics {
|
||||||
System.arraycopy(ptypes, 0, result, 1, ptypes.length);
|
System.arraycopy(ptypes, 0, result, 1, ptypes.length);
|
||||||
ICPPClassType owner= ((ICPPMethod) fn).getClassOwner();
|
ICPPClassType owner= ((ICPPMethod) fn).getClassOwner();
|
||||||
if (owner instanceof ICPPClassTemplate) {
|
if (owner instanceof ICPPClassTemplate) {
|
||||||
IBinding within= CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) owner);
|
owner= CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) owner);
|
||||||
if (within instanceof ICPPClassType)
|
|
||||||
owner = (ICPPClassType)within;
|
|
||||||
}
|
}
|
||||||
IType implicitType= owner;
|
IType implicitType= owner;
|
||||||
if (ftype.isConst() || ftype.isVolatile()) {
|
if (ftype.isConst() || ftype.isVolatile()) {
|
||||||
|
|
|
@ -17,6 +17,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.dom.IName;
|
||||||
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;
|
||||||
|
@ -57,6 +58,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
|
||||||
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;
|
||||||
|
@ -86,9 +88,11 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
import org.eclipse.cdt.core.parser.util.ObjectMap;
|
import org.eclipse.cdt.core.parser.util.ObjectMap;
|
||||||
import org.eclipse.cdt.core.parser.util.ObjectSet;
|
import org.eclipse.cdt.core.parser.util.ObjectSet;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
|
||||||
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.ProblemBinding;
|
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.Value;
|
import org.eclipse.cdt.internal.core.dom.parser.Value;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassInstance;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassInstance;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassSpecialization;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassSpecialization;
|
||||||
|
@ -130,7 +134,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalClassTemplate;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownClassInstance;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownClassInstance;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownClassType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownClassType;
|
||||||
import org.eclipse.core.runtime.Assert;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collection of static methods to perform template instantiation, member specialization and
|
* Collection of static methods to perform template instantiation, member specialization and
|
||||||
|
@ -139,33 +142,122 @@ import org.eclipse.core.runtime.Assert;
|
||||||
public class CPPTemplates {
|
public class CPPTemplates {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a template with the given arguments. May return <code>null</code>.
|
* Instantiates a class template with the given arguments. May return <code>null</code>.
|
||||||
*/
|
*/
|
||||||
public static IBinding instantiate(ICPPTemplateDefinition template, ICPPTemplateArgument[] arguments) {
|
public static IBinding instantiate(ICPPClassTemplate template, ICPPTemplateArgument[] arguments) {
|
||||||
try {
|
try {
|
||||||
arguments= SemanticUtil.getSimplifiedArguments(arguments);
|
arguments= SemanticUtil.getSimplifiedArguments(arguments);
|
||||||
if (template instanceof ICPPTemplateTemplateParameter || hasDependentArgument(arguments)) {
|
if (template instanceof ICPPTemplateTemplateParameter || hasDependentArgument(arguments)) {
|
||||||
return deferredInstance(template, arguments);
|
return deferredInstance(template, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (template instanceof ICPPClassTemplate) {
|
if (template instanceof ICPPClassTemplatePartialSpecialization) {
|
||||||
template= CPPTemplates.selectSpecialization((ICPPClassTemplate) template, arguments);
|
return instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) template, arguments);
|
||||||
if (template == null || template instanceof IProblemBinding)
|
|
||||||
return template;
|
|
||||||
|
|
||||||
if (template instanceof ICPPClassTemplatePartialSpecialization) {
|
|
||||||
final ICPPClassTemplatePartialSpecialization partialSpec = (ICPPClassTemplatePartialSpecialization) template;
|
|
||||||
return instantiatePartialSpecialization(partialSpec, arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
return instantiateSelectedTemplate(template, arguments);
|
|
||||||
}
|
}
|
||||||
return instantiateSelectedTemplate(template, arguments);
|
|
||||||
|
// check whether we need to use default arguments
|
||||||
|
final ICPPTemplateParameter[] parameters= template.getTemplateParameters();
|
||||||
|
final int numArgs = arguments.length;
|
||||||
|
final int numParams= parameters.length;
|
||||||
|
if (numParams == 0 || numParams < numArgs)
|
||||||
|
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_USING);
|
||||||
|
|
||||||
|
ICPPTemplateArgument[] completeArgs= new ICPPTemplateArgument[numParams];
|
||||||
|
CPPTemplateParameterMap map= new CPPTemplateParameterMap(numParams);
|
||||||
|
|
||||||
|
boolean hasDependentDefaultArg= false;
|
||||||
|
for (int i = 0; i < numParams; i++) {
|
||||||
|
ICPPTemplateArgument arg;
|
||||||
|
ICPPTemplateParameter param= parameters[i];
|
||||||
|
if (i < numArgs) {
|
||||||
|
arg= arguments[i];
|
||||||
|
} else {
|
||||||
|
ICPPTemplateArgument defaultArg= param.getDefaultValue();
|
||||||
|
if (defaultArg == null) {
|
||||||
|
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_USING);
|
||||||
|
}
|
||||||
|
arg= instantiateArgument(defaultArg, map, null);
|
||||||
|
arg= SemanticUtil.getSimplifiedArgument(arg);
|
||||||
|
hasDependentDefaultArg |= isDependentArgument(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasDependentDefaultArg) {
|
||||||
|
arg= CPPTemplates.matchTemplateParameterAndArgument(param, arg, map);
|
||||||
|
if (arg == null)
|
||||||
|
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_USING);
|
||||||
|
}
|
||||||
|
|
||||||
|
map.put(param, arg);
|
||||||
|
completeArgs[i]= arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasDependentDefaultArg)
|
||||||
|
return deferredInstance(template, completeArgs);
|
||||||
|
|
||||||
|
|
||||||
|
ICPPTemplateDefinition tdef = CPPTemplates.selectSpecialization(template, completeArgs);
|
||||||
|
if (tdef == null || tdef instanceof IProblemBinding)
|
||||||
|
return tdef;
|
||||||
|
|
||||||
|
if (tdef instanceof ICPPClassTemplatePartialSpecialization) {
|
||||||
|
return instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) tdef, completeArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return instantiatePrimaryTemplate(template, completeArgs, map);
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
return e.getProblem();
|
return e.getProblem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IBinding createProblem(ICPPClassTemplate template, int id) {
|
||||||
|
IASTNode node= null;
|
||||||
|
if (template instanceof ICPPInternalBinding) {
|
||||||
|
ICPPInternalBinding internal= (ICPPInternalBinding) template;
|
||||||
|
node= internal.getDefinition();
|
||||||
|
if (node == null) {
|
||||||
|
IASTNode[] decls= internal.getDeclarations();
|
||||||
|
if (decls != null && decls.length > 0)
|
||||||
|
node= decls[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node == null) {
|
||||||
|
node= new CPPASTName(template.getNameCharArray());
|
||||||
|
}
|
||||||
|
return new ProblemBinding(node, id, template.getNameCharArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
static IBinding isUsedInClassTemplateScope(ICPPClassTemplate ct, IASTName name) {
|
||||||
|
try {
|
||||||
|
IScope scope= CPPVisitor.getContainingScope(name);
|
||||||
|
while (scope instanceof IASTInternalScope) {
|
||||||
|
final IASTInternalScope internalScope = (IASTInternalScope) scope;
|
||||||
|
if (scope instanceof ICPPClassScope) {
|
||||||
|
final IName scopeName = internalScope.getScopeName();
|
||||||
|
if (scopeName instanceof IASTName) {
|
||||||
|
IBinding b= ((IASTName) scopeName).resolveBinding();
|
||||||
|
if (b instanceof IType && ct.isSameType((IType) b)) {
|
||||||
|
return CPPTemplates.instantiateWithinClassTemplate(ct);
|
||||||
|
}
|
||||||
|
if (b instanceof ICPPClassTemplatePartialSpecialization) {
|
||||||
|
ICPPClassTemplatePartialSpecialization pspec= (ICPPClassTemplatePartialSpecialization) b;
|
||||||
|
if (ct.isSameType(pspec.getPrimaryClassTemplate())) {
|
||||||
|
return CPPTemplates.instantiateWithinClassTemplate(pspec);
|
||||||
|
}
|
||||||
|
} else if (b instanceof ICPPClassSpecialization) {
|
||||||
|
ICPPClassSpecialization specialization= (ICPPClassSpecialization) b;
|
||||||
|
if (ct.isSameType(specialization.getSpecializedBinding())) {
|
||||||
|
return specialization;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scope= CPPVisitor.getContainingScope(internalScope.getPhysicalNode());
|
||||||
|
}
|
||||||
|
} catch (DOMException e) {
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a partial class template specialization.
|
* Instantiates a partial class template specialization.
|
||||||
*/
|
*/
|
||||||
|
@ -193,11 +285,25 @@ public class CPPTemplates {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates the selected template, without looking for specializations. May return <code>null</code>.
|
* Instantiates the selected template, without looking for specializations. May return <code>null</code>.
|
||||||
|
* @param map
|
||||||
*/
|
*/
|
||||||
private static IBinding instantiateSelectedTemplate(ICPPTemplateDefinition template, ICPPTemplateArgument[] arguments)
|
private static IBinding instantiatePrimaryTemplate(ICPPClassTemplate template, ICPPTemplateArgument[] arguments,
|
||||||
throws DOMException {
|
CPPTemplateParameterMap map) throws DOMException {
|
||||||
Assert.isTrue(!(template instanceof ICPPClassTemplatePartialSpecialization));
|
|
||||||
|
assert !(template instanceof ICPPClassTemplatePartialSpecialization);
|
||||||
|
ICPPTemplateInstance instance= getInstance(template, arguments);
|
||||||
|
if (instance != null) {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
IBinding owner= template.getOwner();
|
||||||
|
instance = CPPTemplates.createInstance(owner, template, map, arguments);
|
||||||
|
addInstance(template, arguments, instance);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IBinding instantiateFunctionTemplate(ICPPFunctionTemplate template, ICPPTemplateArgument[] arguments)
|
||||||
|
throws DOMException {
|
||||||
ICPPTemplateParameter[] parameters= template.getTemplateParameters();
|
ICPPTemplateParameter[] parameters= template.getTemplateParameters();
|
||||||
if (parameters == null || parameters.length == 0)
|
if (parameters == null || parameters.length == 0)
|
||||||
return null;
|
return null;
|
||||||
|
@ -228,7 +334,7 @@ public class CPPTemplates {
|
||||||
arg= CPPTemplates.matchTemplateParameterAndArgument(param, arg, map);
|
arg= CPPTemplates.matchTemplateParameterAndArgument(param, arg, map);
|
||||||
if (arg == null)
|
if (arg == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (!argIsParameter(arg, param)) {
|
if (!argIsParameter(arg, param)) {
|
||||||
map.put(param, arg);
|
map.put(param, arg);
|
||||||
}
|
}
|
||||||
|
@ -304,7 +410,7 @@ public class CPPTemplates {
|
||||||
/**
|
/**
|
||||||
* Instantiates the template for usage within its own body. May return <code>null</code>.
|
* Instantiates the template for usage within its own body. May return <code>null</code>.
|
||||||
*/
|
*/
|
||||||
public static IBinding instantiateWithinClassTemplate(ICPPClassTemplate template) throws DOMException {
|
public static ICPPClassType instantiateWithinClassTemplate(ICPPClassTemplate template) throws DOMException {
|
||||||
ICPPTemplateArgument[] args;
|
ICPPTemplateArgument[] args;
|
||||||
if (template instanceof ICPPClassTemplatePartialSpecialization) {
|
if (template instanceof ICPPClassTemplatePartialSpecialization) {
|
||||||
args= ((ICPPClassTemplatePartialSpecialization) template).getTemplateArguments();
|
args= ((ICPPClassTemplatePartialSpecialization) template).getTemplateArguments();
|
||||||
|
@ -323,7 +429,11 @@ public class CPPTemplates {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return deferredInstance(template, args);
|
IBinding result = deferredInstance(template, args);
|
||||||
|
if (result instanceof ICPPClassType)
|
||||||
|
return (ICPPClassType) result;
|
||||||
|
|
||||||
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1311,7 +1421,7 @@ public class CPPTemplates {
|
||||||
try {
|
try {
|
||||||
ICPPTemplateArgument[] args= deduceTemplateFunctionArguments(template, templateArguments, fnArgs, map);
|
ICPPTemplateArgument[] args= deduceTemplateFunctionArguments(template, templateArguments, fnArgs, map);
|
||||||
if (args != null) {
|
if (args != null) {
|
||||||
IBinding temp= instantiate(template, args);
|
IBinding temp= instantiateFunctionTemplate(template, args);
|
||||||
if (temp instanceof IFunction) {
|
if (temp instanceof IFunction) {
|
||||||
instances = (IFunction[]) ArrayUtil.append(IFunction.class, instances, temp);
|
instances = (IFunction[]) ArrayUtil.append(IFunction.class, instances, temp);
|
||||||
}
|
}
|
||||||
|
@ -1587,13 +1697,13 @@ public class CPPTemplates {
|
||||||
CPPTemplateParameterMap m2= new CPPTemplateParameterMap(2);
|
CPPTemplateParameterMap m2= new CPPTemplateParameterMap(2);
|
||||||
|
|
||||||
ICPPTemplateArgument[] args = createArgsForFunctionTemplateOrdering(f1);
|
ICPPTemplateArgument[] args = createArgsForFunctionTemplateOrdering(f1);
|
||||||
IBinding function = instantiate(f1, args);
|
IBinding function = instantiateFunctionTemplate(f1, args);
|
||||||
if (function instanceof ICPPFunction)
|
if (function instanceof ICPPFunction)
|
||||||
if (!deduceTemplateParameterMapFromFunctionParameters(f2, ((ICPPFunction) function).getType().getParameterTypes(), m1))
|
if (!deduceTemplateParameterMapFromFunctionParameters(f2, ((ICPPFunction) function).getType().getParameterTypes(), m1))
|
||||||
m1= null;
|
m1= null;
|
||||||
|
|
||||||
args = createArgsForFunctionTemplateOrdering(f2);
|
args = createArgsForFunctionTemplateOrdering(f2);
|
||||||
function = instantiate(f2, args);
|
function = instantiateFunctionTemplate(f2, args);
|
||||||
if (function instanceof ICPPFunction)
|
if (function instanceof ICPPFunction)
|
||||||
if (!deduceTemplateParameterMapFromFunctionParameters(f1, ((ICPPFunction) function).getType().getParameterTypes(), m2))
|
if (!deduceTemplateParameterMapFromFunctionParameters(f1, ((ICPPFunction) function).getType().getParameterTypes(), m2))
|
||||||
m2= null;
|
m2= null;
|
||||||
|
@ -1754,7 +1864,8 @@ public class CPPTemplates {
|
||||||
static private ICPPFunctionTemplate classTemplateSpecializationToFunctionTemplate(ICPPClassTemplatePartialSpecialization specialization) {
|
static private ICPPFunctionTemplate classTemplateSpecializationToFunctionTemplate(ICPPClassTemplatePartialSpecialization specialization) {
|
||||||
try {
|
try {
|
||||||
// ICPPTemplateArgument[] args= specialization.getTemplateArguments();
|
// ICPPTemplateArgument[] args= specialization.getTemplateArguments();
|
||||||
IBinding paramType = instantiateWithinClassTemplate(specialization);
|
ICPPTemplateArgument[] args= (specialization).getTemplateArguments();
|
||||||
|
IBinding paramType = deferredInstance(specialization, args);
|
||||||
if (!(paramType instanceof IType))
|
if (!(paramType instanceof IType))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
@ -1881,10 +1992,14 @@ public class CPPTemplates {
|
||||||
ICPPTemplateParameter par= pars[i];
|
ICPPTemplateParameter par= pars[i];
|
||||||
ICPPTemplateArgument arg = args[i];
|
ICPPTemplateArgument arg = args[i];
|
||||||
if (par instanceof IType) {
|
if (par instanceof IType) {
|
||||||
|
if (arg.isNonTypeValue())
|
||||||
|
return false;
|
||||||
IType argType= arg.getTypeValue();
|
IType argType= arg.getTypeValue();
|
||||||
if (argType == null || !argType.isSameType((IType) par))
|
if (argType == null || !argType.isSameType((IType) par))
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
if (arg.isTypeValue())
|
||||||
|
return false;
|
||||||
int parpos= Value.isTemplateParameter(arg.getNonTypeValue());
|
int parpos= Value.isTemplateParameter(arg.getNonTypeValue());
|
||||||
if (parpos != par.getParameterID())
|
if (parpos != par.getParameterID())
|
||||||
return false;
|
return false;
|
||||||
|
@ -1998,7 +2113,11 @@ public class CPPTemplates {
|
||||||
}
|
}
|
||||||
if (unknown instanceof ICPPUnknownClassInstance && result instanceof ICPPTemplateDefinition) {
|
if (unknown instanceof ICPPUnknownClassInstance && result instanceof ICPPTemplateDefinition) {
|
||||||
ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments(((ICPPUnknownClassInstance) unknown).getArguments(), tpMap, within);
|
ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments(((ICPPUnknownClassInstance) unknown).getArguments(), tpMap, within);
|
||||||
result = instantiate((ICPPTemplateDefinition) result, newArgs);
|
if (result instanceof ICPPClassTemplate)
|
||||||
|
result = instantiate((ICPPClassTemplate) result, newArgs);
|
||||||
|
else if (result instanceof ICPPFunctionTemplate) {
|
||||||
|
result= instantiateFunctionTemplate((ICPPFunctionTemplate) result, newArgs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1802,9 +1802,7 @@ public class CPPVisitor extends ASTQueries {
|
||||||
ICPPClassScope cScope = (ICPPClassScope) s;
|
ICPPClassScope cScope = (ICPPClassScope) s;
|
||||||
IType type = cScope.getClassType();
|
IType type = cScope.getClassType();
|
||||||
if (type instanceof ICPPClassTemplate) {
|
if (type instanceof ICPPClassTemplate) {
|
||||||
IBinding within = CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) type);
|
type= CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) type);
|
||||||
if (within instanceof ICPPClassType)
|
|
||||||
type = (ICPPClassType)within;
|
|
||||||
}
|
}
|
||||||
if (dtor.isConst() || dtor.isVolatile())
|
if (dtor.isConst() || dtor.isVolatile())
|
||||||
type = new CPPQualifierType(type, dtor.isConst(), dtor.isVolatile());
|
type = new CPPQualifierType(type, dtor.isConst(), dtor.isVolatile());
|
||||||
|
|
|
@ -304,13 +304,7 @@ public class SemanticUtil {
|
||||||
final ICPPTemplateArgument arg= args[i];
|
final ICPPTemplateArgument arg= args[i];
|
||||||
ICPPTemplateArgument newArg= arg;
|
ICPPTemplateArgument newArg= arg;
|
||||||
if (arg != null) {
|
if (arg != null) {
|
||||||
if (arg.isTypeValue()) {
|
newArg = getSimplifiedArgument(arg);
|
||||||
final IType type= arg.getTypeValue();
|
|
||||||
final IType newType= getSimplifiedType(type);
|
|
||||||
if (newType != type) {
|
|
||||||
newArg= new CPPTemplateArgument(newType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (result != args) {
|
if (result != args) {
|
||||||
result[i]= newArg;
|
result[i]= newArg;
|
||||||
} else if (arg != newArg) {
|
} else if (arg != newArg) {
|
||||||
|
@ -325,6 +319,17 @@ public class SemanticUtil {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ICPPTemplateArgument getSimplifiedArgument(final ICPPTemplateArgument arg) {
|
||||||
|
if (arg.isTypeValue()) {
|
||||||
|
final IType type= arg.getTypeValue();
|
||||||
|
final IType newType= getSimplifiedType(type);
|
||||||
|
if (newType != type) {
|
||||||
|
return new CPPTemplateArgument(newType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adjusts the parameter type according to 8.3.5-3:
|
* Adjusts the parameter type according to 8.3.5-3:
|
||||||
* cv-qualifiers are deleted, arrays and function types are converted to pointers.
|
* cv-qualifiers are deleted, arrays and function types are converted to pointers.
|
||||||
|
|
Loading…
Add table
Reference in a new issue