mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-08 08:45:44 +02:00
Current partial specialisation selection matches deduced type by IBinding, not by IType, meaning that it can't work for types (such as primitive types) that aren't represented by an IBinding. Fix that by wrapping the result of resolution in a type which can handle either.
This commit is contained in:
parent
f6481742dd
commit
232b24cd80
3 changed files with 93 additions and 22 deletions
|
@ -6903,6 +6903,37 @@ public class AST2TemplateTests extends AST2CPPTestBase {
|
||||||
assertTrue(varIp.getType().isSameType(varJp.getType()));
|
assertTrue(varIp.getType().isSameType(varJp.getType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template <typename A, typename B = typename A::t1>
|
||||||
|
// struct C {
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// template <typename A>
|
||||||
|
// struct C<A, decltype(typename A::t1())> {
|
||||||
|
// int ccc1;
|
||||||
|
// using t = int;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// template <typename A>
|
||||||
|
// struct C<A, decltype(typename A::t2())> {
|
||||||
|
// int ccc2;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// struct marker {
|
||||||
|
// using t1 = int;
|
||||||
|
// using t2 = long;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// int b1 = C<marker>().ccc1;
|
||||||
|
// C<marker>::t b2;
|
||||||
|
public void testSfinae_d() throws Exception {
|
||||||
|
BindingAssertionHelper bh = getAssertionHelper();
|
||||||
|
|
||||||
|
IVariable varB1 = bh.assertNonProblem("b1");
|
||||||
|
IVariable varB2 = bh.assertNonProblem("b2");
|
||||||
|
assertFalse(varB1.getInitialValue() instanceof IProblemBinding);
|
||||||
|
assertTrue(varB1.getType().isSameType(varB2.getType()));
|
||||||
|
}
|
||||||
|
|
||||||
// template<typename T>
|
// template<typename T>
|
||||||
// struct is_pod {
|
// struct is_pod {
|
||||||
// static const bool value = __is_pod(T);
|
// static const bool value = __is_pod(T);
|
||||||
|
|
|
@ -1614,19 +1614,23 @@ public class CPPTemplates {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (type instanceof TypeOfUnknownMember) {
|
} else if (type instanceof TypeOfUnknownMember) {
|
||||||
IBinding binding = resolveUnknown(((TypeOfUnknownMember) type).getUnknownMember(), context);
|
BindingOrType bindingType = resolveUnknownBindingOrType(
|
||||||
if (binding instanceof IType) {
|
((TypeOfUnknownMember) type).getUnknownMember(), context);
|
||||||
return (IType) binding;
|
if (bindingType.getType() != null) {
|
||||||
} else if (binding instanceof IVariable) {
|
return bindingType.getType();
|
||||||
|
} else {
|
||||||
|
IBinding binding = bindingType.getBinding();
|
||||||
|
if (binding instanceof IVariable) {
|
||||||
return ((IVariable) binding).getType();
|
return ((IVariable) binding).getType();
|
||||||
} else if (binding instanceof IFunction) {
|
} else if (binding instanceof IFunction) {
|
||||||
return ((IFunction) binding).getType();
|
return ((IFunction) binding).getType();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return type;
|
return type;
|
||||||
} else {
|
} else {
|
||||||
IBinding binding = resolveUnknown((ICPPUnknownBinding) type, context);
|
BindingOrType bindingType = resolveUnknownBindingOrType((ICPPUnknownBinding) type, context);
|
||||||
if (binding instanceof IType)
|
if (bindingType.getType() != null)
|
||||||
return (IType) binding;
|
return bindingType.getType();
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
@ -3116,29 +3120,63 @@ public class CPPTemplates {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to (partially) resolve an unknown binding with the given arguments.
|
* Attempts to (partially) resolve an unknown binding with the given arguments.
|
||||||
|
* Cannot resolved types that are not representable as a binding.
|
||||||
*/
|
*/
|
||||||
public static IBinding resolveUnknown(ICPPUnknownBinding unknown, InstantiationContext context)
|
public static IBinding resolveUnknown(ICPPUnknownBinding unknown, InstantiationContext context)
|
||||||
throws DOMException {
|
throws DOMException {
|
||||||
|
BindingOrType bindingType = resolveUnknownBindingOrType(unknown, context);
|
||||||
|
if (bindingType.getBinding() != null)
|
||||||
|
return bindingType.getBinding();
|
||||||
|
return unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BindingOrType {
|
||||||
|
Object bindingOrType;
|
||||||
|
|
||||||
|
BindingOrType(IBinding binding) {
|
||||||
|
bindingOrType = binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
BindingOrType(IType type) {
|
||||||
|
bindingOrType = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
IType getType() {
|
||||||
|
if (bindingOrType instanceof IType)
|
||||||
|
return (IType) bindingOrType;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
IBinding getBinding() {
|
||||||
|
if (bindingOrType instanceof IBinding)
|
||||||
|
return (IBinding) bindingOrType;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to (partially) resolve an unknown binding with the given arguments.
|
||||||
|
*/
|
||||||
|
public static BindingOrType resolveUnknownBindingOrType(ICPPUnknownBinding unknown, InstantiationContext context)
|
||||||
|
throws DOMException {
|
||||||
if (unknown instanceof ICPPDeferredClassInstance) {
|
if (unknown instanceof ICPPDeferredClassInstance) {
|
||||||
return resolveDeferredClassInstance((ICPPDeferredClassInstance) unknown, context);
|
return new BindingOrType(resolveDeferredClassInstance((ICPPDeferredClassInstance) unknown, context));
|
||||||
}
|
}
|
||||||
if (unknown instanceof ICPPDeferredVariableInstance) {
|
if (unknown instanceof ICPPDeferredVariableInstance) {
|
||||||
return resolveDeferredVariableInstance((ICPPDeferredVariableInstance) unknown, context);
|
return new BindingOrType(resolveDeferredVariableInstance((ICPPDeferredVariableInstance) unknown, context));
|
||||||
}
|
}
|
||||||
if (unknown instanceof ICPPUnknownMember) {
|
if (unknown instanceof ICPPUnknownMember) {
|
||||||
return resolveUnknownMember((ICPPUnknownMember) unknown, context);
|
return new BindingOrType(resolveUnknownMember((ICPPUnknownMember) unknown, context));
|
||||||
}
|
}
|
||||||
if (unknown instanceof ICPPTemplateParameter && unknown instanceof IType) {
|
if (unknown instanceof ICPPTemplateParameter && unknown instanceof IType) {
|
||||||
IType type = resolveTemplateTypeParameter((ICPPTemplateParameter) unknown, context);
|
IType type = resolveTemplateTypeParameter((ICPPTemplateParameter) unknown, context);
|
||||||
if (type instanceof IBinding)
|
return new BindingOrType(type);
|
||||||
return (IBinding) type;
|
|
||||||
}
|
}
|
||||||
if (unknown instanceof TypeOfDependentExpression) {
|
if (unknown instanceof TypeOfDependentExpression) {
|
||||||
IType type = instantiateType((IType) unknown, context);
|
IType type = instantiateType((IType) unknown, context);
|
||||||
if (type instanceof IBinding)
|
return new BindingOrType(type);
|
||||||
return (IBinding) type;
|
|
||||||
}
|
}
|
||||||
return unknown;
|
return new BindingOrType(unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IBinding resolveUnknownMember(ICPPUnknownMember unknown, InstantiationContext context)
|
private static IBinding resolveUnknownMember(ICPPUnknownMember unknown, InstantiationContext context)
|
||||||
|
|
|
@ -1044,11 +1044,13 @@ public class TemplateArgumentDeduction {
|
||||||
|
|
||||||
// Verify that the resolved binding matches the argument type.
|
// Verify that the resolved binding matches the argument type.
|
||||||
InstantiationContext context = InstantiationContext.forDeduction(fDeducedArgs);
|
InstantiationContext context = InstantiationContext.forDeduction(fDeducedArgs);
|
||||||
IBinding binding = CPPTemplates.resolveUnknown((ICPPUnknownBinding) p, context);
|
CPPTemplates.BindingOrType bindingType = CPPTemplates
|
||||||
if (binding instanceof ICPPUnknownBinding)
|
.resolveUnknownBindingOrType((ICPPUnknownBinding) p, context);
|
||||||
|
if (bindingType.getBinding() instanceof ICPPUnknownBinding)
|
||||||
return true; // An unknown type may match anything.
|
return true; // An unknown type may match anything.
|
||||||
|
if (bindingType.getType() != null) {
|
||||||
return binding instanceof IType && ((IType) binding).isSameType(a);
|
return bindingType.getType().isSameType(a);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return p.isSameType(a);
|
return p.isSameType(a);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue