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 a96c26dbdaa..c94a187f0f4 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 @@ -103,6 +103,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; 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; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition; @@ -373,6 +375,7 @@ public class CPPSemantics { public static final int DERIVED_TO_BASE_CONVERSION = 3; public static final int USERDEFINED_CONVERSION_RANK = 4; public static final int ELLIPSIS_CONVERSION = 5; + public static final int FUZZY_TEMPLATE_PARAMETERS = 6; public int compare( Cost cost ) throws DOMException{ int result = 0; @@ -1783,7 +1786,7 @@ public class CPPSemantics { Object [] fParams = data.functionParameters; int numParameters = ( fParams != null ) ? fParams.length : 0; int num; - + boolean def = data.forDefinition(); //Trim the list down to the set of viable functions IFunction function = null; int size = functions.length; @@ -1794,7 +1797,7 @@ public class CPPSemantics { //if there are m arguments in the list, all candidate functions having m parameters //are viable if( num == numParameters ){ - if( data.forDefinition() && !isMatchingFunctionDeclaration( function, data ) ){ + if( def && !isMatchingFunctionDeclaration( function, data ) ){ functions[i] = null; } continue; @@ -1807,6 +1810,12 @@ public class CPPSemantics { continue; } + if( def ){ + //if this is for a definition, we had to match the number of parameters. + functions[i] = null; + continue; + } + //A candidate function having fewer than m parameters is viable only if it has an //ellipsis in its parameter list. if( num < numParameters ){ @@ -1822,7 +1831,6 @@ public class CPPSemantics { for( int j = num - 1; j >= numParameters; j-- ){ if( ((ICPPParameter)params[j]).getDefaultValue() == null ){ functions[i] = null; - size--; break; } } @@ -2025,17 +2033,15 @@ public class CPPSemantics { cost.rank = Cost.IDENTITY_RANK; //exact match, no cost } else { cost = checkStandardConversionSequence( source, target ); - if( !data.forDefinition() ){ - //12.3-4 At most one user-defined conversion is implicitly applied to - //a single value. (also prevents infinite loop) - if( cost.rank == Cost.NO_MATCH_RANK && !data.forUserDefinedConversion ){ - temp = checkUserDefinedConversionSequence( source, target ); - if( temp != null ){ - cost = temp; - } + //12.3-4 At most one user-defined conversion is implicitly applied to + //a single value. (also prevents infinite loop) + if( (cost.rank == Cost.NO_MATCH_RANK || cost.rank == Cost.FUZZY_TEMPLATE_PARAMETERS ) && + !data.forUserDefinedConversion ) + { + temp = checkUserDefinedConversionSequence( source, target ); + if( temp != null ){ + cost = temp; } - } else { - cost.rank = Cost.NO_MATCH_RANK; } } @@ -2400,6 +2406,9 @@ public class CPPSemantics { derivedToBaseConversion( cost ); + if( cost.rank == -1 ){ + relaxTemplateParameters( cost ); + } return cost; } @@ -2807,6 +2816,16 @@ public class CPPSemantics { } } } + static private void relaxTemplateParameters( Cost cost ){ + IType s = getUltimateType( cost.source, false ); + IType t = getUltimateType( cost.target, false ); + + if( (s instanceof ICPPTemplateTypeParameter && t instanceof ICPPTemplateTypeParameter) || + (s instanceof ICPPTemplateTemplateParameter && t instanceof ICPPTemplateTemplateParameter ) ) + { + cost.rank = Cost.FUZZY_TEMPLATE_PARAMETERS; + } + } static private int hasBaseClass( IBinding symbol, IBinding base, boolean needVisibility ) throws DOMException { if( symbol == base ){ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java index c8bd6512b21..b506941bb75 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java @@ -119,6 +119,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; +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.ICPPTemplateNonTypeParameter; @@ -1759,7 +1760,12 @@ public class CPPVisitor { return e.getProblem(); } } else if( op == IASTUnaryExpression.op_amper ){ - return new CPPPointerType( type ); + if( type instanceof ICPPReferenceType ) + try { + return new CPPPointerType( ((ICPPReferenceType)type).getType() ); + } catch (DOMException e) { + } + return new CPPPointerType( type ); } else if ( type instanceof CPPBasicType ){ ((CPPBasicType)type).setValue( expression ); }