From d3275f02321c1249a80ce74710cfdc74e496fd4c Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Tue, 28 Sep 2010 12:21:15 +0000 Subject: [PATCH] Bug 326076: Address of unique template function instance. --- .../parser/tests/ast2/AST2TemplateTests.java | 18 ++++++- .../parser/cpp/semantics/CPPSemantics.java | 50 +++++++++++++++---- .../parser/cpp/semantics/CPPTemplates.java | 2 +- .../semantics/TemplateArgumentDeduction.java | 14 +++--- 4 files changed, 66 insertions(+), 18 deletions(-) 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 13ab69ba355..e0be1cdbfb0 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 @@ -99,7 +99,11 @@ public class AST2TemplateTests extends AST2BaseTest { public static TestSuite suite() { return suite(AST2TemplateTests.class); } - + + private IASTTranslationUnit parseAndCheckBindings() throws Exception { + return parseAndCheckBindings(getAboveComment()); + } + private IASTTranslationUnit parseAndCheckBindings(final String code) throws Exception { return parseAndCheckBindings(code, ParserLanguage.CPP); } @@ -4587,7 +4591,7 @@ public class AST2TemplateTests extends AST2BaseTest { // int k = g(5.6); // Y is deduced to be double, Z is deduced to an empty sequence // f(g); // Y for outer f deduced to be // } // 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(); BindingAssertionHelper bh= new BindingAssertionHelper(code, true); bh.assertNonProblem("f(5.6)", 6); @@ -5140,4 +5144,14 @@ public class AST2TemplateTests extends AST2BaseTest { final IBinding reference = name.resolveBinding(); assertSame(method, ((ICPPSpecialization) reference).getSpecializedBinding()); } + + // template bool MySort(const T& a); + // bool MySort(const int& a); + // template void sort(V __comp); + // void test() { + // sort(MySort); + // } + public void testAdressOfUniqueTemplateInst_Bug326076() throws Exception { + parseAndCheckBindings(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index 06e46219e38..fead1c39dea 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -2282,15 +2282,7 @@ public class CPPSemantics { // No arguments to resolve function if (!data.hasFunctionArguments()) { - ICPPFunction cand= fns[0]; - 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); + return createFunctionSet(data.astName, fns); } if (data.astName instanceof ICPPASTConversionName) { @@ -2410,6 +2402,46 @@ public class CPPSemantics { 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) { for (IType argType : argTypes) { if (argType instanceof FunctionSetType) { 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 8938438e84a..e078f8156d9 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 @@ -1672,7 +1672,7 @@ public class CPPTemplates { name= (IASTName) name.getParent(); } try { - if (isDependentType(target)) { + if (target != null && isDependentType(target)) { return CPPUnknownFunction.createForSample(template); } 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 a2398fe9236..c3150d3e17f 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 @@ -168,17 +168,19 @@ public class TemplateArgumentDeduction { if (isDependentPar) { TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(tmplParams, map, new CPPTemplateParameterMap(tmplParams.length), 0); par= SemanticUtil.getNestedType(par, SemanticUtil.TDEF); - if (!deduct.fromType(par, arg, false)) + if (arg != null && !deduct.fromType(par, arg, false)) return null; if (!map.mergeToExplicit(deduct.fDeducedArgs)) return null; - if (!verifyDeduction(tmplParams, map, true)) - return null; - - par= CPPTemplates.instantiateType(par, map, -1, null); } + + if (!verifyDeduction(tmplParams, map, true)) + return null; + + if (isDependentPar) + par= CPPTemplates.instantiateType(par, map, -1, null); - if (arg.isSameType(par)) { + if (arg == null || arg.isSameType(par)) { List result= new ArrayList(numTmplParams); for (ICPPTemplateParameter tpar : tmplParams) { if (tpar.isParameterPack()) {