1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Further alignment of template argument deduction with c++-specification, follow up for bug 294539.

This commit is contained in:
Markus Schorn 2009-11-10 10:57:12 +00:00
parent cb50de1748
commit f0383cf814
3 changed files with 22 additions and 47 deletions

View file

@ -143,6 +143,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownClassType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank;
/**
@ -678,9 +679,9 @@ public class CPPTemplates {
ICPPTemplateArgument[] result = new ICPPTemplateArgument[length];
IType a= SemanticUtil.getSimplifiedType(conversionType);
final boolean isReferenceType = a instanceof ICPPReferenceType;
final IType p= getArgumentTypeForDeduction(template.getType().getReturnType(), isReferenceType);
a= getParameterTypeForDeduction(a, isReferenceType);
IType p= template.getType().getReturnType();
p= getArgumentTypeForDeduction(p, a instanceof ICPPReferenceType);
a= SemanticUtil.getNestedType(a, SemanticUtil.REF | SemanticUtil.TDEF);
if (!deduceTemplateParameterMap(p, a, map)) {
return null;
}
@ -1478,17 +1479,17 @@ public class CPPTemplates {
boolean isDependentPar= isDependentType(par);
if (checkExactMatch || isDependentPar) {
par= SemanticUtil.getNestedType(par, SemanticUtil.TDEF); // adjustParameterType preserves typedefs
par= SemanticUtil.adjustParameterType(par, false);
// 14.8.2.1.2 and 14.8.2.1.3
final boolean isReferenceType = par instanceof ICPPReferenceType;
IType arg= getArgumentTypeForDeduction(fnArgs[j], isReferenceType);
par= getParameterTypeForDeduction(par, isReferenceType);
// 14.8.2.1-2
final boolean isReferenceTypeParameter = par instanceof ICPPReferenceType;
IType arg= getArgumentTypeForDeduction(fnArgs[j], isReferenceTypeParameter);
if (isReferenceTypeParameter)
par= SemanticUtil.getNestedType(par, SemanticUtil.REF | SemanticUtil.TDEF);
// 14.8.2.1.3
if (!checkExactMatch) {
// 14.8.2.1-3
CVQualifier cvPar= SemanticUtil.getCVQualifier(par);
CVQualifier cvArg= SemanticUtil.getCVQualifier(arg);
if (cvPar == cvArg || (isReferenceType && cvPar.isAtLeastAsQualifiedAs(cvArg))) {
if (cvPar == cvArg || (isReferenceTypeParameter && cvPar.isAtLeastAsQualifiedAs(cvArg))) {
IType pcheck= SemanticUtil.getNestedType(par, CVTYPE);
if (!(pcheck instanceof ICPPTemplateParameter)) {
par= pcheck;
@ -1584,19 +1585,6 @@ public class CPPTemplates {
return deduceTemplateParameterMap(p.getTypeValue(), a.getTypeValue(), map);
}
/**
* 14.8.2.1-2 If P is a cv-qualified type, the top level cv-qualifiers of P's type are ignored for type
* deduction. If P is a reference type, the type referred to by P is used for Type deduction.
*
* Also 14.8.2.3-2 where the same logics is used in reverse.
*/
static private IType getParameterTypeForDeduction(IType pType, boolean isReferenceType) {
if (isReferenceType) {
return SemanticUtil.getNestedType(pType, SemanticUtil.REF | SemanticUtil.TDEF);
}
return SemanticUtil.getNestedType(pType, SemanticUtil.TDEF | SemanticUtil.ALLCVQ);
}
/**
* 14.8.2.1-2
* if P is not a reference type
@ -2090,7 +2078,7 @@ public class CPPTemplates {
} else if (paramType instanceof IArrayType) {
paramType = new CPPPointerType(((IArrayType) paramType).getType());
}
Cost cost = Conversions.checkStandardConversionSequence(arg, paramType, false);
Cost cost = Conversions.checkImplicitConversionSequence(true, arg, paramType, UDCMode.noUDC, false);
return cost != null && cost.getRank() != Rank.NO_MATCH;
}

View file

@ -162,7 +162,7 @@ public class Conversions {
// We must do a non-reference initialization
if (!illformed) {
return nonReferenceConversion(sourceIsLValue, source, cv1T1, udc, isImpliedObject);
return nonReferenceConversion(sourceIsLValue, source, T1, udc, isImpliedObject);
}
}
}
@ -186,16 +186,13 @@ public class Conversions {
}
}
// [13.3.3.1-6] Subsume cv-qualifications
if (!(uqsource instanceof ICPPClassType) && !(uqtarget instanceof ICPPClassType)) {
source= uqsource;
target= uqtarget;
}
return nonReferenceConversion(sourceIsLValue, source, target, udc, isImpliedObject);
return nonReferenceConversion(sourceIsLValue, source, uqtarget, udc, isImpliedObject);
}
private static Cost nonReferenceConversion(boolean sourceIsLValue, IType source, IType target, UDCMode udc, boolean isImpliedObject) throws DOMException {
Cost cost= checkStandardConversionSequence(source, target, isImpliedObject);
// [13.3.3.1-6] Subsume cv-qualifications
IType uqSource= SemanticUtil.getNestedType(source, TDEF | ALLCVQ);
Cost cost= checkStandardConversionSequence(uqSource, target, isImpliedObject);
if (cost.getRank() != Rank.NO_MATCH || udc == UDCMode.noUDC)
return cost;
@ -330,7 +327,7 @@ public class Conversions {
* base conversion does not cause any costs.
* @throws DOMException
*/
protected static final Cost checkStandardConversionSequence(IType source, IType target,
private static final Cost checkStandardConversionSequence(IType source, IType target,
boolean isImplicitThis) throws DOMException {
final Cost cost= new Cost(source, target, Rank.IDENTITY);
if (lvalue_to_rvalue(cost))
@ -607,17 +604,6 @@ public class Conversions {
}
}
// This should actually be done before the conversion is attempted, see for instance 13.3.3.1-6 and 8.5.14.
// However, it does not hurt to do it here either.
IType unqualifiedTarget= getNestedType(target, ALLCVQ | TDEF | REF);
if (!(unqualifiedTarget instanceof ICPPClassType)) {
IType unqualifiedSource= getNestedType(source, ALLCVQ | TDEF | REF);
if (!(unqualifiedSource instanceof ICPPClassType)) {
source= unqualifiedSource;
target= unqualifiedTarget;
}
}
if (source == null || target == null) {
cost.setRank(Rank.NO_MATCH);
return true;

View file

@ -436,9 +436,10 @@ public class SemanticUtil {
return new CPPPointerType(pt);
}
//8.3.5-3
//Any cv-qualifier modifying a parameter type is deleted.
if (forFunctionType && (t instanceof IQualifierType || t instanceof IPointerType)) {
// 8.3.5-3
// Any cv-qualifier modifying a parameter type is deleted. The parameter type remains
// to be qualified.
if (forFunctionType && SemanticUtil.getCVQualifier(t) != CVQualifier._) {
return SemanticUtil.getNestedType(t, TDEF | ALLCVQ);
}
return pt;