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.
9 // Copyright 2011 Xamarin Inc
12 // Notice that during parsing we create objects of type Literal, but the
13 // types are not loaded (thats why the Resolve method has to assign the
14 // type at that point).
16 // Literals differ from the constants in that we know we encountered them
17 // as a literal in the source code (and some extra rules apply there) and
18 // they have to be resolved (since during parsing we have not loaded the
19 // types yet) while constants are created only after types have been loaded
20 // and are fully resolved when born.
24 using IKVM.Reflection.Emit;
26 using System.Reflection.Emit;
31 public interface ILiteralConstant
34 char[] ParsedValue { get; set; }
41 // Note: C# specification null-literal is NullLiteral of NullType type
43 public class NullLiteral : NullConstant
46 // Default type of null is an object
48 public NullLiteral (Location loc)
49 : base (InternalType.NullLiteral, loc)
53 public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec t, bool expl)
55 if (t.IsGenericParameter) {
56 ec.Report.Error(403, loc,
57 "Cannot convert null to the type parameter `{0}' because it could be a value " +
58 "type. Consider using `default ({0})' instead", t.Name);
62 if (TypeSpec.IsValueType (t)) {
63 ec.Report.Error(37, loc, "Cannot convert null to `{0}' because it is a value type",
64 t.GetSignatureForError ());
68 base.Error_ValueCannotBeConverted (ec, t, expl);
71 public override string GetValueAsLiteral ()
76 public override bool IsLiteral {
80 public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)
82 return System.Linq.Expressions.Expression.Constant (null);
86 public class BoolLiteral : BoolConstant, ILiteralConstant
88 public BoolLiteral (BuiltinTypes types, bool val, Location loc)
89 : base (types, val, loc)
93 public override bool IsLiteral {
98 public char[] ParsedValue { get; set; }
101 public override object Accept (StructuralVisitor visitor)
103 return visitor.Visit (this);
107 public class CharLiteral : CharConstant, ILiteralConstant
109 public CharLiteral (BuiltinTypes types, char c, Location loc)
110 : base (types, c, loc)
114 public override bool IsLiteral {
119 public char[] ParsedValue { get; set; }
122 public override object Accept (StructuralVisitor visitor)
124 return visitor.Visit (this);
128 public class IntLiteral : IntConstant, ILiteralConstant
130 public IntLiteral (BuiltinTypes types, int l, Location loc)
131 : base (types, l, loc)
135 public override Constant ConvertImplicitly (TypeSpec type)
138 // The 0 literal can be converted to an enum value
140 if (Value == 0 && type.IsEnum) {
141 Constant c = ConvertImplicitly (EnumSpec.GetUnderlyingType (type));
145 return new EnumConstant (c, type);
148 return base.ConvertImplicitly (type);
151 public override bool IsLiteral {
156 public char[] ParsedValue { get; set; }
159 public override object Accept (StructuralVisitor visitor)
161 return visitor.Visit (this);
165 public class UIntLiteral : UIntConstant, ILiteralConstant
167 public UIntLiteral (BuiltinTypes types, uint l, Location loc)
168 : base (types, l, loc)
172 public override bool IsLiteral {
177 public char[] ParsedValue { get; set; }
180 public override object Accept (StructuralVisitor visitor)
182 return visitor.Visit (this);
186 public class LongLiteral : LongConstant, ILiteralConstant
188 public LongLiteral (BuiltinTypes types, long l, Location loc)
189 : base (types, l, loc)
193 public override bool IsLiteral {
198 public char[] ParsedValue { get; set; }
201 public override object Accept (StructuralVisitor visitor)
203 return visitor.Visit (this);
207 public class ULongLiteral : ULongConstant, ILiteralConstant
209 public ULongLiteral (BuiltinTypes types, ulong l, Location loc)
210 : base (types, l, loc)
214 public override bool IsLiteral {
219 public char[] ParsedValue { get; set; }
222 public override object Accept (StructuralVisitor visitor)
224 return visitor.Visit (this);
228 public class FloatLiteral : FloatConstant, ILiteralConstant
230 public FloatLiteral (BuiltinTypes types, float f, Location loc)
231 : base (types, f, loc)
235 public override bool IsLiteral {
240 public char[] ParsedValue { get; set; }
243 public override object Accept (StructuralVisitor visitor)
245 return visitor.Visit (this);
249 public class DoubleLiteral : DoubleConstant, ILiteralConstant
251 public DoubleLiteral (BuiltinTypes types, double d, Location loc)
252 : base (types, d, loc)
256 public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
258 if (target.BuiltinType == BuiltinTypeSpec.Type.Float) {
259 Error_664 (ec, loc, "float", "f");
263 if (target.BuiltinType == BuiltinTypeSpec.Type.Decimal) {
264 Error_664 (ec, loc, "decimal", "m");
268 base.Error_ValueCannotBeConverted (ec, target, expl);
271 static void Error_664 (ResolveContext ec, Location loc, string type, string suffix)
273 ec.Report.Error (664, loc,
274 "Literal of type double cannot be implicitly converted to type `{0}'. Add suffix `{1}' to create a literal of this type",
278 public override bool IsLiteral {
283 public char[] ParsedValue { get; set; }
286 public override object Accept (StructuralVisitor visitor)
288 return visitor.Visit (this);
292 public class DecimalLiteral : DecimalConstant, ILiteralConstant
294 public DecimalLiteral (BuiltinTypes types, decimal d, Location loc)
295 : base (types, d, loc)
299 public override bool IsLiteral {
304 public char[] ParsedValue { get; set; }
307 public override object Accept (StructuralVisitor visitor)
309 return visitor.Visit (this);
313 public class StringLiteral : StringConstant, ILiteralConstant
315 public StringLiteral (BuiltinTypes types, string s, Location loc)
316 : base (types, s, loc)
320 public override bool IsLiteral {
325 public char[] ParsedValue { get; set; }
328 public override object Accept (StructuralVisitor visitor)
330 return visitor.Visit (this);