* Control.cs: Don't do anything in WmShowWindow if the control has been
[mono.git] / mcs / mcs / literal.cs
1 //
2 // literal.cs: Literal representation for the IL tree.
3 //
4 // Author:
5 //   Miguel de Icaza (miguel@ximian.com)
6 //   Marek Safar (marek.safar@seznam.cz)
7 //
8 // (C) 2001 Ximian, Inc.
9 //
10 //
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).
14 //
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.
20 //
21
22 using System;
23 using System.Reflection;
24 using System.Reflection.Emit;
25
26 //
27 // I put System.Null just so we do not have to special case it on 
28 // TypeManager.CSharpName
29 //
30 namespace System {
31         //
32         // Represents the Null Type, just used as a placeholder for the type in NullLiteral
33         //
34         public class Null {
35         }
36 }
37         
38 namespace Mono.CSharp {
39
40         //
41         // The NullType just exists to compare type equality, and for
42         // expressions that might have the `null type'
43         //
44         public class NullType {
45         }
46
47
48         public class NullConstant : Constant
49         {
50                 public NullConstant (Location loc):
51                         base (loc)
52                 {
53                         eclass = ExprClass.Value;
54                         type = TypeManager.null_type;
55                 }
56                 
57                 override public string AsString ()
58                 {
59                         return "null";
60                 }
61
62                 public override object GetValue ()
63                 {
64                         return null;
65                 }
66
67                 public override void Emit (EmitContext ec)
68                 {
69                         ec.ig.Emit(OpCodes.Ldnull);
70                 }
71                 
72                 public override string ExprClassName {
73                         get {
74                                 return GetSignatureForError ();
75                         }
76                 }
77
78                 public override string GetSignatureForError ()
79                 {
80                         return "null";
81                 }
82
83                 public override Constant Increment ()
84                 {
85                         throw new NotSupportedException ();
86                 }
87
88                 public override bool IsDefaultValue 
89                 {
90                         get { return true; }
91                 }
92
93                 public override bool IsNegative 
94                 {
95                         get { return false; }
96                 }
97
98                 public override bool IsZeroInteger 
99                 {
100                         get { return true; }
101                 }
102
103                 public override Constant ConvertExplicitly(bool inCheckedContext, Type target_type)
104                 {
105                         if (!TypeManager.IsValueType (target_type))
106                                 return new EmptyConstantCast (this, target_type);
107
108                         return null;
109                 }
110
111                 public override Constant ConvertImplicitly (Type targetType)
112                 {
113                         if (!TypeManager.IsValueType (targetType))
114                                 return new EmptyConstantCast (this, targetType);
115
116                         return null;
117                 }
118         }
119
120         //
121         // Represents default(X) when result can be reduced to null
122         //
123         public class NullDefault : EmptyConstantCast
124         {
125                 public NullDefault(Constant value, Type type)
126                         : base (value, type)
127                 {
128                 }
129
130                 public override void Error_ValueCannotBeConverted (EmitContext ec, Location loc, Type target, bool expl)
131                 {
132                         base.Error_ValueCannotBeConverted (ec, loc, target, expl);
133                 }
134         }
135
136         //
137         // The null Literal constant
138         //
139         public class NullLiteral : NullConstant {
140                 public NullLiteral (Location loc):
141                         base (loc)
142                 {
143                 }
144
145                 public override Expression DoResolve (EmitContext ec)
146                 {
147                         type = TypeManager.null_type;
148                         return this;
149                 }
150
151                 public override void Error_ValueCannotBeConverted (EmitContext ec, Location loc, Type t, bool expl)
152                 {
153                         if (TypeManager.IsGenericParameter (t)) {
154                                 Report.Error(403, loc,
155                                         "Cannot convert null to the type parameter `{0}' because it could be a value " +
156                                         "type. Consider using `default ({0})' instead", t.Name);
157                         } else {
158                                 Report.Error(37, loc, "Cannot convert null to `{0}' because it is a value type",
159                                         TypeManager.CSharpName(t));
160                         }
161                 }
162
163                 public override Constant ConvertImplicitly (Type targetType)
164                 {
165                         if (targetType.IsPointer)
166                                 return new EmptyConstantCast (NullPointer.Null, targetType);
167
168                         if (TypeManager.IsGenericParameter(targetType)) {
169                                 GenericConstraints gc = null;
170
171 #if GMCS_SOURCE
172                                 gc = TypeManager.GetTypeParameterConstraints(targetType);
173 #endif
174                                 if (gc != null && gc.IsReferenceType)
175                                         return new EmptyConstantCast (this, targetType);
176
177                                 return null;
178                         }
179
180                         return base.ConvertImplicitly(targetType);
181                 }
182
183         }
184
185         //
186         // A null literal in a pointer context
187         //
188         public class NullPointer : NullLiteral {
189                 public static readonly NullLiteral Null;
190
191                 static NullPointer ()
192                 {
193                         Null = new NullPointer ();
194                 }
195
196                 private NullPointer ():
197                         base (Location.Null)
198                 {
199                         type = TypeManager.object_type;
200                 }
201
202                 public override void Emit (EmitContext ec)
203                 {
204                         ILGenerator ig = ec.ig;
205                                 
206                         // TODO: why not use Ldnull instead ?
207                         ig.Emit (OpCodes.Ldc_I4_0);
208                         ig.Emit (OpCodes.Conv_U);
209                 }
210         }
211
212         public class BoolLiteral : BoolConstant {
213                 public BoolLiteral (bool val, Location loc) : base (val, loc)
214                 {
215                 }
216
217                 public override Expression DoResolve (EmitContext ec)
218                 {
219                         type = TypeManager.bool_type;
220                         return this;
221                 }
222         }
223
224         public class CharLiteral : CharConstant {
225                 public CharLiteral (char c, Location loc) : base (c, loc)
226                 {
227                 }
228
229                 public override Expression DoResolve (EmitContext ec)
230                 {
231                         type = TypeManager.char_type;
232                         return this;
233                 }
234         }
235
236         public class IntLiteral : IntConstant {
237                 public IntLiteral (int l, Location loc) : base (l, loc)
238                 {
239                 }
240
241                 public override Expression DoResolve (EmitContext ec)
242                 {
243                         type = TypeManager.int32_type;
244                         return this;
245                 }
246
247                 public override Constant ConvertImplicitly (Type type)
248                 {
249                         ///
250                         /// The 0 literal can be converted to an enum value,
251                         ///
252                         if (Value == 0 && TypeManager.IsEnumType (type)) {
253                                 Constant c = ConvertImplicitly (TypeManager.EnumToUnderlying (type));
254                                 if (c == null)
255                                         return null;
256
257                                 return new EnumConstant (c, type);
258                         }
259                         return base.ConvertImplicitly (type);
260                 }
261
262         }
263
264         public class UIntLiteral : UIntConstant {
265                 public UIntLiteral (uint l, Location loc) : base (l, loc)
266                 {
267                 }
268
269                 public override Expression DoResolve (EmitContext ec)
270                 {
271                         type = TypeManager.uint32_type;
272                         return this;
273                 }
274         }
275         
276         public class LongLiteral : LongConstant {
277                 public LongLiteral (long l, Location loc) : base (l, loc)
278                 {
279                 }
280
281                 public override Expression DoResolve (EmitContext ec)
282                 {
283                         type = TypeManager.int64_type;
284
285                         return this;
286                 }
287         }
288
289         public class ULongLiteral : ULongConstant {
290                 public ULongLiteral (ulong l, Location loc) : base (l, loc)
291                 {
292                 }
293
294                 public override Expression DoResolve (EmitContext ec)
295                 {
296                         type = TypeManager.uint64_type;
297                         return this;
298                 }
299         }
300         
301         public class FloatLiteral : FloatConstant {
302                 
303                 public FloatLiteral (float f, Location loc) : base (f, loc)
304                 {
305                 }
306
307                 public override Expression DoResolve (EmitContext ec)
308                 {
309                         type = TypeManager.float_type;
310                         return this;
311                 }
312         }
313
314         public class DoubleLiteral : DoubleConstant {
315                 public DoubleLiteral (double d, Location loc) : base (d, loc)
316                 {
317                 }
318
319                 public override Expression DoResolve (EmitContext ec)
320                 {
321                         type = TypeManager.double_type;
322
323                         return this;
324                 }
325
326                 public override void Error_ValueCannotBeConverted (EmitContext ec, Location loc, Type target, bool expl)
327                 {
328                         if (target == TypeManager.float_type) {
329                                 Error_664 (loc, "float", "f");
330                                 return;
331                         }
332
333                         if (target == TypeManager.decimal_type) {
334                                 Error_664 (loc, "decimal", "m");
335                                 return;
336                         }
337
338                         base.Error_ValueCannotBeConverted (ec, loc, target, expl);
339                 }
340
341                 static void Error_664 (Location loc, string type, string suffix)
342                 {
343                         Report.Error (664, loc,
344                                 "Literal of type double cannot be implicitly converted to type `{0}'. Add suffix `{1}' to create a literal of this type",
345                                 type, suffix);
346                 }
347         }
348
349         public class DecimalLiteral : DecimalConstant {
350                 public DecimalLiteral (decimal d, Location loc) : base (d, loc)
351                 {
352                 }
353
354                 public override Expression DoResolve (EmitContext ec)
355                 {
356                         type = TypeManager.decimal_type;
357                         return this;
358                 }
359         }
360
361         public class StringLiteral : StringConstant {
362                 public StringLiteral (string s, Location loc) : base (s, loc)
363                 {
364                 }
365
366                 public override Expression DoResolve (EmitContext ec)
367                 {
368                         type = TypeManager.string_type;
369
370                         return this;
371                 }
372         }
373 }