diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java index b1624fb67ca..74e1c6332c1 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java @@ -464,6 +464,36 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa checkBindings(); } + // template + // struct A { + // typedef T t; + // }; + + // template + // struct B {}; + // + // typedef B C; + // + // template + // struct D { + // typedef A t2; + // }; + // + // template + // void waldo(const U& a, typename U::t2::t& b); + // template + // void waldo(U& a, typename U::t2::t& b); + // + // void test() { + // typedef A E; + // D x; + // E y; + // waldo(x, y); + // } + public void testOverloadedFunctionTemplate_429624() throws Exception { + checkBindings(); + } + // template class S> // class Foo { // public: @@ -975,13 +1005,11 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa // void func(U& u, const typename U::t& v) { // } - // template class A { + // template struct A { // typedef T t; // }; // - // void test() { - // const A& a; - // int b; + // void test(const A& a, int b) { // func(a, b); // } public void testFunctionTemplate_319498() throws Exception { 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 13f1e1da7a3..bf972718ef0 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 @@ -356,7 +356,9 @@ public class CPPTemplates { IBinding owner= template.getOwner(); instance = createInstance(owner, template, map, arguments, point); - addInstance(template, arguments, instance); + if (instance instanceof ICPPFunction && SemanticUtil.isValidType(((ICPPFunction) instance).getType())) { + addInstance(template, arguments, instance); + } return instance; } @@ -1992,7 +1994,7 @@ public class CPPTemplates { IBinding instance= instantiateFunctionTemplate(template, args, map, point); if (instance instanceof ICPPFunction) { final ICPPFunction f = (ICPPFunction) instance; - if (isValidType(f.getType())) + if (SemanticUtil.isValidType(f.getType())) return f; } } @@ -2358,37 +2360,13 @@ public class CPPTemplates { return TemplateArgumentDeduction.fromTemplateArguments(tpars2, targs2, transferredArgs1, deductionMap, point); } - static boolean isValidType(IType t) { - while (true) { - if (t instanceof ISemanticProblem) { - return false; - } else if (t instanceof IFunctionType) { - IFunctionType ft= (IFunctionType) t; - for (IType parameterType : ft.getParameterTypes()) { - if (!isValidType(parameterType)) - return false; - } - t= ft.getReturnType(); - } else if (t instanceof ICPPPointerToMemberType) { - ICPPPointerToMemberType mptr= (ICPPPointerToMemberType) t; - if (!isValidType(mptr.getMemberOfClass())) - return false; - t= mptr.getType(); - } else if (t instanceof ITypeContainer) { - t= ((ITypeContainer) t).getType(); - } else { - return true; - } - } - } - static boolean isValidArgument(ICPPTemplateArgument arg) { - return arg != null && isValidType(arg.isTypeValue() ? arg.getTypeValue() : arg.getTypeOfNonTypeValue()); + return arg != null && SemanticUtil.isValidType(arg.isTypeValue() ? arg.getTypeValue() : arg.getTypeOfNonTypeValue()); } static ICPPTemplateArgument matchTemplateParameterAndArgument(ICPPTemplateDefinition template, ICPPTemplateParameter param, ICPPTemplateArgument arg, CPPTemplateParameterMap map, IASTNode point) { - if (arg == null || !isValidType(arg.getTypeValue())) { + if (arg == null || !SemanticUtil.isValidType(arg.getTypeValue())) { return null; } if (param instanceof ICPPTemplateTypeParameter) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java index fe1a1c4b590..266f86edf73 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java @@ -40,6 +40,7 @@ import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IQualifierType; +import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.IValue; @@ -450,6 +451,33 @@ public class SemanticUtil { } } + /** + * Checks if the given type is problem-free. + */ + public static boolean isValidType(IType t) { + while (true) { + if (t instanceof ISemanticProblem) { + return false; + } else if (t instanceof IFunctionType) { + IFunctionType ft= (IFunctionType) t; + for (IType parameterType : ft.getParameterTypes()) { + if (!isValidType(parameterType)) + return false; + } + t= ft.getReturnType(); + } else if (t instanceof ICPPPointerToMemberType) { + ICPPPointerToMemberType mptr= (ICPPPointerToMemberType) t; + if (!isValidType(mptr.getMemberOfClass())) + return false; + t= mptr.getType(); + } else if (t instanceof ITypeContainer) { + t= ((ITypeContainer) t).getType(); + } else { + return true; + } + } + } + public static IType mapToAST(IType type, IASTNode node) { if (node == null) return type; 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 6e1104260a8..5c8691dfd26 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 @@ -134,7 +134,7 @@ public class TemplateArgumentDeduction { } par= CPPTemplates.instantiateType(par, map, -1, null, point); - if (!CPPTemplates.isValidType(par)) + if (!SemanticUtil.isValidType(par)) return false; if (CPPTemplates.isDependentType(par)) { @@ -326,7 +326,7 @@ public class TemplateArgumentDeduction { IType par= template.getType(); par= CPPTemplates.instantiateType(par, map, -1, null, point); - if (!CPPTemplates.isValidType(par)) + if (!SemanticUtil.isValidType(par)) return null; boolean isDependentPar= CPPTemplates.isDependentType(par); @@ -398,7 +398,7 @@ public class TemplateArgumentDeduction { IType a= SemanticUtil.getSimplifiedType(ftype); IType p= CPPTemplates.instantiateType(template.getType(), map, -1, null, point); - if (!CPPTemplates.isValidType(p)) + if (!SemanticUtil.isValidType(p)) return null; TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(tmplParams, map, new CPPTemplateParameterMap(tmplParams.length), 0); @@ -1038,7 +1038,7 @@ public class TemplateArgumentDeduction { p= parameterPack; deduct.incPackOffset(); p= CPPTemplates.instantiateType(p, fExplicitArgs, deduct.fPackOffset, null, point); - if (!CPPTemplates.isValidType(p)) + if (!SemanticUtil.isValidType(p)) return false; } else { p= pParams[i]; @@ -1046,7 +1046,7 @@ public class TemplateArgumentDeduction { p= parameterPack= ((ICPPParameterPackType) p).getType(); deduct= new TemplateArgumentDeduction(this, aParams.length - i); p= CPPTemplates.instantiateType(p, fExplicitArgs, deduct.fPackOffset, null, point); - if (!CPPTemplates.isValidType(p)) + if (!SemanticUtil.isValidType(p)) return false; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/TypeMarshalBuffer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/TypeMarshalBuffer.java index 7db1e97c803..8846cc615be 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/TypeMarshalBuffer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/TypeMarshalBuffer.java @@ -26,6 +26,7 @@ import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.core.runtime.CoreException; @@ -202,7 +203,7 @@ public final class TypeMarshalBuffer implements ITypeMarshalBuffer { fPos = oldPos; IType type = unmarshalType(); IType originalType = unmarshalType(); - if (originalType == null || originalType == UNSTORABLE_TYPE_PROBLEM) + if (originalType == null || !SemanticUtil.isValidType(originalType)) originalType= type; return new CPPTemplateTypeArgument(type, originalType); }