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.ICPPUnknownClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownClassType; 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.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; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank;
/** /**
@ -678,9 +679,9 @@ public class CPPTemplates {
ICPPTemplateArgument[] result = new ICPPTemplateArgument[length]; ICPPTemplateArgument[] result = new ICPPTemplateArgument[length];
IType a= SemanticUtil.getSimplifiedType(conversionType); IType a= SemanticUtil.getSimplifiedType(conversionType);
final boolean isReferenceType = a instanceof ICPPReferenceType; IType p= template.getType().getReturnType();
final IType p= getArgumentTypeForDeduction(template.getType().getReturnType(), isReferenceType); p= getArgumentTypeForDeduction(p, a instanceof ICPPReferenceType);
a= getParameterTypeForDeduction(a, isReferenceType); a= SemanticUtil.getNestedType(a, SemanticUtil.REF | SemanticUtil.TDEF);
if (!deduceTemplateParameterMap(p, a, map)) { if (!deduceTemplateParameterMap(p, a, map)) {
return null; return null;
} }
@ -1478,17 +1479,17 @@ public class CPPTemplates {
boolean isDependentPar= isDependentType(par); boolean isDependentPar= isDependentType(par);
if (checkExactMatch || isDependentPar) { if (checkExactMatch || isDependentPar) {
par= SemanticUtil.getNestedType(par, SemanticUtil.TDEF); // adjustParameterType preserves typedefs par= SemanticUtil.getNestedType(par, SemanticUtil.TDEF); // adjustParameterType preserves typedefs
par= SemanticUtil.adjustParameterType(par, false); // 14.8.2.1-2
// 14.8.2.1.2 and 14.8.2.1.3 final boolean isReferenceTypeParameter = par instanceof ICPPReferenceType;
final boolean isReferenceType = par instanceof ICPPReferenceType; IType arg= getArgumentTypeForDeduction(fnArgs[j], isReferenceTypeParameter);
IType arg= getArgumentTypeForDeduction(fnArgs[j], isReferenceType); if (isReferenceTypeParameter)
par= getParameterTypeForDeduction(par, isReferenceType); par= SemanticUtil.getNestedType(par, SemanticUtil.REF | SemanticUtil.TDEF);
// 14.8.2.1.3
if (!checkExactMatch) { if (!checkExactMatch) {
// 14.8.2.1-3
CVQualifier cvPar= SemanticUtil.getCVQualifier(par); CVQualifier cvPar= SemanticUtil.getCVQualifier(par);
CVQualifier cvArg= SemanticUtil.getCVQualifier(arg); 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); IType pcheck= SemanticUtil.getNestedType(par, CVTYPE);
if (!(pcheck instanceof ICPPTemplateParameter)) { if (!(pcheck instanceof ICPPTemplateParameter)) {
par= pcheck; par= pcheck;
@ -1584,19 +1585,6 @@ public class CPPTemplates {
return deduceTemplateParameterMap(p.getTypeValue(), a.getTypeValue(), map); 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 * 14.8.2.1-2
* if P is not a reference type * if P is not a reference type
@ -2090,7 +2078,7 @@ public class CPPTemplates {
} else if (paramType instanceof IArrayType) { } else if (paramType instanceof IArrayType) {
paramType = new CPPPointerType(((IArrayType) paramType).getType()); 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; return cost != null && cost.getRank() != Rank.NO_MATCH;
} }

View file

@ -162,7 +162,7 @@ public class Conversions {
// We must do a non-reference initialization // We must do a non-reference initialization
if (!illformed) { 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 return nonReferenceConversion(sourceIsLValue, source, uqtarget, udc, isImpliedObject);
if (!(uqsource instanceof ICPPClassType) && !(uqtarget instanceof ICPPClassType)) {
source= uqsource;
target= uqtarget;
}
return nonReferenceConversion(sourceIsLValue, source, target, udc, isImpliedObject);
} }
private static Cost nonReferenceConversion(boolean sourceIsLValue, IType source, IType target, UDCMode udc, boolean isImpliedObject) throws DOMException { 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) if (cost.getRank() != Rank.NO_MATCH || udc == UDCMode.noUDC)
return cost; return cost;
@ -330,7 +327,7 @@ public class Conversions {
* base conversion does not cause any costs. * base conversion does not cause any costs.
* @throws DOMException * @throws DOMException
*/ */
protected static final Cost checkStandardConversionSequence(IType source, IType target, private static final Cost checkStandardConversionSequence(IType source, IType target,
boolean isImplicitThis) throws DOMException { boolean isImplicitThis) throws DOMException {
final Cost cost= new Cost(source, target, Rank.IDENTITY); final Cost cost= new Cost(source, target, Rank.IDENTITY);
if (lvalue_to_rvalue(cost)) 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) { if (source == null || target == null) {
cost.setRank(Rank.NO_MATCH); cost.setRank(Rank.NO_MATCH);
return true; return true;

View file

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