using System.Reflection;
using System.Reflection.Emit;
+//
+// I put System.Null just so we do not have to special case it on
+// TypeManager.CSharpName
+//
+namespace System {
+ //
+ // Represents the Null Type, just used as a placeholder for the type in NullLiteral
+ //
+ public class Null {
+ }
+}
+
namespace Mono.CSharp {
- public class NullLiteral : Constant {
- public static readonly NullLiteral Null;
+ //
+ // The NullType just exists to compare type equality, and for
+ // expressions that might have the `null type'
+ //
+ public class NullType {
+ }
- static NullLiteral ()
- {
- Null = new NullLiteral ();
- }
-
- public NullLiteral ()
+ //
+ // The null Literal constant
+ //
+ public class NullLiteral : Constant {
+ public NullLiteral (Location loc):
+ base (loc)
{
eclass = ExprClass.Value;
}
public override Expression DoResolve (EmitContext ec)
{
- type = TypeManager.object_type;
+ type = TypeManager.null_type;
return this;
}
{
ec.ig.Emit (OpCodes.Ldnull);
}
-
+
+ public override Constant Increment ()
+ {
+ throw new NotSupportedException ();
+ }
+
+ public override bool IsDefaultValue {
+ get {
+ return true;
+ }
+ }
+
+ public override bool IsNegative {
+ get {
+ return false;
+ }
+ }
+
public override bool IsZeroInteger {
get { return true; }
}
+
+ public override string GetSignatureForError()
+ {
+ return "null";
+ }
+
+ public override void Error_ValueCannotBeConverted (Location loc, Type t, bool expl)
+ {
+ Report.Error (37, loc, "Cannot convert null to `{0}' because it is a value type",
+ TypeManager.CSharpName (t));
+ }
+
+ public override Constant ToType (Type type, Location loc)
+ {
+ if (!type.IsValueType && !TypeManager.IsEnumType (type))
+ return this;
+
+ return base.ToType (type, loc);
+ }
+
+ public override Constant Reduce(EmitContext ec, Type target_type)
+ {
+ if (!TypeManager.IsValueType (target_type))
+ return new NullCast (this, target_type);
+
+ return null;
+ }
}
//
// A null literal in a pointer context
//
public class NullPointer : NullLiteral {
- public new static readonly NullLiteral Null;
+ public static readonly NullLiteral Null;
static NullPointer ()
{
Null = new NullPointer ();
}
-
+
+ private NullPointer ():
+ base (Location.Null)
+ {
+ type = TypeManager.object_type;
+ }
+
public override void Emit (EmitContext ec)
{
ILGenerator ig = ec.ig;
}
public class BoolLiteral : BoolConstant {
- public BoolLiteral (bool val) : base (val)
+ public BoolLiteral (bool val, Location loc) : base (val, loc)
{
}
}
public class CharLiteral : CharConstant {
- public CharLiteral (char c) : base (c)
+ public CharLiteral (char c, Location loc) : base (c, loc)
{
}
}
public class IntLiteral : IntConstant {
- public static IntLiteral One, Zero;
-
- static IntLiteral ()
- {
- Zero = new IntLiteral (0);
- One = new IntLiteral (1);
- }
-
- public IntLiteral (int l) : base (l)
+ public IntLiteral (int l, Location loc) : base (l, loc)
{
}
}
public class UIntLiteral : UIntConstant {
- public UIntLiteral (uint l) : base (l)
+ public UIntLiteral (uint l, Location loc) : base (l, loc)
{
}
}
public class LongLiteral : LongConstant {
- public LongLiteral (long l) : base (l)
+ public LongLiteral (long l, Location loc) : base (l, loc)
{
}
}
public class ULongLiteral : ULongConstant {
- public ULongLiteral (ulong l) : base (l)
+ public ULongLiteral (ulong l, Location loc) : base (l, loc)
{
}
public class FloatLiteral : FloatConstant {
- public FloatLiteral (float f) : base (f)
+ public FloatLiteral (float f, Location loc) : base (f, loc)
{
}
}
public class DoubleLiteral : DoubleConstant {
- public DoubleLiteral (double d) : base (d)
+ public DoubleLiteral (double d, Location loc) : base (d, loc)
{
}
}
public class DecimalLiteral : DecimalConstant {
- public DecimalLiteral (decimal d) : base (d)
+ public DecimalLiteral (decimal d, Location loc) : base (d, loc)
{
}
}
public class StringLiteral : StringConstant {
- public StringLiteral (string s) : base (s)
+ public StringLiteral (string s, Location loc) : base (s, loc)
{
}