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:
parent
cb50de1748
commit
f0383cf814
3 changed files with 22 additions and 47 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Reference in a new issue