mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-08 08:45:44 +02:00
Bug 294543: Built-in candidates for overloaded operators.
This commit is contained in:
parent
59ab06fad1
commit
a7397911f1
14 changed files with 738 additions and 113 deletions
|
@ -402,10 +402,10 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
|||
// X* xs = new X[5];
|
||||
// delete[] x;
|
||||
// }
|
||||
public void _testImplicitNewAndDelete() throws Exception {
|
||||
public void testImplicitNewAndDelete() throws Exception {
|
||||
BindingAssertionHelper ba = new BindingAssertionHelper(getAboveComment(), true);
|
||||
ba.assertNoImplicitName("new X", 3);
|
||||
ba.assertNoImplicitName("delete[]", 6); // fails because its picking up the implicit global delete[]
|
||||
ba.assertNoImplicitName("delete[]", 6);
|
||||
}
|
||||
|
||||
// typedef long unsigned int size_t
|
||||
|
|
|
@ -8562,4 +8562,25 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
String code= getAboveComment();
|
||||
parseAndCheckBindings(code);
|
||||
}
|
||||
|
||||
// struct D {};
|
||||
// struct C {
|
||||
// operator D();
|
||||
// operator char();
|
||||
// };
|
||||
// long operator+(D d, char a);
|
||||
// void f(long);
|
||||
// void f(int);
|
||||
// void xx() {
|
||||
// C c;
|
||||
// f(c+1); // converts c to a char and calls operator+(int, int)
|
||||
// }
|
||||
public void testBuiltinOperators_294543() throws Exception {
|
||||
String code= getAboveComment();
|
||||
parseAndCheckBindings(code);
|
||||
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
||||
IFunction fint= bh.assertNonProblem("f(int)", 1);
|
||||
IFunction f= bh.assertNonProblem("f(c+1)", 1);
|
||||
assertSame(fint, f);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<component id="org.eclipse.cdt.core" version="2">
|
||||
<resource path="parser/org/eclipse/cdt/core/dom/ast/IASTImplicitName.java" type="org.eclipse.cdt.core.dom.ast.IASTImplicitName">
|
||||
<filter id="403853384">
|
||||
<message_arguments>
|
||||
<message_argument value="org.eclipse.cdt.core.dom.ast.IASTImplicitName"/>
|
||||
</message_arguments>
|
||||
</filter>
|
||||
</resource>
|
||||
<resource path="parser/org/eclipse/cdt/core/dom/ast/IASTImplicitNameOwner.java" type="org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner">
|
||||
<filter id="403853384">
|
||||
<message_arguments>
|
||||
<message_argument value="org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner"/>
|
||||
</message_arguments>
|
||||
</filter>
|
||||
</resource>
|
||||
<resource path="parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTArraySubscriptExpression.java" type="org.eclipse.cdt.core.dom.ast.cpp.ICPPASTArraySubscriptExpression">
|
||||
<filter id="403853384">
|
||||
<message_arguments>
|
||||
<message_argument value="org.eclipse.cdt.core.dom.ast.cpp.ICPPASTArraySubscriptExpression"/>
|
||||
</message_arguments>
|
||||
</filter>
|
||||
</resource>
|
||||
<resource path="parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTExpressionList.java" type="org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList">
|
||||
<filter id="403853384">
|
||||
<message_arguments>
|
||||
<message_argument value="org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList"/>
|
||||
</message_arguments>
|
||||
</filter>
|
||||
</resource>
|
||||
<resource path="parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTFunctionCallExpression.java" type="org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression">
|
||||
<filter id="403853384">
|
||||
<message_arguments>
|
||||
<message_argument value="org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression"/>
|
||||
</message_arguments>
|
||||
</filter>
|
||||
</resource>
|
||||
<resource path="parser/org/eclipse/cdt/core/parser/IInactiveCodeToken.java" type="org.eclipse.cdt.core.parser.IInactiveCodeToken">
|
||||
<filter id="403853384">
|
||||
<message_arguments>
|
||||
<message_argument value="org.eclipse.cdt.core.parser.IInactiveCodeToken"/>
|
||||
</message_arguments>
|
||||
</filter>
|
||||
</resource>
|
||||
</component>
|
|
@ -96,7 +96,7 @@ public class CPPASTArraySubscriptExpression extends ASTNode implements ICPPASTAr
|
|||
public IASTImplicitName[] getImplicitNames() {
|
||||
if (implicitNames == null) {
|
||||
ICPPFunction overload = getOverload();
|
||||
if (overload == null)
|
||||
if (overload == null || overload instanceof CPPImplicitFunction)
|
||||
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||
|
||||
// create separate implicit names for the two brackets
|
||||
|
|
|
@ -21,12 +21,13 @@ import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
||||
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
|
||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
|
||||
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.ICPPPointerToMemberType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
||||
|
@ -113,7 +114,7 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
|
|||
public IASTImplicitName[] getImplicitNames() {
|
||||
if (implicitNames == null) {
|
||||
ICPPFunction overload = getOverload();
|
||||
if (overload == null) {
|
||||
if (overload == null || (overload instanceof CPPImplicitFunction && !(overload instanceof ICPPMethod))) {
|
||||
implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||
} else {
|
||||
CPPASTImplicitName operatorName = new CPPASTImplicitName(overload.getNameCharArray(), this);
|
||||
|
|
|
@ -100,7 +100,7 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
|
|||
|
||||
if (!isGlobal) {
|
||||
ICPPFunction deleteOperator = CPPSemantics.findOverloadedOperator(this);
|
||||
if (deleteOperator != null) {
|
||||
if (deleteOperator != null && !(deleteOperator instanceof CPPImplicitFunction)) {
|
||||
CPPASTImplicitName deleteName = new CPPASTImplicitName(deleteOperator.getNameCharArray(), this);
|
||||
deleteName.setOperator(true);
|
||||
deleteName.setBinding(deleteOperator);
|
||||
|
|
|
@ -120,7 +120,7 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
|
|||
ICPPFunction[] overloads = getOverloads();
|
||||
for(int i = 0; i < overloads.length; i++) {
|
||||
ICPPFunction overload = overloads[i];
|
||||
if(overload != null) {
|
||||
if(overload != null && !(overload instanceof CPPImplicitFunction)) {
|
||||
CPPASTImplicitName operatorName = new CPPASTImplicitName(OverloadableOperator.COMMA, this);
|
||||
operatorName.setBinding(overload);
|
||||
operatorName.computeOperatorOffsets(exprs[i], true);
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
|||
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.ICPPReferenceType;
|
||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||
|
@ -133,12 +134,16 @@ public class CPPASTFieldReference extends ASTNode implements ICPPASTFieldReferen
|
|||
|
||||
// create a name to wrap each binding
|
||||
implicitNames = new IASTImplicitName[functionBindings.size()];
|
||||
for(int i = 0, n = functionBindings.size(); i < n; i++) {
|
||||
CPPASTImplicitName operatorName = new CPPASTImplicitName(OverloadableOperator.ARROW, this);
|
||||
operatorName.setBinding(functionBindings.get(i));
|
||||
operatorName.computeOperatorOffsets(owner, true);
|
||||
implicitNames[i] = operatorName;
|
||||
int i=-1;
|
||||
for (ICPPFunction op : functionBindings) {
|
||||
if (op != null && !(op instanceof CPPImplicitFunction)) {
|
||||
CPPASTImplicitName operatorName = new CPPASTImplicitName(OverloadableOperator.ARROW, this);
|
||||
operatorName.setBinding(op);
|
||||
operatorName.computeOperatorOffsets(owner, true);
|
||||
implicitNames[++i] = operatorName;
|
||||
}
|
||||
}
|
||||
implicitNames= ArrayUtil.trimAt(IASTImplicitName.class, implicitNames, i);
|
||||
}
|
||||
|
||||
return implicitNames;
|
||||
|
|
|
@ -109,7 +109,7 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
|
|||
public IASTImplicitName[] getImplicitNames() {
|
||||
if (implicitNames == null) {
|
||||
ICPPFunction overload = getOperator();
|
||||
if (overload == null)
|
||||
if (overload == null || overload instanceof CPPImplicitFunction)
|
||||
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||
|
||||
// create separate implicit names for the two brackets
|
||||
|
@ -246,13 +246,9 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
|
|||
if (t instanceof IFunctionType) {
|
||||
return ((IFunctionType) t).getReturnType();
|
||||
} else if (t instanceof ICPPClassType) {
|
||||
ICPPFunction op = CPPSemantics.findOverloadedOperator(this, (ICPPClassType)t);
|
||||
if (op != null) {
|
||||
// overload can be a surrogate function call, which consists of a conversion and a call to
|
||||
// a dynamically computed function pointer.
|
||||
if (!(op instanceof CPPImplicitFunction))
|
||||
overload = op;
|
||||
return op.getType().getReturnType();
|
||||
overload = CPPSemantics.findOverloadedOperator(this, (ICPPClassType)t);
|
||||
if (overload != null) {
|
||||
return overload.getType().getReturnType();
|
||||
}
|
||||
} else if (t instanceof IPointerType) {
|
||||
t= SemanticUtil.getUltimateTypeUptoPointers(((IPointerType) t).getType());
|
||||
|
|
|
@ -139,7 +139,7 @@ public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression
|
|||
public IASTImplicitName[] getImplicitNames() {
|
||||
if (implicitNames == null) {
|
||||
ICPPFunction operatorFunction = CPPSemantics.findOverloadedOperator(this);
|
||||
if (operatorFunction == null) {
|
||||
if (operatorFunction == null || operatorFunction instanceof CPPImplicitFunction) {
|
||||
implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||
} else {
|
||||
CPPASTImplicitName operatorName = new CPPASTImplicitName(operatorFunction.getNameCharArray(), this);
|
||||
|
|
|
@ -26,12 +26,12 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
||||
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||
|
@ -100,7 +100,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
|
|||
public IASTImplicitName[] getImplicitNames() {
|
||||
if (implicitNames == null) {
|
||||
ICPPFunction overload = getOverload();
|
||||
if (overload == null) {
|
||||
if (overload == null || overload instanceof CPPImplicitFunction) {
|
||||
implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||
} else {
|
||||
CPPASTImplicitName operatorName = new CPPASTImplicitName(overload.getNameCharArray(), this);
|
||||
|
|
|
@ -0,0 +1,658 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 Wind River Systems, Inc. and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
||||
|
||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
||||
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
|
||||
import org.eclipse.cdt.core.dom.ast.IEnumeration;
|
||||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
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.ICPPMethod;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
||||
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.CPPBuiltinParameter;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitFunction;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
|
||||
|
||||
/**
|
||||
* Generates built-in operators according to 13.6
|
||||
*/
|
||||
class BuiltinOperators {
|
||||
private static final ICPPFunction[] EMPTY = {};
|
||||
private static final int FIRST = 0;
|
||||
private static final int SECOND = 1;
|
||||
private static final IType BOOL = new CPPBasicType(Kind.eBoolean, 0);
|
||||
private static final IType PTR_DIFF = new CPPBasicType(Kind.eInt, 0);
|
||||
|
||||
public static ICPPFunction[] create(OverloadableOperator operator, IASTInitializerClause[] args, IASTTranslationUnit tu) {
|
||||
if (operator == null || args == null || args.length == 0)
|
||||
return EMPTY;
|
||||
|
||||
return new BuiltinOperators(operator, args, tu.getScope()).create();
|
||||
}
|
||||
|
||||
private final OverloadableOperator fOperator;
|
||||
private final boolean fUnary;
|
||||
private IType fType1;
|
||||
private IType fType2;
|
||||
private IType[][] fClassConversionTypes= {null, null};
|
||||
private boolean[] fIsClass= {false,false};
|
||||
private IScope fFileScope;
|
||||
private List<ICPPFunction> fResult;
|
||||
private Set<String> fSignatures;
|
||||
|
||||
BuiltinOperators(OverloadableOperator operator, IASTInitializerClause[] args, IScope fileScope) {
|
||||
fFileScope= fileScope;
|
||||
fOperator= operator;
|
||||
fUnary= args.length<2;
|
||||
if (args.length > 0 && args[0] instanceof IASTExpression) {
|
||||
IType type= ((IASTExpression) args[0]).getExpressionType();
|
||||
if (!(type instanceof IProblemBinding))
|
||||
fType1= type;
|
||||
|
||||
}
|
||||
if (args.length > 1 && args[1] instanceof IASTExpression) {
|
||||
IType type= ((IASTExpression) args[1]).getExpressionType();
|
||||
if (!(type instanceof IProblemBinding))
|
||||
fType2= type;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private ICPPFunction[] create() {
|
||||
switch(fOperator) {
|
||||
case ARROW:
|
||||
case COMMA:
|
||||
case DELETE:
|
||||
case DELETE_ARRAY:
|
||||
case NEW:
|
||||
case NEW_ARRAY:
|
||||
case PAREN:
|
||||
return EMPTY;
|
||||
|
||||
case INCR:
|
||||
case DECR:
|
||||
opIncOrDec();
|
||||
break;
|
||||
|
||||
case STAR:
|
||||
if (fUnary) {
|
||||
opDeref();
|
||||
} else {
|
||||
binaryPromotedArithmetic(true, ReturnType.CONVERT);
|
||||
}
|
||||
break;
|
||||
|
||||
case DIV:
|
||||
binaryPromotedArithmetic(true, ReturnType.CONVERT);
|
||||
break;
|
||||
|
||||
case PLUS:
|
||||
if (fUnary) {
|
||||
unaryPointer();
|
||||
unaryPromotedArithmetic(true);
|
||||
} else {
|
||||
binaryPromotedArithmetic(true, ReturnType.CONVERT);
|
||||
pointerArithmetic(false, false);
|
||||
}
|
||||
break;
|
||||
|
||||
case BRACKET:
|
||||
pointerArithmetic(true, false);
|
||||
break;
|
||||
|
||||
case MINUS:
|
||||
if (fUnary) {
|
||||
unaryPromotedArithmetic(true);
|
||||
} else {
|
||||
binaryPromotedArithmetic(true, ReturnType.CONVERT);
|
||||
pointerArithmetic(false, true);
|
||||
}
|
||||
break;
|
||||
|
||||
case BITCOMPLEMENT:
|
||||
unaryPromotedArithmetic(false);
|
||||
break;
|
||||
|
||||
case ARROWSTAR:
|
||||
opArrowStar();
|
||||
break;
|
||||
|
||||
case EQUAL:
|
||||
case NOTEQUAL:
|
||||
binaryPromotedArithmetic(true, ReturnType.USE_BOOL);
|
||||
comparison(true);
|
||||
break;
|
||||
|
||||
case GT:
|
||||
case GTEQUAL:
|
||||
case LT:
|
||||
case LTEQUAL:
|
||||
binaryPromotedArithmetic(true, ReturnType.USE_BOOL);
|
||||
comparison(false);
|
||||
break;
|
||||
|
||||
case AMPER:
|
||||
if (fUnary)
|
||||
return EMPTY;
|
||||
|
||||
binaryPromotedArithmetic(false, ReturnType.CONVERT);
|
||||
break;
|
||||
|
||||
case BITOR:
|
||||
case XOR:
|
||||
case MOD:
|
||||
binaryPromotedArithmetic(false, ReturnType.CONVERT);
|
||||
break;
|
||||
|
||||
case SHIFTL:
|
||||
case SHIFTR:
|
||||
binaryPromotedArithmetic(false, ReturnType.USE_FIRST);
|
||||
break;
|
||||
|
||||
case ASSIGN:
|
||||
arithmeticAssignement(true, true, false);
|
||||
break;
|
||||
|
||||
case MINUSASSIGN:
|
||||
case PLUSASSIGN:
|
||||
arithmeticAssignement(true, false, true);
|
||||
break;
|
||||
|
||||
case DIVASSIGN:
|
||||
case STARASSIGN:
|
||||
arithmeticAssignement(true, false, false);
|
||||
break;
|
||||
|
||||
case AMPERASSIGN:
|
||||
case BITORASSIGN:
|
||||
case MODASSIGN:
|
||||
case SHIFTLASSIGN:
|
||||
case SHIFTRASSIGN:
|
||||
case XORASSIGN:
|
||||
arithmeticAssignement(false, false, false);
|
||||
break;
|
||||
|
||||
case AND:
|
||||
case OR:
|
||||
addFunction(BOOL, BOOL, BOOL);
|
||||
break;
|
||||
|
||||
case NOT:
|
||||
addFunction(BOOL, BOOL);
|
||||
break;
|
||||
}
|
||||
|
||||
if (fResult == null)
|
||||
return EMPTY;
|
||||
|
||||
return fResult.toArray(new ICPPFunction[fResult.size()]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 13.6-3, 13.6-4, 13.6-5
|
||||
private void opIncOrDec() {
|
||||
IType[] types= getClassConversionTypes(FIRST);
|
||||
for (IType type : types) {
|
||||
type= SemanticUtil.getNestedType(type, TDEF);
|
||||
if (type instanceof ICPPReferenceType) {
|
||||
IType nested= ((ICPPReferenceType) type).getType();
|
||||
CVQualifier cvq= SemanticUtil.getCVQualifier(nested);
|
||||
if (!cvq.isConst()) {
|
||||
nested= SemanticUtil.getNestedType(nested, TDEF | CVTYPE);
|
||||
boolean ok= false;
|
||||
if (isArithmetic(nested)) {
|
||||
// 13.6-3 and 1.3.6-4
|
||||
if (fOperator == OverloadableOperator.INCR || !isBoolean(type)) {
|
||||
ok= true;
|
||||
}
|
||||
} else if (isPointer(nested)) {
|
||||
// 13.6-5
|
||||
nested= ((IPointerType) nested).getType();
|
||||
if (!(SemanticUtil.getNestedType(nested, TDEF) instanceof IFunctionType)) {
|
||||
ok= true;
|
||||
}
|
||||
}
|
||||
if (ok) {
|
||||
if (fType2 != null) {
|
||||
addFunction(type, type, fType2);
|
||||
} else {
|
||||
addFunction(type, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 13.6-6, 13.6-7
|
||||
private void opDeref() {
|
||||
IType[] types= getClassConversionTypes(FIRST);
|
||||
for (IType type : types) {
|
||||
type= SemanticUtil.getNestedType(type, TDEF);
|
||||
if (isPointer(type)) {
|
||||
IType nested= SemanticUtil.getNestedType(((IPointerType) type).getType(), TDEF);
|
||||
if (nested instanceof ICPPFunctionType) {
|
||||
ICPPFunctionType ft= (ICPPFunctionType) nested;
|
||||
if (ft.isConst() || ft.isVolatile())
|
||||
return;
|
||||
}
|
||||
addFunction(new CPPReferenceType(nested, false), type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 13.6-8
|
||||
private void unaryPointer() {
|
||||
IType[] types= getClassConversionTypes(FIRST);
|
||||
for (IType type : types) {
|
||||
type= SemanticUtil.getNestedType(type, TDEF|REF);
|
||||
if (isPointer(type)) {
|
||||
addFunction(type, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 13.6-9, 13.6-10
|
||||
private void unaryPromotedArithmetic(boolean includeFloatingPoint) {
|
||||
IType[] types= getClassConversionTypes(FIRST);
|
||||
for (IType type : types) {
|
||||
type= SemanticUtil.getNestedType(type, TDEF|REF|CVTYPE);
|
||||
if (isFloatingPoint(type)) {
|
||||
if (includeFloatingPoint) {
|
||||
addFunction(type, type);
|
||||
}
|
||||
} else {
|
||||
type= CPPArithmeticConversion.promoteCppType(type);
|
||||
if (type != null) {
|
||||
addFunction(type, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 13.6-11
|
||||
private void opArrowStar() {
|
||||
List<IPointerType> classPointers= null;
|
||||
List<ICPPPointerToMemberType> memberPointers= null;
|
||||
IType[] types= getClassConversionTypes(FIRST);
|
||||
for (IType type : types) {
|
||||
type= SemanticUtil.getNestedType(type, TDEF | REF);
|
||||
if (isPointer(type)) {
|
||||
final IPointerType ptrType = (IPointerType) type;
|
||||
if (SemanticUtil.getNestedType(ptrType.getType(), TDEF | CVTYPE) instanceof ICPPClassType) {
|
||||
if (classPointers == null) {
|
||||
classPointers= new ArrayList<IPointerType>();
|
||||
}
|
||||
classPointers.add(ptrType);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (classPointers == null)
|
||||
return;
|
||||
|
||||
types= getClassConversionTypes(SECOND);
|
||||
for (IType type : types) {
|
||||
type= SemanticUtil.getNestedType(type, TDEF | REF);
|
||||
if (type instanceof ICPPPointerToMemberType) {
|
||||
if (memberPointers == null) {
|
||||
memberPointers= new ArrayList<ICPPPointerToMemberType>();
|
||||
}
|
||||
memberPointers.add((ICPPPointerToMemberType) type);
|
||||
}
|
||||
}
|
||||
if (memberPointers == null)
|
||||
return;
|
||||
|
||||
for (IPointerType clsPtr : classPointers) {
|
||||
IType cvClass= SemanticUtil.getNestedType(clsPtr.getType(), TDEF);
|
||||
CVQualifier cv1= SemanticUtil.getCVQualifier(cvClass);
|
||||
ICPPClassType c1= (ICPPClassType) SemanticUtil.getNestedType(cvClass, TDEF | CVTYPE);
|
||||
for (ICPPPointerToMemberType memPtr : memberPointers) {
|
||||
IType t2= SemanticUtil.getNestedType(memPtr.getMemberOfClass(), TDEF);
|
||||
if (t2 instanceof ICPPClassType) {
|
||||
ICPPClassType c2= (ICPPClassType) t2;
|
||||
try {
|
||||
if (SemanticUtil.calculateInheritanceDepth(c1, c2) >= 0) {
|
||||
IType cvt= SemanticUtil.getNestedType(memPtr.getType(), TDEF);
|
||||
IType rt= new CPPReferenceType(
|
||||
SemanticUtil.addQualifiers(cvt, cv1.isConst(), cv1.isVolatile()), false);
|
||||
addFunction(rt, clsPtr, memPtr);
|
||||
}
|
||||
} catch (DOMException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 13.6-12, 13.6-17
|
||||
private static enum ReturnType {CONVERT, USE_FIRST, USE_BOOL}
|
||||
private void binaryPromotedArithmetic(boolean fltPt, ReturnType rstrat) {
|
||||
List<IType> p1= null, p2= null;
|
||||
|
||||
IType[] types1= getClassConversionTypes(FIRST);
|
||||
IType[] types2= getClassConversionTypes(SECOND);
|
||||
if (types1.length == 0 && types2.length == 0)
|
||||
return;
|
||||
|
||||
for (IType t : types1) {
|
||||
p1 = addPromotedArithmetic(t, fltPt, p1);
|
||||
}
|
||||
for (IType t : types2) {
|
||||
p2 = addPromotedArithmetic(t, fltPt, p2);
|
||||
}
|
||||
p1= addPromotedArithmetic(fType1, fltPt, p1);
|
||||
p2= addPromotedArithmetic(fType2, fltPt, p2);
|
||||
if (p1 == null || p2 == null)
|
||||
return;
|
||||
|
||||
for (IType t1 : p1) {
|
||||
for (IType t2 : p2) {
|
||||
IType rt= null;
|
||||
switch(rstrat) {
|
||||
case USE_BOOL:
|
||||
rt= BOOL;
|
||||
break;
|
||||
case USE_FIRST:
|
||||
rt= t1;
|
||||
break;
|
||||
case CONVERT:
|
||||
rt= CPPArithmeticConversion.convertCppOperandTypes(IASTBinaryExpression.op_plus, t1, t2);
|
||||
break;
|
||||
}
|
||||
addFunction(rt, t1, t2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<IType> addPromotedArithmetic(IType t, boolean fltPt, List<IType> p1) {
|
||||
IType type= SemanticUtil.getNestedType(t, TDEF|REF|CVTYPE);
|
||||
if (isFloatingPoint(type)) {
|
||||
if (!fltPt) {
|
||||
type= null;
|
||||
}
|
||||
} else {
|
||||
type= CPPArithmeticConversion.promoteCppType(type);
|
||||
}
|
||||
if (type != null) {
|
||||
if (p1 == null) {
|
||||
p1= new ArrayList<IType>();
|
||||
}
|
||||
p1.add(type);
|
||||
}
|
||||
return p1;
|
||||
}
|
||||
|
||||
|
||||
// 13.6-13, 13.6.14
|
||||
private void pointerArithmetic(boolean useRef, boolean isDiff) {
|
||||
IType[] types= getClassConversionTypes(FIRST);
|
||||
if (types.length == 0 && !fIsClass[FIRST]) {
|
||||
types= new IType[] {fType1};
|
||||
}
|
||||
for (IType type : types) {
|
||||
type= SemanticUtil.getNestedType(type, TDEF|REF);
|
||||
if (isPointer(type)) {
|
||||
final IType ptrTarget = ((IPointerType) type).getType();
|
||||
final IType uqPtrTarget = SemanticUtil.getNestedType(ptrTarget, TDEF|CVTYPE);
|
||||
if (!(uqPtrTarget instanceof IFunctionType)) {
|
||||
final IType retType= useRef ? new CPPReferenceType(ptrTarget, false) : type;
|
||||
addFunction(retType, type, PTR_DIFF);
|
||||
if (isDiff) {
|
||||
addFunction(PTR_DIFF, type, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
types= getClassConversionTypes(SECOND);
|
||||
if (types.length == 0 && !fIsClass[SECOND]) {
|
||||
types= new IType[] {fType2};
|
||||
}
|
||||
for (IType type : types) {
|
||||
type= SemanticUtil.getNestedType(type, TDEF|REF);
|
||||
if (isPointer(type)) {
|
||||
final IType ptrTarget = ((IPointerType) type).getType();
|
||||
final IType uqPtrTarget = SemanticUtil.getNestedType(ptrTarget, TDEF|CVTYPE);
|
||||
if (!(uqPtrTarget instanceof IFunctionType)) {
|
||||
if (isDiff) {
|
||||
addFunction(PTR_DIFF, type, type);
|
||||
} else {
|
||||
final IType retType= useRef ? new CPPReferenceType(ptrTarget, false) : type;
|
||||
addFunction(retType, PTR_DIFF, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 13.6-15, 13.6.16
|
||||
private void comparison(boolean ordered) {
|
||||
for (int i = FIRST; i <= SECOND; i++) {
|
||||
IType[] types= getClassConversionTypes(i);
|
||||
for (IType type : types) {
|
||||
type= SemanticUtil.getNestedType(type, TDEF|REF|CVTYPE);
|
||||
if (isPointer(type) || isEnumeration(type) || (!ordered && isPointerToMember(type))) {
|
||||
addFunction(BOOL, type, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 13.6-18, 13.6-29, 13.6-20, 13.6-22
|
||||
private void arithmeticAssignement(boolean fltPt, boolean self, boolean ptr) {
|
||||
List<IType> p1= null, p2= null;
|
||||
|
||||
IType[] types1= getClassConversionTypes(FIRST);
|
||||
IType[] types2= getClassConversionTypes(SECOND);
|
||||
if (types1.length == 0 && types2.length == 0)
|
||||
return;
|
||||
|
||||
for (IType t : types1) {
|
||||
p1 = addArithmeticRef(t, fltPt, p1, self, ptr);
|
||||
}
|
||||
p1= addArithmeticRef(fType1, fltPt, p1, false, false);
|
||||
for (IType t : types2) {
|
||||
p2 = addPromotedArithmetic(t, fltPt, p2);
|
||||
}
|
||||
p2= addPromotedArithmetic(fType2, fltPt, p2);
|
||||
if (p1 == null || p2 == null)
|
||||
return;
|
||||
|
||||
for (IType t1 : p1) {
|
||||
for (IType t2 : p2) {
|
||||
addFunction(t1, t1, t2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<IType> addArithmeticRef(IType t, boolean fltPt, List<IType> p1, boolean self, boolean ptr) {
|
||||
final IType type= t= SemanticUtil.getNestedType(t, TDEF);
|
||||
if (type instanceof ICPPReferenceType) {
|
||||
t= SemanticUtil.getNestedType(((ICPPReferenceType) t).getType(), TDEF);
|
||||
if (!SemanticUtil.getCVQualifier(t).isConst()) {
|
||||
t = SemanticUtil.getNestedType(t, TDEF|CVTYPE);
|
||||
if (fltPt ? isArithmetic(t) : isIntegral(t)) {
|
||||
if (p1 == null) {
|
||||
p1= new ArrayList<IType>();
|
||||
}
|
||||
p1.add(type);
|
||||
}
|
||||
if (self && (isEnumeration(t) || isPointerToMember(t) || isPointer(t))) {
|
||||
addFunction(type, type, SemanticUtil.getNestedType(t, TDEF|ALLCVQ));
|
||||
}
|
||||
if (ptr && isPointer(t)) {
|
||||
addFunction(type, type, PTR_DIFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
return p1;
|
||||
}
|
||||
|
||||
private void addFunction(IType returnType, IType p1) {
|
||||
addFunction(returnType, new IType[] {p1});
|
||||
}
|
||||
|
||||
private void addFunction(IType returnType, IType p1, IType p2) {
|
||||
addFunction(returnType, new IType[] {p1, p2});
|
||||
}
|
||||
|
||||
private void addFunction(IType returnType, IType[] parameterTypes) {
|
||||
ICPPParameter[] parameter = new ICPPParameter[parameterTypes.length];
|
||||
ICPPFunctionType functionType = new CPPFunctionType(returnType, parameterTypes);
|
||||
String sig= ASTTypeUtil.getType(functionType, true);
|
||||
if (fSignatures == null) {
|
||||
fSignatures= new HashSet<String>();
|
||||
}
|
||||
if (fSignatures.add(sig)) {
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
IType t = parameterTypes[i];
|
||||
parameter[i]= new CPPBuiltinParameter(t);
|
||||
}
|
||||
if (fResult == null) {
|
||||
fResult= new ArrayList<ICPPFunction>();
|
||||
}
|
||||
fResult.add(new CPPImplicitFunction(fOperator.toCharArray(), fFileScope, functionType, parameter, false));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEnumeration(IType type) {
|
||||
return type instanceof IEnumeration;
|
||||
}
|
||||
|
||||
private boolean isPointer(IType type) {
|
||||
return type instanceof IPointerType && !(type instanceof ICPPPointerToMemberType);
|
||||
}
|
||||
|
||||
private boolean isPointerToMember(IType type) {
|
||||
return type instanceof ICPPPointerToMemberType;
|
||||
}
|
||||
|
||||
private boolean isBoolean(IType type) {
|
||||
return type instanceof IBasicType && ((IBasicType) type).getKind() == Kind.eBoolean;
|
||||
}
|
||||
|
||||
private boolean isFloatingPoint(IType type) {
|
||||
if (type instanceof IBasicType) {
|
||||
IBasicType.Kind kind= ((IBasicType) type).getKind();
|
||||
switch(kind) {
|
||||
case eDouble:
|
||||
case eFloat:
|
||||
return true;
|
||||
case eBoolean:
|
||||
case eChar:
|
||||
case eChar16:
|
||||
case eChar32:
|
||||
case eInt:
|
||||
case eWChar:
|
||||
case eUnspecified:
|
||||
case eVoid:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isArithmetic(IType type) {
|
||||
if (type instanceof IBasicType) {
|
||||
IBasicType.Kind kind= ((IBasicType) type).getKind();
|
||||
switch(kind) {
|
||||
case eBoolean:
|
||||
case eChar:
|
||||
case eChar16:
|
||||
case eChar32:
|
||||
case eDouble:
|
||||
case eFloat:
|
||||
case eInt:
|
||||
case eWChar:
|
||||
return true;
|
||||
case eUnspecified:
|
||||
case eVoid:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isIntegral(IType type) {
|
||||
if (type instanceof IBasicType) {
|
||||
IBasicType.Kind kind= ((IBasicType) type).getKind();
|
||||
switch(kind) {
|
||||
case eBoolean:
|
||||
case eChar:
|
||||
case eChar16:
|
||||
case eChar32:
|
||||
case eInt:
|
||||
case eWChar:
|
||||
return true;
|
||||
case eDouble:
|
||||
case eFloat:
|
||||
case eUnspecified:
|
||||
case eVoid:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private IType[] getClassConversionTypes(int idx) {
|
||||
IType[] result = fClassConversionTypes[idx];
|
||||
if (result == null) {
|
||||
result= IType.EMPTY_TYPE_ARRAY;
|
||||
IType type= idx == 0 ? fType1 : fType2;
|
||||
if (type != null) {
|
||||
type= SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE);
|
||||
if (type instanceof ICPPClassType) {
|
||||
fIsClass[idx]= true;
|
||||
try {
|
||||
ICPPMethod[] ops = SemanticUtil.getConversionOperators((ICPPClassType) type);
|
||||
result= new IType[ops.length];
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
final ICPPFunctionType functionType = ops[i].getType();
|
||||
if (functionType != null) {
|
||||
result[i]= functionType.getReturnType();
|
||||
}
|
||||
}
|
||||
} catch (DOMException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
fClassConversionTypes[idx]= result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -2662,7 +2662,6 @@ public class CPPSemantics {
|
|||
if (!fieldReference.isPointerDereference())
|
||||
return type;
|
||||
|
||||
char[] operatorName = OverloadableOperator.ARROW.toCharArray();
|
||||
IASTExpression[] args = {owner};
|
||||
|
||||
// bug 205964: as long as the type is a class type, recurse.
|
||||
|
@ -2700,7 +2699,7 @@ public class CPPSemantics {
|
|||
IASTFieldReference innerFR= new CPPASTFieldReference(arw, new CPPASTIdExpression(x));
|
||||
innerFR.setParent(fieldReference); // connect to the AST
|
||||
|
||||
ICPPFunction op = findOverloadedOperator(innerFR, args, uTemp, operatorName, NonMemberMode.none);
|
||||
ICPPFunction op = findOverloadedOperator(innerFR, args, uTemp, OverloadableOperator.ARROW, NonMemberMode.none);
|
||||
if (op == null)
|
||||
break;
|
||||
|
||||
|
@ -2723,15 +2722,13 @@ public class CPPSemantics {
|
|||
}
|
||||
|
||||
public static ICPPFunction findOverloadedOperator(IASTArraySubscriptExpression exp) {
|
||||
char[] name = OverloadableOperator.BRACKET.toCharArray();
|
||||
IASTInitializerClause[] args = {exp.getArrayExpression(), exp.getArgument()};
|
||||
IType type = exp.getArrayExpression().getExpressionType();
|
||||
type = SemanticUtil.getUltimateTypeUptoPointers(type);
|
||||
return findOverloadedOperator(exp, args, type, name, NonMemberMode.none);
|
||||
return findOverloadedOperator(exp, args, type, OverloadableOperator.BRACKET, NonMemberMode.none);
|
||||
}
|
||||
|
||||
public static ICPPFunction findOverloadedOperator(IASTFunctionCallExpression exp, ICPPClassType type) {
|
||||
char[] name = OverloadableOperator.PAREN.toCharArray();
|
||||
IASTInitializerClause[] args = exp.getArguments();
|
||||
ArrayList<IASTInitializerClause> argsToPass = new ArrayList<IASTInitializerClause>(args.length + 1);
|
||||
argsToPass.add(exp.getFunctionNameExpression());
|
||||
|
@ -2740,7 +2737,7 @@ public class CPPSemantics {
|
|||
}
|
||||
args = argsToPass.toArray(new IASTInitializerClause[argsToPass.size()]);
|
||||
|
||||
return findOverloadedOperator(exp, args, type, name, NonMemberMode.none);
|
||||
return findOverloadedOperator(exp, args, type, OverloadableOperator.PAREN, NonMemberMode.none);
|
||||
}
|
||||
|
||||
public static ICPPFunction findOverloadedOperator(ICPPASTNewExpression exp) {
|
||||
|
@ -2764,14 +2761,14 @@ public class CPPSemantics {
|
|||
}
|
||||
}
|
||||
IASTInitializerClause[] argArray = args.toArray(new IASTInitializerClause[args.size()]);
|
||||
return findOverloadedOperator(exp, argArray, type, op.toCharArray(), NonMemberMode.all);
|
||||
return findOverloadedOperator(exp, argArray, type, op, NonMemberMode.all);
|
||||
}
|
||||
|
||||
public static ICPPFunction findOverloadedOperator(ICPPASTDeleteExpression exp) {
|
||||
OverloadableOperator op = OverloadableOperator.fromDeleteExpression(exp);
|
||||
IASTExpression[] args = { exp.getOperand() };
|
||||
IType classType = getNestedClassType(exp);
|
||||
return findOverloadedOperator(exp, args, classType, op.toCharArray(), NonMemberMode.all);
|
||||
return findOverloadedOperator(exp, args, classType, op, NonMemberMode.all);
|
||||
}
|
||||
|
||||
private static ICPPClassType getNestedClassType(ICPPASTDeleteExpression exp) {
|
||||
|
@ -2907,7 +2904,7 @@ public class CPPSemantics {
|
|||
if (!isUserDefined(type))
|
||||
return null;
|
||||
|
||||
return findOverloadedOperator(exp, args, type, op.toCharArray(), NonMemberMode.limited);
|
||||
return findOverloadedOperator(exp, args, type, op, NonMemberMode.limited);
|
||||
}
|
||||
|
||||
public static ICPPFunction findOverloadedOperator(IASTBinaryExpression exp) {
|
||||
|
@ -2928,7 +2925,7 @@ public class CPPSemantics {
|
|||
lookupNonMember= NonMemberMode.limited;
|
||||
}
|
||||
|
||||
return findOverloadedOperator(exp, args, op1type, op.toCharArray(), lookupNonMember);
|
||||
return findOverloadedOperator(exp, args, op1type, op, lookupNonMember);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2946,16 +2943,23 @@ public class CPPSemantics {
|
|||
};
|
||||
dummy.setParent(first);
|
||||
|
||||
char[] name = OverloadableOperator.COMMA.toCharArray();
|
||||
IASTExpression[] args = new IASTExpression[] { dummy , second };
|
||||
return findOverloadedOperator(dummy, args, lookupType, name, NonMemberMode.limited);
|
||||
return findOverloadedOperator(dummy, args, lookupType, OverloadableOperator.COMMA, NonMemberMode.limited);
|
||||
}
|
||||
|
||||
enum NonMemberMode {none, limited, all}
|
||||
private static enum NonMemberMode {none, limited, all}
|
||||
private static ICPPFunction findOverloadedOperator(IASTExpression parent, IASTInitializerClause[] args, IType methodLookupType,
|
||||
char[] operatorName, NonMemberMode mode) {
|
||||
OverloadableOperator operator, NonMemberMode mode) {
|
||||
ICPPClassType callToObjectOfClassType= null;
|
||||
|
||||
IType type2= null;
|
||||
if (args.length >= 2 && args[1] instanceof IASTExpression) {
|
||||
type2= getUltimateTypeUptoPointers(((IASTExpression) args[1]).getExpressionType());
|
||||
}
|
||||
|
||||
if (methodLookupType instanceof ICPPUnknownType || type2 instanceof ICPPUnknownType) {
|
||||
return new CPPUnknownFunction(null, operator.toCharArray());
|
||||
}
|
||||
|
||||
// Find a method
|
||||
LookupData methodData = null;
|
||||
CPPASTName methodName = null;
|
||||
|
@ -2964,7 +2968,7 @@ public class CPPSemantics {
|
|||
if (methodLookupType instanceof ICPPClassType) {
|
||||
ICPPClassType classType = (ICPPClassType) methodLookupType;
|
||||
|
||||
methodName = new CPPASTName(operatorName);
|
||||
methodName = new CPPASTName(operator.toCharArray());
|
||||
methodName.setParent(parent);
|
||||
methodName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
|
||||
methodData = new LookupData(methodName);
|
||||
|
@ -2986,16 +2990,13 @@ public class CPPSemantics {
|
|||
}
|
||||
|
||||
// Find a function
|
||||
LookupData funcData = null;
|
||||
CPPASTName funcName = null;
|
||||
CPPASTName funcName = new CPPASTName(operator.toCharArray());
|
||||
funcName.setParent(parent);
|
||||
funcName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
|
||||
LookupData funcData = new LookupData(funcName);
|
||||
funcData.setFunctionArguments(args);
|
||||
funcData.ignoreMembers = true; // (13.3.1.2.3)
|
||||
if (mode != NonMemberMode.none || callToObjectOfClassType != null) {
|
||||
funcName = new CPPASTName(operatorName);
|
||||
funcName.setParent(parent);
|
||||
funcName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
|
||||
funcData = new LookupData(funcName);
|
||||
funcData.setFunctionArguments(args);
|
||||
funcData.ignoreMembers = true; // (13.3.1.2.3)
|
||||
|
||||
try {
|
||||
if (mode != NonMemberMode.none) {
|
||||
IScope scope = CPPVisitor.getContainingScope(parent);
|
||||
|
@ -3033,10 +3034,6 @@ public class CPPSemantics {
|
|||
// 13.3.1.2.3
|
||||
// However, if no operand type has class type, only those non-member functions ...
|
||||
if (mode == NonMemberMode.limited) {
|
||||
IType type2= null;
|
||||
if (args.length >= 2 && args[1] instanceof IASTExpression) {
|
||||
type2= getUltimateTypeUptoPointers(((IASTExpression) args[1]).getExpressionType());
|
||||
}
|
||||
if (funcData.foundItems != null && !(methodLookupType instanceof ICPPClassType) && !(type2 instanceof ICPPClassType)) {
|
||||
IEnumeration enum1= null;
|
||||
IEnumeration enum2= null;
|
||||
|
@ -3092,14 +3089,19 @@ public class CPPSemantics {
|
|||
}
|
||||
}
|
||||
|
||||
if (methodLookupType instanceof ICPPClassType || type2 instanceof ICPPClassType) {
|
||||
ICPPFunction[] builtins= BuiltinOperators.create(operator, args, parent.getTranslationUnit());
|
||||
mergeResults(funcData, builtins, false);
|
||||
}
|
||||
|
||||
try {
|
||||
IBinding binding = null;
|
||||
if (methodData != null && funcData != null) {
|
||||
if (methodData != null && funcData.hasResults()) {
|
||||
// if there was two lookups then merge the results
|
||||
mergeResults(funcData, methodData.foundItems, false);
|
||||
funcData.firstArgIsImpliedMethodArg = true;
|
||||
binding = resolveAmbiguities(funcData, funcName);
|
||||
} else if (funcData != null) {
|
||||
} else if (funcData.hasResults()) {
|
||||
binding = resolveAmbiguities(funcData, funcName);
|
||||
} else if (methodData != null) {
|
||||
binding = resolveAmbiguities(methodData, methodName);
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.eclipse.cdt.core.dom.ast.IScope;
|
|||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator;
|
||||
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.ICPPASTConstructorChainInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
||||
|
@ -65,7 +66,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
|
@ -625,17 +625,4 @@ public class LookupData {
|
|||
}
|
||||
return IBinding.EMPTY_BINDING_ARRAY;
|
||||
}
|
||||
|
||||
public int getFoundItemCount() {
|
||||
if (foundItems instanceof Object[]) {
|
||||
Object[] items = (Object[]) foundItems;
|
||||
int len;
|
||||
for (len= items.length-1; len >=0; len--) {
|
||||
if (items[len] != null)
|
||||
break;
|
||||
}
|
||||
return len+1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue