mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-01 06:05:24 +02:00
Amend list-initialization handling of class or aggregate
This commit is contained in:
parent
ae3a0adb81
commit
84322c30f4
11 changed files with 131 additions and 100 deletions
|
@ -16,6 +16,7 @@ import java.util.TreeSet;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
|
||||||
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.ICompositeType;
|
import org.eclipse.cdt.core.dom.ast.ICompositeType;
|
||||||
|
@ -147,13 +148,24 @@ public final class CompositeValue implements IValue {
|
||||||
ICPPEvaluation[] values = new ICPPEvaluation[fields.length];
|
ICPPEvaluation[] values = new ICPPEvaluation[fields.length];
|
||||||
ICPPEvaluation[] clauses = initList.getClauses();
|
ICPPEvaluation[] clauses = initList.getClauses();
|
||||||
for (int i = 0; i < fields.length; i++) {
|
for (int i = 0; i < fields.length; i++) {
|
||||||
if (i == clauses.length)
|
|
||||||
break;
|
|
||||||
IField field = fields[i];
|
IField field = fields[i];
|
||||||
ICPPEvaluation eval = clauses[i];
|
|
||||||
IType fieldType = field.getType();
|
IType fieldType = field.getType();
|
||||||
IValue value = getValue(fieldType, eval);
|
IValue value;
|
||||||
values[i] = new EvalFixed(fieldType, eval.getValueCategory(), value);
|
ValueCategory valueCategory;
|
||||||
|
if (i < clauses.length) {
|
||||||
|
ICPPEvaluation eval = clauses[i];
|
||||||
|
value = getValue(fieldType, eval);
|
||||||
|
valueCategory = eval.getValueCategory();
|
||||||
|
} else {
|
||||||
|
// (dcl.init.aggr-7) from brace-or-equal-initializer or from {}
|
||||||
|
value = field.getInitialValue();
|
||||||
|
// Writing IntegralValue.UNKNOWN to PDOM stores null, convert it back
|
||||||
|
if (value == null || value == IntegralValue.UNKNOWN) {
|
||||||
|
value = IntegralValue.create(0);
|
||||||
|
}
|
||||||
|
valueCategory = ValueCategory.PRVALUE;
|
||||||
|
}
|
||||||
|
values[i] = new EvalFixed(fieldType, valueCategory, value);
|
||||||
}
|
}
|
||||||
return new CompositeValue(initList, values);
|
return new CompositeValue(initList, values);
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,7 @@ class AggregateInitialization {
|
||||||
}
|
}
|
||||||
|
|
||||||
Cost costWithoutElision = Conversions.checkImplicitConversionSequence(nestedType, initializer.getType(),
|
Cost costWithoutElision = Conversions.checkImplicitConversionSequence(nestedType, initializer.getType(),
|
||||||
initializer.getValueCategory(), UDCMode.ALLOWED, Context.ORDINARY);
|
initializer.getValueCategory(), UDCMode.ALLOWED, Context.ORDINARY, false);
|
||||||
if (costWithoutElision.converts()) {
|
if (costWithoutElision.converts()) {
|
||||||
// p3: The elements of the initializer list are taken as initializers for the elements
|
// p3: The elements of the initializer list are taken as initializers for the elements
|
||||||
// of the aggregate, in order.
|
// of the aggregate, in order.
|
||||||
|
|
|
@ -195,7 +195,7 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
|
||||||
ValueCategory valueCategory = argument.getValueCategory();
|
ValueCategory valueCategory = argument.getValueCategory();
|
||||||
if (uqType instanceof ICPPClassType) {
|
if (uqType instanceof ICPPClassType) {
|
||||||
Cost cost = Conversions.initializationByConversion(valueCategory, type, (ICPPClassType) uqType,
|
Cost cost = Conversions.initializationByConversion(valueCategory, type, (ICPPClassType) uqType,
|
||||||
targetType, false, allowContextualConversion);
|
targetType, false, allowContextualConversion, false);
|
||||||
ICPPFunction conversion = cost.getUserDefinedConversion();
|
ICPPFunction conversion = cost.getUserDefinedConversion();
|
||||||
if (conversion != null) {
|
if (conversion != null) {
|
||||||
if (onlyConstexprConversion && !conversion.isConstexpr()) {
|
if (onlyConstexprConversion && !conversion.isConstexpr()) {
|
||||||
|
@ -210,7 +210,7 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
|
||||||
// Source type is not a class type, or is but a conversion operator wasn't used.
|
// Source type is not a class type, or is but a conversion operator wasn't used.
|
||||||
// Check for standard conversions.
|
// Check for standard conversions.
|
||||||
Cost cost = Conversions.checkImplicitConversionSequence(targetType, type, valueCategory, UDCMode.FORBIDDEN,
|
Cost cost = Conversions.checkImplicitConversionSequence(targetType, type, valueCategory, UDCMode.FORBIDDEN,
|
||||||
Context.ORDINARY);
|
Context.ORDINARY, false);
|
||||||
if (!cost.converts()) {
|
if (!cost.converts()) {
|
||||||
return EvalFixed.INCOMPLETE;
|
return EvalFixed.INCOMPLETE;
|
||||||
} else if (cost.getRank() == Rank.CONVERSION) {
|
} else if (cost.getRank() == Rank.CONVERSION) {
|
||||||
|
|
|
@ -3169,7 +3169,14 @@ public class CPPSemantics {
|
||||||
|
|
||||||
if (potentialCosts != null) {
|
if (potentialCosts != null) {
|
||||||
for (FunctionCost fnCost : potentialCosts) {
|
for (FunctionCost fnCost : potentialCosts) {
|
||||||
if (!fnCost.mustBeWorse(bestFnCost) && fnCost.performUDC()) {
|
if (!fnCost.mustBeWorse(bestFnCost) && fnCost.performUDC(data.fNoNarrowing)) {
|
||||||
|
if (data.fNoNarrowing) {
|
||||||
|
for (int i = 0; i < fnCost.getLength(); ++i) {
|
||||||
|
if (fnCost.getCost(i).isNarrowingConversion()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
int cmp = fnCost.compareTo(tu, bestFnCost, data.getFunctionArgumentCount());
|
int cmp = fnCost.compareTo(tu, bestFnCost, data.getFunctionArgumentCount());
|
||||||
if (cmp < 0) {
|
if (cmp < 0) {
|
||||||
bestFnCost = fnCost;
|
bestFnCost = fnCost;
|
||||||
|
@ -3473,7 +3480,7 @@ public class CPPSemantics {
|
||||||
Context context = ftype.hasRefQualifier() ? Context.IMPLICIT_OBJECT_FOR_METHOD_WITH_REF_QUALIFIER
|
Context context = ftype.hasRefQualifier() ? Context.IMPLICIT_OBJECT_FOR_METHOD_WITH_REF_QUALIFIER
|
||||||
: Context.IMPLICIT_OBJECT_FOR_METHOD_WITHOUT_REF_QUALIFIER;
|
: Context.IMPLICIT_OBJECT_FOR_METHOD_WITHOUT_REF_QUALIFIER;
|
||||||
cost = Conversions.checkImplicitConversionSequence(implicitParameterType, impliedObjectType,
|
cost = Conversions.checkImplicitConversionSequence(implicitParameterType, impliedObjectType,
|
||||||
impliedObjectValueCategory, UDCMode.FORBIDDEN, context);
|
impliedObjectValueCategory, UDCMode.FORBIDDEN, context, data.fNoNarrowing);
|
||||||
if (cost.converts()) {
|
if (cost.converts()) {
|
||||||
cost.setImpliedObject();
|
cost.setImpliedObject();
|
||||||
} else {
|
} else {
|
||||||
|
@ -3530,7 +3537,9 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cost = Conversions.checkImplicitConversionSequence(paramType, argType, argValueCategory, udc, ctx);
|
cost = Conversions.checkImplicitConversionSequence(paramType, argType, argValueCategory, udc, ctx,
|
||||||
|
data.fNoNarrowing);
|
||||||
|
// TODO: see if isNarrowingConversion() is re-checked while performing UDC again later
|
||||||
if (data.fNoNarrowing && cost.isNarrowingConversion()) {
|
if (data.fNoNarrowing && cost.isNarrowingConversion()) {
|
||||||
cost = Cost.NO_CONVERSION;
|
cost = Cost.NO_CONVERSION;
|
||||||
}
|
}
|
||||||
|
@ -4118,10 +4127,16 @@ public class CPPSemantics {
|
||||||
if (initializer == null) {
|
if (initializer == null) {
|
||||||
IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration) parent).getDeclSpecifier();
|
IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration) parent).getDeclSpecifier();
|
||||||
parent = parent.getParent();
|
parent = parent.getParent();
|
||||||
if (parent instanceof IASTCompositeTypeSpecifier
|
// (c++11:class.base.init 12.6.2-8) [..no initializer..]
|
||||||
|
// if the entity is an anonymous union or a variant member, no initialization is performed
|
||||||
|
// otherwise the entity is default-initialized
|
||||||
|
// (c++11:dcl.init 8.5-7)
|
||||||
|
// if T is a (possibly cv-qualified) class type .. the default constructor for T is called
|
||||||
|
if ((parent instanceof IASTCompositeTypeSpecifier compositeType
|
||||||
|
&& compositeType.getKey() == ICompositeType.k_union)
|
||||||
|| declSpec.getStorageClass() == IASTDeclSpecifier.sc_extern) {
|
|| declSpec.getStorageClass() == IASTDeclSpecifier.sc_extern) {
|
||||||
// No initialization is performed for class members and extern declarations
|
// No initialization is performed for class members which are of union type,
|
||||||
// without an initializer.
|
// and for extern declarations without an initializer.
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4182,6 +4197,20 @@ public class CPPSemantics {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IBinding findConstructorForDirectListInitialization(ICPPClassType type, EvalInitList eval,
|
||||||
|
IASTNode typeId) throws DOMException {
|
||||||
|
Cost c = Conversions.listInitializationSequence(eval, type, UDCMode.ALLOWED, true);
|
||||||
|
if (c.converts()) {
|
||||||
|
ICPPFunction f = c.getUserDefinedConversion();
|
||||||
|
if (f instanceof ICPPConstructor) {
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return new ProblemBinding(null, typeId, ISemanticProblem.BINDING_NOT_FOUND, type.getConstructors());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private static IBinding findImplicitlyCalledConstructor(ICPPClassType type, IASTInitializer initializer,
|
private static IBinding findImplicitlyCalledConstructor(ICPPClassType type, IASTInitializer initializer,
|
||||||
IASTNode typeId) {
|
IASTNode typeId) {
|
||||||
pushLookupPoint(typeId);
|
pushLookupPoint(typeId);
|
||||||
|
@ -4207,10 +4236,10 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
Cost c;
|
Cost c;
|
||||||
if (calculateInheritanceDepth(sourceType, type) >= 0) {
|
if (calculateInheritanceDepth(sourceType, type) >= 0) {
|
||||||
c = Conversions.copyInitializationOfClass(isLValue, sourceType, type, false);
|
c = Conversions.copyInitializationOfClass(isLValue, sourceType, type, false, false);
|
||||||
} else {
|
} else {
|
||||||
c = Conversions.checkImplicitConversionSequence(type, sourceType, isLValue, UDCMode.ALLOWED,
|
c = Conversions.checkImplicitConversionSequence(type, sourceType, isLValue, UDCMode.ALLOWED,
|
||||||
Context.ORDINARY);
|
Context.ORDINARY, false);
|
||||||
}
|
}
|
||||||
if (c.converts()) {
|
if (c.converts()) {
|
||||||
ICPPFunction f = c.getUserDefinedConversion();
|
ICPPFunction f = c.getUserDefinedConversion();
|
||||||
|
@ -4225,7 +4254,7 @@ public class CPPSemantics {
|
||||||
} else if (initializer instanceof ICPPASTInitializerList) {
|
} else if (initializer instanceof ICPPASTInitializerList) {
|
||||||
// List initialization.
|
// List initialization.
|
||||||
ICPPEvaluation eval = ((ICPPASTInitializerClause) initializer).getEvaluation();
|
ICPPEvaluation eval = ((ICPPASTInitializerClause) initializer).getEvaluation();
|
||||||
if (eval instanceof EvalInitList) {
|
if (eval instanceof EvalInitList evalInitList) {
|
||||||
if (CPPTemplates.isDependentType(eval.getType())) {
|
if (CPPTemplates.isDependentType(eval.getType())) {
|
||||||
ICPPEvaluation[] clauses = ((EvalInitList) eval).getClauses();
|
ICPPEvaluation[] clauses = ((EvalInitList) eval).getClauses();
|
||||||
IType[] tmp = new IType[clauses.length];
|
IType[] tmp = new IType[clauses.length];
|
||||||
|
@ -4235,14 +4264,9 @@ public class CPPSemantics {
|
||||||
setTargetedFunctionsToUnknown(tmp);
|
setTargetedFunctionsToUnknown(tmp);
|
||||||
return CPPDeferredFunction.createForCandidates(type.getConstructors());
|
return CPPDeferredFunction.createForCandidates(type.getConstructors());
|
||||||
}
|
}
|
||||||
Cost c = Conversions.listInitializationSequence((EvalInitList) eval, type, UDCMode.ALLOWED, true);
|
IBinding b = findConstructorForDirectListInitialization(type, evalInitList, typeId);
|
||||||
if (c.converts()) {
|
if (b != null) {
|
||||||
ICPPFunction f = c.getUserDefinedConversion();
|
return b;
|
||||||
if (f instanceof ICPPConstructor)
|
|
||||||
return f;
|
|
||||||
} else {
|
|
||||||
return new ProblemBinding(null, typeId, ISemanticProblem.BINDING_NOT_FOUND,
|
|
||||||
type.getConstructors());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (initializer instanceof ICPPASTConstructorInitializer) {
|
} else if (initializer instanceof ICPPASTConstructorInitializer) {
|
||||||
|
|
|
@ -2983,7 +2983,8 @@ public class CPPTemplates {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Cost cost = Conversions.checkImplicitConversionSequence(p, a, LVALUE, UDCMode.FORBIDDEN, Context.ORDINARY);
|
Cost cost = Conversions.checkImplicitConversionSequence(p, a, LVALUE, UDCMode.FORBIDDEN, Context.ORDINARY,
|
||||||
|
false);
|
||||||
if (cost == null || !cost.converts()) {
|
if (cost == null || !cost.converts()) {
|
||||||
ICPPEvaluation eval = arg.getNonTypeEvaluation();
|
ICPPEvaluation eval = arg.getNonTypeEvaluation();
|
||||||
ICPPEvaluation newEval = CPPEvaluation.maybeApplyConversion(eval, p, false, true);
|
ICPPEvaluation newEval = CPPEvaluation.maybeApplyConversion(eval, p, false, true);
|
||||||
|
|
|
@ -99,7 +99,7 @@ public class Conversions {
|
||||||
* @throws DOMException
|
* @throws DOMException
|
||||||
*/
|
*/
|
||||||
public static Cost checkImplicitConversionSequence(IType target, IType exprType, ValueCategory valueCat,
|
public static Cost checkImplicitConversionSequence(IType target, IType exprType, ValueCategory valueCat,
|
||||||
UDCMode udc, Context ctx) throws DOMException {
|
UDCMode udc, Context ctx, boolean noNarrowing) throws DOMException {
|
||||||
final boolean isImpliedObject = ctx == Context.IMPLICIT_OBJECT_FOR_METHOD_WITHOUT_REF_QUALIFIER
|
final boolean isImpliedObject = ctx == Context.IMPLICIT_OBJECT_FOR_METHOD_WITHOUT_REF_QUALIFIER
|
||||||
|| ctx == Context.IMPLICIT_OBJECT_FOR_METHOD_WITH_REF_QUALIFIER;
|
|| ctx == Context.IMPLICIT_OBJECT_FOR_METHOD_WITH_REF_QUALIFIER;
|
||||||
if (isImpliedObject)
|
if (isImpliedObject)
|
||||||
|
@ -211,7 +211,7 @@ public class Conversions {
|
||||||
|
|
||||||
// 13.3.3.1.7 no temporary object when converting the implicit object parameter
|
// 13.3.3.1.7 no temporary object when converting the implicit object parameter
|
||||||
if (!isImpliedObject && ctx != Context.REQUIRE_DIRECT_BINDING) {
|
if (!isImpliedObject && ctx != Context.REQUIRE_DIRECT_BINDING) {
|
||||||
Cost cost = nonReferenceConversion(valueCat, cv2T2, T1, udc);
|
Cost cost = nonReferenceConversion(valueCat, cv2T2, T1, udc, noNarrowing);
|
||||||
if (cost.converts()) {
|
if (cost.converts()) {
|
||||||
cost.setReferenceBinding(refBindingType);
|
cost.setReferenceBinding(refBindingType);
|
||||||
}
|
}
|
||||||
|
@ -232,7 +232,7 @@ public class Conversions {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Non-reference binding
|
// Non-reference binding
|
||||||
return nonReferenceConversion(valueCat, exprType, T1, udc);
|
return nonReferenceConversion(valueCat, exprType, T1, udc, noNarrowing);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -297,8 +297,8 @@ public class Conversions {
|
||||||
/**
|
/**
|
||||||
* 8.5-16
|
* 8.5-16
|
||||||
*/
|
*/
|
||||||
private static Cost nonReferenceConversion(ValueCategory valueCat, IType source, IType target, UDCMode udc)
|
private static Cost nonReferenceConversion(ValueCategory valueCat, IType source, IType target, UDCMode udc,
|
||||||
throws DOMException {
|
boolean noNarrowing) throws DOMException {
|
||||||
if (source instanceof InitializerListType) {
|
if (source instanceof InitializerListType) {
|
||||||
return listInitializationSequence(((InitializerListType) source).getEvaluation(), target, udc, false);
|
return listInitializationSequence(((InitializerListType) source).getEvaluation(), target, udc, false);
|
||||||
}
|
}
|
||||||
|
@ -321,7 +321,8 @@ public class Conversions {
|
||||||
if (udc == UDCMode.FORBIDDEN)
|
if (udc == UDCMode.FORBIDDEN)
|
||||||
return Cost.NO_CONVERSION;
|
return Cost.NO_CONVERSION;
|
||||||
|
|
||||||
return copyInitializationOfClass(valueCat, source, (ICPPClassType) uqTarget, udc == UDCMode.DEFER);
|
return copyInitializationOfClass(valueCat, source, (ICPPClassType) uqTarget, udc == UDCMode.DEFER,
|
||||||
|
noNarrowing);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uqSource instanceof ICPPClassType) {
|
if (uqSource instanceof ICPPClassType) {
|
||||||
|
@ -329,7 +330,7 @@ public class Conversions {
|
||||||
return Cost.NO_CONVERSION;
|
return Cost.NO_CONVERSION;
|
||||||
|
|
||||||
return initializationByConversion(valueCat, source, (ICPPClassType) uqSource, target, udc == UDCMode.DEFER,
|
return initializationByConversion(valueCat, source, (ICPPClassType) uqSource, target, udc == UDCMode.DEFER,
|
||||||
false);
|
false, noNarrowing);
|
||||||
}
|
}
|
||||||
|
|
||||||
return checkStandardConversionSequence(uqSource, target);
|
return checkStandardConversionSequence(uqSource, target);
|
||||||
|
@ -352,7 +353,7 @@ public class Conversions {
|
||||||
Cost worstCost = new Cost(arg.getType(), target, Rank.IDENTITY);
|
Cost worstCost = new Cost(arg.getType(), target, Rank.IDENTITY);
|
||||||
for (ICPPEvaluation clause : arg.getClauses()) {
|
for (ICPPEvaluation clause : arg.getClauses()) {
|
||||||
Cost cost = checkImplicitConversionSequence(listType, clause.getType(), clause.getValueCategory(),
|
Cost cost = checkImplicitConversionSequence(listType, clause.getType(), clause.getValueCategory(),
|
||||||
UDCMode.ALLOWED, Context.ORDINARY);
|
UDCMode.ALLOWED, Context.ORDINARY, false);
|
||||||
if (!cost.converts())
|
if (!cost.converts())
|
||||||
return cost;
|
return cost;
|
||||||
if (cost.isNarrowingConversion()) {
|
if (cost.isNarrowingConversion()) {
|
||||||
|
@ -389,7 +390,7 @@ public class Conversions {
|
||||||
final ICPPEvaluation firstArg = args[0];
|
final ICPPEvaluation firstArg = args[0];
|
||||||
if (!firstArg.isInitializerList()) {
|
if (!firstArg.isInitializerList()) {
|
||||||
Cost cost = checkImplicitConversionSequence(target, firstArg.getType(), firstArg.getValueCategory(),
|
Cost cost = checkImplicitConversionSequence(target, firstArg.getType(), firstArg.getValueCategory(),
|
||||||
udc, Context.ORDINARY);
|
udc, Context.ORDINARY, false);
|
||||||
if (cost.isNarrowingConversion()) {
|
if (cost.isNarrowingConversion()) {
|
||||||
return Cost.NO_CONVERSION;
|
return Cost.NO_CONVERSION;
|
||||||
}
|
}
|
||||||
|
@ -614,24 +615,7 @@ public class Conversions {
|
||||||
data.fNoNarrowing = true;
|
data.fNoNarrowing = true;
|
||||||
|
|
||||||
// 13.3.3.1.4
|
// 13.3.3.1.4
|
||||||
ICPPConstructor[] filteredConstructors = constructors;
|
final IBinding result = CPPSemantics.resolveFunction(data, constructors, true, false);
|
||||||
if (expandedArgs.length == 1) {
|
|
||||||
filteredConstructors = new ICPPConstructor[constructors.length];
|
|
||||||
int j = 0;
|
|
||||||
for (ICPPConstructor ctor : constructors) {
|
|
||||||
if (ctor.getRequiredArgumentCount() < 2) {
|
|
||||||
IType[] ptypes = ctor.getType().getParameterTypes();
|
|
||||||
if (ptypes.length > 0) {
|
|
||||||
IType ptype = getNestedType(ptypes[0], TDEF | REF | CVTYPE);
|
|
||||||
if (!t.isSameType(ptype)) {
|
|
||||||
filteredConstructors[j++] = ctor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final IBinding result = CPPSemantics.resolveFunction(data, filteredConstructors, true, false);
|
|
||||||
final Cost c;
|
final Cost c;
|
||||||
if (result instanceof ICPPMethod) {
|
if (result instanceof ICPPMethod) {
|
||||||
if (!isDirect && ((ICPPMethod) result).isExplicit()) {
|
if (!isDirect && ((ICPPMethod) result).isExplicit()) {
|
||||||
|
@ -658,8 +642,8 @@ public class Conversions {
|
||||||
/**
|
/**
|
||||||
* 13.3.1.4 Copy-initialization of class by user-defined conversion [over.match.copy]
|
* 13.3.1.4 Copy-initialization of class by user-defined conversion [over.match.copy]
|
||||||
*/
|
*/
|
||||||
static final Cost copyInitializationOfClass(ValueCategory valueCat, IType source, ICPPClassType t, boolean deferUDC)
|
static final Cost copyInitializationOfClass(ValueCategory valueCat, IType source, ICPPClassType t, boolean deferUDC,
|
||||||
throws DOMException {
|
boolean noNarrowing) throws DOMException {
|
||||||
if (deferUDC) {
|
if (deferUDC) {
|
||||||
Cost c = new Cost(source, t, Rank.USER_DEFINED_CONVERSION);
|
Cost c = new Cost(source, t, Rank.USER_DEFINED_CONVERSION);
|
||||||
c.setDeferredUDC(DeferredUDC.COPY_INIT_OF_CLASS);
|
c.setDeferredUDC(DeferredUDC.COPY_INIT_OF_CLASS);
|
||||||
|
@ -698,8 +682,14 @@ public class Conversions {
|
||||||
if (ctor.getRequiredArgumentCount() > 1)
|
if (ctor.getRequiredArgumentCount() > 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
c1 = new FunctionCost(ctor, checkImplicitConversionSequence(ptype, source, valueCat,
|
Cost cost = checkImplicitConversionSequence(ptype, source, valueCat, UDCMode.FORBIDDEN,
|
||||||
UDCMode.FORBIDDEN, Context.ORDINARY));
|
Context.ORDINARY, noNarrowing);
|
||||||
|
|
||||||
|
if (noNarrowing && cost.isNarrowingConversion()) {
|
||||||
|
cost = Cost.NO_CONVERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
c1 = new FunctionCost(ctor, cost);
|
||||||
}
|
}
|
||||||
int cmp = c1.compareTo(null, cost1, 1);
|
int cmp = c1.compareTo(null, cost1, 1);
|
||||||
if (cmp <= 0) {
|
if (cmp <= 0) {
|
||||||
|
@ -761,7 +751,7 @@ public class Conversions {
|
||||||
* 13.3.1.5 Initialization by conversion function [over.match.conv]
|
* 13.3.1.5 Initialization by conversion function [over.match.conv]
|
||||||
*/
|
*/
|
||||||
static Cost initializationByConversion(ValueCategory valueCat, IType source, ICPPClassType uqSource, IType target,
|
static Cost initializationByConversion(ValueCategory valueCat, IType source, ICPPClassType uqSource, IType target,
|
||||||
boolean deferUDC, boolean allowExplicitConversion) throws DOMException {
|
boolean deferUDC, boolean allowExplicitConversion, boolean noNarrowing) throws DOMException {
|
||||||
if (deferUDC) {
|
if (deferUDC) {
|
||||||
Cost c = new Cost(source, target, Rank.USER_DEFINED_CONVERSION);
|
Cost c = new Cost(source, target, Rank.USER_DEFINED_CONVERSION);
|
||||||
c.setDeferredUDC(DeferredUDC.INIT_BY_CONVERSION);
|
c.setDeferredUDC(DeferredUDC.INIT_BY_CONVERSION);
|
||||||
|
@ -783,7 +773,7 @@ public class Conversions {
|
||||||
final IType returnType = functionType.getReturnType();
|
final IType returnType = functionType.getReturnType();
|
||||||
IType uqReturnType = getNestedType(returnType, TDEF | ALLCVQ);
|
IType uqReturnType = getNestedType(returnType, TDEF | ALLCVQ);
|
||||||
Cost c2 = checkImplicitConversionSequence(target, uqReturnType,
|
Cost c2 = checkImplicitConversionSequence(target, uqReturnType,
|
||||||
valueCategoryFromReturnType(uqReturnType), UDCMode.FORBIDDEN, Context.ORDINARY);
|
valueCategoryFromReturnType(uqReturnType), UDCMode.FORBIDDEN, Context.ORDINARY, noNarrowing);
|
||||||
if (c2.converts()) {
|
if (c2.converts()) {
|
||||||
if (isExplicitConversion && c2.getRank() != Rank.IDENTITY)
|
if (isExplicitConversion && c2.getRank() != Rank.IDENTITY)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -306,7 +306,7 @@ public class EvalConditional extends CPPDependentEvaluation {
|
||||||
if (vcat2.isGLValue()) {
|
if (vcat2.isGLValue()) {
|
||||||
IType target = new CPPReferenceType(t2, vcat2 == XVALUE);
|
IType target = new CPPReferenceType(t2, vcat2 == XVALUE);
|
||||||
Cost c = Conversions.checkImplicitConversionSequence(target, t1, vcat1, UDCMode.ALLOWED,
|
Cost c = Conversions.checkImplicitConversionSequence(target, t1, vcat1, UDCMode.ALLOWED,
|
||||||
Context.REQUIRE_DIRECT_BINDING);
|
Context.REQUIRE_DIRECT_BINDING, false);
|
||||||
if (c.converts()) {
|
if (c.converts()) {
|
||||||
fType = t2;
|
fType = t2;
|
||||||
fValueCategory = vcat2;
|
fValueCategory = vcat2;
|
||||||
|
@ -333,7 +333,8 @@ public class EvalConditional extends CPPDependentEvaluation {
|
||||||
if (vcat2 != PRVALUE) {
|
if (vcat2 != PRVALUE) {
|
||||||
t2 = Conversions.lvalue_to_rvalue(t2, false);
|
t2 = Conversions.lvalue_to_rvalue(t2, false);
|
||||||
}
|
}
|
||||||
Cost c = Conversions.checkImplicitConversionSequence(t2, t1, vcat1, UDCMode.ALLOWED, Context.ORDINARY);
|
Cost c = Conversions.checkImplicitConversionSequence(t2, t1, vcat1, UDCMode.ALLOWED, Context.ORDINARY,
|
||||||
|
false);
|
||||||
if (c.converts()) {
|
if (c.converts()) {
|
||||||
fType = t2;
|
fType = t2;
|
||||||
fValueCategory = PRVALUE;
|
fValueCategory = PRVALUE;
|
||||||
|
|
|
@ -35,7 +35,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
||||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||||
|
@ -234,7 +233,9 @@ public class EvalTypeId extends CPPDependentEvaluation {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean computeIsConstantExpression() {
|
private boolean computeIsConstantExpression() {
|
||||||
if (getConstructor() == null && fArguments.length == 1) {
|
ICPPFunction constructor = getConstructor();
|
||||||
|
|
||||||
|
if (constructor == null && fArguments.length == 1) {
|
||||||
// maybe EvalTypeID represents a conversion
|
// maybe EvalTypeID represents a conversion
|
||||||
ICPPEvaluation conversionEval = maybeApplyConversion(fArguments[0], fInputType, false, false);
|
ICPPEvaluation conversionEval = maybeApplyConversion(fArguments[0], fInputType, false, false);
|
||||||
if (isEquivalentTo(conversionEval)) {
|
if (isEquivalentTo(conversionEval)) {
|
||||||
|
@ -244,9 +245,13 @@ public class EvalTypeId extends CPPDependentEvaluation {
|
||||||
|
|
||||||
if (!conversionEval.isConstantExpression())
|
if (!conversionEval.isConstantExpression())
|
||||||
return false;
|
return false;
|
||||||
|
} else if (constructor == AGGREGATE_INITIALIZATION) {
|
||||||
|
// A literal type is one for which it might be possible to create an object within a constant expression.
|
||||||
|
// See also CPPImplicitConstructor.isConstExpr()
|
||||||
|
return getInputType() instanceof ICPPClassType classType && TypeTraits.isLiteralClass(classType);
|
||||||
}
|
}
|
||||||
return !fRepresentsNewExpression && areAllConstantExpressions(fArguments)
|
|
||||||
&& isNullOrConstexprFunc(getConstructor());
|
return !fRepresentsNewExpression && areAllConstantExpressions(fArguments) && isNullOrConstexprFunc(constructor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -285,38 +290,35 @@ public class EvalTypeId extends CPPDependentEvaluation {
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
IType simplifiedType = SemanticUtil.getNestedType(fInputType, TDEF | CVTYPE);
|
IType simplifiedType = SemanticUtil.getNestedType(fInputType, TDEF | CVTYPE);
|
||||||
if (simplifiedType instanceof ICPPClassType) {
|
if (simplifiedType instanceof ICPPClassType classType) {
|
||||||
ICPPClassType classType = (ICPPClassType) simplifiedType;
|
if (fUsesBracedInitList) {
|
||||||
ICPPEvaluation[] arguments = fArguments;
|
// (dcl.init.list)
|
||||||
ICPPConstructor[] constructors = classType.getConstructors();
|
EvalInitList evalInitList = new EvalInitList(fArguments, getTemplateDefinition());
|
||||||
if (fUsesBracedInitList && arguments.length > 0) {
|
|
||||||
// List-initialization of a class (dcl.init.list-3).
|
try {
|
||||||
// e.g. A{1,2}
|
// List-initialization of a class (dcl.init.list-3).
|
||||||
ICPPConstructor[] ctors = getInitializerListConstructors(constructors);
|
// e.g. A{1,2}
|
||||||
if (ctors.length != 0) {
|
IBinding binding = CPPSemantics.findConstructorForDirectListInitialization(classType, evalInitList,
|
||||||
constructors = ctors;
|
null);
|
||||||
arguments = new EvalInitList[] { new EvalInitList(arguments, getTemplateDefinition()) };
|
if (binding instanceof ICPPConstructor constructor) {
|
||||||
}
|
return constructor;
|
||||||
} else if (arguments.length == 1 && arguments[0] instanceof EvalInitList && !fUsesBracedInitList) {
|
} else if (binding instanceof IProblemBinding) {
|
||||||
// List-initialization of a class (dcl.init.list-3).
|
return new CPPFunction.CPPFunctionProblem(null, ISemanticProblem.BINDING_NOT_FOUND,
|
||||||
// e.g. A({1,2})
|
classType.getNameCharArray());
|
||||||
if (TypeTraits.isAggregateClass(classType)) {
|
} else if (TypeTraits.isAggregateClass(classType)) {
|
||||||
// Pretend that aggregate initialization is calling the default constructor.
|
// If Conversions.listInitializationSequence() did not returned problem binding,
|
||||||
return findDefaultConstructor(classType, constructors);
|
// this is a list-initialization of aggregate class, and there is no constructor.
|
||||||
}
|
return AGGREGATE_INITIALIZATION;
|
||||||
if (((EvalInitList) arguments[0]).getClauses().length == 0) {
|
}
|
||||||
ICPPMethod ctor = findDefaultConstructor(classType, constructors);
|
} catch (DOMException e) {
|
||||||
if (ctor != null)
|
CCorePlugin.log(e);
|
||||||
return ctor;
|
|
||||||
}
|
|
||||||
ICPPConstructor[] ctors = getInitializerListConstructors(constructors);
|
|
||||||
if (ctors.length != 0) {
|
|
||||||
constructors = ctors;
|
|
||||||
} else {
|
|
||||||
arguments = ((EvalInitList) arguments[0]).getClauses();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ICPPEvaluation[] arguments = fArguments;
|
||||||
|
ICPPConstructor[] constructors = classType.getConstructors();
|
||||||
LookupData data = new LookupData(classType.getNameCharArray(), null, CPPSemantics.getCurrentLookupPoint());
|
LookupData data = new LookupData(classType.getNameCharArray(), null, CPPSemantics.getCurrentLookupPoint());
|
||||||
data.foundItems = constructors;
|
data.foundItems = constructors;
|
||||||
data.setFunctionArguments(false, arguments);
|
data.setFunctionArguments(false, arguments);
|
||||||
|
|
|
@ -98,7 +98,7 @@ class FunctionCost {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean performUDC() throws DOMException {
|
public boolean performUDC(boolean noNarrowing) throws DOMException {
|
||||||
for (int i = 0; i < fCosts.length; i++) {
|
for (int i = 0; i < fCosts.length; i++) {
|
||||||
Cost cost = fCosts[i];
|
Cost cost = fCosts[i];
|
||||||
Cost udcCost = null;
|
Cost udcCost = null;
|
||||||
|
@ -107,12 +107,12 @@ class FunctionCost {
|
||||||
continue;
|
continue;
|
||||||
case COPY_INIT_OF_CLASS:
|
case COPY_INIT_OF_CLASS:
|
||||||
udcCost = Conversions.copyInitializationOfClass(fValueCategories[i], cost.source,
|
udcCost = Conversions.copyInitializationOfClass(fValueCategories[i], cost.source,
|
||||||
(ICPPClassType) cost.target, false);
|
(ICPPClassType) cost.target, false, noNarrowing);
|
||||||
break;
|
break;
|
||||||
case INIT_BY_CONVERSION:
|
case INIT_BY_CONVERSION:
|
||||||
IType uqSource = getNestedType(cost.source, TDEF | REF | CVTYPE);
|
IType uqSource = getNestedType(cost.source, TDEF | REF | CVTYPE);
|
||||||
udcCost = Conversions.initializationByConversion(fValueCategories[i], cost.source,
|
udcCost = Conversions.initializationByConversion(fValueCategories[i], cost.source,
|
||||||
(ICPPClassType) uqSource, cost.target, false, allowsContextualBooleanConversion());
|
(ICPPClassType) uqSource, cost.target, false, allowsContextualBooleanConversion(), noNarrowing);
|
||||||
break;
|
break;
|
||||||
case LIST_INIT_OF_CLASS:
|
case LIST_INIT_OF_CLASS:
|
||||||
udcCost = Conversions.listInitializationOfClass(((InitializerListType) cost.source).getEvaluation(),
|
udcCost = Conversions.listInitializationOfClass(((InitializerListType) cost.source).getEvaluation(),
|
||||||
|
@ -126,6 +126,7 @@ class FunctionCost {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fCosts[i] = udcCost;
|
fCosts[i] = udcCost;
|
||||||
|
|
||||||
if (!udcCost.converts()) {
|
if (!udcCost.converts()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
||||||
Bundle-ManifestVersion: 2
|
Bundle-ManifestVersion: 2
|
||||||
Bundle-Name: %pluginName
|
Bundle-Name: %pluginName
|
||||||
Bundle-SymbolicName: org.eclipse.cdt.ui; singleton:=true
|
Bundle-SymbolicName: org.eclipse.cdt.ui; singleton:=true
|
||||||
Bundle-Version: 8.1.200.qualifier
|
Bundle-Version: 8.1.300.qualifier
|
||||||
Bundle-Activator: org.eclipse.cdt.ui.CUIPlugin
|
Bundle-Activator: org.eclipse.cdt.ui.CUIPlugin
|
||||||
Bundle-Vendor: %providerName
|
Bundle-Vendor: %providerName
|
||||||
Bundle-Localization: plugin
|
Bundle-Localization: plugin
|
||||||
|
@ -104,7 +104,7 @@ Export-Package: org.eclipse.cdt.internal.corext;x-internal:=true,
|
||||||
org.eclipse.cdt.ui.wizards.conversion,
|
org.eclipse.cdt.ui.wizards.conversion,
|
||||||
org.eclipse.cdt.utils.ui.controls
|
org.eclipse.cdt.utils.ui.controls
|
||||||
Import-Package: org.apache.commons.io;version="[2.8.0,3.0.0)"
|
Import-Package: org.apache.commons.io;version="[2.8.0,3.0.0)"
|
||||||
Require-Bundle: org.eclipse.cdt.core;bundle-version="[8.3.0,9.0.0)",
|
Require-Bundle: org.eclipse.cdt.core;bundle-version="[8.4.0,9.0.0)",
|
||||||
org.eclipse.compare;bundle-version="[3.8.500,4.0.0)",
|
org.eclipse.compare;bundle-version="[3.8.500,4.0.0)",
|
||||||
org.eclipse.core.expressions;bundle-version="[3.8.200,4.0.0)",
|
org.eclipse.core.expressions;bundle-version="[3.8.200,4.0.0)",
|
||||||
org.eclipse.core.filesystem;bundle-version="[1.9.500,2.0.0)",
|
org.eclipse.core.filesystem;bundle-version="[1.9.500,2.0.0)",
|
||||||
|
|
|
@ -180,7 +180,7 @@ public class ParameterGuesser {
|
||||||
private boolean isImplicitlyConvertible(IType orginType, IType candidateType) {
|
private boolean isImplicitlyConvertible(IType orginType, IType candidateType) {
|
||||||
try {
|
try {
|
||||||
Cost cost = Conversions.checkImplicitConversionSequence(orginType, candidateType, ValueCategory.LVALUE,
|
Cost cost = Conversions.checkImplicitConversionSequence(orginType, candidateType, ValueCategory.LVALUE,
|
||||||
UDCMode.ALLOWED, Context.ORDINARY);
|
UDCMode.ALLOWED, Context.ORDINARY, false);
|
||||||
if (cost.converts())
|
if (cost.converts())
|
||||||
return true;
|
return true;
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue