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 a95ce65e7da..9206fb6ae1e 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 @@ -7488,4 +7488,12 @@ public class AST2TemplateTests extends AST2TestBase { public void testRegression_401743b() throws Exception { parseAndCheckBindings(); } + + // template + // void foo(T t) { + // bar(t); + // } + public void testUnqualifiedFunctionCallInTemplate_402498() throws Exception { + parseAndCheckBindings(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunction.java index 88f0d3b79d8..a9902441692 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunction.java @@ -28,6 +28,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ProblemType; public class CPPDeferredFunction extends CPPUnknownBinding implements ICPPFunction, ICPPComputableFunction { private static final ICPPFunctionType FUNCTION_TYPE= new CPPFunctionType(ProblemType.UNKNOWN_FOR_EXPRESSION, IType.EMPTY_TYPE_ARRAY); + private static final ICPPFunction[] NO_CANDIDATES= {}; /** * Creates a CPPDeferredFunction given a set of overloaded functions @@ -43,6 +44,16 @@ public class CPPDeferredFunction extends CPPUnknownBinding implements ICPPFuncti final IBinding owner = candidates[0].getOwner(); return new CPPDeferredFunction(owner, candidates[0].getNameCharArray(), candidates); } + + /** + * Creates a CPPDeferredFunction given a name. This is for cases where there + * are no candidates that could be passed to createForCandidates(). + * @param name the name of the function + * @return the constructed CPPDeferredFunction + */ + public static ICPPFunction createForName(char[] name) { + return new CPPDeferredFunction(null, name, NO_CANDIDATES); + } private final IBinding fOwner; private final ICPPFunction[] fCandidates; 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 1186983820e..d9154a68c6a 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 @@ -518,6 +518,15 @@ public class CPPSemantics { } } + // If this is the unqualified name of a function in a function call in a template and some + // of the function arguments are dependent, the name could be resolved via argument-dependent + // lookup at the point of instantiation. + if (binding == null) { + if (!data.qualified && data.isFunctionCall() && CPPTemplates.containsDependentType(data.getFunctionArgumentTypes())) { + binding = CPPDeferredFunction.createForName(lookupName.getSimpleID()); + } + } + // If we're still null... if (binding == null) { if (name instanceof ICPPASTQualifiedName && declaration != null) { @@ -555,7 +564,6 @@ public class CPPSemantics { private static void doKoenigLookup(LookupData data) throws DOMException { data.ignoreUsingDirectives = true; - data.qualified = true; Set friendFns = new HashSet(2); Set associated = getAssociatedScopes(data, friendFns); for (ICPPNamespaceScope scope : associated) {