public virtual void VisitIncDec(BoundIncDecEx x) { Accept(x.Target); Accept(x.Value); }
public virtual void VisitIncDec(BoundIncDecEx x) { Accept(x.Value); }
public virtual TResult VisitIncDec(BoundIncDecEx x) => DefaultVisitOperation(x);
public override void VisitIncDec(BoundIncDecEx x) { // <target> = <target> +/- 1L Debug.Assert(x.Access.IsRead || x.Access.IsNone); Debug.Assert(x.Target.Access.IsRead && x.Target.Access.IsWrite); Visit(x.Target, BoundAccess.Read); Visit(x.Value, BoundAccess.Read); Debug.Assert(IsNumberOnly(x.Value)); // 1L TypeRefMask resulttype; TypeRefMask sourcetype = x.Target.TypeRefMask; // type of target before operation if (IsDoubleOnly(x.Target)) { // double++ => double resulttype = TypeCtx.GetDoubleTypeMask(); } else if (IsLTInt64Max(x.Target)) // we'd like to keep long if we are sure we don't overflow to double { // long++ [< long.MaxValue] => long resulttype = TypeCtx.GetLongTypeMask(); } else { // long|double|anything++ => number resulttype = TypeCtx.GetNumberTypeMask(); } Visit(x.Target, BoundAccess.Write.WithWrite(resulttype)); // x.Target.Access = x.Target.Access.WithRead(); // put read access back to the target x.TypeRefMask = (x.IncrementKind == UnaryOperationKind.OperatorPrefixIncrement || x.IncrementKind == UnaryOperationKind.OperatorPrefixDecrement) ? resulttype : sourcetype; }