Skip to content

Commit

Permalink
Lower CmpExp between classes to __cmp call
Browse files Browse the repository at this point in the history
  • Loading branch information
edi33416 committed Dec 17, 2021
1 parent 1c66d43 commit afcbe15
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 5 deletions.
38 changes: 37 additions & 1 deletion src/dmd/expressionsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -11333,7 +11333,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return setError();
}

EXP cmpop;

EXP cmpop = exp.op;
if (auto e = exp.op_overload(sc, &cmpop))
{
if (!e.type.isscalar() && e.type.equals(exp.e1.type))
Expand All @@ -11343,13 +11344,48 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
if (e.op == EXP.call)
{

if (t1.ty == Tclass && t2.ty == Tclass)
{
// Lower to object.__cmp(e1, e2)
Expression cl = new IdentifierExp(exp.loc, Id.empty);
cl = new DotIdExp(exp.loc, cl, Id.object);
cl = new DotIdExp(exp.loc, cl, Id.__cmp);
cl = cl.expressionSemantic(sc);

CallExp cexp = cast(CallExp) e;

auto arguments = new Expressions();
// Check if op_overload found a better match by calling e2.opCmp(e1)
// If the operands were swapped, then the result must be reversed
// e1.opCmp(e2) == -e2.opCmp(e1)
// cmpop takes care of this
if (exp.op == cmpop)
{
arguments.push(exp.e1);
arguments.push(exp.e2);
}
else
{
// Use better match found by op_overload
arguments.push(exp.e2);
arguments.push(exp.e1);
}

cl = new CallExp(exp.loc, cl, arguments);
cl = new CmpExp(cmpop, exp.loc, cl, new IntegerExp(0));
result = cl.expressionSemantic(sc);
return;
}

e = new CmpExp(cmpop, exp.loc, e, IntegerExp.literal!0);
e = e.expressionSemantic(sc);
}
result = e;
return;
}


if (Expression ex = typeCombine(exp, sc))
{
result = ex;
Expand Down
8 changes: 4 additions & 4 deletions src/dmd/opover.d
Original file line number Diff line number Diff line change
Expand Up @@ -853,11 +853,11 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
{
// Rewrite (e1 op e2) as e2.opfunc(e1)
result = build_overload(e.loc, sc, e.e2, e.e1, m.lastf ? m.lastf : s);
// When reversing operands of comparison operators,
// need to reverse the sense of the op
if (pop)
*pop = reverseRelation(e.op);
}
// When reversing operands of comparison operators,
// need to reverse the sense of the op
if (pop)
*pop = reverseRelation(e.op);
return;
}
}
Expand Down

0 comments on commit afcbe15

Please sign in to comment.