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.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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue