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 afa8c76d131..9ae7649f3ad 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 @@ -88,6 +88,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknownScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; public class AST2TemplateTests extends AST2BaseTest { @@ -5655,17 +5656,14 @@ public class AST2TemplateTests extends AST2BaseTest { // typedef typename C::type pointer; // }; // - // void f(int*); - // void f(int); - // - // void test(B::pointer a) { - // f(a); - // } + // B::pointer a; public void testDependentExpressions_b() throws Exception { parseAndCheckBindings(); BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), CPP); - ICPPFunction func= bh.assertNonProblem("f(a)", 1, ICPPFunction.class); - assertFalse(func instanceof ICPPUnknownBinding); + ICPPVariable var= bh.assertNonProblem("a;", 1, ICPPVariable.class); + IType type = var.getType(); + type = SemanticUtil.getNestedType(type, TDEF); + assertEquals("int *", type.toString()); } // template void* foo(int); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java index fe5266bae77..9328c13ddcf 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java @@ -173,18 +173,18 @@ public class EvalComma extends CPPEvaluation { @Override public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, int maxdepth, IASTNode point) { - ICPPEvaluation[] args = null; + ICPPEvaluation[] args = fArguments; for (int i = 0; i < fArguments.length; i++) { ICPPEvaluation arg = fArguments[i].instantiate(tpMap, packOffset, within, maxdepth, point); if (arg != fArguments[i]) { - if (args == null) { + if (args == fArguments) { args = new ICPPEvaluation[fArguments.length]; System.arraycopy(fArguments, 0, args, 0, fArguments.length); } args[i] = arg; } } - if (args == null) + if (args == fArguments) return this; return new EvalComma(args); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java index db34d140b8d..6bf4ddc8f91 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java @@ -20,11 +20,8 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti import java.util.Arrays; -import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTNode; -import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.ISemanticProblem; @@ -40,7 +37,6 @@ import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; -import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics.LookupMode; import org.eclipse.core.runtime.CoreException; @@ -187,34 +183,23 @@ public class EvalFunctionCall extends CPPEvaluation { @Override public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, int maxdepth, IASTNode point) { - ICPPEvaluation[] args = null; + ICPPEvaluation[] args = fArguments; for (int i = 0; i < fArguments.length; i++) { ICPPEvaluation arg = fArguments[i].instantiate(tpMap, packOffset, within, maxdepth, point); if (arg != fArguments[i]) { - if (args == null) { + if (args == fArguments) { args = new ICPPEvaluation[fArguments.length]; System.arraycopy(fArguments, 0, args, 0, fArguments.length); } args[i] = arg; } } - if (args == null) + if (args == fArguments) return this; - if (args[0] instanceof EvalFunctionSet) { + if (args[0] instanceof EvalFunctionSet && getOverload(point) == null) { // Resolve the function using the parameters of the function call. - CPPFunctionSet functionSet = ((EvalFunctionSet) args[0]).getFunctionSet(); - ICPPFunction[] functions = functionSet.getBindings(); - LookupData data = new LookupData(functions[0].getNameCharArray(), - functionSet.getTemplateArguments(), point); - data.setFunctionArguments(false, Arrays.copyOfRange(args, 1, args.length)); - try { - IBinding binding = CPPSemantics.resolveFunction(data, functions, true); - if (binding instanceof ICPPFunction && !(binding instanceof ICPPUnknownBinding)) - args[0] = new EvalBinding(binding, null); - } catch (DOMException e) { - CCorePlugin.log(e); - } + args[0] = ((EvalFunctionSet) args[0]).resolveFunction(Arrays.copyOfRange(args, 1, args.length), point); } return new EvalFunctionCall(args); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java index 47fc4b8a99e..881db03f857 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java @@ -15,6 +15,8 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import java.util.Arrays; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; @@ -168,6 +170,29 @@ public class EvalFunctionSet extends CPPEvaluation { return new EvalFunctionSet(new CPPFunctionSet(functions, arguments, null), fAddressOf); } + /** + * Attempts to resolve the function using the parameters of a function call. + * + * @param args the arguments of a function call + * @param point the name lookup context + * @return the resolved or the original evaluation depending on whether function resolution + * succeeded or not + */ + public ICPPEvaluation resolveFunction(ICPPEvaluation[] args, IASTNode point) { + ICPPFunction[] functions = fFunctionSet.getBindings(); + LookupData data = new LookupData(functions[0].getNameCharArray(), + fFunctionSet.getTemplateArguments(), point); + data.setFunctionArguments(false, args); + try { + IBinding binding = CPPSemantics.resolveFunction(data, functions, true); + if (binding instanceof ICPPFunction && !(binding instanceof ICPPUnknownBinding)) + return new EvalBinding(binding, null); + } catch (DOMException e) { + CCorePlugin.log(e); + } + return this; + } + @Override public int determinePackSize(ICPPTemplateParameterMap tpMap) { int r = CPPTemplates.PACK_SIZE_NOT_FOUND; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java index f5547474e44..ae55002ba98 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java @@ -14,8 +14,6 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; -import java.util.Arrays; - import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; @@ -291,7 +289,6 @@ public class EvalID extends CPPEvaluation { IBinding nameOwner = fNameOwner; if (nameOwner instanceof ICPPClassTemplate) { - // TODO(sprigogin): Figure out why testDependentExpressions_a fails without special-casing ICPPClassTemplate nameOwner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) nameOwner), tpMap, packOffset, within, point); } else if (nameOwner instanceof IType) { @@ -303,7 +300,7 @@ public class EvalID extends CPPEvaluation { if (fieldOwner instanceof IProblemBinding || nameOwner instanceof IProblemBinding) return this; - if (Arrays.equals(templateArgs, fTemplateArgs) && fieldOwner == fFieldOwner && nameOwner == fNameOwner) + if (templateArgs == fTemplateArgs && fieldOwner == fFieldOwner && nameOwner == fNameOwner) return this; ICPPEvaluation eval = resolveName((ICPPClassType) nameOwner, templateArgs, point); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java index db7d1c46bba..02eb709506e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java @@ -105,18 +105,18 @@ public class EvalInitList extends CPPEvaluation { @Override public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, int maxdepth, IASTNode point) { - ICPPEvaluation[] clauses = null; + ICPPEvaluation[] clauses = fClauses; for (int i = 0; i < fClauses.length; i++) { ICPPEvaluation clause = fClauses[i].instantiate(tpMap, packOffset, within, maxdepth, point); if (clause != fClauses[i]) { - if (clauses == null) { + if (clauses == fClauses) { clauses = new ICPPEvaluation[fClauses.length]; System.arraycopy(fClauses, 0, clauses, 0, fClauses.length); } clauses[i] = clause; } } - if (clauses == null) + if (clauses == fClauses) return this; return new EvalInitList(clauses); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java index c0c25271eba..f17201b2139 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java @@ -146,11 +146,11 @@ public class EvalTypeId extends CPPEvaluation { @Override public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, int maxdepth, IASTNode point) { - ICPPEvaluation[] args = null; + ICPPEvaluation[] args = fArguments; for (int i = 0; i < fArguments.length; i++) { ICPPEvaluation arg = fArguments[i].instantiate(tpMap, packOffset, within, maxdepth, point); if (arg != fArguments[i]) { - if (args == null) { + if (args == fArguments) { args = new ICPPEvaluation[fArguments.length]; System.arraycopy(fArguments, 0, args, 0, fArguments.length); } @@ -158,11 +158,8 @@ public class EvalTypeId extends CPPEvaluation { } } IType type = CPPTemplates.instantiateType(fInputType, tpMap, packOffset, within, point); - if (args == null) { - if (type == fInputType) - return this; - args = fArguments; - } + if (args == fArguments && type == fInputType) + return this; return new EvalTypeId(type, args); }