diff options
author | Mike Kucera | 2009-03-20 15:24:45 +0000 |
---|---|---|
committer | Mike Kucera | 2009-03-20 15:24:45 +0000 |
commit | 6045ee44784e5a4e924170e78457cacfcb2e3765 (patch) | |
tree | ca018d6ecef4d2f0d63a7b569c6c21910b299334 /core/org.eclipse.cdt.core/parser/org/eclipse/cdt | |
parent | 2d935d7b6e6afb6827a206b7fa12b8fd0e50a717 (diff) | |
download | org.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')
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 */ |