diff options
author | Sergey Prigogin | 2009-01-18 00:23:48 +0000 |
---|---|---|
committer | Sergey Prigogin | 2009-01-18 00:23:48 +0000 |
commit | 6494e815f58208c0548c76c9f8d75ed4ccabe3a6 (patch) | |
tree | 67889c00a02b87710eb17bce2cbb3c08ec207bf9 | |
parent | a860fe6af94b064a541e894e38c7f42adda3ffe6 (diff) | |
download | org.eclipse.cdt-6494e815f58208c0548c76c9f8d75ed4ccabe3a6.tar.gz org.eclipse.cdt-6494e815f58208c0548c76c9f8d75ed4ccabe3a6.tar.xz org.eclipse.cdt-6494e815f58208c0548c76c9f8d75ed4ccabe3a6.zip |
Bug 259927. Fix and test case.
3 files changed, 108 insertions, 40 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 82a45a0eac5..bc9748f036f 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -6199,11 +6199,11 @@ public class AST2CPPTests extends AST2BaseTest { // }; // // struct B { - // A operator-(B b2); - // A operator+(B& b2); - // A operator*(const B& b2); - // A operator/(B b2) const; - // A operator%(const B& b2) const; + // A operator-(B b); + // A operator+(B& b); + // A operator*(const B& b); + // A operator/(B b) const; + // A operator%(const B& b) const; // }; // // void test(B p1, B p2) { @@ -6213,7 +6213,7 @@ public class AST2CPPTests extends AST2BaseTest { // (p1 / p2).a; //4 // (p1 % p2).a; //5 // } - public void testOverloadedBinaryOperator_259927() throws Exception { + public void testOverloadedBinaryOperator_259927_1() throws Exception { BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true); ba.assertNonProblem("a; //1", 1, ICPPField.class); ba.assertNonProblem("a; //2", 1, ICPPField.class); @@ -6221,4 +6221,34 @@ public class AST2CPPTests extends AST2BaseTest { ba.assertNonProblem("a; //4", 1, ICPPField.class); ba.assertNonProblem("a; //5", 1, ICPPField.class); } + + // struct A { + // int a; + // }; + // struct B {}; + // enum E { zero }; + // + // A operator-(B p1, int p2); + // A operator+(int p1, const B& p2); + // A operator*(E p1, int p2); + // A operator/(int p1, const E& p2); + // A operator%(const B& p1, const B& p2); + // + // void test(B b, E e, int i) { + // (b - i).a; //1 + // (i + b).a; //2 + // (e * i).a; //3 + // (i / e).a; //4 + // (b % b).a; //5 + // (b + i).a; //6 + // } + public void testOverloadedBinaryOperator_259927_2() throws Exception { + BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true); + ba.assertNonProblem("a; //1", 1, ICPPField.class); + ba.assertNonProblem("a; //2", 1, ICPPField.class); + ba.assertNonProblem("a; //3", 1, ICPPField.class); + ba.assertNonProblem("a; //4", 1, ICPPField.class); + ba.assertNonProblem("a; //5", 1, ICPPField.class); + ba.assertProblem("a; //6", 1); + } } 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 df4ac015b6f..c013b188084 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 @@ -2467,7 +2467,7 @@ public class CPPSemantics { CPPASTName astName = new CPPASTName(); astName.setParent(exp); astName.setPropertyInParent(STRING_LOOKUP_PROPERTY); - LookupData data = null; + LookupData data; if (exp instanceof IASTUnaryExpression) { astName.setName(OverloadableOperator.STAR.toCharArray()); @@ -2520,7 +2520,40 @@ 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); + 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.functionParameters = new IASTExpression[] { exp.getOperand1(), exp.getOperand2() }; + + try { + lookup(data, scope); + IBinding binding = resolveAmbiguities(data, astName); + if (binding instanceof ICPPFunction) + return (ICPPFunction) binding; + } catch (DOMException e) { + } + return null; + } + public static IBinding[] findBindings(IScope scope, String name, boolean qualified) throws DOMException{ return findBindings(scope, name.toCharArray(), qualified); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index e8544545d3d..8d378334d1c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -1920,32 +1920,40 @@ public class CPPVisitor extends ASTQueries { // Check for overloaded operator. IType type1 = getExpressionType(binary.getOperand1()); - while (type1 instanceof ITypedef) { - try { - type1 = ((ITypedef) type1).getType(); - } catch (DOMException e) { - break; - } + IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1); + if (ultimateType1 instanceof IProblemBinding) { + return type1; } - try { - if (type1 instanceof ICPPReferenceType) { - type1 = ((ICPPReferenceType) type1).getType(); - } - if (type1 instanceof IQualifierType) { - type1 = ((IQualifierType) type1).getType(); + if (ultimateType1 instanceof ICPPClassType) { + ICPPFunction operator= CPPSemantics.findOperator(expression, (ICPPClassType) ultimateType1); + if (operator != null) { + try { + return operator.getType().getReturnType(); + } catch (DOMException e) { + return e.getProblem(); + } } - if (type1 instanceof ICPPClassType) { - ICPPFunction operator= CPPSemantics.findOperator(expression, (ICPPClassType) type1); - if (operator != null) { + } + IType type2 = getExpressionType(binary.getOperand2()); + IType ultimateType2 = SemanticUtil.getUltimateTypeUptoPointers(type2); + if (ultimateType2 instanceof IProblemBinding) { + return type2; + } + if (ultimateType1 instanceof ICPPClassType || ultimateType1 instanceof IEnumeration || + ultimateType2 instanceof ICPPClassType || ultimateType2 instanceof IEnumeration) { + // If at least one of the types is user defined, the operator can be overloaded. + ICPPFunction operator = CPPSemantics.findOverloadedOperator(binary); + if (operator != null) { + try { return operator.getType().getReturnType(); + } catch (DOMException e) { + return e.getProblem(); } } - } catch (DOMException e) { - return e.getProblem(); } - + final int op = binary.getOperator(); - switch(op) { + switch (op) { case IASTBinaryExpression.op_lessEqual: case IASTBinaryExpression.op_lessThan: case IASTBinaryExpression.op_greaterEqual: @@ -1958,16 +1966,13 @@ public class CPPVisitor extends ASTQueries { basicType.setValue(expression); return basicType; case IASTBinaryExpression.op_plus: - IType t2 = getExpressionType(binary.getOperand2()); - if (SemanticUtil.getUltimateTypeViaTypedefs(t2) instanceof IPointerType) { - return t2; + if (ultimateType2 instanceof IPointerType) { + return ultimateType2; } break; case IASTBinaryExpression.op_minus: - t2= getExpressionType(binary.getOperand2()); - if (SemanticUtil.getUltimateTypeViaTypedefs(t2) instanceof IPointerType) { - IType t1 = getExpressionType(binary.getOperand1()); - if (SemanticUtil.getUltimateTypeViaTypedefs(t1) instanceof IPointerType) { + if (ultimateType2 instanceof IPointerType) { + if (ultimateType1 instanceof IPointerType) { IScope scope = getContainingScope(expression); try { IBinding[] bs = scope.find(PTRDIFF_T); @@ -1984,22 +1989,22 @@ public class CPPVisitor extends ASTQueries { basicType.setValue(expression); return basicType; } - return t1; + return ultimateType1; } break; case ICPPASTBinaryExpression.op_pmarrow: case ICPPASTBinaryExpression.op_pmdot: - IType type = getExpressionType(((IASTBinaryExpression) expression).getOperand2()); - if (type instanceof ICPPPointerToMemberType) { + if (type2 instanceof ICPPPointerToMemberType) { try { - return ((ICPPPointerToMemberType)type).getType(); + return ((ICPPPointerToMemberType) type2).getType(); } catch (DOMException e) { return e.getProblem(); } } - return new ProblemBinding(binary, IProblemBinding.SEMANTIC_INVALID_TYPE, new char[0]); + return new ProblemBinding(binary, IProblemBinding.SEMANTIC_INVALID_TYPE, + expression.getRawSignature().toCharArray()); } - return getExpressionType(((IASTBinaryExpression) expression).getOperand1()); + return type1; } else if (expression instanceof IASTUnaryExpression) { final int op= ((IASTUnaryExpression)expression).getOperator(); switch (op) { |