2 // literal.cs: Literal representation for the IL tree.
5 // Miguel de Icaza (miguel@ximian.com)
6 // Marek Safar (marek.safar@seznam.cz)
8 // Copyright 2001 Ximian, Inc.
11 // Notice that during parsing we create objects of type Literal, but the
12 // types are not loaded (thats why the Resolve method has to assign the
13 // type at that point).
15 // Literals differ from the constants in that we know we encountered them
16 // as a literal in the source code (and some extra rules apply there) and
17 // they have to be resolved (since during parsing we have not loaded the
18 // types yet) while constants are created only after types have been loaded
19 // and are fully resolved when born.
23 using System
.Reflection
;
24 using System
.Reflection
.Emit
;
26 namespace Mono
.CSharp
{
31 // Note: C# specification null-literal is NullLiteral of NullType type
33 public class NullLiteral
: NullConstant
36 // Default type of null is an object
38 public NullLiteral (Location loc
)
39 : base (InternalType
.Null
, loc
)
43 public override void Error_ValueCannotBeConverted (ResolveContext ec
, Location loc
, TypeSpec t
, bool expl
)
45 if (t
.IsGenericParameter
) {
46 ec
.Report
.Error(403, loc
,
47 "Cannot convert null to the type parameter `{0}' because it could be a value " +
48 "type. Consider using `default ({0})' instead", t
.Name
);
52 if (TypeManager
.IsValueType (t
)) {
53 ec
.Report
.Error(37, loc
, "Cannot convert null to `{0}' because it is a value type",
54 TypeManager
.CSharpName(t
));
58 base.Error_ValueCannotBeConverted (ec
, loc
, t
, expl
);
61 public override bool IsLiteral
{
65 public override System
.Linq
.Expressions
.Expression
MakeExpression (BuilderContext ctx
)
67 return System
.Linq
.Expressions
.Expression
.Constant (null);
72 // A null literal in a pointer context
74 class NullPointer
: NullLiteral
{
75 public NullPointer (Location loc
):
78 type
= TypeManager
.object_type
;
81 public override void Emit (EmitContext ec
)
86 ec
.Emit (OpCodes
.Ldc_I4_0
);
87 ec
.Emit (OpCodes
.Conv_U
);
91 public class BoolLiteral
: BoolConstant
{
92 public BoolLiteral (bool val
, Location loc
) : base (val
, loc
)
96 public override bool IsLiteral
{
101 public class CharLiteral
: CharConstant
{
102 public CharLiteral (char c
, Location loc
) : base (c
, loc
)
106 public override bool IsLiteral
{
111 public class IntLiteral
: IntConstant
{
112 public IntLiteral (int l
, Location loc
) : base (l
, loc
)
116 public override Constant
ConvertImplicitly (ResolveContext rc
, TypeSpec type
)
119 // The 0 literal can be converted to an enum value
121 if (Value
== 0 && TypeManager
.IsEnumType (type
)) {
122 Constant c
= ConvertImplicitly (rc
, EnumSpec
.GetUnderlyingType (type
));
126 return new EnumConstant (c
, type
).Resolve (rc
);
129 return base.ConvertImplicitly (rc
, type
);
132 public override bool IsLiteral
{
137 public class UIntLiteral
: UIntConstant
{
138 public UIntLiteral (uint l
, Location loc
) : base (l
, loc
)
142 public override bool IsLiteral
{
147 public class LongLiteral
: LongConstant
{
148 public LongLiteral (long l
, Location loc
) : base (l
, loc
)
152 public override bool IsLiteral
{
157 public class ULongLiteral
: ULongConstant
{
158 public ULongLiteral (ulong l
, Location loc
) : base (l
, loc
)
162 public override bool IsLiteral
{
167 public class FloatLiteral
: FloatConstant
{
169 public FloatLiteral (float f
, Location loc
) : base (f
, loc
)
173 public override bool IsLiteral
{
179 public class DoubleLiteral
: DoubleConstant
{
180 public DoubleLiteral (double d
, Location loc
) : base (d
, loc
)
184 public override void Error_ValueCannotBeConverted (ResolveContext ec
, Location loc
, TypeSpec target
, bool expl
)
186 if (target
== TypeManager
.float_type
) {
187 Error_664 (ec
, loc
, "float", "f");
191 if (target
== TypeManager
.decimal_type
) {
192 Error_664 (ec
, loc
, "decimal", "m");
196 base.Error_ValueCannotBeConverted (ec
, loc
, target
, expl
);
199 static void Error_664 (ResolveContext ec
, Location loc
, string type
, string suffix
)
201 ec
.Report
.Error (664, loc
,
202 "Literal of type double cannot be implicitly converted to type `{0}'. Add suffix `{1}' to create a literal of this type",
206 public override bool IsLiteral
{
212 public class DecimalLiteral
: DecimalConstant
{
213 public DecimalLiteral (decimal d
, Location loc
) : base (d
, loc
)
217 public override bool IsLiteral
{
222 public class StringLiteral
: StringConstant
{
223 public StringLiteral (string s
, Location loc
) : base (s
, loc
)
227 public override bool IsLiteral
{