|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CSharp.RuntimeBinder.Syntax;
namespace Microsoft.CSharp.RuntimeBinder.Semantics
{
internal readonly partial struct ExpressionBinder
{
private class BinOpSig
{
protected BinOpSig()
{
}
public BinOpSig(PredefinedType pt1, PredefinedType pt2,
BinOpMask mask, int cbosSkip, PfnBindBinOp pfn, OpSigFlags grfos, BinOpFuncKind fnkind)
{
this.pt1 = pt1;
this.pt2 = pt2;
this.mask = mask;
this.cbosSkip = cbosSkip;
this.pfn = pfn;
this.grfos = grfos;
this.fnkind = fnkind;
}
public PredefinedType pt1;
public PredefinedType pt2;
public BinOpMask mask;
public int cbosSkip;
public PfnBindBinOp pfn;
public OpSigFlags grfos;
public BinOpFuncKind fnkind;
public bool ConvertOperandsBeforeBinding()
{
return (grfos & OpSigFlags.Convert) != 0;
}
public bool CanLift()
{
return (grfos & OpSigFlags.CanLift) != 0;
}
public bool AutoLift()
{
return (grfos & OpSigFlags.AutoLift) != 0;
}
}
private sealed class BinOpFullSig : BinOpSig
{
private readonly LiftFlags _grflt;
private readonly CType _type1;
private readonly CType _type2;
public BinOpFullSig(CType type1, CType type2, PfnBindBinOp pfn, OpSigFlags grfos,
LiftFlags grflt, BinOpFuncKind fnkind)
{
this.pt1 = PredefinedType.PT_UNDEFINEDINDEX;
this.pt2 = PredefinedType.PT_UNDEFINEDINDEX;
this.mask = BinOpMask.None;
this.cbosSkip = 0;
this.pfn = pfn;
this.grfos = grfos;
_type1 = type1;
_type2 = type2;
_grflt = grflt;
this.fnkind = fnkind;
}
/***************************************************************************************************
Set the values of the BinOpFullSig from the given BinOpSig. The ExpressionBinder is needed to get
the predefined types. Returns true iff the predef types are found.
***************************************************************************************************/
[RequiresUnreferencedCode(Binder.TrimmerWarning)]
public BinOpFullSig(BinOpSig bos)
{
this.pt1 = bos.pt1;
this.pt2 = bos.pt2;
this.mask = bos.mask;
this.cbosSkip = bos.cbosSkip;
this.pfn = bos.pfn;
this.grfos = bos.grfos;
this.fnkind = bos.fnkind;
_type1 = pt1 != PredefinedType.PT_UNDEFINEDINDEX ? GetPredefindType(pt1) : null;
_type2 = pt2 != PredefinedType.PT_UNDEFINEDINDEX ? GetPredefindType(pt2) : null;
_grflt = LiftFlags.None;
}
public bool FPreDef()
{
return pt1 != PredefinedType.PT_UNDEFINEDINDEX;
}
public bool isLifted()
{
if (_grflt == LiftFlags.None)
{
return false;
}
// We can't both convert and lift.
Debug.Assert(((_grflt & LiftFlags.Lift1) == 0) || ((_grflt & LiftFlags.Convert1) == 0));
Debug.Assert(((_grflt & LiftFlags.Lift2) == 0) || ((_grflt & LiftFlags.Convert2) == 0));
return true;
}
public bool ConvertFirst()
{
return (_grflt & LiftFlags.Convert1) != 0;
}
public bool ConvertSecond()
{
return (_grflt & LiftFlags.Convert2) != 0;
}
public CType Type1()
{
return _type1;
}
public CType Type2()
{
return _type2;
}
}
}
}
|