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:
parent
c5ecc6fe90
commit
dbd35a059a
15 changed files with 183 additions and 69 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue