diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPImplicitNameTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPImplicitNameTests.java
index cdbb29226ca..0ca7cea5bd4 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPImplicitNameTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPImplicitNameTests.java
@@ -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
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
index 350fe623b3e..a11985d0718 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
@@ -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);
+ }
}
diff --git a/core/org.eclipse.cdt.core/.settings/.api_filters b/core/org.eclipse.cdt.core/.settings/.api_filters
deleted file mode 100644
index 2aae30a0706..00000000000
--- a/core/org.eclipse.cdt.core/.settings/.api_filters
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java
index f12c5b4d292..afa4b5270a8 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java
@@ -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
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java
index c76dc48ea4d..fa2275f6834 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java
@@ -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);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java
index 7b91cacf894..9d7a6e06bca 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java
@@ -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);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java
index e81d93f125b..c59cb91b50c 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java
@@ -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);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java
index ecf2753c3db..2e530f87eb2 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java
@@ -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;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java
index 6fcddc24a0d..7b6bc969e8d 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java
@@ -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());
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java
index c55c2bd5ed2..b96c0bcca1c 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java
@@ -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);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java
index 69d0e2386f2..c699a1da229 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java
@@ -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);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java
new file mode 100644
index 00000000000..b4f097574f2
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java
@@ -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 fResult;
+ private Set 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 classPointers= null;
+ List 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();
+ }
+ 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();
+ }
+ 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 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 addPromotedArithmetic(IType t, boolean fltPt, List 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();
+ }
+ 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 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 addArithmeticRef(IType t, boolean fltPt, List 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();
+ }
+ 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();
+ }
+ 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();
+ }
+ 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;
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
index ac84b781b63..76ce81c9c0d 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
@@ -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 argsToPass = new ArrayList(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);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java
index 3717aa99091..865de1d4003 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java
@@ -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;
- }
}