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 e5ba1b9bbc2..93e53ecaa7f 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2009 IBM Corporation and others. + * Copyright (c) 2005, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -4739,5 +4739,19 @@ public class AST2TemplateTests extends AST2BaseTest { ub= bh.assertNonProblem("f(5 ...)", 1); // no diagnostics in CDT, treated as unknown function. ub= bh.assertNonProblem("f(args)", 1); // no diagnostics in CDT ub= bh.assertNonProblem("f(h(args...) + args...)", 1); - } + } + + // struct Test { + // void Update() {} + // }; + // template void bind(R (T::*f) ()) {} + // template void bind(R T::*f) {} + // + // void test() { + // bind(&Test::Update); + // } + public void testFunctionOrdering_299608() throws Exception { + final String code= getAboveComment(); + parseAndCheckBindings(code, ParserLanguage.CPP); + } } 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 9bc8c88a757..1b0bf15b435 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 @@ -2055,7 +2055,7 @@ public class CPPSemantics { return CPPUnknownFunction.createForSample(firstViable); } - boolean ambiguous = false; // ambiguity, 2 functions are equally good + IFunction[] ambiguousFunctions= null; // ambiguity, 2 functions are equally good FunctionCost bestFnCost = null; // the cost of the best function // Loop over all functions @@ -2084,9 +2084,9 @@ public class CPPSemantics { int cmp= fnCost.compareTo(data, bestFnCost); if (cmp < 0) { bestFnCost= fnCost; - ambiguous= false; + ambiguousFunctions= null; } else if (cmp == 0) { - ambiguous= true; + ambiguousFunctions= (IFunction[]) ArrayUtil.append(IFunction.class, ambiguousFunctions, fn); } } @@ -2096,9 +2096,9 @@ public class CPPSemantics { int cmp= fnCost.compareTo(data, bestFnCost); if (cmp < 0) { bestFnCost= fnCost; - ambiguous= false; + ambiguousFunctions= null; } else if (cmp == 0) { - ambiguous= true; + ambiguousFunctions= (IFunction[]) ArrayUtil.append(IFunction.class, ambiguousFunctions, fnCost.getFunction()); } } } @@ -2107,7 +2107,12 @@ public class CPPSemantics { if (bestFnCost == null) return null; - if (ambiguous || bestFnCost.hasAmbiguousUserDefinedConversion()) { + if (ambiguousFunctions != null) { + ambiguousFunctions= (IFunction[]) ArrayUtil.append(IFunction.class, ambiguousFunctions, bestFnCost.getFunction()); + return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, + ambiguousFunctions); + } + if (bestFnCost.hasAmbiguousUserDefinedConversion()) { return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.getFoundBindings()); } 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 7345e64f1d8..5512b48841a 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2009 IBM Corporation and others. + * Copyright (c) 2005, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -34,6 +34,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IArrayType; +import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumerator; @@ -1110,14 +1111,18 @@ public class CPPTemplates { ICPPPointerToMemberType ptm = (ICPPPointerToMemberType) typeContainer; IType memberOfClass = ptm.getMemberOfClass(); IType newMemberOfClass = instantiateType(memberOfClass, tpMap, packOffset, within); - if (newNestedType != nestedType || newMemberOfClass != memberOfClass) { - if (newMemberOfClass instanceof ICPPClassType) { - return new CPPPointerToMemberType(newNestedType, newMemberOfClass, - ptm.isConst(), ptm.isVolatile()); - } - return typeContainer; + if (!(newMemberOfClass instanceof ICPPClassType) && + !(newMemberOfClass instanceof IBasicType && ((IBasicType) newMemberOfClass).getModifiers() == CPPBasicType.UNIQUE_TYPE_QUALIFIER) && + !(newMemberOfClass instanceof ICPPUnknownBinding)) { + newMemberOfClass= memberOfClass; } - } else if (typeContainer instanceof IArrayType) { + if (newNestedType != nestedType || newMemberOfClass != memberOfClass) { + return new CPPPointerToMemberType(newNestedType, newMemberOfClass, + ptm.isConst(), ptm.isVolatile()); + } + return typeContainer; + } + if (typeContainer instanceof IArrayType) { IArrayType at= (IArrayType) typeContainer; IValue asize= at.getSize(); if (asize != null) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java index 91f33848690..e6c3b0bd9d1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2009 IBM Corporation and others. + * Copyright (c) 2004, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -248,8 +248,7 @@ public class SemanticUtil { if (p.isConst() || p.isVolatile()) { if (p instanceof ICPPPointerToMemberType) { final IType memberOfClass = ((ICPPPointerToMemberType) p).getMemberOfClass(); - if (memberOfClass instanceof ICPPClassType) - return new CPPPointerToMemberType(p.getType(), memberOfClass, false, false); + return new CPPPointerToMemberType(p.getType(), memberOfClass, false, false); } else { return new CPPPointerType(p.getType(), false, false); }