Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Kucera2009-03-20 15:24:45 +0000
committerMike Kucera2009-03-20 15:24:45 +0000
commit6045ee44784e5a4e924170e78457cacfcb2e3765 (patch)
treeca018d6ecef4d2f0d63a7b569c6c21910b299334 /core/org.eclipse.cdt.core/parser/org/eclipse/cdt
parent2d935d7b6e6afb6827a206b7fa12b8fd0e50a717 (diff)
downloadorg.eclipse.cdt-6045ee44784e5a4e924170e78457cacfcb2e3765.tar.gz
org.eclipse.cdt-6045ee44784e5a4e924170e78457cacfcb2e3765.tar.xz
org.eclipse.cdt-6045ee44784e5a4e924170e78457cacfcb2e3765.zip
Fixes bugs 269365, 268534, and 266211. Fixed overload resolution for operator functions and also fixed expression lists.
Diffstat (limited to 'core/org.eclipse.cdt.core/parser/org/eclipse/cdt')
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java23
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java13
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java35
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java41
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java83
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java2
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java26
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java104
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java433
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java18
10 files changed, 374 insertions, 404 deletions
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java
index c442c1a95c5..263b15c91ee 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java
@@ -9,6 +9,7 @@
* Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
* Andrew Ferguson (Symbian)
+ * Mike Kucera (IBM)
*******************************************************************************/
package org.eclipse.cdt.core.parser.util;
@@ -386,4 +387,26 @@ public class ArrayUtil {
}
return result;
}
+
+
+ /**
+ * Returns a new array that contains all of the elements of the
+ * given array except the first one.
+ *
+ * @since 5.1
+ * @throws NullPointerException if args is null
+ * @throws IllegalArgumentException if args.length <= 0
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T[] removeFirst(T[] args) {
+ int n = args.length;
+ if(n <= 0)
+ throw new IllegalArgumentException();
+
+ T[] newArgs = (T[]) Array.newInstance(args.getClass().getComponentType(), n-1);
+ for(int i = 1; i < n; i++) {
+ newArgs[i-1] = args[i];
+ }
+ return newArgs;
+ }
}
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 0b73f49cb4a..312d2ef238f 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
@@ -18,7 +18,6 @@ import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IArrayType;
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.cpp.ICPPASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
@@ -105,15 +104,7 @@ public class CPPASTArraySubscriptExpression extends ASTNode implements ICPPASTAr
public ICPPFunction getOverload() {
- IType type1 = arrayExpression.getExpressionType();
- IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
- if (ultimateType1 instanceof IProblemBinding) {
- return null;
- }
- if (ultimateType1 instanceof ICPPClassType) {
- return CPPSemantics.findOperator(this, (ICPPClassType) ultimateType1);
- }
- return null;
+ return CPPSemantics.findOverloadedOperator(this);
}
@Override
@@ -172,7 +163,7 @@ public class CPPASTArraySubscriptExpression extends ASTNode implements ICPPASTAr
return CPPUnknownClass.createUnnamedInstance();
}
if (t instanceof ICPPClassType) {
- ICPPFunction op = CPPSemantics.findOperator(this, (ICPPClassType) t);
+ ICPPFunction op = getOverload();
if (op != null) {
return op.getType().getReturnType();
}
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 c51e907bf4c..c20b1eeb3a1 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
@@ -17,13 +17,11 @@ import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
-import org.eclipse.cdt.core.dom.ast.IEnumeration;
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.cpp.ICPPASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
-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.ICPPPointerToMemberType;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
@@ -171,35 +169,9 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
if (overload != UNINITIALIZED)
return overload;
- return overload= computeOverload();
+ return overload = CPPSemantics.findOverloadedOperator(this);
}
- private ICPPFunction computeOverload() {
- IType type1 = getOperand1().getExpressionType();
- IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
- if (ultimateType1 instanceof IProblemBinding) {
- return null;
- }
- if (ultimateType1 instanceof ICPPClassType) {
- ICPPFunction operator = CPPSemantics.findOperator(this, (ICPPClassType) ultimateType1);
- if (operator != null)
- return operator;
- }
-
- // try to find a function
- if(op != op_assign) {
- IType type2 = getOperand2().getExpressionType();
- IType ultimateType2 = SemanticUtil.getUltimateTypeUptoPointers(type2);
- if (ultimateType2 instanceof IProblemBinding)
- return null;
- if (isUserDefined(ultimateType1) || isUserDefined(ultimateType2))
- return CPPSemantics.findOverloadedOperator(this);
- }
- return null;
- }
-
-
-
private IType createExpressionType() {
// Check for overloaded operator.
ICPPFunction o= getOverload();
@@ -262,10 +234,5 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
}
return type1;
}
-
-
- private static boolean isUserDefined(IType type) {
- return type instanceof ICPPClassType || type instanceof IEnumeration;
- }
}
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 a4263dc88ef..94cba9f2f75 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
@@ -14,17 +14,13 @@ import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
-import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
-import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
-import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpression {
@@ -87,18 +83,14 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
}
/**
- * Try to resolve both the destructor and the operator delete.
+ * Try to resolve both the destructor and operator delete.
*/
public IASTImplicitName[] getImplicitNames() {
if(implicitNames == null) {
- ICPPClassType nestedType = getNestedClassType();
- if(nestedType == null)
- return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
-
List<IASTImplicitName> names = new ArrayList<IASTImplicitName>();
if(!isVectored) {
- ICPPFunction destructor = CPPSemantics.findDestructor(this, nestedType);
+ ICPPFunction destructor = CPPSemantics.findDestructor(this);
if(destructor != null) {
CPPASTImplicitName destructorName = new CPPASTImplicitName(destructor.getNameCharArray(), this);
destructorName.setBinding(destructor);
@@ -108,7 +100,7 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
}
if(!isGlobal) {
- ICPPFunction deleteOperator = findOperatorFunction(nestedType);
+ ICPPFunction deleteOperator = CPPSemantics.findOverloadedOperator(this);
if(deleteOperator != null) {
CPPASTImplicitName deleteName = new CPPASTImplicitName(deleteOperator.getNameCharArray(), this);
deleteName.setOperator(true);
@@ -128,33 +120,6 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
}
- private ICPPClassType getNestedClassType() {
- IType type1 = operand.getExpressionType();
- IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
- if(ultimateType1 instanceof IPointerType) {
- try {
- IType classType = ((IPointerType)ultimateType1).getType();
- if(classType instanceof ICPPClassType)
- return (ICPPClassType) classType;
- } catch (DOMException e) {
- return null;
- }
- }
- return null;
- }
-
- // TODO this code is repeated in too many places
- private ICPPFunction findOperatorFunction(IType type) {
- if(type instanceof ICPPClassType) {
- ICPPFunction operator = CPPSemantics.findOperator(this, (ICPPClassType) type);
- if(operator != null)
- return operator;
- return CPPSemantics.findOverloadedOperator(this);
- }
-
- return null;
- }
-
@Override
public boolean accept( ASTVisitor action ){
if( action.shouldVisitExpressions ){
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 22fb700f923..c4a4d8752f0 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
@@ -12,21 +12,18 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
+import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
-import org.eclipse.cdt.core.dom.ast.IEnumeration;
-import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList;
-import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
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;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionList, IASTAmbiguityParent {
@@ -38,6 +35,8 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
*/
private IASTImplicitName[] implicitNames;
+ private ICPPFunction[] overloads = null;
+
public CPPASTExpressionList copy() {
CPPASTExpressionList copy = new CPPASTExpressionList();
@@ -112,11 +111,9 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
implicitNames = new IASTImplicitName[exprs.length-1];
- if(getPropertyInParent() == IASTFunctionCallExpression.PARAMETERS)
- return implicitNames;
-
- for(int i = 0, n = exprs.length-1; i < n; i++) {
- ICPPFunction overload = getOverload(i);
+ ICPPFunction[] overloads = getOverloads();
+ for(int i = 0; i < overloads.length; i++) {
+ ICPPFunction overload = overloads[i];
if(overload != null) {
CPPASTImplicitName operatorName = new CPPASTImplicitName(OverloadableOperator.COMMA, this);
operatorName.setBinding(overload);
@@ -135,39 +132,35 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
}
- /**
- * @param index the index of the first argument
- */
- private ICPPFunction getOverload(int index) {
- // try to find a method
- IASTExpression[] exprs = getExpressions();
+ private ICPPFunction[] getOverloads() {
+ if(overloads == null) {
+ IASTExpression[] exprs = getExpressions();
+ if(exprs.length < 2 || getPropertyInParent() == IASTFunctionCallExpression.PARAMETERS)
+ return overloads = new ICPPFunction[0];
+
+ overloads = new ICPPFunction[exprs.length-1];
+ IType lookupType = exprs[0].getExpressionType();
+
+ for(int i = 1; i < exprs.length; i++) {
+ IASTExpression e1 = exprs[i-1], e2 = exprs[i];
+ ICPPFunction overload = CPPSemantics.findOverloadedOperatorComma(e1, e2, lookupType);
+ if(overload == null) {
+ lookupType = e2.getExpressionType();
+ }
+ else {
+ overloads[i-1] = overload;
+ try {
+ lookupType = overload.getType().getReturnType();
+ } catch (DOMException e) {
+ lookupType = e2.getExpressionType();
+ }
+ }
+ }
+ }
- IType type1 = exprs[index].getExpressionType();
- IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
- if (ultimateType1 instanceof IProblemBinding) {
- return null;
- }
- if (ultimateType1 instanceof ICPPClassType) {
- ICPPFunction operator = CPPSemantics.findOperatorComma(this, index, (ICPPClassType) ultimateType1);
- if (operator != null)
- return operator;
- }
-
- // try to find a function
- IType type2 = exprs[index+1].getExpressionType();
- IType ultimateType2 = SemanticUtil.getUltimateTypeUptoPointers(type2);
- if (ultimateType2 instanceof IProblemBinding)
- return null;
- if (isUserDefined(ultimateType1) || isUserDefined(ultimateType2))
- return CPPSemantics.findOverloadedOperator(this, index);
-
- return null;
- }
-
- private static boolean isUserDefined(IType type) {
- return type instanceof ICPPClassType || type instanceof IEnumeration;
+ return overloads;
}
-
+
public void replace(IASTNode child, IASTNode other) {
if( expressions == null ) return;
for (int i = 0; i < expressions.length; ++i) {
@@ -180,6 +173,16 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
}
public IType getExpressionType() {
+ ICPPFunction[] overloads = getOverloads();
+ if(overloads.length > 0) {
+ ICPPFunction last = overloads[overloads.length-1];
+ if(last != null) {
+ try {
+ return last.getType().getReturnType();
+ } catch (DOMException e) { }
+ }
+ }
+
for (int i = expressions.length-1; i >= 0 ; i--) {
IASTExpression expr= expressions[i];
if (expr != null)
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 e6428015e1a..da6718f0092 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
@@ -219,7 +219,7 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
if (t instanceof IFunctionType) {
return ((IFunctionType) t).getReturnType();
} else if (t instanceof ICPPClassType) {
- ICPPFunction op = CPPSemantics.findOperator(this, (ICPPClassType) t);
+ ICPPFunction op = CPPSemantics.findOverloadedOperator(this, (ICPPClassType)t);
if (op != null) {
if(overload != null)
overload[0] = op;
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 b442627c937..c243bb39ccd 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
@@ -23,12 +23,9 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IArrayType;
-import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
-import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
-import org.eclipse.cdt.core.parser.IProblem;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
@@ -180,17 +177,7 @@ public class CPPASTNewExpression extends ASTNode implements
public IASTImplicitName[] getImplicitNames() {
if(implicitNames == null) {
- IType type = getExpressionType();
- if(type instanceof IProblem)
- return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
-
- try {
- type = ((IPointerType)type).getType();
- } catch (DOMException e) {
- return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
- }
-
- ICPPFunction operatorFunction = findOperatorFunction(type);
+ ICPPFunction operatorFunction = CPPSemantics.findOverloadedOperator(this);
if(operatorFunction == null) {
implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
}
@@ -205,17 +192,6 @@ public class CPPASTNewExpression extends ASTNode implements
return implicitNames;
}
-
-
- // TODO this code is repeated in too many places
- private ICPPFunction findOperatorFunction(IType type) {
- if(type instanceof ICPPClassType) {
- ICPPFunction operator = CPPSemantics.findOperator(this, (ICPPClassType) type);
- if(operator != null)
- return operator;
- }
- return CPPSemantics.findOverloadedOperator(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 f53b78f04f6..6c9bd21059a 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
@@ -31,7 +31,6 @@ import org.eclipse.cdt.core.dom.ast.IType;
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.ICPPBasicType;
-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.ICPPMember;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
@@ -46,9 +45,11 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
* Unary expression in c++
*/
public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpression, IASTAmbiguityParent {
+ private static final ICPPFunction UNINITIALIZED = new CPPFunction(null);
private int op;
private IASTExpression operand;
+ private ICPPFunction overload = UNINITIALIZED;
private IASTImplicitName[] implicitNames = null;
public CPPASTUnaryExpression() {
@@ -155,13 +156,46 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
public ICPPFunction getOverload() {
- if(operand == null)
- return null;
- if(getExpressionType() instanceof CPPPointerToMemberType) // then it must be the builtin &
- return null;
- IType type = operand.getExpressionType();
- type = SemanticUtil.getNestedType(type, TDEF | REF);
- return findOperatorFunction(type);
+ if (overload != UNINITIALIZED)
+ return overload;
+
+ overload = CPPSemantics.findOverloadedOperator(this);
+ if(operand != null && op == op_amper && computePointerToMemberType() instanceof CPPPointerToMemberType)
+ overload = null;
+
+ return overload;
+ }
+
+
+
+ private IType computePointerToMemberType() {
+ IASTNode child= operand;
+ boolean inParenthesis= false;
+ while (child instanceof IASTUnaryExpression && ((IASTUnaryExpression) child).getOperator() == IASTUnaryExpression.op_bracketedPrimary) {
+ child= ((IASTUnaryExpression) child).getOperand();
+ inParenthesis= true;
+ }
+ if (child instanceof IASTIdExpression) {
+ IASTName name= ((IASTIdExpression) child).getName();
+ IBinding b= name.resolveBinding();
+ if (b instanceof ICPPMember) {
+ ICPPMember member= (ICPPMember) b;
+ try {
+ if (name instanceof ICPPASTQualifiedName) {
+ if (!member.isStatic()) { // so if the member is static it will fall through
+ if (!inParenthesis) {
+ return new CPPPointerToMemberType(member.getType(), member.getClassOwner(), false, false);
+ } else if (member instanceof IFunction) {
+ return new ProblemBinding(operand, IProblemBinding.SEMANTIC_INVALID_TYPE, operand.getRawSignature().toCharArray());
+ }
+ }
+ }
+ } catch (DOMException e) {
+ return e.getProblem();
+ }
+ }
+ }
+ return null;
}
@@ -177,40 +211,16 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
final IASTExpression operand = getOperand();
if (op == op_amper) { // check for pointer to member
- IASTNode child= operand;
- boolean inParenthesis= false;
- while (child instanceof IASTUnaryExpression && ((IASTUnaryExpression) child).getOperator() == IASTUnaryExpression.op_bracketedPrimary) {
- child= ((IASTUnaryExpression) child).getOperand();
- inParenthesis= true;
- }
- if (child instanceof IASTIdExpression) {
- IASTName name= ((IASTIdExpression) child).getName();
- IBinding b= name.resolveBinding();
- if (b instanceof ICPPMember) {
- ICPPMember member= (ICPPMember) b;
- try {
- if (name instanceof ICPPASTQualifiedName) {
- if (!member.isStatic()) { // so if the member is static it will fall through
- if (!inParenthesis) {
- return new CPPPointerToMemberType(member.getType(), member.getClassOwner(), false, false);
- } else if (member instanceof IFunction) {
- return new ProblemBinding(operand, IProblemBinding.SEMANTIC_INVALID_TYPE, operand.getRawSignature().toCharArray());
- }
- }
- }
- } catch (DOMException e) {
- return e.getProblem();
- }
- }
- }
+ IType ptm = computePointerToMemberType();
+ if(ptm != null)
+ return ptm;
- IType type= operand.getExpressionType();
- type = SemanticUtil.getNestedType(type, TDEF | REF);
-
- IType operator = findOperatorReturnType(type);
+ IType operator = findOperatorReturnType();
if(operator != null)
return operator;
+ IType type= operand.getExpressionType();
+ type = SemanticUtil.getNestedType(type, TDEF | REF);
return new CPPPointerType(type);
}
@@ -222,7 +232,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
return type;
}
try {
- IType operator = findOperatorReturnType(type);
+ IType operator = findOperatorReturnType();
if(operator != null) {
return operator;
} else if (type instanceof IPointerType || type instanceof IArrayType) {
@@ -239,7 +249,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
IType type= operand.getExpressionType();
type = SemanticUtil.getNestedType(type, TDEF | REF);
- IType operator = findOperatorReturnType(type);
+ IType operator = findOperatorReturnType();
if(operator != null) {
return operator;
}
@@ -254,8 +264,8 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
}
- private IType findOperatorReturnType(IType type) {
- ICPPFunction operatorFunction = findOperatorFunction(type);
+ private IType findOperatorReturnType() {
+ ICPPFunction operatorFunction = getOverload();
if(operatorFunction != null) {
try {
return operatorFunction.getType().getReturnType();
@@ -267,14 +277,4 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
}
- private ICPPFunction findOperatorFunction(IType type) {
- if(type instanceof ICPPClassType) {
- ICPPFunction operator = CPPSemantics.findOperator(this, (ICPPClassType) type);
- if(operator != null)
- return operator;
- return CPPSemantics.findOverloadedOperator(this);
- }
-
- return null;
- }
}
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 53b3a9c0f40..7d8403bc9d2 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
@@ -84,7 +84,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
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.ICPPASTExpressionList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
@@ -136,6 +135,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFileSet;
+import org.eclipse.cdt.core.parser.IProblem;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
@@ -154,6 +154,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypeIdExpression;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTUnaryExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPCompositeBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPNamespace;
@@ -248,8 +249,10 @@ public class CPPSemantics {
return postResolution(binding, data);
}
+
private static IBinding postResolution(IBinding binding, LookupData data) {
- if (data.checkAssociatedScopes()) {
+ // If the normal lookup of the unqualified name finds a class member function, then ADL does not occur
+ if (data.checkAssociatedScopes() && !data.hasMemberFunctionResult()) {
// 3.4.2 argument dependent name lookup, aka Koenig lookup
try {
boolean doKoenig= true;
@@ -753,13 +756,14 @@ public class CPPSemantics {
scope= (ICPPScope) data.tu.mapToASTScope(((IIndexScope) scope));
}
- if (!data.usingDirectivesOnly) {
+ if (!data.usingDirectivesOnly && !(data.ignoreMembers && scope instanceof ICPPClassScope)) {
IBinding[] bindings= getBindingsFromScope(scope, fileSet, data);
if (data.typesOnly) {
removeObjects(bindings);
}
mergeResults(data, bindings, true);
+
// store using-directives found in this block or namespace for later use.
if ((!data.hasResults() || !data.qualified() || data.contentAssist) && scope instanceof ICPPNamespaceScope) {
final ICPPNamespaceScope blockScope= (ICPPNamespaceScope) scope;
@@ -1928,14 +1932,15 @@ public class CPPSemantics {
return;
final boolean def = data.forFunctionDeclaration();
- int numArgs= data.getFunctionArgumentCount();
- if (def && numArgs == 1) {
+ int argumentCount = data.getFunctionArgumentCount();
+
+ if (def && argumentCount == 1) {
// check for parameter of type void
final IType[] argTypes = data.getFunctionArgumentTypes();
if (argTypes.length == 1) {
IType t= getNestedType(argTypes[0], TDEF);
if (t instanceof IBasicType && ((IBasicType)t).getType() == IBasicType.t_void) {
- numArgs= 0;
+ argumentCount= 0;
}
}
}
@@ -1962,6 +1967,11 @@ public class CPPSemantics {
// as long as possible.
final IType[] parameterTypes = function.getType().getParameterTypes();
int numPars = parameterTypes.length;
+
+ int numArgs = argumentCount;
+ if(function instanceof ICPPMethod && data.firstArgIsImpliedMethodArg)
+ numArgs--;
+
if (numArgs < 2 && numPars == 1) {
// check for void
IType t = getNestedType(parameterTypes[0], TDEF);
@@ -2059,15 +2069,13 @@ public class CPPSemantics {
IFunction bestFn = null; // the best function
Cost[] bestFnCost = null; // the cost of the best function
boolean bestHasAmbiguousParam = false; // bestFn has an ambiguous parameter conversion (not ok, ambiguous)
-
- final IType thisType = data.getImpliedObjectArgument();
-
+
// Loop over all functions
for (IFunction fn : fns) {
if (fn == null || bestFn == fn)
continue;
- final Cost[] fnCost= costForFunctionCall(fn, thisType, argTypes, args, allowUDC);
+ final Cost[] fnCost= costForFunctionCall(fn, argTypes, args, allowUDC, data);
if (fnCost == null)
continue;
@@ -2166,8 +2174,7 @@ public class CPPSemantics {
return bestFn;
}
- private static Cost[] costForFunctionCall(IFunction fn, IType thisType, IType[] argTypes, IASTExpression[] args,
- boolean allowUDC) throws DOMException {
+ private static Cost[] costForFunctionCall(IFunction fn, IType[] argTypes, IASTExpression[] args, boolean allowUDC, LookupData data) throws DOMException {
final ICPPFunctionType ftype= (ICPPFunctionType) fn.getType();
if (ftype == null)
return null;
@@ -2176,8 +2183,12 @@ public class CPPSemantics {
final IType[] paramTypes= ftype.getParameterTypes();
if (fn instanceof ICPPMethod && !(fn instanceof ICPPConstructor)) {
implicitType = getImplicitType((ICPPMethod) fn, ftype.isConst(), ftype.isVolatile());
+ if(data.firstArgIsImpliedMethodArg) {
+ argTypes = ArrayUtil.removeFirst(argTypes);
+ args = ArrayUtil.removeFirst(args);
+ }
}
-
+
int k= 0;
Cost cost;
final int sourceLen= argTypes.length;
@@ -2186,6 +2197,9 @@ public class CPPSemantics {
result= new Cost[sourceLen];
} else {
result= new Cost[sourceLen+1];
+
+ final IType thisType = data.getImpliedObjectArgument();
+
if (ASTInternal.isStatic(fn, false)) {
// 13.3.1-4 for static member functions, the implicit object parameter always matches, no cost
cost = new Cost(thisType, implicitType, Rank.IDENTITY);
@@ -2559,6 +2573,9 @@ public class CPPSemantics {
if (!fieldReference.isPointerDereference())
return type;
+ char[] operatorName = OverloadableOperator.ARROW.toCharArray();
+ IASTExpression[] args = {null};
+
// bug 205964: as long as the type is a class type, recurse.
// Be defensive and allow a max of 10 levels.
boolean foundOperator= false;
@@ -2594,7 +2611,7 @@ public class CPPSemantics {
IASTFieldReference innerFR= new CPPASTFieldReference(arw, new CPPASTIdExpression(x));
innerFR.setParent(fieldReference); // connect to the AST
- ICPPFunction op = CPPSemantics.findOperator(innerFR, (ICPPClassType) uTemp);
+ ICPPFunction op = findOverloadedOperator(innerFR, args, uTemp, operatorName, false);
if (op == null)
break;
@@ -2615,112 +2632,99 @@ public class CPPSemantics {
}
};
}
+
- public static ICPPFunction findOperator(IASTExpression exp, ICPPClassType cls) {
- IScope scope = null;
- try {
- scope = cls.getCompositeScope();
- } catch (DOMException e1) {
- return null;
- }
- if (scope == null)
- return null;
+ public static ICPPFunction findOverloadedOperator(IASTArraySubscriptExpression exp) {
+ char[] name = OverloadableOperator.BRACKET.toCharArray();
+ IASTExpression[] args = { null, exp.getSubscriptExpression() };
+ IType type1 = exp.getArrayExpression().getExpressionType();
+ IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
+ return findOverloadedOperator(exp, args, ultimateType1, name, false);
+ }
+
+
+ public static ICPPFunction findOverloadedOperator(IASTFunctionCallExpression exp, ICPPClassType type) {
+ char[] name = OverloadableOperator.PAREN.toCharArray();
+ IASTExpression param = exp.getParameterExpression();
+ IASTExpression[] args;
+ if(param instanceof IASTExpressionList) {
+ IASTExpression[] actualArgs = ((IASTExpressionList)param).getExpressions();
+ ArrayList<IASTExpression> argsToPass = new ArrayList<IASTExpression>(actualArgs.length + 1);
+ argsToPass.add(null);
+ for(IASTExpression e : actualArgs) {
+ argsToPass.add(e);
+ }
+ args = argsToPass.toArray(new IASTExpression[argsToPass.size()]);
+ }
+ else if(param != null) {
+ args = new IASTExpression[] { null, param };
+ }
+ else {
+ args = new IASTExpression[] { null };
+ }
+
+ return findOverloadedOperator(exp, args, type, name, false);
+ }
+
+ public static ICPPFunction findOverloadedOperator(ICPPASTNewExpression exp) {
+ OverloadableOperator op = OverloadableOperator.fromNewExpression(exp);
- CPPASTName astName = new CPPASTName();
- astName.setParent(exp);
- astName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
- LookupData data = new LookupData(astName);
- data.forceQualified = true;
-
- if (exp instanceof IASTArraySubscriptExpression) {
- astName.setName(OverloadableOperator.BRACKET.toCharArray());
- data.setFunctionArguments(((IASTArraySubscriptExpression) exp).getSubscriptExpression());
- } else if (exp instanceof IASTFieldReference) {
- astName.setName(OverloadableOperator.ARROW.toCharArray());
- data.setFunctionArguments(IASTExpression.EMPTY_EXPRESSION_ARRAY);
- } else if (exp instanceof IASTFunctionCallExpression) {
- astName.setName(OverloadableOperator.PAREN.toCharArray());
- data.setFunctionArguments(((IASTFunctionCallExpression) exp).getParameterExpression());
- } else if (exp instanceof ICPPASTDeleteExpression) {
- OverloadableOperator oo = OverloadableOperator.fromDeleteExpression((ICPPASTDeleteExpression)exp);
- astName.setName(oo.toCharArray());
- data.setFunctionArguments(IASTExpression.EMPTY_EXPRESSION_ARRAY);
- } else if (exp instanceof ICPPASTNewExpression) {
- ICPPASTNewExpression newExpression = (ICPPASTNewExpression) exp;
- OverloadableOperator operator = OverloadableOperator.fromNewExpression(newExpression);
- astName.setName(operator.toCharArray());
- data.setFunctionArguments(newExpression.getNewPlacement());
- } else if (exp instanceof IASTBinaryExpression) {
- final IASTBinaryExpression binary = (IASTBinaryExpression) exp;
- OverloadableOperator operator = OverloadableOperator.fromBinaryExpression(binary);
- if (operator == null)
- return null;
- astName.setName(operator.toCharArray());
- data.setFunctionArguments(new IASTExpression[] { binary.getOperand2() });
- } else if (exp instanceof IASTUnaryExpression) {
- IASTUnaryExpression unary = (IASTUnaryExpression) exp;
- OverloadableOperator operator = OverloadableOperator.fromUnaryExpression(unary);
- if(operator == null)
- return null;
- astName.setName(operator.toCharArray());
- int op = unary.getOperator();
- if(op == IASTUnaryExpression.op_postFixDecr || op == IASTUnaryExpression.op_postFixIncr)
- data.setFunctionArguments(new IASTExpression[] { CPPASTLiteralExpression.INT_ZERO });
- else
- data.setFunctionArguments(IASTExpression.EMPTY_EXPRESSION_ARRAY);
- } else {
+ IType type = exp.getExpressionType();
+ if(type instanceof IProblem)
return null;
- }
-
try {
- lookup(data, scope);
- IBinding binding = resolveAmbiguities(data, astName);
- if (binding instanceof ICPPFunction)
- return (ICPPFunction) binding;
+ type = ((IPointerType)type).getType();
} catch (DOMException e) {
- }
- return null;
- }
-
-
- /**
- *
- * @param expressionList
- * @param index the index of the first parameter
- */
- public static ICPPFunction findOperatorComma(ICPPASTExpressionList expressionList, int index, ICPPClassType cls) {
- IScope scope = null;
- try {
- scope = cls.getCompositeScope();
- } catch (DOMException e1) {
return null;
}
- if (scope == null)
- return null;
- CPPASTName astName = new CPPASTName();
- astName.setParent(expressionList);
- astName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
- astName.setName(OverloadableOperator.COMMA.toCharArray());
-
- LookupData data = new LookupData(astName);
- data.forceQualified = true;
- IASTExpression[] exprs = expressionList.getExpressions();
- data.setFunctionArguments(new IASTExpression[] { exprs[index], exprs[index+1] });
-
- try {
- lookup(data, scope);
- IBinding binding = resolveAmbiguities(data, astName);
- if (binding instanceof ICPPFunction)
- return (ICPPFunction) binding;
- } catch (DOMException e) {
- }
+ IASTTypeId typeId = exp.getTypeId().copy();
+ IASTExpression sizeExpression = new CPPASTTypeIdExpression(IASTTypeIdExpression.op_sizeof, typeId);
+ sizeExpression.setParent(exp);
+
+ IASTExpression placement = exp.getNewPlacement();
+ List<IASTExpression> args = new ArrayList<IASTExpression>();
+ args.add(sizeExpression);
+ if(placement instanceof IASTExpressionList) {
+ for(IASTExpression p : ((IASTExpressionList)placement).getExpressions())
+ args.add(p);
+ }
+ else if(placement != null) {
+ args.add(placement);
+ }
+
+ IASTExpression[] argArray = args.toArray(new IASTExpression[args.size()]);
+ return findOverloadedOperator(exp, argArray, type, op.toCharArray(), true);
+ }
+
+
+ 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(), true);
+ }
+
+ private static ICPPClassType getNestedClassType(ICPPASTDeleteExpression exp) {
+ IType type1 = exp.getOperand().getExpressionType();
+ IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
+ if(ultimateType1 instanceof IPointerType) {
+ try {
+ IType classType = ((IPointerType)ultimateType1).getType();
+ if(classType instanceof ICPPClassType)
+ return (ICPPClassType) classType;
+ } catch (DOMException e) {
+ return null;
+ }
+ }
return null;
}
-
-
- public static ICPPFunction findDestructor(ICPPASTDeleteExpression expr, ICPPClassType cls) {
+ public static ICPPFunction findDestructor(ICPPASTDeleteExpression expr) {
+ ICPPClassType cls = getNestedClassType(expr);
+ if(cls == null)
+ return null;
+
IScope scope = null;
try {
scope = cls.getCompositeScope();
@@ -2749,120 +2753,145 @@ public class CPPSemantics {
return null;
}
-
- /**
- * Returns the overloaded operator corresponding to a binary expression, or {@code null}
- * if no such operator is found.
- * @param exp a binary expression
- * @return the overloaded operator, or {@code null}.
- */
- public static ICPPFunction findOverloadedOperator(IASTBinaryExpression exp) {
- OverloadableOperator operator = OverloadableOperator.fromBinaryExpression(exp);
- IASTExpression[] args = { exp.getOperand1(), exp.getOperand2() };
- return findOverloadedOperator(exp, operator, args);
- }
-
-
- /**
- * Returns the overloaded operator corresponding to a binary expression, or {@code null}
- * if no such operator is found.
- * @param exp a binary expression
- * @return the overloaded operator, or {@code null}.
- */
- public static ICPPFunction findOverloadedOperator(ICPPASTDeleteExpression exp) {
- OverloadableOperator operator = OverloadableOperator.fromDeleteExpression(exp);
- IASTExpression[] args = { exp.getOperand() };
- return findOverloadedOperator(exp, operator, args);
- }
-
-
- /**
- * Returns the overloaded operator corresponding to a unary expression, or {@code null}
- * if no such operator is found.
- */
public static ICPPFunction findOverloadedOperator(IASTUnaryExpression exp) {
- OverloadableOperator operator = OverloadableOperator.fromUnaryExpression(exp);
-
- IASTExpression[] args = null;
- int op = exp.getOperator();
- if(op == IASTUnaryExpression.op_postFixDecr || op == IASTUnaryExpression.op_postFixIncr)
+ if(exp.getOperand() == null)
+ return null;
+
+ OverloadableOperator op = OverloadableOperator.fromUnaryExpression(exp);
+ if(op == null)
+ return null;
+
+ IASTExpression[] args;
+ int operator = exp.getOperator();
+ if(operator == IASTUnaryExpression.op_postFixDecr || operator == IASTUnaryExpression.op_postFixIncr)
args = new IASTExpression[] { exp.getOperand(), CPPASTLiteralExpression.INT_ZERO };
else
args = new IASTExpression[] { exp.getOperand() };
- return findOverloadedOperator(exp, operator, args);
- }
+ IType type = exp.getOperand().getExpressionType();
+ type = SemanticUtil.getNestedType(type, TDEF | REF | CVQ);
+ return findOverloadedOperator(exp, args, type, op.toCharArray(), true);
+ }
- /**
- * Returns the overloaded operator corresponding to a comma in an expression list,
- * or {@code null} if no such operator is found.
- * @param index the index of the left argument to the comma operator
- * @throws IndexOutOfBoundsException if index is invalid
- */
- public static ICPPFunction findOverloadedOperator(ICPPASTExpressionList exp, int index) {
- OverloadableOperator operator = OverloadableOperator.COMMA;
- IASTExpression[] exprs = exp.getExpressions();
- IASTExpression[] args = { exprs[index], exprs[index+1] };
- return findOverloadedOperator(exp, operator, args);
+
+ public static ICPPFunction findOverloadedOperator(IASTBinaryExpression exp) {
+ OverloadableOperator op = OverloadableOperator.fromBinaryExpression(exp);
+ if(op == null)
+ return null;
+
+ IType op1type = SemanticUtil.getUltimateTypeUptoPointers(exp.getOperand1().getExpressionType());
+ IASTExpression[] args = new IASTExpression[] { exp.getOperand1(), exp.getOperand2() } ;
+
+ boolean lookupNonMember = false;
+ if(exp.getOperator() != IASTBinaryExpression.op_assign) {
+ IType op2type = SemanticUtil.getUltimateTypeUptoPointers(exp.getOperand2().getExpressionType());
+ if(op2type instanceof IProblemBinding)
+ return null;
+ if(isUserDefined(op1type) || isUserDefined(op2type))
+ lookupNonMember = true;
+ }
+
+ return findOverloadedOperator(exp, args, op1type, op.toCharArray(), lookupNonMember);
}
+
/**
- * Returns the overloaded operator corresponding to a comma in an expression list,
- * or {@code null} if no such operator is found.
- * @throws IndexOutOfBoundsException if index is invalid
+ * Returns the operator,() function that would apply to the two given arguments.
+ * The lookup type of the class where the operator,() might be found must also be provided.
*/
- public static ICPPFunction findOverloadedOperator(ICPPASTNewExpression exp) {
- OverloadableOperator operator = OverloadableOperator.fromNewExpression(exp);
-
- IASTTypeId typeId = exp.getTypeId().copy();
- IASTExpression sizeExpression = new CPPASTTypeIdExpression(IASTTypeIdExpression.op_sizeof, typeId);
- sizeExpression.setParent(exp);
-
- IASTExpression placement = exp.getNewPlacement();
-
- List<IASTExpression> args = new ArrayList<IASTExpression>();
- args.add(sizeExpression);
+ public static ICPPFunction findOverloadedOperatorComma(IASTExpression first, IASTExpression second, final IType lookupType) {
+ IASTUnaryExpression dummy = new CPPASTUnaryExpression() {
+ @Override public IType getExpressionType() { return lookupType; }
+ @Override public IASTExpression getOperand() {
+ return new CPPASTUnaryExpression() {
+ @Override public IType getExpressionType() { return lookupType; }
+ };
+ }
+ };
+ dummy.setParent(first);
- if(placement instanceof IASTExpressionList) {
- for(IASTExpression p : ((IASTExpressionList)placement).getExpressions())
- args.add(p);
- }
- else if(placement != null) {
- args.add(placement);
- }
-
- return findOverloadedOperator(exp, operator, args.toArray(new IASTExpression[args.size()]));
+ char[] name = OverloadableOperator.COMMA.toCharArray();
+ IASTExpression[] args = new IASTExpression[] { dummy , second };
+ return findOverloadedOperator(dummy, args, lookupType, name, true);
}
- private static ICPPFunction findOverloadedOperator(IASTExpression exp, OverloadableOperator operator, IASTExpression[] args) {
- if (operator == null) {
- return null;
- }
-
- IScope scope = CPPVisitor.getContainingScope(exp);
- if (scope == null)
- return null;
-
- CPPASTName astName = new CPPASTName();
- astName.setParent(exp);
- astName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
- astName.setName(operator.toCharArray());
- LookupData data = new LookupData(astName);
- data.setFunctionArguments(args);
-
- try {
- lookup(data, scope);
- IBinding binding = resolveAmbiguities(data, astName);
+ private static ICPPFunction findOverloadedOperator(IASTExpression parent, IASTExpression[] args, IType methodLookupType, char[] operatorName, boolean lookupNonMember) {
+ // find a method
+ LookupData methodData = null;
+ CPPASTName methodName = null;
+ if(methodLookupType instanceof IProblemBinding)
+ return null;
+ if(methodLookupType instanceof ICPPClassType) {
+ methodName = new CPPASTName(operatorName);
+ methodName.setParent(parent);
+ methodName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
+ methodData = new LookupData(methodName);
+ methodData.setFunctionArguments(ArrayUtil.removeFirst(args));
+ methodData.forceQualified = true; // (13.3.1.2.3)
+
+ try {
+ IScope scope = ((ICPPClassType)methodLookupType).getCompositeScope();
+ if (scope == null)
+ return null;
+ lookup(methodData, scope);
+ } catch (DOMException e) {
+ return null;
+ }
+ }
+
+ // find a function
+ LookupData funcData = null;
+ CPPASTName funcName = null;
+ if(lookupNonMember) {
+ 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 {
+ IScope scope = CPPVisitor.getContainingScope(parent);
+ if (scope == null)
+ return null;
+ lookup(funcData, scope);
+ } catch (DOMException e) {
+ return null;
+ }
+ }
+
+ // resolve ambiguities
+ try {
+ IBinding binding = null;
+ if(methodData != null && funcData != null) {
+ // 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) {
+ binding = resolveAmbiguities(funcData, funcName);
+ }
+ else if(methodData != null) {
+ binding = resolveAmbiguities(methodData, methodName);
+ }
+
if (binding instanceof ICPPFunction)
return (ICPPFunction) binding;
- } catch (DOMException e) {}
+
+ } catch (DOMException e) {
+ }
+
return null;
}
-
+ private static boolean isUserDefined(IType type) {
+ return type instanceof ICPPClassType || type instanceof IEnumeration;
+ }
+
public static IBinding[] findBindings(IScope scope, String name, boolean qualified) throws DOMException {
return findBindings(scope, name.toCharArray(), qualified, null);
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 551b6f3f7c4..2610740d16e 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
@@ -63,6 +63,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
+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.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
@@ -104,7 +105,9 @@ public class LookupData {
public boolean considerConstructors = false;
public boolean checkPointOfDecl= true; // for lookup of unknown bindings the point of declaration can be reversed.
public boolean usesEnclosingScope= true; // for field references or qualified names, enclosing template declarations are ignored.
-
+ public boolean firstArgIsImpliedMethodArg = false; // when computing the cost of a method call treat the first argument as the implied method argument
+ public boolean ignoreMembers = false;
+
public ICPPClassType skippedScope;
public Object foundItems = null;
private Object[] functionArgs;
@@ -370,6 +373,19 @@ public class LookupData {
return false;
}
+ public boolean hasMemberFunctionResult() {
+ if(foundItems == null)
+ return false;
+ if(foundItems instanceof Object[]) {
+ for(Object item : (Object[])foundItems) {
+ if(item instanceof ICPPMethod) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
/**
* an IType[] of function arguments, including the implied object argument
*/

Back to the top