mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 09:46:02 +02:00
Bug 259927. Fix and test case.
This commit is contained in:
parent
ff95da70c2
commit
07fe9a9e75
3 changed files with 114 additions and 53 deletions
|
@ -6352,11 +6352,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) {
|
||||
|
@ -6366,7 +6366,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);
|
||||
|
@ -6374,6 +6374,36 @@ 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);
|
||||
}
|
||||
|
||||
// int a,b,c,d ;
|
||||
// class X {
|
||||
|
|
|
@ -2480,7 +2480,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());
|
||||
|
@ -2532,8 +2532,41 @@ public class CPPSemantics {
|
|||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -1865,28 +1865,36 @@ 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 (type1 instanceof ICPPClassType) {
|
||||
ICPPFunction operator= CPPSemantics.findOperator(expression, (ICPPClassType) type1);
|
||||
if (operator != null) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
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();
|
||||
|
@ -1903,16 +1911,13 @@ public class CPPVisitor extends ASTQueries {
|
|||
basicType.setFromExpression(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= CPPSemantics.findBindings(scope, PTRDIFF_T, false, expression);
|
||||
|
@ -1929,22 +1934,22 @@ public class CPPVisitor extends ASTQueries {
|
|||
basicType.setFromExpression(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) {
|
||||
|
@ -1955,21 +1960,14 @@ public class CPPVisitor extends ASTQueries {
|
|||
}
|
||||
|
||||
IType type = getExpressionType(((IASTUnaryExpression) expression).getOperand());
|
||||
while (type instanceof ITypedef) {
|
||||
try {
|
||||
type = ((ITypedef) type).getType();
|
||||
} catch (DOMException e) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
type = SemanticUtil.getUltimateTypeViaTypedefs(type);
|
||||
|
||||
if (op == IASTUnaryExpression.op_star) {
|
||||
try {
|
||||
if (type instanceof ICPPReferenceType) {
|
||||
type = ((ICPPReferenceType) type).getType();
|
||||
}
|
||||
if (type instanceof IQualifierType) {
|
||||
type = ((IQualifierType) type).getType();
|
||||
}
|
||||
type = SemanticUtil.getUltimateTypeUptoPointers(type);
|
||||
if (type instanceof IProblemBinding) {
|
||||
return type;
|
||||
}
|
||||
if (type instanceof ICPPClassType) {
|
||||
ICPPFunction operator= CPPSemantics.findOperator(expression, (ICPPClassType) type);
|
||||
if (operator != null) {
|
||||
|
|
Loading…
Add table
Reference in a new issue