1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 22:52:11 +02:00

Bug 486149 - Name resolution problem with dependent conversion operator

Change-Id: I696b91f7703451f9ada8dbd60987c5f19d82ad27
This commit is contained in:
Sergey Prigogin 2016-01-21 17:44:46 -08:00
parent c5ecc6fe90
commit dbd35a059a
15 changed files with 183 additions and 69 deletions

View file

@ -8736,6 +8736,29 @@ public class AST2TemplateTests extends AST2TestBase {
parseAndCheckBindings();
}
// template<bool, typename T = void>
// struct enable_if {};
//
// template<typename T>
// struct enable_if<true, T> {
// typedef T type;
// };
//
// template<typename>
// struct A {
// constexpr operator int() const { return false; }
// };
//
// template <class T>
// typename enable_if<!A<T>()>::type waldo(T a);
//
// void test() {
// waldo(0);
// }
public void testDependentConversionOperator_486149() throws Exception {
parseAndCheckBindings();
}
// template <typename>
// struct C {
// friend bool operator==(C, C);

View file

@ -473,7 +473,7 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider {
IBinding b = fCpp ?
new CPPImplicitFunction(toCharArray(name), fScope, (ICPPFunctionType) ft,
(ICPPParameter[]) theParms, varargs) :
(ICPPParameter[]) theParms, false, varargs) :
new CImplicitFunction(toCharArray(name), fScope, ft, theParms, varargs);
fBindingList.add(b);
}

View file

@ -91,12 +91,12 @@ public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPAST
ICPPFunctionType newFunctionType = new CPPFunctionType(cpp_void_p, newParms);
ICPPParameter[] newTheParms = new ICPPParameter[1];
newTheParms[0] = new CPPBuiltinParameter(newParms[0]);
temp = new CPPImplicitFunction(OverloadableOperator.NEW.toCharArray(), theScope, newFunctionType, newTheParms, false);
temp = new CPPImplicitFunction(OverloadableOperator.NEW.toCharArray(), theScope, newFunctionType, newTheParms, false, false);
theScope.addBinding(temp);
// void* operator new[](std::size_t);
temp = null;
temp = new CPPImplicitFunction(OverloadableOperator.NEW_ARRAY.toCharArray(), theScope, newFunctionType, newTheParms, false);
temp = new CPPImplicitFunction(OverloadableOperator.NEW_ARRAY.toCharArray(), theScope, newFunctionType, newTheParms, false, false);
theScope.addBinding(temp);
// void operator delete(void*);
@ -106,12 +106,14 @@ public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPAST
ICPPFunctionType deleteFunctionType = new CPPFunctionType(cpp_void, deleteParms);
ICPPParameter[] deleteTheParms = new ICPPParameter[1];
deleteTheParms[0] = new CPPBuiltinParameter(deleteParms[0]);
temp = new CPPImplicitFunction(OverloadableOperator.DELETE.toCharArray(), theScope, deleteFunctionType, deleteTheParms, false);
temp = new CPPImplicitFunction(OverloadableOperator.DELETE.toCharArray(), theScope,
deleteFunctionType, deleteTheParms, false, false);
theScope.addBinding(temp);
// void operator delete[](void*);
temp = null;
temp = new CPPImplicitFunction(OverloadableOperator.DELETE_ARRAY.toCharArray(), theScope, deleteFunctionType, deleteTheParms, false);
temp = new CPPImplicitFunction(OverloadableOperator.DELETE_ARRAY.toCharArray(), theScope,
deleteFunctionType, deleteTheParms, false, false);
theScope.addBinding(temp);
}

View file

@ -113,14 +113,15 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
if (!ia.hasUserDeclaredConstructor()) {
// Default constructor: A(void)
ICPPMethod m = new CPPImplicitConstructor(this, className, EMPTY_CPPPARAMETER_ARRAY);
boolean isConstexpr = ia.isDefaultConstructorConstexpr();
ICPPMethod m = new CPPImplicitConstructor(this, className, EMPTY_CPPPARAMETER_ARRAY, isConstexpr);
implicits[i++] = m;
addBinding(m);
}
if (!ia.hasUserDeclaredCopyConstructor()) {
// Copy constructor: A(const A &)
ICPPMethod m = new CPPImplicitConstructor(this, className, params);
ICPPMethod m = new CPPImplicitConstructor(this, className, params, false);
implicits[i++] = m;
addBinding(m);
}
@ -129,7 +130,8 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
// Copy assignment operator: A& operator = (const A &)
IType refType = new CPPReferenceType(classType, false);
ICPPFunctionType ft= CPPVisitor.createImplicitFunctionType(refType, params, false, false);
ICPPMethod m = new CPPImplicitMethod(this, OverloadableOperator.ASSIGN.toCharArray(), ft, params);
ICPPMethod m =
new CPPImplicitMethod(this, OverloadableOperator.ASSIGN.toCharArray(), ft, params, false);
implicits[i++] = m;
addBinding(m);
}
@ -137,7 +139,8 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
if (!ia.hasUserDeclaredDestructor()) {
// Destructor: ~A()
char[] dtorName = CharArrayUtils.concat("~".toCharArray(), className); //$NON-NLS-1$
ICPPMethod m = new CPPImplicitMethod(this, dtorName, DESTRUCTOR_FUNCTION_TYPE, EMPTY_CPPPARAMETER_ARRAY);
ICPPMethod m = new CPPImplicitMethod(this, dtorName, DESTRUCTOR_FUNCTION_TYPE, EMPTY_CPPPARAMETER_ARRAY,
false);
implicits[i++] = m;
addBinding(m);
}

View file

@ -79,25 +79,26 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
ICPPMethod[] result= new ICPPMethod[needConversionOperator ? 6 : 5];
// Deleted default constructor: A()
CPPImplicitConstructor ctor= new CPPImplicitConstructor(scope, CharArrayUtils.EMPTY, ICPPParameter.EMPTY_CPPPARAMETER_ARRAY);
CPPImplicitConstructor ctor=
new CPPImplicitConstructor(scope, CharArrayUtils.EMPTY, ICPPParameter.EMPTY_CPPPARAMETER_ARRAY, false);
ctor.setDeleted(true);
result[0]= ctor;
// Copy constructor: A(const A &)
IType pType = new CPPReferenceType(SemanticUtil.constQualify(this), false);
ICPPParameter[] ps = new ICPPParameter[] { new CPPParameter(pType, 0) };
ctor = new CPPImplicitConstructor(scope, CharArrayUtils.EMPTY, ps);
ctor = new CPPImplicitConstructor(scope, CharArrayUtils.EMPTY, ps, false);
result[1]= ctor;
// Deleted copy assignment operator: A& operator = (const A &)
IType refType = new CPPReferenceType(this, false);
ICPPFunctionType ft= CPPVisitor.createImplicitFunctionType(refType, ps, false, false);
ICPPMethod m = new CPPImplicitMethod(scope, OverloadableOperator.ASSIGN.toCharArray(), ft, ps);
ICPPMethod m = new CPPImplicitMethod(scope, OverloadableOperator.ASSIGN.toCharArray(), ft, ps, false);
result[2]= m;
// Destructor: ~A()
ft= CPPVisitor.createImplicitFunctionType(UNSPECIFIED_TYPE, ICPPParameter.EMPTY_CPPPARAMETER_ARRAY, false, false);
m = new CPPImplicitMethod(scope, new char[] {'~'}, ft, ICPPParameter.EMPTY_CPPPARAMETER_ARRAY);
m = new CPPImplicitMethod(scope, new char[] {'~'}, ft, ICPPParameter.EMPTY_CPPPARAMETER_ARRAY, false);
result[3]= m;
// Function call operator
@ -109,7 +110,7 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
for (int i = 0; i < params.length; i++) {
params[i]= new CPPParameter(parameterTypes[i], i);
}
m= new CPPImplicitMethod(scope, OverloadableOperator.PAREN.toCharArray(), ft, params) {
m= new CPPImplicitMethod(scope, OverloadableOperator.PAREN.toCharArray(), ft, params, false) {
@Override
public boolean isImplicit() { return false; }
};
@ -119,7 +120,7 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
if (needConversionOperator) {
final CPPFunctionType conversionTarget = new CPPFunctionType(returnType, parameterTypes);
ft= new CPPFunctionType(conversionTarget, IType.EMPTY_TYPE_ARRAY, true, false, false, false, false);
m= new CPPImplicitMethod(scope, CPPASTConversionName.createName(conversionTarget, null), ft, params);
m= new CPPImplicitMethod(scope, CPPASTConversionName.createName(conversionTarget, null), ft, params, false);
result[5]= m;
}
return result;

View file

@ -8,6 +8,7 @@
* Contributors:
* Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -25,8 +26,8 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
*/
public class CPPImplicitConstructor extends CPPImplicitMethod implements ICPPConstructor {
public CPPImplicitConstructor(ICPPClassScope scope, char[] name, ICPPParameter[] params) {
super(scope, name, createFunctionType(params), params);
public CPPImplicitConstructor(ICPPClassScope scope, char[] name, ICPPParameter[] params, boolean isConstexpr) {
super(scope, name, createFunctionType(params), params, isConstexpr);
}
private static ICPPFunctionType createFunctionType(IParameter[] params) {

View file

@ -8,6 +8,7 @@
* Contributors:
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -26,18 +27,20 @@ public class CPPImplicitFunction extends CPPFunction {
private ICPPParameter[] params;
private IScope scope;
private ICPPFunctionType functionType;
private final boolean isConstexpr;
private final boolean takesVarArgs;
private boolean isDeleted;
private final char[] name;
public CPPImplicitFunction(char[] name, IScope scope, ICPPFunctionType type,
ICPPParameter[] params, boolean takesVarArgs) {
ICPPParameter[] params, boolean isConstexpr, boolean takesVarArgs) {
super(null);
this.name= name;
this.scope= scope;
this.functionType= type;
this.params= params;
this.takesVarArgs= takesVarArgs;
this.isConstexpr = isConstexpr;
}
@Override
@ -49,7 +52,7 @@ public class CPPImplicitFunction extends CPPFunction {
public ICPPFunctionType getType() {
return functionType;
}
@Override
public String getName() {
return String.valueOf(name);
@ -64,27 +67,32 @@ public class CPPImplicitFunction extends CPPFunction {
public IScope getScope() {
return scope;
}
@Override
public IScope getFunctionScope() {
return null;
}
@Override
public boolean isConstexpr() {
return isConstexpr;
}
@Override
public boolean takesVarArgs() {
return takesVarArgs;
}
@Override
public boolean isDeleted() {
return isDeleted;
}
@Override
public IBinding getOwner() {
return null;
}
public void setDeleted(boolean val) {
isDeleted= val;
}

View file

@ -9,6 +9,7 @@
* Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
* Thomas Corbat (IFS)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -42,8 +43,9 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
*/
public class CPPImplicitMethod extends CPPImplicitFunction implements ICPPMethod {
public CPPImplicitMethod(ICPPClassScope scope, char[] name, ICPPFunctionType type, ICPPParameter[] params) {
super(name, scope, type, params, false);
public CPPImplicitMethod(ICPPClassScope scope, char[] name, ICPPFunctionType type, ICPPParameter[] params,
boolean isConstexpr) {
super(name, scope, type, params, isConstexpr, false);
}
@Override

View file

@ -28,7 +28,7 @@ public class CPPInheritedConstructor extends CPPImplicitMethod implements ICPPCo
public CPPInheritedConstructor(ICPPClassScope scope, char[] name, ICPPConstructor prototype,
ICPPParameter[] params) {
super(scope, name, createFunctionType(params), params);
super(scope, name, createFunctionType(params), params, false);
this.prototype = prototype;
}

View file

@ -23,15 +23,19 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
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.ICPPReferenceType;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
@ -48,14 +52,17 @@ final class ImplicitsAnalysis {
private static final IASTParameterDeclaration[][] EMPTY_ARRAY_OF_PARAMETER_ARRAYS = {};
private final ICPPClassType classType;
private final ICPPASTCompositeTypeSpecifier compositeTypeSpecifier;
private boolean hasConstructor;
private boolean hasCopyConstructor;
private boolean hasCopyAssignmentOperator;
private boolean hasDestructor;
private IASTParameterDeclaration[][] parametersOfNontrivialConstructors = EMPTY_ARRAY_OF_PARAMETER_ARRAYS;
private boolean hasNonStaticFields;
ImplicitsAnalysis(ICPPASTCompositeTypeSpecifier compositeTypeSpecifier, ICPPClassType classType) {
this.classType= classType;
this.compositeTypeSpecifier = compositeTypeSpecifier;
analyzeMembers(compositeTypeSpecifier);
}
@ -124,43 +131,45 @@ final class ImplicitsAnalysis {
spec = ((IASTFunctionDefinition) member).getDeclSpecifier();
}
if (!(dcltor instanceof ICPPASTFunctionDeclarator))
continue;
IASTName memberName = ASTQueries.findInnermostDeclarator(dcltor).getName();
char[] declName = memberName.getLookupKey();
if (spec instanceof IASTSimpleDeclSpecifier &&
((IASTSimpleDeclSpecifier) spec).getType() == IASTSimpleDeclSpecifier.t_unspecified) {
if (CharArrayUtils.equals(declName, name)) {
hasConstructor = true;
if (dcltor instanceof ICPPASTFunctionDeclarator) {
IASTName memberName = ASTQueries.findInnermostDeclarator(dcltor).getName();
char[] declName = memberName.getLookupKey();
if (spec instanceof IASTSimpleDeclSpecifier &&
((IASTSimpleDeclSpecifier) spec).getType() == IASTSimpleDeclSpecifier.t_unspecified) {
if (CharArrayUtils.equals(declName, name)) {
hasConstructor = true;
IASTParameterDeclaration[] params = ((ICPPASTFunctionDeclarator) dcltor).getParameters();
if (params.length != 0) {
if (hasTypeReferenceToClassType(params[0])) {
if (parametersHaveInitializers(params, 1)) {
hasCopyConstructor = true;
}
if (params.length > 1) {
parametersOfNontrivialConstructors =
appendAt(parametersOfNontrivialConstructors, numNontrivialConstructors++, params);
}
} else {
parametersOfNontrivialConstructors =
appendAt(parametersOfNontrivialConstructors, numNontrivialConstructors++, params);
}
}
} if (declName.length != 0 && declName[0] == '~' &&
CharArrayUtils.equals(declName, 1, name.length, name)) {
hasDestructor = true;
}
} if (CharArrayUtils.equals(declName, OverloadableOperator.ASSIGN.toCharArray())) {
IASTParameterDeclaration[] params = ((ICPPASTFunctionDeclarator) dcltor).getParameters();
if (params.length != 0) {
if (hasTypeReferenceToClassType(params[0])) {
if (parametersHaveInitializers(params, 1)) {
hasCopyConstructor = true;
}
if (params.length > 1) {
parametersOfNontrivialConstructors =
appendAt(parametersOfNontrivialConstructors, numNontrivialConstructors++, params);
}
} else {
parametersOfNontrivialConstructors =
appendAt(parametersOfNontrivialConstructors, numNontrivialConstructors++, params);
}
}
} if (declName.length != 0 && declName[0] == '~' &&
CharArrayUtils.equals(declName, 1, name.length, name)) {
hasDestructor = true;
if (params.length == 1 && hasTypeReferenceToClassType(params[0]))
hasCopyAssignmentOperator = true;
}
} if (CharArrayUtils.equals(declName, OverloadableOperator.ASSIGN.toCharArray())) {
IASTParameterDeclaration[] params = ((ICPPASTFunctionDeclarator) dcltor).getParameters();
if (params.length == 1 && hasTypeReferenceToClassType(params[0]))
hasCopyAssignmentOperator = true;
}
if (hasCopyConstructor && hasDestructor && hasCopyAssignmentOperator && baseSpecifiers.length == 0) {
break; // Nothing else to look for.
if (hasCopyConstructor && hasDestructor && hasCopyAssignmentOperator && baseSpecifiers.length == 0) {
break; // Nothing else to look for.
}
} else if (dcltor instanceof ICPPASTFieldDeclarator &&
spec != null && spec.getStorageClass() != IASTDeclSpecifier.sc_static) {
hasNonStaticFields = true;
}
}
@ -192,4 +201,38 @@ final class ImplicitsAnalysis {
}
return true;
}
public boolean isDefaultConstructorConstexpr() {
// The following condition is stronger than necessary. It is sufficient if the class doesn't contain
// non-static fields that don't have constexpr default constructors.
// TODO(sprigogin): Relax the condition in accordance with [dcl.constexpr] 7.1.5-4.
if (hasNonStaticFields)
return false;
ICPPBase[] bases = ClassTypeHelper.getBases(classType, compositeTypeSpecifier);
for (ICPPBase base : bases) {
if (base.isVirtual())
return true;
}
ICPPClassType[] baseClasses = ClassTypeHelper.getAllBases(classType, compositeTypeSpecifier);
for (ICPPClassType baseClass : baseClasses) {
ICPPConstructor ctor = getDefaultConstructor(baseClass, compositeTypeSpecifier);
if (ctor == null || !ctor.isConstexpr()) {
return false;
}
}
return true;
}
/**
* Returns a user-defined or implicit default constructor for the given class.
*/
private static ICPPConstructor getDefaultConstructor(ICPPClassType classType, IASTNode point) {
for (ICPPConstructor ctor : ClassTypeHelper.getConstructors(classType, point)) {
if (ClassTypeHelper.getMethodKind(classType, ctor) == ClassTypeHelper.MethodKind.DEFAULT_CTOR)
return ctor;
}
return null;
}
}

View file

@ -566,7 +566,7 @@ class BuiltinOperators {
if (fResult == null) {
fResult= new ArrayList<>();
}
fResult.add(new CPPImplicitFunction(fOperator.toCharArray(), fFileScope, functionType, parameter, false));
fResult.add(new CPPImplicitFunction(fOperator.toCharArray(), fFileScope, functionType, parameter, true, false));
}
}

View file

@ -70,7 +70,7 @@ public abstract class CPPDependentEvaluation extends CPPEvaluation {
/**
* If the given node is contained in some template declaration,
* return the binding for that template. Otherwise return null.
* returns the binding for that template. Otherwise returns null.
*/
protected static IBinding findEnclosingTemplate(IASTNode node) {
while (node != null) {

View file

@ -3794,7 +3794,7 @@ public class CPPSemantics {
theParms[i]= new CPPBuiltinParameter(t);
}
ICPPFunctionType functionType = new CPPFunctionType(returnType, parms);
return new CPPImplicitFunction(CALL_FUNCTION, scope, functionType, theParms, false);
return new CPPImplicitFunction(CALL_FUNCTION, scope, functionType, theParms, false, false);
}
static boolean isUserDefined(IType type) {

View file

@ -135,6 +135,8 @@ public class EvalTypeId extends CPPDependentEvaluation {
@Override
public boolean isValueDependent() {
if (CPPTemplates.isDependentType(fInputType))
return true;
for (ICPPEvaluation arg : fArguments) {
if (arg.isValueDependent())
return true;

View file

@ -37,6 +37,7 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTNode;
@ -46,7 +47,9 @@ import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
@ -61,6 +64,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArithmeticConversion;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClosureType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
@ -276,9 +280,34 @@ public class EvalUnary extends CPPDependentEvaluation {
if (isValueDependent())
return Value.create(this);
if (getOverload(point) != null) {
// TODO(sprigogin): Simulate execution of a function call.
return Value.create(this);
ICPPEvaluation arg = fArgument;
ICPPFunction overload = getOverload(point);
if (overload != null) {
ICPPFunctionType functionType = overload.getType();
IType targetType = functionType.getParameterTypes()[0];
ValueCategory valueCategory = fArgument.getValueCategory(point);
IType type = fArgument.getType(point);
ICPPFunction conversion = null;
try {
Cost cost = Conversions.initializationByConversion(valueCategory, type, (ICPPClassType) type, targetType, false, point);
conversion = cost.getUserDefinedConversion();
} catch (DOMException e) {
CCorePlugin.log(e);
}
if (conversion != null) {
if (!conversion.isConstexpr())
return Value.ERROR;
ICPPEvaluation eval = new EvalBinding(conversion, null, (IBinding) null);
arg = new EvalFunctionCall(new ICPPEvaluation[] {eval, arg}, (IBinding) null);
}
if (!(overload instanceof CPPImplicitFunction)) {
if (!overload.isConstexpr())
return Value.ERROR;
ICPPEvaluation eval = new EvalBinding(overload, null, (IBinding) null);
arg = new EvalFunctionCall(new ICPPEvaluation[] {eval, arg}, (IBinding) null);
return arg.getValue(point);
}
}
switch (fOperator) {
@ -302,7 +331,7 @@ public class EvalUnary extends CPPDependentEvaluation {
return Value.UNKNOWN; // TODO(sprigogin): Implement
}
IValue val = fArgument.getValue(point);
IValue val = arg.getValue(point);
if (val == null)
return Value.UNKNOWN;