/// <summary>
/// Returns a stringified representation of the Operator
/// </summary>
- string OperName ()
+ static public string OperName (Operator oper)
{
switch (oper){
case Operator.UnaryPlus:
oper_names [(int) Operator.AddressOf] = "op_AddressOf";
}
- void error23 (Type t)
+ void Error23 (Type t)
{
Report.Error (
- 23, loc, "Operator " + OperName () +
+ 23, loc, "Operator " + OperName (oper) +
" cannot be applied to operand of type `" +
TypeManager.CSharpName (t) + "'");
}
case Operator.LogicalNot:
if (expr_type != TypeManager.bool_type) {
- error23 (expr_type);
+ Error23 (expr_type);
return null;
}
(expr_type == TypeManager.int64_type) ||
(expr_type == TypeManager.uint64_type) ||
(expr_type.IsSubclassOf (TypeManager.enum_type)))){
- error23 (expr_type);
+ Error23 (expr_type);
return null;
}
if (expr_type == TypeManager.uint64_type)
return new ULongConstant (~ ((ULongConstant) e).Value);
- throw new Exception (
- "FIXME: Implement constant OnesComplement of:" +
- expr_type);
+ Error23 (expr_type);
+ return null;
}
throw new Exception ("Can not constant fold");
}
ec, (MethodGroupExpr) mg, expr, loc);
if (e == null){
- error23 (expr_type);
+ Error23 (expr_type);
return null;
}
if (oper == Operator.LogicalNot){
if (expr_type != TypeManager.bool_type) {
- error23 (expr.Type);
+ Error23 (expr.Type);
return null;
}
(expr_type == TypeManager.int64_type) ||
(expr_type == TypeManager.uint64_type) ||
(expr_type.IsSubclassOf (TypeManager.enum_type)))){
- error23 (expr.Type);
+ Error23 (expr.Type);
return null;
}
type = expr_type;
// -92233720368547758087 (-2^63) to be wrote as
// decimal integer literal.
//
- error23 (expr_type);
+ Error23 (expr_type);
return null;
}
return this;
}
- error23 (expr_type);
+ Error23 (expr_type);
return null;
}
return new Indirection (expr);
}
- Error (187, loc, "No such operator '" + OperName () + "' defined for type '" +
+ Error (187, loc, "No such operator '" + OperName (oper) + "' defined for type '" +
TypeManager.CSharpName (expr_type) + "'");
return null;
}
break;
case Operator.AddressOf:
- ((IMemoryLocation)expr).AddressOf (ec);
+ ((IMemoryLocation)expr).AddressOf (ec, AddressOp.LoadStore);
break;
default:
StoreFromPtr (ec.ig, type);
}
- public void AddressOf (EmitContext ec)
+ public void AddressOf (EmitContext ec, AddressOp Mode)
{
expr.Emit (ec);
}
expr = e;
}
- string OperName ()
+ static string OperName (Mode mode)
{
return (mode == Mode.PreIncrement || mode == Mode.PostIncrement) ?
"++" : "--";
}
- void error23 (Type t)
+ void Error23 (Type t)
{
Report.Error (
- 23, loc, "Operator " + OperName () +
+ 23, loc, "Operator " + OperName (mode) +
" cannot be applied to operand of type `" +
TypeManager.CSharpName (t) + "'");
}
return null;
}
- Error (187, loc, "No such operator '" + OperName () + "' defined for type '" +
+ Error (187, loc, "No such operator '" + OperName (mode) + "' defined for type '" +
TypeManager.CSharpName (expr_type) + "'");
return null;
}
/// <summary>
/// Returns a stringified representation of the Operator
/// </summary>
- string OperName ()
+ static string OperName (Operator oper)
{
switch (oper){
case Operator.Multiply:
return ConvertImplicit (ec, expr, target_type, new Location (-1));
}
-
+
+ public static void Error_OperatorAmbiguous (Location loc, Operator oper, Type l, Type r)
+ {
+ Report.Error (
+ 34, loc, "Operator `" + OperName (oper)
+ + "' is ambiguous on operands of type `"
+ + TypeManager.CSharpName (l) + "' "
+ + "and `" + TypeManager.CSharpName (r)
+ + "'");
+ }
+
//
// Note that handling the case l == Decimal || r == Decimal
// is taken care of by the Step 1 Operator Overload resolution.
type = TypeManager.double_type;
} else if (l == TypeManager.float_type || r == TypeManager.float_type){
//
- // if either operand is of type float, th eother operand is
- // converd to type float.
+ // if either operand is of type float, the other operand is
+ // converted to type float.
//
if (r != TypeManager.double_type)
right = ConvertImplicit (ec, right, TypeManager.float_type, loc);
if ((other == TypeManager.sbyte_type) ||
(other == TypeManager.short_type) ||
(other == TypeManager.int32_type) ||
- (other == TypeManager.int64_type)){
- string oper = OperName ();
-
- Error (34, loc, "Operator `" + OperName ()
- + "' is ambiguous on operands of type `"
- + TypeManager.CSharpName (l) + "' "
- + "and `" + TypeManager.CSharpName (r)
- + "'");
- }
+ (other == TypeManager.int64_type))
+ Error_OperatorAmbiguous (loc, oper, l, r);
type = TypeManager.uint64_type;
} else if (l == TypeManager.int64_type || r == TypeManager.int64_type){
//
return true;
}
- void error19 ()
+ static public void Error_OperatorCannotBeApplied (Location loc, string name, Type l, Type r)
{
Error (19, loc,
- "Operator " + OperName () + " cannot be applied to operands of type `" +
- TypeManager.CSharpName (left.Type) + "' and `" +
- TypeManager.CSharpName (right.Type) + "'");
-
+ "Operator " + name + " cannot be applied to operands of type `" +
+ TypeManager.CSharpName (l) + "' and `" +
+ TypeManager.CSharpName (r) + "'");
+ }
+
+ void error19 ()
+ {
+ Error_OperatorCannotBeApplied (loc, OperName (oper), left.Type, right.Type);
}
static bool is_32_or_64 (Type t)
return this;
}
- /// <summary>
- /// Constant expression reducer for binary operations
- /// </summary>
- public Expression ConstantFold (EmitContext ec)
- {
- object l = ((Constant) left).GetValue ();
- object r = ((Constant) right).GetValue ();
-
- Type result_type = null;
-
- //
- // Enumerator folding
- //
- if (left.Type == right.Type && left is EnumConstant)
- result_type = left.Type;
-
- switch (oper){
- case Operator.BitwiseOr:
- if ((l is int) && (r is int)){
- IntConstant v;
- int res = (int)l | (int)r;
-
- v = new IntConstant (res);
- if (result_type == null)
- return v;
- else
- return new EnumConstant (v, result_type);
- }
- break;
-
- case Operator.BitwiseAnd:
- if ((l is int) && (r is int)){
- IntConstant v;
- int res = (int)l & (int)r;
-
- v = new IntConstant (res);
- if (result_type == null)
- return v;
- else
- return new EnumConstant (v, result_type);
- }
- break;
-
- case Operator.Addition:
- if (l is string && r is string)
- return new StringConstant ((string) l + (string) r);
- break;
- }
-
- return null;
- }
-
public override Expression DoResolve (EmitContext ec)
{
left = left.Resolve (ec);
eclass = ExprClass.Value;
if (left is Constant && right is Constant){
- //
- // This is temporary until we do the full folding
- //
- Expression e = ConstantFold (ec);
+ Expression e = ConstantFold.BinaryFold (
+ ec, oper, (Constant) left, (Constant) right, loc);
if (e != null)
return e;
}
Store (ig, vi.Idx);
}
- public void AddressOf (EmitContext ec)
+ public void AddressOf (EmitContext ec, AddressOp mode)
{
VariableInfo vi = VariableInfo;
int idx = vi.Idx;
- vi.Used = true;
- vi.Assigned = true;
+ if ((mode & AddressOp.Load) != 0)
+ vi.Used = true;
+ if ((mode & AddressOp.Store) != 0)
+ vi.Assigned = true;
if (idx <= 255)
ec.ig.Emit (OpCodes.Ldloca_S, (byte) idx);
}
- public void AddressOf (EmitContext ec)
+ public void AddressOf (EmitContext ec, AddressOp mode)
{
int arg_idx = idx;
// to pass just the value
//
if (ArgType == AType.Ref || ArgType == AType.Out){
+ AddressOp mode = AddressOp.Store;
+
+ if (ArgType == AType.Ref)
+ mode |= AddressOp.Load;
+
if (expr is ParameterReference){
ParameterReference pr = (ParameterReference) expr;
if (pr.is_ref)
pr.EmitLoad (ec);
- else
- pr.AddressOf (ec);
+ else {
+
+ pr.AddressOf (ec, mode);
+ }
} else
- ((IMemoryLocation)expr).AddressOf (ec);
+ ((IMemoryLocation)expr).AddressOf (ec, mode);
} else
expr.Emit (ec);
}
// it.
if (instance_expr is IMemoryLocation){
((IMemoryLocation)instance_expr).
- AddressOf (ec);
+ AddressOf (ec, AddressOp.LoadStore);
}
else {
Type t = instance_expr.Type;
value_target = new LocalTemporary (ec, type);
ml = (IMemoryLocation) value_target;
- ml.AddressOf (ec);
+ ml.AddressOf (ec, AddressOp.Store);
}
if (method != null)
{
int factor;
byte [] data;
-
+ byte [] element;
int count = ArrayData.Count;
factor = GetTypeSize (underlying_type);
}
}
} else if (underlying_type == TypeManager.float_type) {
- unsafe {
- if (!(v is Expression)){
- float val = (float) v;
-
- byte *ptr = (byte *) &val;
+ if (!(v is Expression)){
+ element = BitConverter.GetBytes ((float) v);
- for (int j = 0; j < factor; ++j)
- data [idx + j] = (byte) ptr [j];
- }
+ for (int j = 0; j < factor; ++j)
+ data [idx + j] = element [j];
}
} else if (underlying_type == TypeManager.double_type) {
- unsafe {
- if (!(v is Expression)){
- double val = (double) v;
+ if (!(v is Expression)){
+ element = BitConverter.GetBytes ((double) v);
- byte *ptr = (byte *) &val;
-
- for (int j = 0; j < factor; ++j)
- data [idx + j] = (byte) ptr [j];
- }
+ for (int j = 0; j < factor; ++j)
+ data [idx + j] = element [j];
}
} else if (underlying_type == TypeManager.char_type){
-
if (!(v is Expression)){
int val = (int) ((char) v);
ec.ig.Emit (OpCodes.Starg, 0);
}
- public void AddressOf (EmitContext ec)
+ public void AddressOf (EmitContext ec, AddressOp mode)
{
ec.ig.Emit (OpCodes.Ldarg_0);
public override Expression DoResolve (EmitContext ec)
{
- Expr = Expr.Resolve (ec);
+ bool last_const_check = ec.ConstantCheckState;
+ ec.ConstantCheckState = true;
+ Expr = Expr.Resolve (ec);
+ ec.ConstantCheckState = last_const_check;
+
if (Expr == null)
return null;
public override void Emit (EmitContext ec)
{
bool last_check = ec.CheckState;
+ bool last_const_check = ec.ConstantCheckState;
ec.CheckState = true;
+ ec.ConstantCheckState = true;
Expr.Emit (ec);
ec.CheckState = last_check;
+ ec.ConstantCheckState = last_const_check;
}
}
public override Expression DoResolve (EmitContext ec)
{
+ bool last_const_check = ec.ConstantCheckState;
+
+ ec.ConstantCheckState = false;
Expr = Expr.Resolve (ec);
+ ec.ConstantCheckState = last_const_check;
if (Expr == null)
return null;
public override void Emit (EmitContext ec)
{
bool last_check = ec.CheckState;
+ bool last_const_check = ec.ConstantCheckState;
ec.CheckState = false;
+ ec.ConstantCheckState = false;
Expr.Emit (ec);
ec.CheckState = last_check;
+ ec.ConstantCheckState = last_const_check;
}
}
}
}
- public void AddressOf (EmitContext ec)
+ public void AddressOf (EmitContext ec, AddressOp mode)
{
int rank = ea.Expr.Type.GetArrayRank ();
ILGenerator ig = ec.ig;