1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 17:56:01 +02:00

Bug 259927. Fix and test case.

This commit is contained in:
Sergey Prigogin 2009-01-18 00:24:17 +00:00
parent ff95da70c2
commit 07fe9a9e75
3 changed files with 114 additions and 53 deletions

View file

@ -6352,11 +6352,11 @@ public class AST2CPPTests extends AST2BaseTest {
// }; // };
// //
// struct B { // struct B {
// A operator-(B b2); // A operator-(B b);
// A operator+(B& b2); // A operator+(B& b);
// A operator*(const B& b2); // A operator*(const B& b);
// A operator/(B b2) const; // A operator/(B b) const;
// A operator%(const B& b2) const; // A operator%(const B& b) const;
// }; // };
// //
// void test(B p1, B p2) { // void test(B p1, B p2) {
@ -6366,7 +6366,7 @@ public class AST2CPPTests extends AST2BaseTest {
// (p1 / p2).a; //4 // (p1 / p2).a; //4
// (p1 % p2).a; //5 // (p1 % p2).a; //5
// } // }
public void testOverloadedBinaryOperator_259927() throws Exception { public void testOverloadedBinaryOperator_259927_1() throws Exception {
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true); BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
ba.assertNonProblem("a; //1", 1, ICPPField.class); ba.assertNonProblem("a; //1", 1, ICPPField.class);
ba.assertNonProblem("a; //2", 1, ICPPField.class); ba.assertNonProblem("a; //2", 1, ICPPField.class);
@ -6374,6 +6374,36 @@ public class AST2CPPTests extends AST2BaseTest {
ba.assertNonProblem("a; //4", 1, ICPPField.class); ba.assertNonProblem("a; //4", 1, ICPPField.class);
ba.assertNonProblem("a; //5", 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);
}
// int a,b,c,d ; // int a,b,c,d ;
// class X { // class X {

View file

@ -2480,7 +2480,7 @@ public class CPPSemantics {
CPPASTName astName = new CPPASTName(); CPPASTName astName = new CPPASTName();
astName.setParent(exp); astName.setParent(exp);
astName.setPropertyInParent(STRING_LOOKUP_PROPERTY); astName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
LookupData data = null; LookupData data;
if (exp instanceof IASTUnaryExpression) { if (exp instanceof IASTUnaryExpression) {
astName.setName(OverloadableOperator.STAR.toCharArray()); astName.setName(OverloadableOperator.STAR.toCharArray());
@ -2532,8 +2532,41 @@ public class CPPSemantics {
} }
return null; return null;
} }
public static IBinding[] findBindings(IScope scope, String name, boolean qualified) throws DOMException{ /**
* 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, null); return findBindings(scope, name.toCharArray(), qualified, null);
} }

View file

@ -1865,28 +1865,36 @@ public class CPPVisitor extends ASTQueries {
// Check for overloaded operator. // Check for overloaded operator.
IType type1 = getExpressionType(binary.getOperand1()); IType type1 = getExpressionType(binary.getOperand1());
while (type1 instanceof ITypedef) { IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
try { if (ultimateType1 instanceof IProblemBinding) {
type1 = ((ITypedef) type1).getType(); return type1;
} catch (DOMException e) {
break;
}
} }
try { if (ultimateType1 instanceof ICPPClassType) {
if (type1 instanceof ICPPReferenceType) { ICPPFunction operator= CPPSemantics.findOperator(expression, (ICPPClassType) ultimateType1);
type1 = ((ICPPReferenceType) type1).getType(); if (operator != null) {
} try {
if (type1 instanceof IQualifierType) {
type1 = ((IQualifierType) type1).getType();
}
if (type1 instanceof ICPPClassType) {
ICPPFunction operator= CPPSemantics.findOperator(expression, (ICPPClassType) type1);
if (operator != null) {
return operator.getType().getReturnType(); return operator.getType().getReturnType();
} catch (DOMException e) {
return e.getProblem();
}
}
}
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(); final int op = binary.getOperator();
@ -1903,16 +1911,13 @@ public class CPPVisitor extends ASTQueries {
basicType.setFromExpression(expression); basicType.setFromExpression(expression);
return basicType; return basicType;
case IASTBinaryExpression.op_plus: case IASTBinaryExpression.op_plus:
IType t2 = getExpressionType(binary.getOperand2()); if (ultimateType2 instanceof IPointerType) {
if (SemanticUtil.getUltimateTypeViaTypedefs(t2) instanceof IPointerType) { return ultimateType2;
return t2;
} }
break; break;
case IASTBinaryExpression.op_minus: case IASTBinaryExpression.op_minus:
t2= getExpressionType(binary.getOperand2()); if (ultimateType2 instanceof IPointerType) {
if (SemanticUtil.getUltimateTypeViaTypedefs(t2) instanceof IPointerType) { if (ultimateType1 instanceof IPointerType) {
IType t1 = getExpressionType(binary.getOperand1());
if (SemanticUtil.getUltimateTypeViaTypedefs(t1) instanceof IPointerType) {
IScope scope = getContainingScope(expression); IScope scope = getContainingScope(expression);
try { try {
IBinding[] bs= CPPSemantics.findBindings(scope, PTRDIFF_T, false, expression); IBinding[] bs= CPPSemantics.findBindings(scope, PTRDIFF_T, false, expression);
@ -1929,22 +1934,22 @@ public class CPPVisitor extends ASTQueries {
basicType.setFromExpression(expression); basicType.setFromExpression(expression);
return basicType; return basicType;
} }
return t1; return ultimateType1;
} }
break; break;
case ICPPASTBinaryExpression.op_pmarrow: case ICPPASTBinaryExpression.op_pmarrow:
case ICPPASTBinaryExpression.op_pmdot: case ICPPASTBinaryExpression.op_pmdot:
IType type = getExpressionType(((IASTBinaryExpression) expression).getOperand2()); if (type2 instanceof ICPPPointerToMemberType) {
if (type instanceof ICPPPointerToMemberType) {
try { try {
return ((ICPPPointerToMemberType) type).getType(); return ((ICPPPointerToMemberType) type2).getType();
} catch (DOMException e) { } catch (DOMException e) {
return e.getProblem(); 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) { } else if (expression instanceof IASTUnaryExpression) {
final int op= ((IASTUnaryExpression) expression).getOperator(); final int op= ((IASTUnaryExpression) expression).getOperator();
switch (op) { switch (op) {
@ -1955,21 +1960,14 @@ public class CPPVisitor extends ASTQueries {
} }
IType type = getExpressionType(((IASTUnaryExpression) expression).getOperand()); IType type = getExpressionType(((IASTUnaryExpression) expression).getOperand());
while (type instanceof ITypedef) { type = SemanticUtil.getUltimateTypeViaTypedefs(type);
try {
type = ((ITypedef) type).getType();
} catch (DOMException e) {
break;
}
}
if (op == IASTUnaryExpression.op_star) { if (op == IASTUnaryExpression.op_star) {
try { try {
if (type instanceof ICPPReferenceType) { type = SemanticUtil.getUltimateTypeUptoPointers(type);
type = ((ICPPReferenceType) type).getType(); if (type instanceof IProblemBinding) {
} return type;
if (type instanceof IQualifierType) { }
type = ((IQualifierType) type).getType();
}
if (type instanceof ICPPClassType) { if (type instanceof ICPPClassType) {
ICPPFunction operator= CPPSemantics.findOperator(expression, (ICPPClassType) type); ICPPFunction operator= CPPSemantics.findOperator(expression, (ICPPClassType) type);
if (operator != null) { if (operator != null) {