mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +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();
|
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>
|
// template <typename>
|
||||||
// struct C {
|
// struct C {
|
||||||
// friend bool operator==(C, C);
|
// friend bool operator==(C, C);
|
||||||
|
|
|
@ -473,7 +473,7 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider {
|
||||||
|
|
||||||
IBinding b = fCpp ?
|
IBinding b = fCpp ?
|
||||||
new CPPImplicitFunction(toCharArray(name), fScope, (ICPPFunctionType) ft,
|
new CPPImplicitFunction(toCharArray(name), fScope, (ICPPFunctionType) ft,
|
||||||
(ICPPParameter[]) theParms, varargs) :
|
(ICPPParameter[]) theParms, false, varargs) :
|
||||||
new CImplicitFunction(toCharArray(name), fScope, ft, theParms, varargs);
|
new CImplicitFunction(toCharArray(name), fScope, ft, theParms, varargs);
|
||||||
fBindingList.add(b);
|
fBindingList.add(b);
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,12 +91,12 @@ public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPAST
|
||||||
ICPPFunctionType newFunctionType = new CPPFunctionType(cpp_void_p, newParms);
|
ICPPFunctionType newFunctionType = new CPPFunctionType(cpp_void_p, newParms);
|
||||||
ICPPParameter[] newTheParms = new ICPPParameter[1];
|
ICPPParameter[] newTheParms = new ICPPParameter[1];
|
||||||
newTheParms[0] = new CPPBuiltinParameter(newParms[0]);
|
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);
|
theScope.addBinding(temp);
|
||||||
|
|
||||||
// void* operator new[](std::size_t);
|
// void* operator new[](std::size_t);
|
||||||
temp = null;
|
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);
|
theScope.addBinding(temp);
|
||||||
|
|
||||||
// void operator delete(void*);
|
// void operator delete(void*);
|
||||||
|
@ -106,12 +106,14 @@ public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPAST
|
||||||
ICPPFunctionType deleteFunctionType = new CPPFunctionType(cpp_void, deleteParms);
|
ICPPFunctionType deleteFunctionType = new CPPFunctionType(cpp_void, deleteParms);
|
||||||
ICPPParameter[] deleteTheParms = new ICPPParameter[1];
|
ICPPParameter[] deleteTheParms = new ICPPParameter[1];
|
||||||
deleteTheParms[0] = new CPPBuiltinParameter(deleteParms[0]);
|
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);
|
theScope.addBinding(temp);
|
||||||
|
|
||||||
// void operator delete[](void*);
|
// void operator delete[](void*);
|
||||||
temp = null;
|
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);
|
theScope.addBinding(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,14 +113,15 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
||||||
|
|
||||||
if (!ia.hasUserDeclaredConstructor()) {
|
if (!ia.hasUserDeclaredConstructor()) {
|
||||||
// Default constructor: A(void)
|
// 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;
|
implicits[i++] = m;
|
||||||
addBinding(m);
|
addBinding(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ia.hasUserDeclaredCopyConstructor()) {
|
if (!ia.hasUserDeclaredCopyConstructor()) {
|
||||||
// Copy constructor: A(const A &)
|
// Copy constructor: A(const A &)
|
||||||
ICPPMethod m = new CPPImplicitConstructor(this, className, params);
|
ICPPMethod m = new CPPImplicitConstructor(this, className, params, false);
|
||||||
implicits[i++] = m;
|
implicits[i++] = m;
|
||||||
addBinding(m);
|
addBinding(m);
|
||||||
}
|
}
|
||||||
|
@ -129,7 +130,8 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
||||||
// Copy assignment operator: A& operator = (const A &)
|
// Copy assignment operator: A& operator = (const A &)
|
||||||
IType refType = new CPPReferenceType(classType, false);
|
IType refType = new CPPReferenceType(classType, false);
|
||||||
ICPPFunctionType ft= CPPVisitor.createImplicitFunctionType(refType, params, false, 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;
|
implicits[i++] = m;
|
||||||
addBinding(m);
|
addBinding(m);
|
||||||
}
|
}
|
||||||
|
@ -137,7 +139,8 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
||||||
if (!ia.hasUserDeclaredDestructor()) {
|
if (!ia.hasUserDeclaredDestructor()) {
|
||||||
// Destructor: ~A()
|
// Destructor: ~A()
|
||||||
char[] dtorName = CharArrayUtils.concat("~".toCharArray(), className); //$NON-NLS-1$
|
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;
|
implicits[i++] = m;
|
||||||
addBinding(m);
|
addBinding(m);
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,25 +79,26 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
|
||||||
ICPPMethod[] result= new ICPPMethod[needConversionOperator ? 6 : 5];
|
ICPPMethod[] result= new ICPPMethod[needConversionOperator ? 6 : 5];
|
||||||
|
|
||||||
// Deleted default constructor: A()
|
// 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);
|
ctor.setDeleted(true);
|
||||||
result[0]= ctor;
|
result[0]= ctor;
|
||||||
|
|
||||||
// Copy constructor: A(const A &)
|
// Copy constructor: A(const A &)
|
||||||
IType pType = new CPPReferenceType(SemanticUtil.constQualify(this), false);
|
IType pType = new CPPReferenceType(SemanticUtil.constQualify(this), false);
|
||||||
ICPPParameter[] ps = new ICPPParameter[] { new CPPParameter(pType, 0) };
|
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;
|
result[1]= ctor;
|
||||||
|
|
||||||
// Deleted copy assignment operator: A& operator = (const A &)
|
// Deleted copy assignment operator: A& operator = (const A &)
|
||||||
IType refType = new CPPReferenceType(this, false);
|
IType refType = new CPPReferenceType(this, false);
|
||||||
ICPPFunctionType ft= CPPVisitor.createImplicitFunctionType(refType, ps, false, 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;
|
result[2]= m;
|
||||||
|
|
||||||
// Destructor: ~A()
|
// Destructor: ~A()
|
||||||
ft= CPPVisitor.createImplicitFunctionType(UNSPECIFIED_TYPE, ICPPParameter.EMPTY_CPPPARAMETER_ARRAY, false, false);
|
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;
|
result[3]= m;
|
||||||
|
|
||||||
// Function call operator
|
// Function call operator
|
||||||
|
@ -109,7 +110,7 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
|
||||||
for (int i = 0; i < params.length; i++) {
|
for (int i = 0; i < params.length; i++) {
|
||||||
params[i]= new CPPParameter(parameterTypes[i], 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
|
@Override
|
||||||
public boolean isImplicit() { return false; }
|
public boolean isImplicit() { return false; }
|
||||||
};
|
};
|
||||||
|
@ -119,7 +120,7 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP
|
||||||
if (needConversionOperator) {
|
if (needConversionOperator) {
|
||||||
final CPPFunctionType conversionTarget = new CPPFunctionType(returnType, parameterTypes);
|
final CPPFunctionType conversionTarget = new CPPFunctionType(returnType, parameterTypes);
|
||||||
ft= new CPPFunctionType(conversionTarget, IType.EMPTY_TYPE_ARRAY, true, false, false, false, false);
|
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;
|
result[5]= m;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Andrew Niefer (IBM Corporation) - initial API and implementation
|
* Andrew Niefer (IBM Corporation) - initial API and implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
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 class CPPImplicitConstructor extends CPPImplicitMethod implements ICPPConstructor {
|
||||||
|
|
||||||
public CPPImplicitConstructor(ICPPClassScope scope, char[] name, ICPPParameter[] params) {
|
public CPPImplicitConstructor(ICPPClassScope scope, char[] name, ICPPParameter[] params, boolean isConstexpr) {
|
||||||
super(scope, name, createFunctionType(params), params);
|
super(scope, name, createFunctionType(params), params, isConstexpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ICPPFunctionType createFunctionType(IParameter[] params) {
|
private static ICPPFunctionType createFunctionType(IParameter[] params) {
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* IBM - Initial API and implementation
|
* IBM - Initial API and implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
|
@ -26,18 +27,20 @@ public class CPPImplicitFunction extends CPPFunction {
|
||||||
private ICPPParameter[] params;
|
private ICPPParameter[] params;
|
||||||
private IScope scope;
|
private IScope scope;
|
||||||
private ICPPFunctionType functionType;
|
private ICPPFunctionType functionType;
|
||||||
|
private final boolean isConstexpr;
|
||||||
private final boolean takesVarArgs;
|
private final boolean takesVarArgs;
|
||||||
private boolean isDeleted;
|
private boolean isDeleted;
|
||||||
private final char[] name;
|
private final char[] name;
|
||||||
|
|
||||||
public CPPImplicitFunction(char[] name, IScope scope, ICPPFunctionType type,
|
public CPPImplicitFunction(char[] name, IScope scope, ICPPFunctionType type,
|
||||||
ICPPParameter[] params, boolean takesVarArgs) {
|
ICPPParameter[] params, boolean isConstexpr, boolean takesVarArgs) {
|
||||||
super(null);
|
super(null);
|
||||||
this.name= name;
|
this.name= name;
|
||||||
this.scope= scope;
|
this.scope= scope;
|
||||||
this.functionType= type;
|
this.functionType= type;
|
||||||
this.params= params;
|
this.params= params;
|
||||||
this.takesVarArgs= takesVarArgs;
|
this.takesVarArgs= takesVarArgs;
|
||||||
|
this.isConstexpr = isConstexpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -49,7 +52,7 @@ public class CPPImplicitFunction extends CPPFunction {
|
||||||
public ICPPFunctionType getType() {
|
public ICPPFunctionType getType() {
|
||||||
return functionType;
|
return functionType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return String.valueOf(name);
|
return String.valueOf(name);
|
||||||
|
@ -64,27 +67,32 @@ public class CPPImplicitFunction extends CPPFunction {
|
||||||
public IScope getScope() {
|
public IScope getScope() {
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IScope getFunctionScope() {
|
public IScope getFunctionScope() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isConstexpr() {
|
||||||
|
return isConstexpr;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean takesVarArgs() {
|
public boolean takesVarArgs() {
|
||||||
return takesVarArgs;
|
return takesVarArgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isDeleted() {
|
public boolean isDeleted() {
|
||||||
return isDeleted;
|
return isDeleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinding getOwner() {
|
public IBinding getOwner() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDeleted(boolean val) {
|
public void setDeleted(boolean val) {
|
||||||
isDeleted= val;
|
isDeleted= val;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
* Andrew Niefer (IBM Corporation) - initial API and implementation
|
* Andrew Niefer (IBM Corporation) - initial API and implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
* Thomas Corbat (IFS)
|
* Thomas Corbat (IFS)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
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 class CPPImplicitMethod extends CPPImplicitFunction implements ICPPMethod {
|
||||||
|
|
||||||
public CPPImplicitMethod(ICPPClassScope scope, char[] name, ICPPFunctionType type, ICPPParameter[] params) {
|
public CPPImplicitMethod(ICPPClassScope scope, char[] name, ICPPFunctionType type, ICPPParameter[] params,
|
||||||
super(name, scope, type, params, false);
|
boolean isConstexpr) {
|
||||||
|
super(name, scope, type, params, isConstexpr, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -28,7 +28,7 @@ public class CPPInheritedConstructor extends CPPImplicitMethod implements ICPPCo
|
||||||
|
|
||||||
public CPPInheritedConstructor(ICPPClassScope scope, char[] name, ICPPConstructor prototype,
|
public CPPInheritedConstructor(ICPPClassScope scope, char[] name, ICPPConstructor prototype,
|
||||||
ICPPParameter[] params) {
|
ICPPParameter[] params) {
|
||||||
super(scope, name, createFunctionType(params), params);
|
super(scope, name, createFunctionType(params), params, false);
|
||||||
this.prototype = prototype;
|
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.IASTDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
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.IASTParameterDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
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;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
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.ICPPASTFunctionDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
|
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.ICPPClassType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
|
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 static final IASTParameterDeclaration[][] EMPTY_ARRAY_OF_PARAMETER_ARRAYS = {};
|
||||||
|
|
||||||
private final ICPPClassType classType;
|
private final ICPPClassType classType;
|
||||||
|
private final ICPPASTCompositeTypeSpecifier compositeTypeSpecifier;
|
||||||
private boolean hasConstructor;
|
private boolean hasConstructor;
|
||||||
private boolean hasCopyConstructor;
|
private boolean hasCopyConstructor;
|
||||||
private boolean hasCopyAssignmentOperator;
|
private boolean hasCopyAssignmentOperator;
|
||||||
private boolean hasDestructor;
|
private boolean hasDestructor;
|
||||||
private IASTParameterDeclaration[][] parametersOfNontrivialConstructors = EMPTY_ARRAY_OF_PARAMETER_ARRAYS;
|
private IASTParameterDeclaration[][] parametersOfNontrivialConstructors = EMPTY_ARRAY_OF_PARAMETER_ARRAYS;
|
||||||
|
private boolean hasNonStaticFields;
|
||||||
|
|
||||||
ImplicitsAnalysis(ICPPASTCompositeTypeSpecifier compositeTypeSpecifier, ICPPClassType classType) {
|
ImplicitsAnalysis(ICPPASTCompositeTypeSpecifier compositeTypeSpecifier, ICPPClassType classType) {
|
||||||
this.classType= classType;
|
this.classType= classType;
|
||||||
|
this.compositeTypeSpecifier = compositeTypeSpecifier;
|
||||||
analyzeMembers(compositeTypeSpecifier);
|
analyzeMembers(compositeTypeSpecifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,43 +131,45 @@ final class ImplicitsAnalysis {
|
||||||
spec = ((IASTFunctionDefinition) member).getDeclSpecifier();
|
spec = ((IASTFunctionDefinition) member).getDeclSpecifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(dcltor instanceof ICPPASTFunctionDeclarator))
|
if (dcltor instanceof ICPPASTFunctionDeclarator) {
|
||||||
continue;
|
IASTName memberName = ASTQueries.findInnermostDeclarator(dcltor).getName();
|
||||||
|
char[] declName = memberName.getLookupKey();
|
||||||
IASTName memberName = ASTQueries.findInnermostDeclarator(dcltor).getName();
|
|
||||||
char[] declName = memberName.getLookupKey();
|
if (spec instanceof IASTSimpleDeclSpecifier &&
|
||||||
|
((IASTSimpleDeclSpecifier) spec).getType() == IASTSimpleDeclSpecifier.t_unspecified) {
|
||||||
if (spec instanceof IASTSimpleDeclSpecifier &&
|
if (CharArrayUtils.equals(declName, name)) {
|
||||||
((IASTSimpleDeclSpecifier) spec).getType() == IASTSimpleDeclSpecifier.t_unspecified) {
|
hasConstructor = true;
|
||||||
if (CharArrayUtils.equals(declName, name)) {
|
IASTParameterDeclaration[] params = ((ICPPASTFunctionDeclarator) dcltor).getParameters();
|
||||||
hasConstructor = true;
|
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();
|
IASTParameterDeclaration[] params = ((ICPPASTFunctionDeclarator) dcltor).getParameters();
|
||||||
if (params.length != 0) {
|
if (params.length == 1 && hasTypeReferenceToClassType(params[0]))
|
||||||
if (hasTypeReferenceToClassType(params[0])) {
|
hasCopyAssignmentOperator = true;
|
||||||
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 (hasCopyConstructor && hasDestructor && hasCopyAssignmentOperator && baseSpecifiers.length == 0) {
|
||||||
if (params.length == 1 && hasTypeReferenceToClassType(params[0]))
|
break; // Nothing else to look for.
|
||||||
hasCopyAssignmentOperator = true;
|
}
|
||||||
}
|
} else if (dcltor instanceof ICPPASTFieldDeclarator &&
|
||||||
|
spec != null && spec.getStorageClass() != IASTDeclSpecifier.sc_static) {
|
||||||
if (hasCopyConstructor && hasDestructor && hasCopyAssignmentOperator && baseSpecifiers.length == 0) {
|
hasNonStaticFields = true;
|
||||||
break; // Nothing else to look for.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,4 +201,38 @@ final class ImplicitsAnalysis {
|
||||||
}
|
}
|
||||||
return true;
|
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) {
|
if (fResult == null) {
|
||||||
fResult= new ArrayList<>();
|
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,
|
* 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) {
|
protected static IBinding findEnclosingTemplate(IASTNode node) {
|
||||||
while (node != null) {
|
while (node != null) {
|
||||||
|
|
|
@ -3794,7 +3794,7 @@ public class CPPSemantics {
|
||||||
theParms[i]= new CPPBuiltinParameter(t);
|
theParms[i]= new CPPBuiltinParameter(t);
|
||||||
}
|
}
|
||||||
ICPPFunctionType functionType = new CPPFunctionType(returnType, parms);
|
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) {
|
static boolean isUserDefined(IType type) {
|
||||||
|
|
|
@ -135,6 +135,8 @@ public class EvalTypeId extends CPPDependentEvaluation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValueDependent() {
|
public boolean isValueDependent() {
|
||||||
|
if (CPPTemplates.isDependentType(fInputType))
|
||||||
|
return true;
|
||||||
for (ICPPEvaluation arg : fArguments) {
|
for (ICPPEvaluation arg : fArguments) {
|
||||||
if (arg.isValueDependent())
|
if (arg.isValueDependent())
|
||||||
return true;
|
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.REF;
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
|
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.DOMException;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
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.ISemanticProblem;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IValue;
|
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.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.ICPPMember;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
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.CPPBasicType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClosureType;
|
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.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.CPPPointerToMemberType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
||||||
|
@ -276,9 +280,34 @@ public class EvalUnary extends CPPDependentEvaluation {
|
||||||
if (isValueDependent())
|
if (isValueDependent())
|
||||||
return Value.create(this);
|
return Value.create(this);
|
||||||
|
|
||||||
if (getOverload(point) != null) {
|
ICPPEvaluation arg = fArgument;
|
||||||
// TODO(sprigogin): Simulate execution of a function call.
|
ICPPFunction overload = getOverload(point);
|
||||||
return Value.create(this);
|
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) {
|
switch (fOperator) {
|
||||||
|
@ -302,7 +331,7 @@ public class EvalUnary extends CPPDependentEvaluation {
|
||||||
return Value.UNKNOWN; // TODO(sprigogin): Implement
|
return Value.UNKNOWN; // TODO(sprigogin): Implement
|
||||||
}
|
}
|
||||||
|
|
||||||
IValue val = fArgument.getValue(point);
|
IValue val = arg.getValue(point);
|
||||||
if (val == null)
|
if (val == null)
|
||||||
return Value.UNKNOWN;
|
return Value.UNKNOWN;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue