1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 17:56:01 +02:00

Bug 326076: Address of unique template function instance.

This commit is contained in:
Markus Schorn 2010-09-28 12:21:15 +00:00
parent cc2fc91b90
commit d3275f0232
4 changed files with 66 additions and 18 deletions

View file

@ -100,6 +100,10 @@ public class AST2TemplateTests extends AST2BaseTest {
return suite(AST2TemplateTests.class); return suite(AST2TemplateTests.class);
} }
private IASTTranslationUnit parseAndCheckBindings() throws Exception {
return parseAndCheckBindings(getAboveComment());
}
private IASTTranslationUnit parseAndCheckBindings(final String code) throws Exception { private IASTTranslationUnit parseAndCheckBindings(final String code) throws Exception {
return parseAndCheckBindings(code, ParserLanguage.CPP); return parseAndCheckBindings(code, ParserLanguage.CPP);
} }
@ -4587,7 +4591,7 @@ public class AST2TemplateTests extends AST2BaseTest {
// int k = g<int>(5.6); // Y is deduced to be double, Z is deduced to an empty sequence // int k = g<int>(5.6); // Y is deduced to be double, Z is deduced to an empty sequence
// f<void>(g<int, bool>); // Y for outer f deduced to be // f<void>(g<int, bool>); // Y for outer f deduced to be
// } // int (*)(bool), Z is deduced to an empty sequence // } // int (*)(bool), Z is deduced to an empty sequence
public void _testVariadicTemplateExamples_280909h() throws Exception { public void testVariadicTemplateExamples_280909h() throws Exception {
final String code= getAboveComment(); final String code= getAboveComment();
BindingAssertionHelper bh= new BindingAssertionHelper(code, true); BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
bh.assertNonProblem("f<int>(5.6)", 6); bh.assertNonProblem("f<int>(5.6)", 6);
@ -5140,4 +5144,14 @@ public class AST2TemplateTests extends AST2BaseTest {
final IBinding reference = name.resolveBinding(); final IBinding reference = name.resolveBinding();
assertSame(method, ((ICPPSpecialization) reference).getSpecializedBinding()); assertSame(method, ((ICPPSpecialization) reference).getSpecializedBinding());
} }
// template<typename T> bool MySort(const T& a);
// bool MySort(const int& a);
// template<typename V> void sort(V __comp);
// void test() {
// sort(MySort<int>);
// }
public void testAdressOfUniqueTemplateInst_Bug326076() throws Exception {
parseAndCheckBindings();
}
} }

View file

@ -2282,15 +2282,7 @@ public class CPPSemantics {
// No arguments to resolve function // No arguments to resolve function
if (!data.hasFunctionArguments()) { if (!data.hasFunctionArguments()) {
ICPPFunction cand= fns[0]; return createFunctionSet(data.astName, fns);
if (!(cand instanceof ICPPFunctionTemplate)) {
if (fns.length == 1)
return cand;
// Just one binding from ast, use it.
if (!(cand instanceof IIndexBinding) && fns[1] instanceof IIndexBinding)
return cand;
}
return new CPPFunctionSet(fns);
} }
if (data.astName instanceof ICPPASTConversionName) { if (data.astName instanceof ICPPASTConversionName) {
@ -2410,6 +2402,46 @@ public class CPPSemantics {
return result; return result;
} }
private static IBinding createFunctionSet(IASTName name, ICPPFunction[] fns) {
// First try to find a unique function
ICPPFunction f= getUniqueFunctionForSet(name, fns);
return f == null ? new CPPFunctionSet(fns) : f;
}
private static ICPPFunction getUniqueFunctionForSet(IASTName name, ICPPFunction[] fns) {
// First try to find a unique function
if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) {
name= (IASTName) name.getParent();
}
final boolean haveTemplateArgs= name instanceof ICPPASTTemplateId;
ICPPFunction result= null;
boolean haveASTResult= false;
for (ICPPFunction f : fns) {
// Use the ast binding
final boolean fromIndex = f instanceof IIndexBinding;
if (haveASTResult && fromIndex)
break;
if (f instanceof ICPPFunctionTemplate) {
// Works only if there are template arguments
if (!haveTemplateArgs || result != null)
return null;
result= f;
haveASTResult= !fromIndex;
} else if (!haveTemplateArgs) {
if (result != null)
return null;
result= f;
haveASTResult= !fromIndex;
}
}
if (result instanceof ICPPFunctionTemplate)
return CPPTemplates.instantiateFunctionTemplate((ICPPFunctionTemplate) result, null, name);
return result;
}
private static void setTargetedFunctionsToUnknown(IType[] argTypes) { private static void setTargetedFunctionsToUnknown(IType[] argTypes) {
for (IType argType : argTypes) { for (IType argType : argTypes) {
if (argType instanceof FunctionSetType) { if (argType instanceof FunctionSetType) {

View file

@ -1672,7 +1672,7 @@ public class CPPTemplates {
name= (IASTName) name.getParent(); name= (IASTName) name.getParent();
} }
try { try {
if (isDependentType(target)) { if (target != null && isDependentType(target)) {
return CPPUnknownFunction.createForSample(template); return CPPUnknownFunction.createForSample(template);
} }

View file

@ -168,17 +168,19 @@ public class TemplateArgumentDeduction {
if (isDependentPar) { if (isDependentPar) {
TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(tmplParams, map, new CPPTemplateParameterMap(tmplParams.length), 0); TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(tmplParams, map, new CPPTemplateParameterMap(tmplParams.length), 0);
par= SemanticUtil.getNestedType(par, SemanticUtil.TDEF); par= SemanticUtil.getNestedType(par, SemanticUtil.TDEF);
if (!deduct.fromType(par, arg, false)) if (arg != null && !deduct.fromType(par, arg, false))
return null; return null;
if (!map.mergeToExplicit(deduct.fDeducedArgs)) if (!map.mergeToExplicit(deduct.fDeducedArgs))
return null; return null;
}
if (!verifyDeduction(tmplParams, map, true)) if (!verifyDeduction(tmplParams, map, true))
return null; return null;
if (isDependentPar)
par= CPPTemplates.instantiateType(par, map, -1, null); par= CPPTemplates.instantiateType(par, map, -1, null);
}
if (arg.isSameType(par)) { if (arg == null || arg.isSameType(par)) {
List<ICPPTemplateArgument> result= new ArrayList<ICPPTemplateArgument>(numTmplParams); List<ICPPTemplateArgument> result= new ArrayList<ICPPTemplateArgument>(numTmplParams);
for (ICPPTemplateParameter tpar : tmplParams) { for (ICPPTemplateParameter tpar : tmplParams) {
if (tpar.isParameterPack()) { if (tpar.isParameterPack()) {