mirror of https://github.com/icsharpcode/ILSpy.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
239 lines
5.1 KiB
239 lines
5.1 KiB
// |
|
// literal.cs: Literal representation for the IL tree. |
|
// |
|
// Author: |
|
// Miguel de Icaza (miguel@ximian.com) |
|
// Marek Safar (marek.safar@seznam.cz) |
|
// |
|
// Copyright 2001 Ximian, Inc. |
|
// |
|
// |
|
// Notice that during parsing we create objects of type Literal, but the |
|
// types are not loaded (thats why the Resolve method has to assign the |
|
// type at that point). |
|
// |
|
// Literals differ from the constants in that we know we encountered them |
|
// as a literal in the source code (and some extra rules apply there) and |
|
// they have to be resolved (since during parsing we have not loaded the |
|
// types yet) while constants are created only after types have been loaded |
|
// and are fully resolved when born. |
|
// |
|
|
|
#if STATIC |
|
using IKVM.Reflection.Emit; |
|
#else |
|
using System.Reflection.Emit; |
|
#endif |
|
|
|
namespace Mono.CSharp { |
|
|
|
// |
|
// The null literal |
|
// |
|
// Note: C# specification null-literal is NullLiteral of NullType type |
|
// |
|
public class NullLiteral : NullConstant |
|
{ |
|
// |
|
// Default type of null is an object |
|
// |
|
public NullLiteral (Location loc) |
|
: base (InternalType.Null, loc) |
|
{ |
|
} |
|
|
|
public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec t, bool expl) |
|
{ |
|
if (t.IsGenericParameter) { |
|
ec.Report.Error(403, loc, |
|
"Cannot convert null to the type parameter `{0}' because it could be a value " + |
|
"type. Consider using `default ({0})' instead", t.Name); |
|
return; |
|
} |
|
|
|
if (TypeManager.IsValueType (t)) { |
|
ec.Report.Error(37, loc, "Cannot convert null to `{0}' because it is a value type", |
|
TypeManager.CSharpName(t)); |
|
return; |
|
} |
|
|
|
base.Error_ValueCannotBeConverted (ec, loc, t, expl); |
|
} |
|
|
|
public override string GetValueAsLiteral () |
|
{ |
|
return "null"; |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
|
|
public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx) |
|
{ |
|
return System.Linq.Expressions.Expression.Constant (null); |
|
} |
|
} |
|
|
|
// |
|
// A null literal in a pointer context |
|
// |
|
class NullPointer : NullLiteral { |
|
public NullPointer (Location loc): |
|
base (loc) |
|
{ |
|
type = TypeManager.object_type; |
|
} |
|
|
|
public override void Emit (EmitContext ec) |
|
{ |
|
// |
|
// Emits null pointer |
|
// |
|
ec.Emit (OpCodes.Ldc_I4_0); |
|
ec.Emit (OpCodes.Conv_U); |
|
} |
|
} |
|
|
|
public class BoolLiteral : BoolConstant { |
|
public BoolLiteral (bool val, Location loc) : base (val, loc) |
|
{ |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
} |
|
|
|
public class CharLiteral : CharConstant { |
|
public CharLiteral (char c, Location loc) : base (c, loc) |
|
{ |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
} |
|
|
|
public class IntLiteral : IntConstant { |
|
public IntLiteral (int l, Location loc) : base (l, loc) |
|
{ |
|
} |
|
|
|
public override Constant ConvertImplicitly (ResolveContext rc, TypeSpec type) |
|
{ |
|
// |
|
// The 0 literal can be converted to an enum value |
|
// |
|
if (Value == 0 && TypeManager.IsEnumType (type)) { |
|
Constant c = ConvertImplicitly (rc, EnumSpec.GetUnderlyingType (type)); |
|
if (c == null) |
|
return null; |
|
|
|
return new EnumConstant (c, type).Resolve (rc); |
|
} |
|
|
|
return base.ConvertImplicitly (rc, type); |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
} |
|
|
|
public class UIntLiteral : UIntConstant { |
|
public UIntLiteral (uint l, Location loc) : base (l, loc) |
|
{ |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
} |
|
|
|
public class LongLiteral : LongConstant { |
|
public LongLiteral (long l, Location loc) : base (l, loc) |
|
{ |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
} |
|
|
|
public class ULongLiteral : ULongConstant { |
|
public ULongLiteral (ulong l, Location loc) : base (l, loc) |
|
{ |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
} |
|
|
|
public class FloatLiteral : FloatConstant { |
|
|
|
public FloatLiteral (float f, Location loc) : base (f, loc) |
|
{ |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
|
|
} |
|
|
|
public class DoubleLiteral : DoubleConstant { |
|
public DoubleLiteral (double d, Location loc) : base (d, loc) |
|
{ |
|
} |
|
|
|
public override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl) |
|
{ |
|
if (target == TypeManager.float_type) { |
|
Error_664 (ec, loc, "float", "f"); |
|
return; |
|
} |
|
|
|
if (target == TypeManager.decimal_type) { |
|
Error_664 (ec, loc, "decimal", "m"); |
|
return; |
|
} |
|
|
|
base.Error_ValueCannotBeConverted (ec, loc, target, expl); |
|
} |
|
|
|
static void Error_664 (ResolveContext ec, Location loc, string type, string suffix) |
|
{ |
|
ec.Report.Error (664, loc, |
|
"Literal of type double cannot be implicitly converted to type `{0}'. Add suffix `{1}' to create a literal of this type", |
|
type, suffix); |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
|
|
} |
|
|
|
public class DecimalLiteral : DecimalConstant { |
|
public DecimalLiteral (decimal d, Location loc) : base (d, loc) |
|
{ |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
} |
|
|
|
public class StringLiteral : StringConstant { |
|
public StringLiteral (string s, Location loc) : base (s, loc) |
|
{ |
|
} |
|
|
|
public override bool IsLiteral { |
|
get { return true; } |
|
} |
|
|
|
} |
|
}
|
|
|