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 d8cccc90a38..7a70c5a3079 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 @@ -1657,7 +1657,7 @@ public class AST2TemplateTests extends AST2BaseTest { IType type = t.getType(); assertTrue( type instanceof ICPPSpecialization ); assertSame( ((ICPPSpecialization)type).getSpecializedBinding(), _T ); - + assertSame( ((IPointerType)((ITypedef)type).getType()).getType(), B ); assertSame( i, col.getName(14).resolveBinding() ); } @@ -1752,8 +1752,6 @@ public class AST2TemplateTests extends AST2BaseTest { } public void testBug98666() throws Exception { - StringBuffer buffer = new StringBuffer(); - IASTTranslationUnit tu = parse( "A::template B b;", ParserLanguage.CPP ); CPPNameCollector col = new CPPNameCollector(); tu.accept( col ); @@ -1796,4 +1794,34 @@ public class AST2TemplateTests extends AST2BaseTest { assertTrue( BI instanceof ICPPTemplateInstance ); assertSame( ((ICPPTemplateInstance)BI).getSpecializedBinding(), spec ); } + + public void testBug95208() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append( "template int f(T); // #1\n"); //$NON-NLS-1$ + buffer.append( "int f(int); // #2\n"); //$NON-NLS-1$ + buffer.append( "int k = f(1); // uses #2\n"); //$NON-NLS-1$ + buffer.append( "int l = f<>(1); // uses #1\n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); + CPPNameCollector col = new CPPNameCollector(); + tu.accept(col); + + ICPPFunctionTemplate f1 = (ICPPFunctionTemplate) col.getName(1).resolveBinding(); + ICPPFunction f2 = (ICPPFunction) col.getName(4).resolveBinding(); + + assertSame( f2, col.getName(7).resolveBinding() ); + + IBinding b = col.getName(9).resolveBinding(); // resolve the binding of the ICPPASTTemplateId first + assertTrue( b instanceof ICPPTemplateInstance ); + assertSame( ((ICPPTemplateInstance)b).getSpecializedBinding(), f1 ); + assertSame( f1, col.getName(10).resolveBinding() ); + + + tu = parse( buffer.toString(),ParserLanguage.CPP ); + col = new CPPNameCollector(); + tu.accept(col); + + f1 = (ICPPFunctionTemplate) col.getName(1).resolveBinding(); + assertSame( f1, col.getName(10).resolveBinding() ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java index fe13c2ac0cb..6a30223b1fb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java @@ -106,6 +106,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope; @@ -460,6 +461,11 @@ public class CPPSemantics { } return false; } + public boolean preferTemplateFunctions() { + if( astName == null ) + return false; + return (astName instanceof ICPPASTTemplateId || astName.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME ); + } } static protected class Cost @@ -703,8 +709,17 @@ public class CPPSemantics { } IASTName name = data.astName; - if( name.getParent() instanceof ICPPASTTemplateId ) - name = (IASTName) name.getParent(); + if( name.getParent() instanceof ICPPASTTemplateId ){ + if( binding instanceof ICPPTemplateInstance ){ + IBinding b = binding; + binding = ((ICPPTemplateInstance)binding).getSpecializedBinding(); + name.setBinding( binding ); + name = (IASTName) name.getParent(); + name.setBinding( b ); + } else { + name = (IASTName) name.getParent(); + } + } if( name.getParent() instanceof ICPPASTQualifiedName ){ IASTName [] ns = ((ICPPASTQualifiedName)name.getParent()).getNames(); if( name == ns [ ns.length - 1] ) @@ -2281,15 +2296,16 @@ public class CPPSemantics { } //we prefer normal functions over template functions, unless we specified template arguments else if( bestIsTemplate && !currIsTemplate ){ - if( data.templateArguments == null ) - hasBetter = true; - else + if( data.preferTemplateFunctions() ) ambiguous = false; + else + hasBetter = true; } else if( !bestIsTemplate && currIsTemplate ){ - if( data.templateArguments == null ) - ambiguous = false; - else + if( data.preferTemplateFunctions() ) hasBetter = true; + else + ambiguous = false; + } if( hasBetter ){ //the new best function.