1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-06 09:16:02 +02:00

Bug 429624 - Template function resolution problem when using index.

This commit is contained in:
Sergey Prigogin 2014-03-05 20:04:12 -08:00
parent 551f5eb2df
commit aae4792550
5 changed files with 73 additions and 38 deletions

View file

@ -464,6 +464,36 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
checkBindings(); checkBindings();
} }
// template<class T>
// struct A {
// typedef T t;
// };
// template<typename T>
// struct B {};
//
// typedef B<int> C;
//
// template <typename T>
// struct D {
// typedef A<const T> t2;
// };
//
// template <typename U>
// void waldo(const U& a, typename U::t2::t& b);
// template <typename U>
// void waldo(U& a, typename U::t2::t& b);
//
// void test() {
// typedef A<C> E;
// D<E> x;
// E y;
// waldo(x, y);
// }
public void testOverloadedFunctionTemplate_429624() throws Exception {
checkBindings();
}
// template<typename T, template<typename U> class S> // template<typename T, template<typename U> class S>
// class Foo { // class Foo {
// public: // public:
@ -975,13 +1005,11 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
// void func(U& u, const typename U::t& v) { // void func(U& u, const typename U::t& v) {
// } // }
// template <typename T> class A { // template <typename T> struct A {
// typedef T t; // typedef T t;
// }; // };
// //
// void test() { // void test(const A<int>& a, int b) {
// const A<int>& a;
// int b;
// func(a, b); // func(a, b);
// } // }
public void testFunctionTemplate_319498() throws Exception { public void testFunctionTemplate_319498() throws Exception {

View file

@ -356,7 +356,9 @@ public class CPPTemplates {
IBinding owner= template.getOwner(); IBinding owner= template.getOwner();
instance = createInstance(owner, template, map, arguments, point); 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; return instance;
} }
@ -1992,7 +1994,7 @@ public class CPPTemplates {
IBinding instance= instantiateFunctionTemplate(template, args, map, point); IBinding instance= instantiateFunctionTemplate(template, args, map, point);
if (instance instanceof ICPPFunction) { if (instance instanceof ICPPFunction) {
final ICPPFunction f = (ICPPFunction) instance; final ICPPFunction f = (ICPPFunction) instance;
if (isValidType(f.getType())) if (SemanticUtil.isValidType(f.getType()))
return f; return f;
} }
} }
@ -2358,37 +2360,13 @@ public class CPPTemplates {
return TemplateArgumentDeduction.fromTemplateArguments(tpars2, targs2, transferredArgs1, deductionMap, point); 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) { 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, static ICPPTemplateArgument matchTemplateParameterAndArgument(ICPPTemplateDefinition template,
ICPPTemplateParameter param, ICPPTemplateArgument arg, CPPTemplateParameterMap map, IASTNode point) { ICPPTemplateParameter param, ICPPTemplateArgument arg, CPPTemplateParameterMap map, IASTNode point) {
if (arg == null || !isValidType(arg.getTypeValue())) { if (arg == null || !SemanticUtil.isValidType(arg.getTypeValue())) {
return null; return null;
} }
if (param instanceof ICPPTemplateTypeParameter) { if (param instanceof ICPPTemplateTypeParameter) {

View file

@ -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.IPointerType;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IQualifierType; 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.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IValue; 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) { public static IType mapToAST(IType type, IASTNode node) {
if (node == null) if (node == null)
return type; return type;

View file

@ -134,7 +134,7 @@ public class TemplateArgumentDeduction {
} }
par= CPPTemplates.instantiateType(par, map, -1, null, point); par= CPPTemplates.instantiateType(par, map, -1, null, point);
if (!CPPTemplates.isValidType(par)) if (!SemanticUtil.isValidType(par))
return false; return false;
if (CPPTemplates.isDependentType(par)) { if (CPPTemplates.isDependentType(par)) {
@ -326,7 +326,7 @@ public class TemplateArgumentDeduction {
IType par= template.getType(); IType par= template.getType();
par= CPPTemplates.instantiateType(par, map, -1, null, point); par= CPPTemplates.instantiateType(par, map, -1, null, point);
if (!CPPTemplates.isValidType(par)) if (!SemanticUtil.isValidType(par))
return null; return null;
boolean isDependentPar= CPPTemplates.isDependentType(par); boolean isDependentPar= CPPTemplates.isDependentType(par);
@ -398,7 +398,7 @@ public class TemplateArgumentDeduction {
IType a= SemanticUtil.getSimplifiedType(ftype); IType a= SemanticUtil.getSimplifiedType(ftype);
IType p= CPPTemplates.instantiateType(template.getType(), map, -1, null, point); IType p= CPPTemplates.instantiateType(template.getType(), map, -1, null, point);
if (!CPPTemplates.isValidType(p)) if (!SemanticUtil.isValidType(p))
return null; return null;
TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(tmplParams, map, new CPPTemplateParameterMap(tmplParams.length), 0); TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(tmplParams, map, new CPPTemplateParameterMap(tmplParams.length), 0);
@ -1038,7 +1038,7 @@ public class TemplateArgumentDeduction {
p= parameterPack; p= parameterPack;
deduct.incPackOffset(); deduct.incPackOffset();
p= CPPTemplates.instantiateType(p, fExplicitArgs, deduct.fPackOffset, null, point); p= CPPTemplates.instantiateType(p, fExplicitArgs, deduct.fPackOffset, null, point);
if (!CPPTemplates.isValidType(p)) if (!SemanticUtil.isValidType(p))
return false; return false;
} else { } else {
p= pParams[i]; p= pParams[i];
@ -1046,7 +1046,7 @@ public class TemplateArgumentDeduction {
p= parameterPack= ((ICPPParameterPackType) p).getType(); p= parameterPack= ((ICPPParameterPackType) p).getType();
deduct= new TemplateArgumentDeduction(this, aParams.length - i); deduct= new TemplateArgumentDeduction(this, aParams.length - i);
p= CPPTemplates.instantiateType(p, fExplicitArgs, deduct.fPackOffset, null, point); p= CPPTemplates.instantiateType(p, fExplicitArgs, deduct.fPackOffset, null, point);
if (!CPPTemplates.isValidType(p)) if (!SemanticUtil.isValidType(p))
return false; return false;
} }
} }

View file

@ -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.CPPTemplateNonTypeArgument;
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.ICPPEvaluation; 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.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
@ -202,7 +203,7 @@ public final class TypeMarshalBuffer implements ITypeMarshalBuffer {
fPos = oldPos; fPos = oldPos;
IType type = unmarshalType(); IType type = unmarshalType();
IType originalType = unmarshalType(); IType originalType = unmarshalType();
if (originalType == null || originalType == UNSTORABLE_TYPE_PROBLEM) if (originalType == null || !SemanticUtil.isValidType(originalType))
originalType= type; originalType= type;
return new CPPTemplateTypeArgument(type, originalType); return new CPPTemplateTypeArgument(type, originalType);
} }