1
0
Fork 0
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:
Markus Schorn 2010-06-17 13:57:03 +00:00
parent 59ab06fad1
commit a7397911f1
14 changed files with 738 additions and 113 deletions

View file

@ -402,10 +402,10 @@ public class AST2CPPImplicitNameTests extends AST2BaseTest {
// X* xs = new X[5]; // X* xs = new X[5];
// delete[] x; // delete[] x;
// } // }
public void _testImplicitNewAndDelete() throws Exception { public void testImplicitNewAndDelete() throws Exception {
BindingAssertionHelper ba = new BindingAssertionHelper(getAboveComment(), true); BindingAssertionHelper ba = new BindingAssertionHelper(getAboveComment(), true);
ba.assertNoImplicitName("new X", 3); 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 // typedef long unsigned int size_t

View file

@ -8562,4 +8562,25 @@ public class AST2CPPTests extends AST2BaseTest {
String code= getAboveComment(); String code= getAboveComment();
parseAndCheckBindings(code); 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);
}
} }

View file

@ -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>

View file

@ -96,7 +96,7 @@ public class CPPASTArraySubscriptExpression extends ASTNode implements ICPPASTAr
public IASTImplicitName[] getImplicitNames() { public IASTImplicitName[] getImplicitNames() {
if (implicitNames == null) { if (implicitNames == null) {
ICPPFunction overload = getOverload(); ICPPFunction overload = getOverload();
if (overload == null) if (overload == null || overload instanceof CPPImplicitFunction)
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY; return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
// create separate implicit names for the two brackets // create separate implicit names for the two brackets

View file

@ -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.IASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IArrayType; 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.IPointerType;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType; 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.ICPPASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; 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.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
@ -113,7 +114,7 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
public IASTImplicitName[] getImplicitNames() { public IASTImplicitName[] getImplicitNames() {
if (implicitNames == null) { if (implicitNames == null) {
ICPPFunction overload = getOverload(); ICPPFunction overload = getOverload();
if (overload == null) { if (overload == null || (overload instanceof CPPImplicitFunction && !(overload instanceof ICPPMethod))) {
implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY; implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
} else { } else {
CPPASTImplicitName operatorName = new CPPASTImplicitName(overload.getNameCharArray(), this); CPPASTImplicitName operatorName = new CPPASTImplicitName(overload.getNameCharArray(), this);

View file

@ -100,7 +100,7 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
if (!isGlobal) { if (!isGlobal) {
ICPPFunction deleteOperator = CPPSemantics.findOverloadedOperator(this); ICPPFunction deleteOperator = CPPSemantics.findOverloadedOperator(this);
if (deleteOperator != null) { if (deleteOperator != null && !(deleteOperator instanceof CPPImplicitFunction)) {
CPPASTImplicitName deleteName = new CPPASTImplicitName(deleteOperator.getNameCharArray(), this); CPPASTImplicitName deleteName = new CPPASTImplicitName(deleteOperator.getNameCharArray(), this);
deleteName.setOperator(true); deleteName.setOperator(true);
deleteName.setBinding(deleteOperator); deleteName.setBinding(deleteOperator);

View file

@ -120,7 +120,7 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
ICPPFunction[] overloads = getOverloads(); ICPPFunction[] overloads = getOverloads();
for(int i = 0; i < overloads.length; i++) { for(int i = 0; i < overloads.length; i++) {
ICPPFunction overload = overloads[i]; ICPPFunction overload = overloads[i];
if(overload != null) { if(overload != null && !(overload instanceof CPPImplicitFunction)) {
CPPASTImplicitName operatorName = new CPPASTImplicitName(OverloadableOperator.COMMA, this); CPPASTImplicitName operatorName = new CPPASTImplicitName(OverloadableOperator.COMMA, this);
operatorName.setBinding(overload); operatorName.setBinding(overload);
operatorName.computeOperatorOffsets(exprs[i], true); operatorName.computeOperatorOffsets(exprs[i], true);

View file

@ -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.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.ICPPReferenceType; 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.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; 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 // create a name to wrap each binding
implicitNames = new IASTImplicitName[functionBindings.size()]; implicitNames = new IASTImplicitName[functionBindings.size()];
for(int i = 0, n = functionBindings.size(); i < n; i++) { int i=-1;
CPPASTImplicitName operatorName = new CPPASTImplicitName(OverloadableOperator.ARROW, this); for (ICPPFunction op : functionBindings) {
operatorName.setBinding(functionBindings.get(i)); if (op != null && !(op instanceof CPPImplicitFunction)) {
operatorName.computeOperatorOffsets(owner, true); CPPASTImplicitName operatorName = new CPPASTImplicitName(OverloadableOperator.ARROW, this);
implicitNames[i] = operatorName; operatorName.setBinding(op);
operatorName.computeOperatorOffsets(owner, true);
implicitNames[++i] = operatorName;
}
} }
implicitNames= ArrayUtil.trimAt(IASTImplicitName.class, implicitNames, i);
} }
return implicitNames; return implicitNames;

View file

@ -109,7 +109,7 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
public IASTImplicitName[] getImplicitNames() { public IASTImplicitName[] getImplicitNames() {
if (implicitNames == null) { if (implicitNames == null) {
ICPPFunction overload = getOperator(); ICPPFunction overload = getOperator();
if (overload == null) if (overload == null || overload instanceof CPPImplicitFunction)
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY; return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
// create separate implicit names for the two brackets // create separate implicit names for the two brackets
@ -246,13 +246,9 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
if (t instanceof IFunctionType) { if (t instanceof IFunctionType) {
return ((IFunctionType) t).getReturnType(); return ((IFunctionType) t).getReturnType();
} else if (t instanceof ICPPClassType) { } else if (t instanceof ICPPClassType) {
ICPPFunction op = CPPSemantics.findOverloadedOperator(this, (ICPPClassType)t); overload = CPPSemantics.findOverloadedOperator(this, (ICPPClassType)t);
if (op != null) { if (overload != null) {
// overload can be a surrogate function call, which consists of a conversion and a call to return overload.getType().getReturnType();
// a dynamically computed function pointer.
if (!(op instanceof CPPImplicitFunction))
overload = op;
return op.getType().getReturnType();
} }
} else if (t instanceof IPointerType) { } else if (t instanceof IPointerType) {
t= SemanticUtil.getUltimateTypeUptoPointers(((IPointerType) t).getType()); t= SemanticUtil.getUltimateTypeUptoPointers(((IPointerType) t).getType());

View file

@ -139,7 +139,7 @@ public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression
public IASTImplicitName[] getImplicitNames() { public IASTImplicitName[] getImplicitNames() {
if (implicitNames == null) { if (implicitNames == null) {
ICPPFunction operatorFunction = CPPSemantics.findOverloadedOperator(this); ICPPFunction operatorFunction = CPPSemantics.findOverloadedOperator(this);
if (operatorFunction == null) { if (operatorFunction == null || operatorFunction instanceof CPPImplicitFunction) {
implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY; implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
} else { } else {
CPPASTImplicitName operatorName = new CPPASTImplicitName(operatorFunction.getNameCharArray(), this); CPPASTImplicitName operatorName = new CPPASTImplicitName(operatorFunction.getNameCharArray(), this);

View file

@ -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.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IArrayType; 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.IBinding;
import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType; 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.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
@ -100,7 +100,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
public IASTImplicitName[] getImplicitNames() { public IASTImplicitName[] getImplicitNames() {
if (implicitNames == null) { if (implicitNames == null) {
ICPPFunction overload = getOverload(); ICPPFunction overload = getOverload();
if (overload == null) { if (overload == null || overload instanceof CPPImplicitFunction) {
implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY; implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
} else { } else {
CPPASTImplicitName operatorName = new CPPASTImplicitName(overload.getNameCharArray(), this); CPPASTImplicitName operatorName = new CPPASTImplicitName(overload.getNameCharArray(), this);

View file

@ -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;
}
}

View file

@ -2662,7 +2662,6 @@ public class CPPSemantics {
if (!fieldReference.isPointerDereference()) if (!fieldReference.isPointerDereference())
return type; return type;
char[] operatorName = OverloadableOperator.ARROW.toCharArray();
IASTExpression[] args = {owner}; IASTExpression[] args = {owner};
// bug 205964: as long as the type is a class type, recurse. // 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)); IASTFieldReference innerFR= new CPPASTFieldReference(arw, new CPPASTIdExpression(x));
innerFR.setParent(fieldReference); // connect to the AST 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) if (op == null)
break; break;
@ -2723,15 +2722,13 @@ public class CPPSemantics {
} }
public static ICPPFunction findOverloadedOperator(IASTArraySubscriptExpression exp) { public static ICPPFunction findOverloadedOperator(IASTArraySubscriptExpression exp) {
char[] name = OverloadableOperator.BRACKET.toCharArray();
IASTInitializerClause[] args = {exp.getArrayExpression(), exp.getArgument()}; IASTInitializerClause[] args = {exp.getArrayExpression(), exp.getArgument()};
IType type = exp.getArrayExpression().getExpressionType(); IType type = exp.getArrayExpression().getExpressionType();
type = SemanticUtil.getUltimateTypeUptoPointers(type); 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) { public static ICPPFunction findOverloadedOperator(IASTFunctionCallExpression exp, ICPPClassType type) {
char[] name = OverloadableOperator.PAREN.toCharArray();
IASTInitializerClause[] args = exp.getArguments(); IASTInitializerClause[] args = exp.getArguments();
ArrayList<IASTInitializerClause> argsToPass = new ArrayList<IASTInitializerClause>(args.length + 1); ArrayList<IASTInitializerClause> argsToPass = new ArrayList<IASTInitializerClause>(args.length + 1);
argsToPass.add(exp.getFunctionNameExpression()); argsToPass.add(exp.getFunctionNameExpression());
@ -2740,7 +2737,7 @@ public class CPPSemantics {
} }
args = argsToPass.toArray(new IASTInitializerClause[argsToPass.size()]); 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) { public static ICPPFunction findOverloadedOperator(ICPPASTNewExpression exp) {
@ -2764,14 +2761,14 @@ public class CPPSemantics {
} }
} }
IASTInitializerClause[] argArray = args.toArray(new IASTInitializerClause[args.size()]); 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) { public static ICPPFunction findOverloadedOperator(ICPPASTDeleteExpression exp) {
OverloadableOperator op = OverloadableOperator.fromDeleteExpression(exp); OverloadableOperator op = OverloadableOperator.fromDeleteExpression(exp);
IASTExpression[] args = { exp.getOperand() }; IASTExpression[] args = { exp.getOperand() };
IType classType = getNestedClassType(exp); 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) { private static ICPPClassType getNestedClassType(ICPPASTDeleteExpression exp) {
@ -2907,7 +2904,7 @@ public class CPPSemantics {
if (!isUserDefined(type)) if (!isUserDefined(type))
return null; 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) { public static ICPPFunction findOverloadedOperator(IASTBinaryExpression exp) {
@ -2928,7 +2925,7 @@ public class CPPSemantics {
lookupNonMember= NonMemberMode.limited; 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); dummy.setParent(first);
char[] name = OverloadableOperator.COMMA.toCharArray();
IASTExpression[] args = new IASTExpression[] { dummy , second }; 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, private static ICPPFunction findOverloadedOperator(IASTExpression parent, IASTInitializerClause[] args, IType methodLookupType,
char[] operatorName, NonMemberMode mode) { OverloadableOperator operator, NonMemberMode mode) {
ICPPClassType callToObjectOfClassType= null; 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 // Find a method
LookupData methodData = null; LookupData methodData = null;
CPPASTName methodName = null; CPPASTName methodName = null;
@ -2964,7 +2968,7 @@ public class CPPSemantics {
if (methodLookupType instanceof ICPPClassType) { if (methodLookupType instanceof ICPPClassType) {
ICPPClassType classType = (ICPPClassType) methodLookupType; ICPPClassType classType = (ICPPClassType) methodLookupType;
methodName = new CPPASTName(operatorName); methodName = new CPPASTName(operator.toCharArray());
methodName.setParent(parent); methodName.setParent(parent);
methodName.setPropertyInParent(STRING_LOOKUP_PROPERTY); methodName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
methodData = new LookupData(methodName); methodData = new LookupData(methodName);
@ -2986,16 +2990,13 @@ public class CPPSemantics {
} }
// Find a function // Find a function
LookupData funcData = null; CPPASTName funcName = new CPPASTName(operator.toCharArray());
CPPASTName funcName = null; 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) { 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 { try {
if (mode != NonMemberMode.none) { if (mode != NonMemberMode.none) {
IScope scope = CPPVisitor.getContainingScope(parent); IScope scope = CPPVisitor.getContainingScope(parent);
@ -3033,10 +3034,6 @@ public class CPPSemantics {
// 13.3.1.2.3 // 13.3.1.2.3
// However, if no operand type has class type, only those non-member functions ... // However, if no operand type has class type, only those non-member functions ...
if (mode == NonMemberMode.limited) { 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)) { if (funcData.foundItems != null && !(methodLookupType instanceof ICPPClassType) && !(type2 instanceof ICPPClassType)) {
IEnumeration enum1= null; IEnumeration enum1= null;
IEnumeration enum2= 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 { try {
IBinding binding = null; IBinding binding = null;
if (methodData != null && funcData != null) { if (methodData != null && funcData.hasResults()) {
// if there was two lookups then merge the results // if there was two lookups then merge the results
mergeResults(funcData, methodData.foundItems, false); mergeResults(funcData, methodData.foundItems, false);
funcData.firstArgIsImpliedMethodArg = true; funcData.firstArgIsImpliedMethodArg = true;
binding = resolveAmbiguities(funcData, funcName); binding = resolveAmbiguities(funcData, funcName);
} else if (funcData != null) { } else if (funcData.hasResults()) {
binding = resolveAmbiguities(funcData, funcName); binding = resolveAmbiguities(funcData, funcName);
} else if (methodData != null) { } else if (methodData != null) {
binding = resolveAmbiguities(methodData, methodName); binding = resolveAmbiguities(methodData, methodName);

View file

@ -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.IType;
import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator; 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;
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.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression; 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.ICPPNamespaceScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; 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.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.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
@ -625,17 +625,4 @@ public class LookupData {
} }
return IBinding.EMPTY_BINDING_ARRAY; 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;
}
} }