diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index 69d883daa88..2886f6a8ce3 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -6903,6 +6903,37 @@ public void testSfinae_c() throws Exception { assertTrue(varIp.getType().isSameType(varJp.getType())); } + // template + // struct C { + // }; + // + // template + // struct C { + // int ccc1; + // using t = int; + // }; + // + // template + // struct C { + // int ccc2; + // }; + // + // struct marker { + // using t1 = int; + // using t2 = long; + // }; + // + // int b1 = C().ccc1; + // C::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 // struct is_pod { // static const bool value = __is_pod(T); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 3f08893f8ba..70ee9da0122 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -1614,19 +1614,23 @@ public static IType instantiateType(final IType type, InstantiationContext conte } } } else if (type instanceof TypeOfUnknownMember) { - IBinding binding = resolveUnknown(((TypeOfUnknownMember) type).getUnknownMember(), context); - if (binding instanceof IType) { - return (IType) binding; - } else if (binding instanceof IVariable) { - return ((IVariable) binding).getType(); - } else if (binding instanceof IFunction) { - return ((IFunction) binding).getType(); + BindingOrType bindingType = resolveUnknownBindingOrType( + ((TypeOfUnknownMember) type).getUnknownMember(), context); + if (bindingType.getType() != null) { + return bindingType.getType(); + } else { + IBinding binding = bindingType.getBinding(); + if (binding instanceof IVariable) { + return ((IVariable) binding).getType(); + } else if (binding instanceof IFunction) { + return ((IFunction) binding).getType(); + } } return type; } else { - IBinding binding = resolveUnknown((ICPPUnknownBinding) type, context); - if (binding instanceof IType) - return (IType) binding; + BindingOrType bindingType = resolveUnknownBindingOrType((ICPPUnknownBinding) type, context); + if (bindingType.getType() != null) + return bindingType.getType(); return type; } @@ -3116,29 +3120,63 @@ public static boolean containsDependentArg(ObjectMap tpMap) { /** * 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) 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) { - return resolveDeferredClassInstance((ICPPDeferredClassInstance) unknown, context); + return new BindingOrType(resolveDeferredClassInstance((ICPPDeferredClassInstance) unknown, context)); } if (unknown instanceof ICPPDeferredVariableInstance) { - return resolveDeferredVariableInstance((ICPPDeferredVariableInstance) unknown, context); + return new BindingOrType(resolveDeferredVariableInstance((ICPPDeferredVariableInstance) unknown, context)); } if (unknown instanceof ICPPUnknownMember) { - return resolveUnknownMember((ICPPUnknownMember) unknown, context); + return new BindingOrType(resolveUnknownMember((ICPPUnknownMember) unknown, context)); } if (unknown instanceof ICPPTemplateParameter && unknown instanceof IType) { IType type = resolveTemplateTypeParameter((ICPPTemplateParameter) unknown, context); - if (type instanceof IBinding) - return (IBinding) type; + return new BindingOrType(type); } if (unknown instanceof TypeOfDependentExpression) { IType type = instantiateType((IType) unknown, context); - if (type instanceof IBinding) - return (IBinding) type; + return new BindingOrType(type); } - return unknown; + return new BindingOrType(unknown); } private static IBinding resolveUnknownMember(ICPPUnknownMember unknown, InstantiationContext context) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java index e290be9b3ed..c5aea790721 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java @@ -1044,11 +1044,13 @@ private boolean fromType(IType p, IType a, boolean allowCVQConversion, boolean v // Verify that the resolved binding matches the argument type. InstantiationContext context = InstantiationContext.forDeduction(fDeducedArgs); - IBinding binding = CPPTemplates.resolveUnknown((ICPPUnknownBinding) p, context); - if (binding instanceof ICPPUnknownBinding) + CPPTemplates.BindingOrType bindingType = CPPTemplates + .resolveUnknownBindingOrType((ICPPUnknownBinding) p, context); + if (bindingType.getBinding() instanceof ICPPUnknownBinding) return true; // An unknown type may match anything. - - return binding instanceof IType && ((IType) binding).isSameType(a); + if (bindingType.getType() != null) { + return bindingType.getType().isSameType(a); + } } else { return p.isSameType(a); }