Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergey Prigogin2009-01-18 00:23:48 +0000
committerSergey Prigogin2009-01-18 00:23:48 +0000
commit6494e815f58208c0548c76c9f8d75ed4ccabe3a6 (patch)
tree67889c00a02b87710eb17bce2cbb3c08ec207bf9
parenta860fe6af94b064a541e894e38c7f42adda3ffe6 (diff)
downloadorg.eclipse.cdt-6494e815f58208c0548c76c9f8d75ed4ccabe3a6.tar.gz
org.eclipse.cdt-6494e815f58208c0548c76c9f8d75ed4ccabe3a6.tar.xz
org.eclipse.cdt-6494e815f58208c0548c76c9f8d75ed4ccabe3a6.zip
Bug 259927. Fix and test case.
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java42
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java37
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java69
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) {

Back to the top