~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to contrib/ICSharpCode.NRefactory.CSharp/Parser/mcs/constant.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//
2
 
// constant.cs: Constants.
3
 
//
4
 
// Author:
5
 
//   Miguel de Icaza (miguel@ximian.com)
6
 
//   Marek Safar (marek.safar@seznam.cz)
7
 
//
8
 
// Copyright 2001-2003 Ximian, Inc.
9
 
// Copyright 2003-2008 Novell, Inc.
10
 
// Copyright 2011 Xamarin Inc
11
 
//
12
 
 
13
 
using System;
14
 
using System.Globalization;
15
 
 
16
 
#if STATIC
17
 
using IKVM.Reflection.Emit;
18
 
#else
19
 
using System.Reflection.Emit;
20
 
#endif
21
 
 
22
 
namespace Mono.CSharp {
23
 
 
24
 
        /// <summary>
25
 
        ///   Base class for constants and literals.
26
 
        /// </summary>
27
 
        public abstract class Constant : Expression
28
 
        {
29
 
                static readonly NumberFormatInfo nfi = CultureInfo.InvariantCulture.NumberFormat;
30
 
 
31
 
                protected Constant (Location loc)
32
 
                {
33
 
                        this.loc = loc;
34
 
                }
35
 
 
36
 
                override public string ToString ()
37
 
                {
38
 
                        return this.GetType ().Name + " (" + GetValueAsLiteral () + ")";
39
 
                }
40
 
 
41
 
                /// <summary>
42
 
                ///  This is used to obtain the actual value of the literal
43
 
                ///  cast into an object.
44
 
                /// </summary>
45
 
                public abstract object GetValue ();
46
 
 
47
 
                public abstract long GetValueAsLong ();
48
 
 
49
 
                public abstract string GetValueAsLiteral ();
50
 
 
51
 
#if !STATIC
52
 
                //
53
 
                // Returns an object value which is typed to contant type
54
 
                //
55
 
                public virtual object GetTypedValue ()
56
 
                {
57
 
                        return GetValue ();
58
 
                }
59
 
#endif
60
 
 
61
 
                public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
62
 
                {
63
 
                        if (!expl && IsLiteral && 
64
 
                                BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (target) &&
65
 
                                BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (type)) {
66
 
                                ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
67
 
                                        GetValueAsLiteral (), TypeManager.CSharpName (target));
68
 
                        } else {
69
 
                                base.Error_ValueCannotBeConverted (ec, target, expl);
70
 
                        }
71
 
                }
72
 
 
73
 
                public Constant ImplicitConversionRequired (ResolveContext ec, TypeSpec type, Location loc)
74
 
                {
75
 
                        Constant c = ConvertImplicitly (type);
76
 
                        if (c == null)
77
 
                                Error_ValueCannotBeConverted (ec, type, false);
78
 
 
79
 
                        return c;
80
 
                }
81
 
 
82
 
                public override bool ContainsEmitWithAwait ()
83
 
                {
84
 
                        return false;
85
 
                }
86
 
 
87
 
                public virtual Constant ConvertImplicitly (TypeSpec type)
88
 
                {
89
 
                        if (this.type == type)
90
 
                                return this;
91
 
 
92
 
                        if (Convert.ImplicitNumericConversion (this, type) == null) 
93
 
                                return null;
94
 
 
95
 
                        bool fail;                      
96
 
                        object constant_value = ChangeType (GetValue (), type, out fail);
97
 
                        if (fail){
98
 
                                //
99
 
                                // We should always catch the error before this is ever
100
 
                                // reached, by calling Convert.ImplicitStandardConversionExists
101
 
                                //
102
 
                                throw new InternalErrorException ("Missing constant conversion between `{0}' and `{1}'",
103
 
                                  TypeManager.CSharpName (Type), TypeManager.CSharpName (type));
104
 
                        }
105
 
 
106
 
                        return CreateConstant (type, constant_value, loc);
107
 
                }
108
 
 
109
 
                //
110
 
                //  Returns a constant instance based on Type
111
 
                //
112
 
                public static Constant CreateConstant (TypeSpec t, object v, Location loc)
113
 
                {
114
 
                        return CreateConstantFromValue (t, v, loc);
115
 
                }
116
 
 
117
 
                public static Constant CreateConstantFromValue (TypeSpec t, object v, Location loc)
118
 
                {
119
 
                        switch (t.BuiltinType) {
120
 
                        case BuiltinTypeSpec.Type.Int:
121
 
                                return new IntConstant (t, (int) v, loc);
122
 
                        case BuiltinTypeSpec.Type.String:
123
 
                                return new StringConstant (t, (string) v, loc);
124
 
                        case BuiltinTypeSpec.Type.UInt:
125
 
                                return new UIntConstant (t, (uint) v, loc);
126
 
                        case BuiltinTypeSpec.Type.Long:
127
 
                                return new LongConstant (t, (long) v, loc);
128
 
                        case BuiltinTypeSpec.Type.ULong:
129
 
                                return new ULongConstant (t, (ulong) v, loc);
130
 
                        case BuiltinTypeSpec.Type.Float:
131
 
                                return new FloatConstant (t, (float) v, loc);
132
 
                        case BuiltinTypeSpec.Type.Double:
133
 
                                return new DoubleConstant (t, (double) v, loc);
134
 
                        case BuiltinTypeSpec.Type.Short:
135
 
                                return new ShortConstant (t, (short) v, loc);
136
 
                        case BuiltinTypeSpec.Type.UShort:
137
 
                                return new UShortConstant (t, (ushort) v, loc);
138
 
                        case BuiltinTypeSpec.Type.SByte:
139
 
                                return new SByteConstant (t, (sbyte) v, loc);
140
 
                        case BuiltinTypeSpec.Type.Byte:
141
 
                                return new ByteConstant (t, (byte) v, loc);
142
 
                        case BuiltinTypeSpec.Type.Char:
143
 
                                return new CharConstant (t, (char) v, loc);
144
 
                        case BuiltinTypeSpec.Type.Bool:
145
 
                                return new BoolConstant (t, (bool) v, loc);
146
 
                        case BuiltinTypeSpec.Type.Decimal:
147
 
                                return new DecimalConstant (t, (decimal) v, loc);
148
 
                        }
149
 
 
150
 
                        if (t.IsEnum) {
151
 
                                var real_type = EnumSpec.GetUnderlyingType (t);
152
 
                                return new EnumConstant (CreateConstantFromValue (real_type, v, loc), t);
153
 
                        }
154
 
 
155
 
                        if (v == null) {
156
 
                                if (t.IsNullableType)
157
 
                                        return Nullable.LiftedNull.Create (t, loc);
158
 
 
159
 
                                if (TypeSpec.IsReferenceType (t))
160
 
                                        return new NullConstant (t, loc);
161
 
                        }
162
 
 
163
 
#if STATIC
164
 
                        throw new InternalErrorException ("Constant value `{0}' has unexpected underlying type `{1}'", v, t.GetSignatureForError ());
165
 
#else
166
 
                        return null;
167
 
#endif
168
 
                }
169
 
 
170
 
                public override Expression CreateExpressionTree (ResolveContext ec)
171
 
                {
172
 
                        Arguments args = new Arguments (2);
173
 
                        args.Add (new Argument (this));
174
 
                        args.Add (new Argument (new TypeOf (type, loc)));
175
 
 
176
 
                        return CreateExpressionFactoryCall (ec, "Constant", args);
177
 
                }
178
 
 
179
 
                /// <summary>
180
 
                /// Maybe ConvertTo name is better. It tries to convert `this' constant to target_type.
181
 
                /// It throws OverflowException 
182
 
                /// </summary>
183
 
                // DON'T CALL THIS METHOD DIRECTLY AS IT DOES NOT HANDLE ENUMS
184
 
                public abstract Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type);
185
 
 
186
 
                // This is a custom version of Convert.ChangeType() which works
187
 
                // with the TypeBuilder defined types when compiling corlib.
188
 
                static object ChangeType (object value, TypeSpec targetType, out bool error)
189
 
                {
190
 
                        IConvertible convert_value = value as IConvertible;
191
 
 
192
 
                        if (convert_value == null) {
193
 
                                error = true;
194
 
                                return null;
195
 
                        }
196
 
 
197
 
                        //
198
 
                        // We cannot rely on build-in type conversions as they are
199
 
                        // more limited than what C# supports.
200
 
                        // See char -> float/decimal/double conversion
201
 
                        //
202
 
                        error = false;
203
 
                        try {
204
 
                                switch (targetType.BuiltinType) {
205
 
                                case BuiltinTypeSpec.Type.Bool:
206
 
                                        return convert_value.ToBoolean (nfi);
207
 
                                case BuiltinTypeSpec.Type.Byte:
208
 
                                        return convert_value.ToByte (nfi);
209
 
                                case BuiltinTypeSpec.Type.Char:
210
 
                                        return convert_value.ToChar (nfi);
211
 
                                case BuiltinTypeSpec.Type.Short:
212
 
                                        return convert_value.ToInt16 (nfi);
213
 
                                case BuiltinTypeSpec.Type.Int:
214
 
                                        return convert_value.ToInt32 (nfi);
215
 
                                case BuiltinTypeSpec.Type.Long:
216
 
                                        return convert_value.ToInt64 (nfi);
217
 
                                case BuiltinTypeSpec.Type.SByte:
218
 
                                        return convert_value.ToSByte (nfi);
219
 
                                case BuiltinTypeSpec.Type.Decimal:
220
 
                                        if (convert_value.GetType () == typeof (char))
221
 
                                                return (decimal) convert_value.ToInt32 (nfi);
222
 
                                        return convert_value.ToDecimal (nfi);
223
 
                                case BuiltinTypeSpec.Type.Double:
224
 
                                        if (convert_value.GetType () == typeof (char))
225
 
                                                return (double) convert_value.ToInt32 (nfi);
226
 
                                        return convert_value.ToDouble (nfi);
227
 
                                case BuiltinTypeSpec.Type.Float:
228
 
                                        if (convert_value.GetType () == typeof (char))
229
 
                                                return (float) convert_value.ToInt32 (nfi);
230
 
                                        return convert_value.ToSingle (nfi);
231
 
                                case BuiltinTypeSpec.Type.String:
232
 
                                        return convert_value.ToString (nfi);
233
 
                                case BuiltinTypeSpec.Type.UShort:
234
 
                                        return convert_value.ToUInt16 (nfi);
235
 
                                case BuiltinTypeSpec.Type.UInt:
236
 
                                        return convert_value.ToUInt32 (nfi);
237
 
                                case BuiltinTypeSpec.Type.ULong:
238
 
                                        return convert_value.ToUInt64 (nfi);
239
 
                                case BuiltinTypeSpec.Type.Object:
240
 
                                        return value;
241
 
                                }
242
 
                        } catch {
243
 
                        }
244
 
 
245
 
                        error = true;
246
 
                        return null;
247
 
                }
248
 
 
249
 
                protected override Expression DoResolve (ResolveContext rc)
250
 
                {
251
 
                        return this;
252
 
                }
253
 
 
254
 
                /// <summary>
255
 
                ///   Attempts to do a compile-time folding of a constant cast.
256
 
                /// </summary>
257
 
                public Constant TryReduce (ResolveContext ec, TypeSpec target_type)
258
 
                {
259
 
                        try {
260
 
                                return TryReduceConstant (ec, target_type);
261
 
                        } catch (OverflowException) {
262
 
                                if (ec.ConstantCheckState && Type.BuiltinType != BuiltinTypeSpec.Type.Decimal) {
263
 
                                        ec.Report.Error (221, loc,
264
 
                                                "Constant value `{0}' cannot be converted to a `{1}' (use `unchecked' syntax to override)",
265
 
                                                GetValueAsLiteral (), target_type.GetSignatureForError ());
266
 
                                } else {
267
 
                                        Error_ValueCannotBeConverted (ec, target_type, false);
268
 
                                }
269
 
 
270
 
                                return New.Constantify (target_type, loc);
271
 
                        }
272
 
                }
273
 
 
274
 
                Constant TryReduceConstant (ResolveContext ec, TypeSpec target_type)
275
 
                {
276
 
                        if (Type == target_type) {
277
 
                                //
278
 
                                // Reducing literal value produces a new constant. Syntactically 10 is not same as (int)10 
279
 
                                //
280
 
                                if (IsLiteral)
281
 
                                        return CreateConstantFromValue (target_type, GetValue (), loc);
282
 
 
283
 
                                return this;
284
 
                        }
285
 
 
286
 
                        Constant c;
287
 
                        if (target_type.IsEnum) {
288
 
                                c = TryReduceConstant (ec, EnumSpec.GetUnderlyingType (target_type));
289
 
                                if (c == null)
290
 
                                        return null;
291
 
 
292
 
                                return new EnumConstant (c, target_type);
293
 
                        }
294
 
 
295
 
                        return ConvertExplicitly (ec.ConstantCheckState, target_type);
296
 
                }
297
 
 
298
 
                /// <summary>
299
 
                /// Need to pass type as the constant can require a boxing
300
 
                /// and in such case no optimization is possible
301
 
                /// </summary>
302
 
                public bool IsDefaultInitializer (TypeSpec type)
303
 
                {
304
 
                        if (type == Type)
305
 
                                return IsDefaultValue;
306
 
 
307
 
                        return this is NullLiteral;
308
 
                }
309
 
 
310
 
                public abstract bool IsDefaultValue {
311
 
                        get;
312
 
                }
313
 
 
314
 
                public abstract bool IsNegative {
315
 
                        get;
316
 
                }
317
 
 
318
 
                //
319
 
                // When constant is declared as literal
320
 
                //
321
 
                public virtual bool IsLiteral {
322
 
                        get { return false; }
323
 
                }
324
 
                
325
 
                public virtual bool IsOneInteger {
326
 
                        get { return false; }
327
 
                }
328
 
 
329
 
                public override bool IsSideEffectFree {
330
 
                        get {
331
 
                                return true;
332
 
                        }
333
 
                }
334
 
 
335
 
                //
336
 
                // Returns true iff 1) the stack type of this is one of Object, 
337
 
                // int32, int64 and 2) this == 0 or this == null.
338
 
                //
339
 
                public virtual bool IsZeroInteger {
340
 
                        get { return false; }
341
 
                }
342
 
 
343
 
                public override void EmitSideEffect (EmitContext ec)
344
 
                {
345
 
                        // do nothing
346
 
                }
347
 
 
348
 
                public sealed override Expression Clone (CloneContext clonectx)
349
 
                {
350
 
                        // No cloning is not needed for constants
351
 
                        return this;
352
 
                }
353
 
 
354
 
                protected override void CloneTo (CloneContext clonectx, Expression target)
355
 
                {
356
 
                        throw new NotSupportedException ("should not be reached");
357
 
                }
358
 
 
359
 
                public override System.Linq.Expressions.Expression MakeExpression (BuilderContext ctx)
360
 
                {
361
 
#if STATIC
362
 
                        return base.MakeExpression (ctx);
363
 
#else
364
 
                        return System.Linq.Expressions.Expression.Constant (GetTypedValue (), type.GetMetaInfo ());
365
 
#endif
366
 
                }
367
 
 
368
 
                public new bool Resolve (ResolveContext rc)
369
 
                {
370
 
                        // It exists only as hint not to call Resolve on constants
371
 
                        return true;
372
 
                }
373
 
                
374
 
                public override object Accept (StructuralVisitor visitor)
375
 
                {
376
 
                        return visitor.Visit (this);
377
 
                }
378
 
 
379
 
        }
380
 
 
381
 
        public abstract class IntegralConstant : Constant
382
 
        {
383
 
                protected IntegralConstant (TypeSpec type, Location loc)
384
 
                        : base (loc)
385
 
                {
386
 
                        this.type = type;
387
 
                        eclass = ExprClass.Value;
388
 
                }
389
 
 
390
 
                public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl)
391
 
                {
392
 
                        try {
393
 
                                ConvertExplicitly (true, target);
394
 
                                base.Error_ValueCannotBeConverted (ec, target, expl);
395
 
                        }
396
 
                        catch
397
 
                        {
398
 
                                ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'",
399
 
                                        GetValue ().ToString (), TypeManager.CSharpName (target));
400
 
                        }
401
 
                }
402
 
 
403
 
                public override string GetValueAsLiteral ()
404
 
                {
405
 
                        return GetValue ().ToString ();
406
 
                }
407
 
                
408
 
                public abstract Constant Increment ();
409
 
        }
410
 
        
411
 
        public class BoolConstant : Constant {
412
 
                public readonly bool Value;
413
 
 
414
 
                public BoolConstant (BuiltinTypes types, bool val, Location loc)
415
 
                        : this (types.Bool, val, loc)
416
 
                {
417
 
                }
418
 
                
419
 
                public BoolConstant (TypeSpec type, bool val, Location loc)
420
 
                        : base (loc)
421
 
                {
422
 
                        eclass = ExprClass.Value;
423
 
                        this.type = type;
424
 
 
425
 
                        Value = val;
426
 
                }
427
 
 
428
 
                public override object GetValue ()
429
 
                {
430
 
                        return (object) Value;
431
 
                }
432
 
 
433
 
                public override string GetValueAsLiteral ()
434
 
                {
435
 
                        return Value ? "true" : "false";
436
 
                }
437
 
 
438
 
                public override long GetValueAsLong ()
439
 
                {
440
 
                        return Value ? 1 : 0;
441
 
                }
442
 
 
443
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
444
 
                {
445
 
                        enc.Encode (Value);
446
 
                }
447
 
                
448
 
                public override void Emit (EmitContext ec)
449
 
                {
450
 
                        if (Value)
451
 
                                ec.EmitInt (1);
452
 
                        else
453
 
                                ec.EmitInt (0);
454
 
                }
455
 
 
456
 
                public override bool IsDefaultValue {
457
 
                        get {
458
 
                                return !Value;
459
 
                        }
460
 
                }
461
 
 
462
 
                public override bool IsNegative {
463
 
                        get {
464
 
                                return false;
465
 
                        }
466
 
                }
467
 
        
468
 
                public override bool IsZeroInteger {
469
 
                        get { return Value == false; }
470
 
                }
471
 
 
472
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
473
 
                {
474
 
                        return null;
475
 
                }
476
 
 
477
 
        }
478
 
 
479
 
        public class ByteConstant : IntegralConstant
480
 
        {
481
 
                public readonly byte Value;
482
 
 
483
 
                public ByteConstant (BuiltinTypes types, byte v, Location loc)
484
 
                        : this (types.Byte, v, loc)
485
 
                {
486
 
                }
487
 
 
488
 
                public ByteConstant (TypeSpec type, byte v, Location loc)
489
 
                        : base (type, loc)
490
 
                {
491
 
                        Value = v;
492
 
                }
493
 
 
494
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
495
 
                {
496
 
                        enc.Encode (Value);
497
 
                }
498
 
 
499
 
                public override void Emit (EmitContext ec)
500
 
                {
501
 
                        ec.EmitInt (Value);
502
 
                }
503
 
 
504
 
                public override object GetValue ()
505
 
                {
506
 
                        return Value;
507
 
                }
508
 
 
509
 
                public override long GetValueAsLong ()
510
 
                {
511
 
                        return Value;
512
 
                }
513
 
 
514
 
                public override Constant Increment ()
515
 
                {
516
 
                        return new ByteConstant (type, checked ((byte)(Value + 1)), loc);
517
 
                }
518
 
 
519
 
                public override bool IsDefaultValue {
520
 
                        get {
521
 
                                return Value == 0;
522
 
                        }
523
 
                }
524
 
 
525
 
                public override bool IsOneInteger {
526
 
                        get {
527
 
                                return Value == 1;
528
 
                        }
529
 
                }               
530
 
 
531
 
                public override bool IsNegative {
532
 
                        get {
533
 
                                return false;
534
 
                        }
535
 
                }
536
 
 
537
 
                public override bool IsZeroInteger {
538
 
                        get { return Value == 0; }
539
 
                }
540
 
 
541
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
542
 
                {
543
 
                        switch (target_type.BuiltinType) {
544
 
                        case BuiltinTypeSpec.Type.SByte:
545
 
                                if (in_checked_context){
546
 
                                        if (Value > SByte.MaxValue)
547
 
                                                throw new OverflowException ();
548
 
                                }
549
 
                                return new SByteConstant (target_type, (sbyte) Value, Location);
550
 
                        case BuiltinTypeSpec.Type.Short:
551
 
                                return new ShortConstant (target_type, (short) Value, Location);
552
 
                        case BuiltinTypeSpec.Type.UShort:
553
 
                                return new UShortConstant (target_type, (ushort) Value, Location);
554
 
                        case BuiltinTypeSpec.Type.Int:
555
 
                                return new IntConstant (target_type, (int) Value, Location);
556
 
                        case BuiltinTypeSpec.Type.UInt:
557
 
                                return new UIntConstant (target_type, (uint) Value, Location);
558
 
                        case BuiltinTypeSpec.Type.Long:
559
 
                                return new LongConstant (target_type, (long) Value, Location);
560
 
                        case BuiltinTypeSpec.Type.ULong:
561
 
                                return new ULongConstant (target_type, (ulong) Value, Location);
562
 
                        case BuiltinTypeSpec.Type.Float:
563
 
                                return new FloatConstant (target_type, (float) Value, Location);
564
 
                        case BuiltinTypeSpec.Type.Double:
565
 
                                return new DoubleConstant (target_type, (double) Value, Location);
566
 
                        case BuiltinTypeSpec.Type.Char:
567
 
                                return new CharConstant (target_type, (char) Value, Location);
568
 
                        case BuiltinTypeSpec.Type.Decimal:
569
 
                                return new DecimalConstant (target_type, (decimal) Value, Location);
570
 
                        }
571
 
 
572
 
                        return null;
573
 
                }
574
 
 
575
 
        }
576
 
 
577
 
        public class CharConstant : Constant {
578
 
                public readonly char Value;
579
 
 
580
 
                public CharConstant (BuiltinTypes types, char v, Location loc)
581
 
                        : this (types.Char, v, loc)
582
 
                {
583
 
                }
584
 
 
585
 
                public CharConstant (TypeSpec type, char v, Location loc)
586
 
                        : base (loc)
587
 
                {
588
 
                        this.type = type;
589
 
                        eclass = ExprClass.Value;
590
 
 
591
 
                        Value = v;
592
 
                }
593
 
 
594
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
595
 
                {
596
 
                        enc.Encode ((ushort) Value);
597
 
                }
598
 
 
599
 
                public override void Emit (EmitContext ec)
600
 
                {
601
 
                        ec.EmitInt (Value);
602
 
                }
603
 
 
604
 
                static string descape (char c)
605
 
                {
606
 
                        switch (c){
607
 
                        case '\a':
608
 
                                return "\\a"; 
609
 
                        case '\b':
610
 
                                return "\\b"; 
611
 
                        case '\n':
612
 
                                return "\\n"; 
613
 
                        case '\t':
614
 
                                return "\\t"; 
615
 
                        case '\v':
616
 
                                return "\\v"; 
617
 
                        case '\r':
618
 
                                return "\\r"; 
619
 
                        case '\\':
620
 
                                return "\\\\";
621
 
                        case '\f':
622
 
                                return "\\f"; 
623
 
                        case '\0':
624
 
                                return "\\0"; 
625
 
                        case '"':
626
 
                                return "\\\""; 
627
 
                        case '\'':
628
 
                                return "\\\'"; 
629
 
                        }
630
 
                        return c.ToString ();
631
 
                }
632
 
 
633
 
                public override object GetValue ()
634
 
                {
635
 
                        return Value;
636
 
                }
637
 
 
638
 
                public override long GetValueAsLong ()
639
 
                {
640
 
                        return Value;
641
 
                }
642
 
 
643
 
                public override string GetValueAsLiteral ()
644
 
                {
645
 
                        return "\"" + descape (Value) + "\"";
646
 
                }
647
 
 
648
 
                public override bool IsDefaultValue {
649
 
                        get {
650
 
                                return Value == 0;
651
 
                        }
652
 
                }
653
 
 
654
 
                public override bool IsNegative {
655
 
                        get {
656
 
                                return false;
657
 
                        }
658
 
                }
659
 
 
660
 
                public override bool IsZeroInteger {
661
 
                        get { return Value == '\0'; }
662
 
                }
663
 
 
664
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
665
 
                {
666
 
                        switch (target_type.BuiltinType) {
667
 
                        case BuiltinTypeSpec.Type.Byte:
668
 
                                if (in_checked_context) {
669
 
                                        if (Value < Byte.MinValue || Value > Byte.MaxValue)
670
 
                                                throw new OverflowException ();
671
 
                                }
672
 
                                return new ByteConstant (target_type, (byte) Value, Location);
673
 
                        case BuiltinTypeSpec.Type.SByte:
674
 
                                if (in_checked_context) {
675
 
                                        if (Value > SByte.MaxValue)
676
 
                                                throw new OverflowException ();
677
 
                                }
678
 
                                return new SByteConstant (target_type, (sbyte) Value, Location);
679
 
 
680
 
                        case BuiltinTypeSpec.Type.Short:
681
 
                                if (in_checked_context) {
682
 
                                        if (Value > Int16.MaxValue)
683
 
                                                throw new OverflowException ();
684
 
                                }
685
 
                                return new ShortConstant (target_type, (short) Value, Location);
686
 
                        case BuiltinTypeSpec.Type.Int:
687
 
                                return new IntConstant (target_type, (int) Value, Location);
688
 
                        case BuiltinTypeSpec.Type.UInt:
689
 
                                return new UIntConstant (target_type, (uint) Value, Location);
690
 
                        case BuiltinTypeSpec.Type.Long:
691
 
                                return new LongConstant (target_type, (long) Value, Location);
692
 
                        case BuiltinTypeSpec.Type.ULong:
693
 
                                return new ULongConstant (target_type, (ulong) Value, Location);
694
 
                        case BuiltinTypeSpec.Type.Float:
695
 
                                return new FloatConstant (target_type, (float) Value, Location);
696
 
                        case BuiltinTypeSpec.Type.Double:
697
 
                                return new DoubleConstant (target_type, (double) Value, Location);
698
 
                        case BuiltinTypeSpec.Type.Decimal:
699
 
                                return new DecimalConstant (target_type, (decimal) Value, Location);
700
 
                        }
701
 
 
702
 
                        return null;
703
 
                }
704
 
 
705
 
        }
706
 
 
707
 
        public class SByteConstant : IntegralConstant
708
 
        {
709
 
                public readonly sbyte Value;
710
 
 
711
 
                public SByteConstant (BuiltinTypes types, sbyte v, Location loc)
712
 
                        : this (types.SByte, v, loc)
713
 
                {
714
 
                }
715
 
 
716
 
                public SByteConstant (TypeSpec type, sbyte v, Location loc)
717
 
                        : base (type, loc)
718
 
                {
719
 
                        Value = v;
720
 
                }
721
 
 
722
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
723
 
                {
724
 
                        enc.Encode (Value);
725
 
                }
726
 
 
727
 
                public override void Emit (EmitContext ec)
728
 
                {
729
 
                        ec.EmitInt (Value);
730
 
                }
731
 
 
732
 
                public override object GetValue ()
733
 
                {
734
 
                        return Value;
735
 
                }
736
 
 
737
 
                public override long GetValueAsLong ()
738
 
                {
739
 
                        return Value;
740
 
                }
741
 
 
742
 
                public override Constant Increment ()
743
 
                {
744
 
                    return new SByteConstant (type, checked((sbyte)(Value + 1)), loc);
745
 
                }
746
 
 
747
 
                public override bool IsDefaultValue {
748
 
                        get {
749
 
                                return Value == 0;
750
 
                        }
751
 
                }
752
 
 
753
 
                public override bool IsNegative {
754
 
                        get {
755
 
                                return Value < 0;
756
 
                        }
757
 
                }
758
 
                
759
 
                public override bool IsOneInteger {
760
 
                        get {
761
 
                                return Value == 1;
762
 
                        }
763
 
                }               
764
 
                
765
 
                public override bool IsZeroInteger {
766
 
                        get { return Value == 0; }
767
 
                }
768
 
 
769
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
770
 
                {
771
 
                        switch (target_type.BuiltinType) {
772
 
                        case BuiltinTypeSpec.Type.Byte:
773
 
                                if (in_checked_context && Value < 0)
774
 
                                        throw new OverflowException ();
775
 
                                return new ByteConstant (target_type, (byte) Value, Location);
776
 
                        case BuiltinTypeSpec.Type.Short:
777
 
                                return new ShortConstant (target_type, (short) Value, Location);
778
 
                        case BuiltinTypeSpec.Type.UShort:
779
 
                                if (in_checked_context && Value < 0)
780
 
                                        throw new OverflowException ();
781
 
                                return new UShortConstant (target_type, (ushort) Value, Location);
782
 
                        case BuiltinTypeSpec.Type.Int:
783
 
                                return new IntConstant (target_type, (int) Value, Location);
784
 
                        case BuiltinTypeSpec.Type.UInt:
785
 
                                if (in_checked_context && Value < 0)
786
 
                                        throw new OverflowException ();
787
 
                                return new UIntConstant (target_type, (uint) Value, Location);
788
 
                        case BuiltinTypeSpec.Type.Long:
789
 
                                return new LongConstant (target_type, (long) Value, Location);
790
 
                        case BuiltinTypeSpec.Type.ULong:
791
 
                                if (in_checked_context && Value < 0)
792
 
                                        throw new OverflowException ();
793
 
                                return new ULongConstant (target_type, (ulong) Value, Location);
794
 
                        case BuiltinTypeSpec.Type.Float:
795
 
                                return new FloatConstant (target_type, (float) Value, Location);
796
 
                        case BuiltinTypeSpec.Type.Double:
797
 
                                return new DoubleConstant (target_type, (double) Value, Location);
798
 
                        case BuiltinTypeSpec.Type.Char:
799
 
                                if (in_checked_context && Value < 0)
800
 
                                        throw new OverflowException ();
801
 
                                return new CharConstant (target_type, (char) Value, Location);
802
 
                        case BuiltinTypeSpec.Type.Decimal:
803
 
                                return new DecimalConstant (target_type, (decimal) Value, Location);
804
 
                        }
805
 
 
806
 
                        return null;
807
 
                }
808
 
 
809
 
        }
810
 
 
811
 
        public class ShortConstant : IntegralConstant {
812
 
                public readonly short Value;
813
 
 
814
 
                public ShortConstant (BuiltinTypes types, short v, Location loc)
815
 
                        : this (types.Short, v, loc)
816
 
                {
817
 
                }
818
 
 
819
 
                public ShortConstant (TypeSpec type, short v, Location loc)
820
 
                        : base (type, loc)
821
 
                {
822
 
                        Value = v;
823
 
                }
824
 
 
825
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
826
 
                {
827
 
                        enc.Encode (Value);
828
 
                }
829
 
 
830
 
                public override void Emit (EmitContext ec)
831
 
                {
832
 
                        ec.EmitInt (Value);
833
 
                }
834
 
 
835
 
                public override object GetValue ()
836
 
                {
837
 
                        return Value;
838
 
                }
839
 
 
840
 
                public override long GetValueAsLong ()
841
 
                {
842
 
                        return Value;
843
 
                }
844
 
 
845
 
                public override Constant Increment ()
846
 
                {
847
 
                        return new ShortConstant (type, checked((short)(Value + 1)), loc);
848
 
                }
849
 
 
850
 
                public override bool IsDefaultValue {
851
 
                        get {
852
 
                                return Value == 0;
853
 
                        }
854
 
                }
855
 
                
856
 
                public override bool IsZeroInteger {
857
 
                        get { return Value == 0; }
858
 
                }
859
 
 
860
 
                public override bool IsNegative {
861
 
                        get {
862
 
                                return Value < 0;
863
 
                        }
864
 
                }
865
 
                
866
 
                public override bool IsOneInteger {
867
 
                        get {
868
 
                                return Value == 1;
869
 
                        }
870
 
                }               
871
 
 
872
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
873
 
                {
874
 
                        switch (target_type.BuiltinType) {
875
 
                        case BuiltinTypeSpec.Type.Byte:
876
 
                                if (in_checked_context) {
877
 
                                        if (Value < Byte.MinValue || Value > Byte.MaxValue)
878
 
                                                throw new OverflowException ();
879
 
                                }
880
 
                                return new ByteConstant (target_type, (byte) Value, Location);
881
 
                        case BuiltinTypeSpec.Type.SByte:
882
 
                                if (in_checked_context) {
883
 
                                        if (Value < SByte.MinValue || Value > SByte.MaxValue)
884
 
                                                throw new OverflowException ();
885
 
                                }
886
 
                                return new SByteConstant (target_type, (sbyte) Value, Location);
887
 
                        case BuiltinTypeSpec.Type.UShort:
888
 
                                if (in_checked_context && Value < 0)
889
 
                                        throw new OverflowException ();
890
 
 
891
 
                                return new UShortConstant (target_type, (ushort) Value, Location);
892
 
                        case BuiltinTypeSpec.Type.Int:
893
 
                                return new IntConstant (target_type, (int) Value, Location);
894
 
                        case BuiltinTypeSpec.Type.UInt:
895
 
                                if (in_checked_context && Value < 0)
896
 
                                        throw new OverflowException ();
897
 
                                return new UIntConstant (target_type, (uint) Value, Location);
898
 
                        case BuiltinTypeSpec.Type.Long:
899
 
                                return new LongConstant (target_type, (long) Value, Location);
900
 
                        case BuiltinTypeSpec.Type.ULong:
901
 
                                if (in_checked_context && Value < 0)
902
 
                                        throw new OverflowException ();
903
 
                                return new ULongConstant (target_type, (ulong) Value, Location);
904
 
                        case BuiltinTypeSpec.Type.Float:
905
 
                                return new FloatConstant (target_type, (float) Value, Location);
906
 
                        case BuiltinTypeSpec.Type.Double:
907
 
                                return new DoubleConstant (target_type, (double) Value, Location);
908
 
                        case BuiltinTypeSpec.Type.Char:
909
 
                                if (in_checked_context) {
910
 
                                        if (Value < Char.MinValue)
911
 
                                                throw new OverflowException ();
912
 
                                }
913
 
                                return new CharConstant (target_type, (char) Value, Location);
914
 
                        case BuiltinTypeSpec.Type.Decimal:
915
 
                                return new DecimalConstant (target_type, (decimal) Value, Location);
916
 
                        }
917
 
 
918
 
                        return null;
919
 
                }
920
 
 
921
 
        }
922
 
 
923
 
        public class UShortConstant : IntegralConstant
924
 
        {
925
 
                public readonly ushort Value;
926
 
 
927
 
                public UShortConstant (BuiltinTypes types, ushort v, Location loc)
928
 
                        : this (types.UShort, v, loc)
929
 
                {
930
 
                }
931
 
 
932
 
                public UShortConstant (TypeSpec type, ushort v, Location loc)
933
 
                        : base (type, loc)
934
 
                {
935
 
                        Value = v;
936
 
                }
937
 
 
938
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
939
 
                {
940
 
                        enc.Encode (Value);
941
 
                }
942
 
 
943
 
                public override void Emit (EmitContext ec)
944
 
                {
945
 
                        ec.EmitInt (Value);
946
 
                }
947
 
 
948
 
                public override object GetValue ()
949
 
                {
950
 
                        return Value;
951
 
                }
952
 
 
953
 
                public override long GetValueAsLong ()
954
 
                {
955
 
                        return Value;
956
 
                }
957
 
        
958
 
                public override Constant Increment ()
959
 
                {
960
 
                        return new UShortConstant (type, checked((ushort)(Value + 1)), loc);
961
 
                }
962
 
 
963
 
                public override bool IsDefaultValue {
964
 
                        get {
965
 
                                return Value == 0;
966
 
                        }
967
 
                }
968
 
 
969
 
                public override bool IsNegative {
970
 
                        get {
971
 
                                return false;
972
 
                        }
973
 
                }
974
 
                
975
 
                public override bool IsOneInteger {
976
 
                        get {
977
 
                                return Value == 1;
978
 
                        }
979
 
                }               
980
 
        
981
 
                public override bool IsZeroInteger {
982
 
                        get { return Value == 0; }
983
 
                }
984
 
 
985
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
986
 
                {
987
 
                        switch (target_type.BuiltinType) {
988
 
                        case BuiltinTypeSpec.Type.Byte:
989
 
                                if (in_checked_context) {
990
 
                                        if (Value > Byte.MaxValue)
991
 
                                                throw new OverflowException ();
992
 
                                }
993
 
                                return new ByteConstant (target_type, (byte) Value, Location);
994
 
                        case BuiltinTypeSpec.Type.SByte:
995
 
                                if (in_checked_context) {
996
 
                                        if (Value > SByte.MaxValue)
997
 
                                                throw new OverflowException ();
998
 
                                }
999
 
                                return new SByteConstant (target_type, (sbyte) Value, Location);
1000
 
                        case BuiltinTypeSpec.Type.Short:
1001
 
                                if (in_checked_context) {
1002
 
                                        if (Value > Int16.MaxValue)
1003
 
                                                throw new OverflowException ();
1004
 
                                }
1005
 
                                return new ShortConstant (target_type, (short) Value, Location);
1006
 
                        case BuiltinTypeSpec.Type.Int:
1007
 
                                return new IntConstant (target_type, (int) Value, Location);
1008
 
                        case BuiltinTypeSpec.Type.UInt:
1009
 
                                return new UIntConstant (target_type, (uint) Value, Location);
1010
 
                        case BuiltinTypeSpec.Type.Long:
1011
 
                                return new LongConstant (target_type, (long) Value, Location);
1012
 
                        case BuiltinTypeSpec.Type.ULong:
1013
 
                                return new ULongConstant (target_type, (ulong) Value, Location);
1014
 
                        case BuiltinTypeSpec.Type.Float:
1015
 
                                return new FloatConstant (target_type, (float) Value, Location);
1016
 
                        case BuiltinTypeSpec.Type.Double:
1017
 
                                return new DoubleConstant (target_type, (double) Value, Location);
1018
 
                        case BuiltinTypeSpec.Type.Char:
1019
 
                                if (in_checked_context) {
1020
 
                                        if (Value > Char.MaxValue)
1021
 
                                                throw new OverflowException ();
1022
 
                                }
1023
 
                                return new CharConstant (target_type, (char) Value, Location);
1024
 
                        case BuiltinTypeSpec.Type.Decimal:
1025
 
                                return new DecimalConstant (target_type, (decimal) Value, Location);
1026
 
                        }
1027
 
 
1028
 
                        return null;
1029
 
                }
1030
 
        }
1031
 
 
1032
 
        public class IntConstant : IntegralConstant
1033
 
        {
1034
 
                public readonly int Value;
1035
 
 
1036
 
                public IntConstant (BuiltinTypes types, int v, Location loc)
1037
 
                        : this (types.Int, v, loc)
1038
 
                {
1039
 
                }
1040
 
 
1041
 
                public IntConstant (TypeSpec type, int v, Location loc)
1042
 
                        : base (type, loc)
1043
 
                {
1044
 
                        Value = v;
1045
 
                }
1046
 
 
1047
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1048
 
                {
1049
 
                        enc.Encode (Value);
1050
 
                }
1051
 
 
1052
 
                public override void Emit (EmitContext ec)
1053
 
                {
1054
 
                        ec.EmitInt (Value);
1055
 
                }
1056
 
 
1057
 
                public override object GetValue ()
1058
 
                {
1059
 
                        return Value;
1060
 
                }
1061
 
 
1062
 
                public override long GetValueAsLong ()
1063
 
                {
1064
 
                        return Value;
1065
 
                }
1066
 
 
1067
 
                public override Constant Increment ()
1068
 
                {
1069
 
                        return new IntConstant (type, checked(Value + 1), loc);
1070
 
                }
1071
 
 
1072
 
                public override bool IsDefaultValue {
1073
 
                        get {
1074
 
                                return Value == 0;
1075
 
                        }
1076
 
                }
1077
 
                
1078
 
                public override bool IsNegative {
1079
 
                        get {
1080
 
                                return Value < 0;
1081
 
                        }
1082
 
                }
1083
 
                
1084
 
                public override bool IsOneInteger {
1085
 
                        get {
1086
 
                                return Value == 1;
1087
 
                        }
1088
 
                }               
1089
 
 
1090
 
                public override bool IsZeroInteger {
1091
 
                        get { return Value == 0; }
1092
 
                }
1093
 
 
1094
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1095
 
                {
1096
 
                        switch (target_type.BuiltinType) {
1097
 
                        case BuiltinTypeSpec.Type.Byte:
1098
 
                                if (in_checked_context) {
1099
 
                                        if (Value < Byte.MinValue || Value > Byte.MaxValue)
1100
 
                                                throw new OverflowException ();
1101
 
                                }
1102
 
                                return new ByteConstant (target_type, (byte) Value, Location);
1103
 
                        case BuiltinTypeSpec.Type.SByte:
1104
 
                                if (in_checked_context) {
1105
 
                                        if (Value < SByte.MinValue || Value > SByte.MaxValue)
1106
 
                                                throw new OverflowException ();
1107
 
                                }
1108
 
                                return new SByteConstant (target_type, (sbyte) Value, Location);
1109
 
                        case BuiltinTypeSpec.Type.Short:
1110
 
                                if (in_checked_context) {
1111
 
                                        if (Value < Int16.MinValue || Value > Int16.MaxValue)
1112
 
                                                throw new OverflowException ();
1113
 
                                }
1114
 
                                return new ShortConstant (target_type, (short) Value, Location);
1115
 
                        case BuiltinTypeSpec.Type.UShort:
1116
 
                                if (in_checked_context) {
1117
 
                                        if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1118
 
                                                throw new OverflowException ();
1119
 
                                }
1120
 
                                return new UShortConstant (target_type, (ushort) Value, Location);
1121
 
                        case BuiltinTypeSpec.Type.UInt:
1122
 
                                if (in_checked_context) {
1123
 
                                        if (Value < UInt32.MinValue)
1124
 
                                                throw new OverflowException ();
1125
 
                                }
1126
 
                                return new UIntConstant (target_type, (uint) Value, Location);
1127
 
                        case BuiltinTypeSpec.Type.Long:
1128
 
                                return new LongConstant (target_type, (long) Value, Location);
1129
 
                        case BuiltinTypeSpec.Type.ULong:
1130
 
                                if (in_checked_context && Value < 0)
1131
 
                                        throw new OverflowException ();
1132
 
                                return new ULongConstant (target_type, (ulong) Value, Location);
1133
 
                        case BuiltinTypeSpec.Type.Float:
1134
 
                                return new FloatConstant (target_type, (float) Value, Location);
1135
 
                        case BuiltinTypeSpec.Type.Double:
1136
 
                                return new DoubleConstant (target_type, (double) Value, Location);
1137
 
                        case BuiltinTypeSpec.Type.Char:
1138
 
                                if (in_checked_context) {
1139
 
                                        if (Value < Char.MinValue || Value > Char.MaxValue)
1140
 
                                                throw new OverflowException ();
1141
 
                                }
1142
 
                                return new CharConstant (target_type, (char) Value, Location);
1143
 
                        case BuiltinTypeSpec.Type.Decimal:
1144
 
                                return new DecimalConstant (target_type, (decimal) Value, Location);
1145
 
                        }
1146
 
 
1147
 
                        return null;
1148
 
                }
1149
 
 
1150
 
                public override Constant ConvertImplicitly (TypeSpec type)
1151
 
                {
1152
 
                        if (this.type == type)
1153
 
                                return this;
1154
 
 
1155
 
                        Constant c = TryImplicitIntConversion (type);
1156
 
                        if (c != null)
1157
 
                                return c; //.Resolve (rc);
1158
 
 
1159
 
                        return base.ConvertImplicitly (type);
1160
 
                }
1161
 
 
1162
 
                /// <summary>
1163
 
                ///   Attempts to perform an implicit constant conversion of the IntConstant
1164
 
                ///   into a different data type using casts (See Implicit Constant
1165
 
                ///   Expression Conversions)
1166
 
                /// </summary>
1167
 
                Constant TryImplicitIntConversion (TypeSpec target_type)
1168
 
                {
1169
 
                        switch (target_type.BuiltinType) {
1170
 
                        case BuiltinTypeSpec.Type.SByte:
1171
 
                                if (Value >= SByte.MinValue && Value <= SByte.MaxValue)
1172
 
                                        return new SByteConstant (target_type, (sbyte) Value, loc);
1173
 
                                break;
1174
 
                        case BuiltinTypeSpec.Type.Byte:
1175
 
                                if (Value >= Byte.MinValue && Value <= Byte.MaxValue)
1176
 
                                        return new ByteConstant (target_type, (byte) Value, loc);
1177
 
                                break;
1178
 
                        case BuiltinTypeSpec.Type.Short:
1179
 
                                if (Value >= Int16.MinValue && Value <= Int16.MaxValue)
1180
 
                                        return new ShortConstant (target_type, (short) Value, loc);
1181
 
                                break;
1182
 
                        case BuiltinTypeSpec.Type.UShort:
1183
 
                                if (Value >= UInt16.MinValue && Value <= UInt16.MaxValue)
1184
 
                                        return new UShortConstant (target_type, (ushort) Value, loc);
1185
 
                                break;
1186
 
                        case BuiltinTypeSpec.Type.UInt:
1187
 
                                if (Value >= 0)
1188
 
                                        return new UIntConstant (target_type, (uint) Value, loc);
1189
 
                                break;
1190
 
                        case BuiltinTypeSpec.Type.ULong:
1191
 
                                //
1192
 
                                // we can optimize this case: a positive int32
1193
 
                                // always fits on a uint64.  But we need an opcode
1194
 
                                // to do it.
1195
 
                                //
1196
 
                                if (Value >= 0)
1197
 
                                        return new ULongConstant (target_type, (ulong) Value, loc);
1198
 
                                break;
1199
 
                        case BuiltinTypeSpec.Type.Double:
1200
 
                                return new DoubleConstant (target_type, (double) Value, loc);
1201
 
                        case BuiltinTypeSpec.Type.Float:
1202
 
                                return new FloatConstant (target_type, (float) Value, loc);
1203
 
                        }
1204
 
 
1205
 
                        return null;
1206
 
                }
1207
 
        }
1208
 
 
1209
 
        public class UIntConstant : IntegralConstant {
1210
 
                public readonly uint Value;
1211
 
 
1212
 
                public UIntConstant (BuiltinTypes types, uint v, Location loc)
1213
 
                        : this (types.UInt, v, loc)
1214
 
                {
1215
 
                }
1216
 
 
1217
 
                public UIntConstant (TypeSpec type, uint v, Location loc)
1218
 
                        : base (type, loc)
1219
 
                {
1220
 
                        Value = v;
1221
 
                }
1222
 
 
1223
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1224
 
                {
1225
 
                        enc.Encode (Value);
1226
 
                }
1227
 
 
1228
 
                public override void Emit (EmitContext ec)
1229
 
                {
1230
 
                        ec.EmitInt (unchecked ((int) Value));
1231
 
                }
1232
 
 
1233
 
                public override object GetValue ()
1234
 
                {
1235
 
                        return Value;
1236
 
                }
1237
 
 
1238
 
                public override long GetValueAsLong ()
1239
 
                {
1240
 
                        return Value;
1241
 
                }
1242
 
 
1243
 
                public override Constant Increment ()
1244
 
                {
1245
 
                        return new UIntConstant (type, checked(Value + 1), loc);
1246
 
                }
1247
 
        
1248
 
                public override bool IsDefaultValue {
1249
 
                        get {
1250
 
                                return Value == 0;
1251
 
                        }
1252
 
                }
1253
 
 
1254
 
                public override bool IsNegative {
1255
 
                        get {
1256
 
                                return false;
1257
 
                        }
1258
 
                }
1259
 
                
1260
 
                public override bool IsOneInteger {
1261
 
                        get {
1262
 
                                return Value == 1;
1263
 
                        }
1264
 
                }               
1265
 
 
1266
 
                public override bool IsZeroInteger {
1267
 
                        get { return Value == 0; }
1268
 
                }
1269
 
 
1270
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1271
 
                {
1272
 
                        switch (target_type.BuiltinType) {
1273
 
                        case BuiltinTypeSpec.Type.Byte:
1274
 
                                if (in_checked_context) {
1275
 
                                        if (Value < 0 || Value > byte.MaxValue)
1276
 
                                                throw new OverflowException ();
1277
 
                                }
1278
 
                                return new ByteConstant (target_type, (byte) Value, Location);
1279
 
                        case BuiltinTypeSpec.Type.SByte:
1280
 
                                if (in_checked_context) {
1281
 
                                        if (Value > SByte.MaxValue)
1282
 
                                                throw new OverflowException ();
1283
 
                                }
1284
 
                                return new SByteConstant (target_type, (sbyte) Value, Location);
1285
 
                        case BuiltinTypeSpec.Type.Short:
1286
 
                                if (in_checked_context) {
1287
 
                                        if (Value > Int16.MaxValue)
1288
 
                                                throw new OverflowException ();
1289
 
                                }
1290
 
                                return new ShortConstant (target_type, (short) Value, Location);
1291
 
                        case BuiltinTypeSpec.Type.UShort:
1292
 
                                if (in_checked_context) {
1293
 
                                        if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1294
 
                                                throw new OverflowException ();
1295
 
                                }
1296
 
                                return new UShortConstant (target_type, (ushort) Value, Location);
1297
 
                        case BuiltinTypeSpec.Type.Int:
1298
 
                                if (in_checked_context) {
1299
 
                                        if (Value > Int32.MaxValue)
1300
 
                                                throw new OverflowException ();
1301
 
                                }
1302
 
                                return new IntConstant (target_type, (int) Value, Location);
1303
 
                        case BuiltinTypeSpec.Type.Long:
1304
 
                                return new LongConstant (target_type, (long) Value, Location);
1305
 
                        case BuiltinTypeSpec.Type.ULong:
1306
 
                                return new ULongConstant (target_type, (ulong) Value, Location);
1307
 
                        case BuiltinTypeSpec.Type.Float:
1308
 
                                return new FloatConstant (target_type, (float) Value, Location);
1309
 
                        case BuiltinTypeSpec.Type.Double:
1310
 
                                return new DoubleConstant (target_type, (double) Value, Location);
1311
 
                        case BuiltinTypeSpec.Type.Char:
1312
 
                                if (in_checked_context) {
1313
 
                                        if (Value < Char.MinValue || Value > Char.MaxValue)
1314
 
                                                throw new OverflowException ();
1315
 
                                }
1316
 
                                return new CharConstant (target_type, (char) Value, Location);
1317
 
                        case BuiltinTypeSpec.Type.Decimal:
1318
 
                                return new DecimalConstant (target_type, (decimal) Value, Location);
1319
 
                        }
1320
 
 
1321
 
                        return null;
1322
 
                }
1323
 
 
1324
 
        }
1325
 
 
1326
 
        public class LongConstant : IntegralConstant {
1327
 
                public readonly long Value;
1328
 
 
1329
 
                public LongConstant (BuiltinTypes types, long v, Location loc)
1330
 
                        : this (types.Long, v, loc)
1331
 
                {
1332
 
                }
1333
 
 
1334
 
                public LongConstant (TypeSpec type, long v, Location loc)
1335
 
                        : base (type, loc)
1336
 
                {
1337
 
                        Value = v;
1338
 
                }
1339
 
 
1340
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1341
 
                {
1342
 
                        enc.Encode (Value);
1343
 
                }
1344
 
 
1345
 
                public override void Emit (EmitContext ec)
1346
 
                {
1347
 
                        ec.EmitLong (Value);
1348
 
                }
1349
 
 
1350
 
                public override object GetValue ()
1351
 
                {
1352
 
                        return Value;
1353
 
                }
1354
 
 
1355
 
                public override long GetValueAsLong ()
1356
 
                {
1357
 
                        return Value;
1358
 
                }
1359
 
 
1360
 
                public override Constant Increment ()
1361
 
                {
1362
 
                        return new LongConstant (type, checked(Value + 1), loc);
1363
 
                }
1364
 
                
1365
 
                public override bool IsDefaultValue {
1366
 
                        get {
1367
 
                                return Value == 0;
1368
 
                        }
1369
 
                }
1370
 
 
1371
 
                public override bool IsNegative {
1372
 
                        get {
1373
 
                                return Value < 0;
1374
 
                        }
1375
 
                }
1376
 
                
1377
 
                public override bool IsOneInteger {
1378
 
                        get {
1379
 
                                return Value == 1;
1380
 
                        }
1381
 
                }               
1382
 
 
1383
 
                public override bool IsZeroInteger {
1384
 
                        get { return Value == 0; }
1385
 
                }
1386
 
 
1387
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1388
 
                {
1389
 
                        switch (target_type.BuiltinType) {
1390
 
                        case BuiltinTypeSpec.Type.Byte:
1391
 
                                if (in_checked_context) {
1392
 
                                        if (Value < Byte.MinValue || Value > Byte.MaxValue)
1393
 
                                                throw new OverflowException ();
1394
 
                                }
1395
 
                                return new ByteConstant (target_type, (byte) Value, Location);
1396
 
                        case BuiltinTypeSpec.Type.SByte:
1397
 
                                if (in_checked_context) {
1398
 
                                        if (Value < SByte.MinValue || Value > SByte.MaxValue)
1399
 
                                                throw new OverflowException ();
1400
 
                                }
1401
 
                                return new SByteConstant (target_type, (sbyte) Value, Location);
1402
 
                        case BuiltinTypeSpec.Type.Short:
1403
 
                                if (in_checked_context) {
1404
 
                                        if (Value < Int16.MinValue || Value > Int16.MaxValue)
1405
 
                                                throw new OverflowException ();
1406
 
                                }
1407
 
                                return new ShortConstant (target_type, (short) Value, Location);
1408
 
                        case BuiltinTypeSpec.Type.UShort:
1409
 
                                if (in_checked_context) {
1410
 
                                        if (Value < UInt16.MinValue || Value > UInt16.MaxValue)
1411
 
                                                throw new OverflowException ();
1412
 
                                }
1413
 
                                return new UShortConstant (target_type, (ushort) Value, Location);
1414
 
                        case BuiltinTypeSpec.Type.Int:
1415
 
                                if (in_checked_context) {
1416
 
                                        if (Value < Int32.MinValue || Value > Int32.MaxValue)
1417
 
                                                throw new OverflowException ();
1418
 
                                }
1419
 
                                return new IntConstant (target_type, (int) Value, Location);
1420
 
                        case BuiltinTypeSpec.Type.UInt:
1421
 
                                if (in_checked_context) {
1422
 
                                        if (Value < UInt32.MinValue || Value > UInt32.MaxValue)
1423
 
                                                throw new OverflowException ();
1424
 
                                }
1425
 
                                return new UIntConstant (target_type, (uint) Value, Location);
1426
 
                        case BuiltinTypeSpec.Type.ULong:
1427
 
                                if (in_checked_context && Value < 0)
1428
 
                                        throw new OverflowException ();
1429
 
                                return new ULongConstant (target_type, (ulong) Value, Location);
1430
 
                        case BuiltinTypeSpec.Type.Float:
1431
 
                                return new FloatConstant (target_type, (float) Value, Location);
1432
 
                        case BuiltinTypeSpec.Type.Double:
1433
 
                                return new DoubleConstant (target_type, (double) Value, Location);
1434
 
                        case BuiltinTypeSpec.Type.Char:
1435
 
                                if (in_checked_context) {
1436
 
                                        if (Value < Char.MinValue || Value > Char.MaxValue)
1437
 
                                                throw new OverflowException ();
1438
 
                                }
1439
 
                                return new CharConstant (target_type, (char) Value, Location);
1440
 
                        case BuiltinTypeSpec.Type.Decimal:
1441
 
                                return new DecimalConstant (target_type, (decimal) Value, Location);
1442
 
                        }
1443
 
 
1444
 
                        return null;
1445
 
                }
1446
 
 
1447
 
                public override Constant ConvertImplicitly (TypeSpec type)
1448
 
                {
1449
 
                        if (Value >= 0 && type.BuiltinType == BuiltinTypeSpec.Type.ULong) {
1450
 
                                return new ULongConstant (type, (ulong) Value, loc);
1451
 
                        }
1452
 
 
1453
 
                        return base.ConvertImplicitly (type);
1454
 
                }
1455
 
        }
1456
 
 
1457
 
        public class ULongConstant : IntegralConstant {
1458
 
                public readonly ulong Value;
1459
 
 
1460
 
                public ULongConstant (BuiltinTypes types, ulong v, Location loc)
1461
 
                        : this (types.ULong, v, loc)
1462
 
                {
1463
 
                }
1464
 
 
1465
 
                public ULongConstant (TypeSpec type, ulong v, Location loc)
1466
 
                        : base (type, loc)
1467
 
                {
1468
 
                        Value = v;
1469
 
                }
1470
 
 
1471
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1472
 
                {
1473
 
                        enc.Encode (Value);
1474
 
                }
1475
 
 
1476
 
                public override void Emit (EmitContext ec)
1477
 
                {
1478
 
                        ec.EmitLong (unchecked ((long) Value));
1479
 
                }
1480
 
 
1481
 
                public override object GetValue ()
1482
 
                {
1483
 
                        return Value;
1484
 
                }
1485
 
 
1486
 
                public override long GetValueAsLong ()
1487
 
                {
1488
 
                        return (long) Value;
1489
 
                }
1490
 
 
1491
 
                public override Constant Increment ()
1492
 
                {
1493
 
                        return new ULongConstant (type, checked(Value + 1), loc);
1494
 
                }
1495
 
 
1496
 
                public override bool IsDefaultValue {
1497
 
                        get {
1498
 
                                return Value == 0;
1499
 
                        }
1500
 
                }
1501
 
 
1502
 
                public override bool IsNegative {
1503
 
                        get {
1504
 
                                return false;
1505
 
                        }
1506
 
                }
1507
 
                
1508
 
                public override bool IsOneInteger {
1509
 
                        get {
1510
 
                                return Value == 1;
1511
 
                        }
1512
 
                }               
1513
 
 
1514
 
                public override bool IsZeroInteger {
1515
 
                        get { return Value == 0; }
1516
 
                }
1517
 
 
1518
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1519
 
                {
1520
 
                        switch (target_type.BuiltinType) {
1521
 
                        case BuiltinTypeSpec.Type.Byte:
1522
 
                                if (in_checked_context && Value > Byte.MaxValue)
1523
 
                                        throw new OverflowException ();
1524
 
                                return new ByteConstant (target_type, (byte) Value, Location);
1525
 
                        case BuiltinTypeSpec.Type.SByte:
1526
 
                                if (in_checked_context && Value > ((ulong) SByte.MaxValue))
1527
 
                                        throw new OverflowException ();
1528
 
                                return new SByteConstant (target_type, (sbyte) Value, Location);
1529
 
                        case BuiltinTypeSpec.Type.Short:
1530
 
                                if (in_checked_context && Value > ((ulong) Int16.MaxValue))
1531
 
                                        throw new OverflowException ();
1532
 
                                return new ShortConstant (target_type, (short) Value, Location);
1533
 
                        case BuiltinTypeSpec.Type.UShort:
1534
 
                                if (in_checked_context && Value > UInt16.MaxValue)
1535
 
                                        throw new OverflowException ();
1536
 
                                return new UShortConstant (target_type, (ushort) Value, Location);
1537
 
                        case BuiltinTypeSpec.Type.Int:
1538
 
                                if (in_checked_context && Value > UInt32.MaxValue)
1539
 
                                        throw new OverflowException ();
1540
 
                                return new IntConstant (target_type, (int) Value, Location);
1541
 
                        case BuiltinTypeSpec.Type.UInt:
1542
 
                                if (in_checked_context && Value > UInt32.MaxValue)
1543
 
                                        throw new OverflowException ();
1544
 
                                return new UIntConstant (target_type, (uint) Value, Location);
1545
 
                        case BuiltinTypeSpec.Type.Long:
1546
 
                                if (in_checked_context && Value > Int64.MaxValue)
1547
 
                                        throw new OverflowException ();
1548
 
                                return new LongConstant (target_type, (long) Value, Location);
1549
 
                        case BuiltinTypeSpec.Type.Float:
1550
 
                                return new FloatConstant (target_type, (float) Value, Location);
1551
 
                        case BuiltinTypeSpec.Type.Double:
1552
 
                                return new DoubleConstant (target_type, (double) Value, Location);
1553
 
                        case BuiltinTypeSpec.Type.Char:
1554
 
                                if (in_checked_context && Value > Char.MaxValue)
1555
 
                                        throw new OverflowException ();
1556
 
                                return new CharConstant (target_type, (char) Value, Location);
1557
 
                        case BuiltinTypeSpec.Type.Decimal:
1558
 
                                return new DecimalConstant (target_type, (decimal) Value, Location);
1559
 
                        }
1560
 
 
1561
 
                        return null;
1562
 
                }
1563
 
 
1564
 
        }
1565
 
 
1566
 
        public class FloatConstant : Constant {
1567
 
                public readonly float Value;
1568
 
 
1569
 
                public FloatConstant (BuiltinTypes types, float v, Location loc)
1570
 
                        : this (types.Float, v, loc)
1571
 
                {
1572
 
                }
1573
 
 
1574
 
                public FloatConstant (TypeSpec type, float v, Location loc)
1575
 
                        : base (loc)
1576
 
                {
1577
 
                        this.type = type;
1578
 
                        eclass = ExprClass.Value;
1579
 
 
1580
 
                        Value = v;
1581
 
                }
1582
 
 
1583
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1584
 
                {
1585
 
                        enc.Encode (Value);
1586
 
                }
1587
 
 
1588
 
                public override void Emit (EmitContext ec)
1589
 
                {
1590
 
                        ec.Emit (OpCodes.Ldc_R4, Value);
1591
 
                }
1592
 
 
1593
 
                public override object GetValue ()
1594
 
                {
1595
 
                        return Value;
1596
 
                }
1597
 
 
1598
 
                public override string GetValueAsLiteral ()
1599
 
                {
1600
 
                        return Value.ToString ();
1601
 
                }
1602
 
 
1603
 
                public override long GetValueAsLong ()
1604
 
                {
1605
 
                        throw new NotSupportedException ();
1606
 
                }
1607
 
 
1608
 
                public override bool IsDefaultValue {
1609
 
                        get {
1610
 
                                return Value == 0;
1611
 
                        }
1612
 
                }
1613
 
 
1614
 
                public override bool IsNegative {
1615
 
                        get {
1616
 
                                return Value < 0;
1617
 
                        }
1618
 
                }
1619
 
 
1620
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1621
 
                {
1622
 
                        switch (target_type.BuiltinType) {
1623
 
                        case BuiltinTypeSpec.Type.Byte:
1624
 
                                if (in_checked_context) {
1625
 
                                        if (Value < byte.MinValue || Value > byte.MaxValue || float.IsNaN (Value))
1626
 
                                                throw new OverflowException ();
1627
 
                                }
1628
 
                                return new ByteConstant (target_type, (byte) Value, Location);
1629
 
                        case BuiltinTypeSpec.Type.SByte:
1630
 
                                if (in_checked_context) {
1631
 
                                        if (Value < sbyte.MinValue || Value > sbyte.MaxValue || float.IsNaN (Value))
1632
 
                                                throw new OverflowException ();
1633
 
                                }
1634
 
                                return new SByteConstant (target_type, (sbyte) Value, Location);
1635
 
                        case BuiltinTypeSpec.Type.Short:
1636
 
                                if (in_checked_context) {
1637
 
                                        if (Value < short.MinValue || Value > short.MaxValue || float.IsNaN (Value))
1638
 
                                                throw new OverflowException ();
1639
 
                                }
1640
 
                                return new ShortConstant (target_type, (short) Value, Location);
1641
 
                        case BuiltinTypeSpec.Type.UShort:
1642
 
                                if (in_checked_context) {
1643
 
                                        if (Value < ushort.MinValue || Value > ushort.MaxValue || float.IsNaN (Value))
1644
 
                                                throw new OverflowException ();
1645
 
                                }
1646
 
                                return new UShortConstant (target_type, (ushort) Value, Location);
1647
 
                        case BuiltinTypeSpec.Type.Int:
1648
 
                                if (in_checked_context) {
1649
 
                                        if (Value < int.MinValue || Value > int.MaxValue || float.IsNaN (Value))
1650
 
                                                throw new OverflowException ();
1651
 
                                }
1652
 
                                return new IntConstant (target_type, (int) Value, Location);
1653
 
                        case BuiltinTypeSpec.Type.UInt:
1654
 
                                if (in_checked_context) {
1655
 
                                        if (Value < uint.MinValue || Value > uint.MaxValue || float.IsNaN (Value))
1656
 
                                                throw new OverflowException ();
1657
 
                                }
1658
 
                                return new UIntConstant (target_type, (uint) Value, Location);
1659
 
                        case BuiltinTypeSpec.Type.Long:
1660
 
                                if (in_checked_context) {
1661
 
                                        if (Value < long.MinValue || Value > long.MaxValue || float.IsNaN (Value))
1662
 
                                                throw new OverflowException ();
1663
 
                                }
1664
 
                                return new LongConstant (target_type, (long) Value, Location);
1665
 
                        case BuiltinTypeSpec.Type.ULong:
1666
 
                                if (in_checked_context) {
1667
 
                                        if (Value < ulong.MinValue || Value > ulong.MaxValue || float.IsNaN (Value))
1668
 
                                                throw new OverflowException ();
1669
 
                                }
1670
 
                                return new ULongConstant (target_type, (ulong) Value, Location);
1671
 
                        case BuiltinTypeSpec.Type.Double:
1672
 
                                return new DoubleConstant (target_type, (double) Value, Location);
1673
 
                        case BuiltinTypeSpec.Type.Char:
1674
 
                                if (in_checked_context) {
1675
 
                                        if (Value < (float) char.MinValue || Value > (float) char.MaxValue || float.IsNaN (Value))
1676
 
                                                throw new OverflowException ();
1677
 
                                }
1678
 
                                return new CharConstant (target_type, (char) Value, Location);
1679
 
                        case BuiltinTypeSpec.Type.Decimal:
1680
 
                                return new DecimalConstant (target_type, (decimal) Value, Location);
1681
 
                        }
1682
 
 
1683
 
                        return null;
1684
 
                }
1685
 
 
1686
 
        }
1687
 
 
1688
 
        public class DoubleConstant : Constant
1689
 
        {
1690
 
                public readonly double Value;
1691
 
 
1692
 
                public DoubleConstant (BuiltinTypes types, double v, Location loc)
1693
 
                        : this (types.Double, v, loc)
1694
 
                {
1695
 
                }
1696
 
 
1697
 
                public DoubleConstant (TypeSpec type, double v, Location loc)
1698
 
                        : base (loc)
1699
 
                {
1700
 
                        this.type = type;
1701
 
                        eclass = ExprClass.Value;
1702
 
 
1703
 
                        Value = v;
1704
 
                }
1705
 
 
1706
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1707
 
                {
1708
 
                        enc.Encode (Value);
1709
 
                }
1710
 
 
1711
 
                public override void Emit (EmitContext ec)
1712
 
                {
1713
 
                        ec.Emit (OpCodes.Ldc_R8, Value);
1714
 
                }
1715
 
 
1716
 
                public override object GetValue ()
1717
 
                {
1718
 
                        return Value;
1719
 
                }
1720
 
 
1721
 
                public override string GetValueAsLiteral ()
1722
 
                {
1723
 
                        return Value.ToString ();
1724
 
                }
1725
 
 
1726
 
                public override long GetValueAsLong ()
1727
 
                {
1728
 
                        throw new NotSupportedException ();
1729
 
                }
1730
 
 
1731
 
                public override bool IsDefaultValue {
1732
 
                        get {
1733
 
                                return Value == 0;
1734
 
                        }
1735
 
                }
1736
 
 
1737
 
                public override bool IsNegative {
1738
 
                        get {
1739
 
                                return Value < 0;
1740
 
                        }
1741
 
                }
1742
 
 
1743
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1744
 
                {
1745
 
                        switch (target_type.BuiltinType) {
1746
 
                        case BuiltinTypeSpec.Type.Byte:
1747
 
                                if (in_checked_context) {
1748
 
                                        if (Value < Byte.MinValue || Value > Byte.MaxValue || double.IsNaN (Value))
1749
 
                                                throw new OverflowException ();
1750
 
                                }
1751
 
                                return new ByteConstant (target_type, (byte) Value, Location);
1752
 
                        case BuiltinTypeSpec.Type.SByte:
1753
 
                                if (in_checked_context) {
1754
 
                                        if (Value < SByte.MinValue || Value > SByte.MaxValue || double.IsNaN (Value))
1755
 
                                                throw new OverflowException ();
1756
 
                                }
1757
 
                                return new SByteConstant (target_type, (sbyte) Value, Location);
1758
 
                        case BuiltinTypeSpec.Type.Short:
1759
 
                                if (in_checked_context) {
1760
 
                                        if (Value < short.MinValue || Value > short.MaxValue || double.IsNaN (Value))
1761
 
                                                throw new OverflowException ();
1762
 
                                }
1763
 
                                return new ShortConstant (target_type, (short) Value, Location);
1764
 
                        case BuiltinTypeSpec.Type.UShort:
1765
 
                                if (in_checked_context) {
1766
 
                                        if (Value < ushort.MinValue || Value > ushort.MaxValue || double.IsNaN (Value))
1767
 
                                                throw new OverflowException ();
1768
 
                                }
1769
 
                                return new UShortConstant (target_type, (ushort) Value, Location);
1770
 
                        case BuiltinTypeSpec.Type.Int:
1771
 
                                if (in_checked_context) {
1772
 
                                        if (Value < int.MinValue || Value > int.MaxValue || double.IsNaN (Value))
1773
 
                                                throw new OverflowException ();
1774
 
                                }
1775
 
                                return new IntConstant (target_type, (int) Value, Location);
1776
 
                        case BuiltinTypeSpec.Type.UInt:
1777
 
                                if (in_checked_context) {
1778
 
                                        if (Value < uint.MinValue || Value > uint.MaxValue || double.IsNaN (Value))
1779
 
                                                throw new OverflowException ();
1780
 
                                }
1781
 
                                return new UIntConstant (target_type, (uint) Value, Location);
1782
 
                        case BuiltinTypeSpec.Type.Long:
1783
 
                                if (in_checked_context) {
1784
 
                                        if (Value < long.MinValue || Value > long.MaxValue || double.IsNaN (Value))
1785
 
                                                throw new OverflowException ();
1786
 
                                }
1787
 
                                return new LongConstant (target_type, (long) Value, Location);
1788
 
                        case BuiltinTypeSpec.Type.ULong:
1789
 
                                if (in_checked_context) {
1790
 
                                        if (Value < ulong.MinValue || Value > ulong.MaxValue || double.IsNaN (Value))
1791
 
                                                throw new OverflowException ();
1792
 
                                }
1793
 
                                return new ULongConstant (target_type, (ulong) Value, Location);
1794
 
                        case BuiltinTypeSpec.Type.Float:
1795
 
                                return new FloatConstant (target_type, (float) Value, Location);
1796
 
                        case BuiltinTypeSpec.Type.Char:
1797
 
                                if (in_checked_context) {
1798
 
                                        if (Value < (double) char.MinValue || Value > (double) char.MaxValue || double.IsNaN (Value))
1799
 
                                                throw new OverflowException ();
1800
 
                                }
1801
 
                                return new CharConstant (target_type, (char) Value, Location);
1802
 
                        case BuiltinTypeSpec.Type.Decimal:
1803
 
                                return new DecimalConstant (target_type, (decimal) Value, Location);
1804
 
                        }
1805
 
 
1806
 
                        return null;
1807
 
                }
1808
 
 
1809
 
        }
1810
 
 
1811
 
        public class DecimalConstant : Constant {
1812
 
                public readonly decimal Value;
1813
 
 
1814
 
                public DecimalConstant (BuiltinTypes types, decimal d, Location loc)
1815
 
                        : this (types.Decimal, d, loc)
1816
 
                {
1817
 
                }
1818
 
 
1819
 
                public DecimalConstant (TypeSpec type, decimal d, Location loc)
1820
 
                        : base (loc)
1821
 
                {
1822
 
                        this.type = type;
1823
 
                        eclass = ExprClass.Value;
1824
 
 
1825
 
                        Value = d;
1826
 
                }
1827
 
 
1828
 
                public override void Emit (EmitContext ec)
1829
 
                {
1830
 
                        MethodSpec m;
1831
 
 
1832
 
                        int [] words = decimal.GetBits (Value);
1833
 
                        int power = (words [3] >> 16) & 0xff;
1834
 
 
1835
 
                        if (power == 0) {
1836
 
                                if (Value <= int.MaxValue && Value >= int.MinValue) {
1837
 
                                        m = ec.Module.PredefinedMembers.DecimalCtorInt.Resolve (loc);
1838
 
                                        if (m == null) {
1839
 
                                                return;
1840
 
                                        }
1841
 
 
1842
 
                                        ec.EmitInt ((int) Value);
1843
 
                                        ec.Emit (OpCodes.Newobj, m);
1844
 
                                        return;
1845
 
                                }
1846
 
 
1847
 
                                if (Value <= long.MaxValue && Value >= long.MinValue) {
1848
 
                                        m = ec.Module.PredefinedMembers.DecimalCtorLong.Resolve (loc);
1849
 
                                        if (m == null) {
1850
 
                                                return;
1851
 
                                        }
1852
 
 
1853
 
                                        ec.EmitLong ((long) Value);
1854
 
                                        ec.Emit (OpCodes.Newobj, m);
1855
 
                                        return;
1856
 
                                }
1857
 
                        }
1858
 
 
1859
 
                        ec.EmitInt (words [0]);
1860
 
                        ec.EmitInt (words [1]);
1861
 
                        ec.EmitInt (words [2]);
1862
 
 
1863
 
                        // sign
1864
 
                        ec.EmitInt (words [3] >> 31);
1865
 
 
1866
 
                        // power
1867
 
                        ec.EmitInt (power);
1868
 
 
1869
 
                        m = ec.Module.PredefinedMembers.DecimalCtor.Resolve (loc);
1870
 
                        if (m != null) {
1871
 
                                ec.Emit (OpCodes.Newobj, m);
1872
 
                        }
1873
 
                }
1874
 
 
1875
 
                public override bool IsDefaultValue {
1876
 
                        get {
1877
 
                                return Value == 0;
1878
 
                        }
1879
 
                }
1880
 
 
1881
 
                public override bool IsNegative {
1882
 
                        get {
1883
 
                                return Value < 0;
1884
 
                        }
1885
 
                }
1886
 
 
1887
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
1888
 
                {
1889
 
                        switch (target_type.BuiltinType) {
1890
 
                        case BuiltinTypeSpec.Type.SByte:
1891
 
                                return new SByteConstant (target_type, (sbyte) Value, loc);
1892
 
                        case BuiltinTypeSpec.Type.Byte:
1893
 
                                return new ByteConstant (target_type, (byte) Value, loc);
1894
 
                        case BuiltinTypeSpec.Type.Short:
1895
 
                                return new ShortConstant (target_type, (short) Value, loc);
1896
 
                        case BuiltinTypeSpec.Type.UShort:
1897
 
                                return new UShortConstant (target_type, (ushort) Value, loc);
1898
 
                        case BuiltinTypeSpec.Type.Int:
1899
 
                                return new IntConstant (target_type, (int) Value, loc);
1900
 
                        case BuiltinTypeSpec.Type.UInt:
1901
 
                                return new UIntConstant (target_type, (uint) Value, loc);
1902
 
                        case BuiltinTypeSpec.Type.Long:
1903
 
                                return new LongConstant (target_type, (long) Value, loc);
1904
 
                        case BuiltinTypeSpec.Type.ULong:
1905
 
                                return new ULongConstant (target_type, (ulong) Value, loc);
1906
 
                        case BuiltinTypeSpec.Type.Char:
1907
 
                                return new CharConstant (target_type, (char) Value, loc);
1908
 
                        case BuiltinTypeSpec.Type.Float:
1909
 
                                return new FloatConstant (target_type, (float) Value, loc);
1910
 
                        case BuiltinTypeSpec.Type.Double:
1911
 
                                return new DoubleConstant (target_type, (double) Value, loc);
1912
 
                        }
1913
 
 
1914
 
                        return null;
1915
 
                }
1916
 
 
1917
 
                public override object GetValue ()
1918
 
                {
1919
 
                        return Value;
1920
 
                }
1921
 
 
1922
 
                public override string GetValueAsLiteral ()
1923
 
                {
1924
 
                        return Value.ToString () + "M";
1925
 
                }
1926
 
 
1927
 
                public override long GetValueAsLong ()
1928
 
                {
1929
 
                        throw new NotSupportedException ();
1930
 
                }
1931
 
        }
1932
 
 
1933
 
        public class StringConstant : Constant {
1934
 
                public readonly string Value;
1935
 
 
1936
 
                public StringConstant (BuiltinTypes types, string s, Location loc)
1937
 
                        : this (types.String, s, loc)
1938
 
                {
1939
 
                }
1940
 
 
1941
 
                public StringConstant (TypeSpec type, string s, Location loc)
1942
 
                        : base (loc)
1943
 
                {
1944
 
                        this.type = type;
1945
 
                        eclass = ExprClass.Value;
1946
 
 
1947
 
                        Value = s;
1948
 
                }
1949
 
 
1950
 
                public override object GetValue ()
1951
 
                {
1952
 
                        return Value;
1953
 
                }
1954
 
 
1955
 
                public override string GetValueAsLiteral ()
1956
 
                {
1957
 
                        // FIXME: Escape the string.
1958
 
                        return "\"" + Value + "\"";
1959
 
                }
1960
 
 
1961
 
                public override long GetValueAsLong ()
1962
 
                {
1963
 
                        throw new NotSupportedException ();
1964
 
                }
1965
 
                
1966
 
                public override void Emit (EmitContext ec)
1967
 
                {
1968
 
                        if (Value == null) {
1969
 
                                ec.EmitNull ();
1970
 
                                return;
1971
 
                        }
1972
 
 
1973
 
                        //
1974
 
                        // Use string.Empty for both literals and constants even if
1975
 
                        // it's not allowed at language level
1976
 
                        //
1977
 
                        if (Value.Length == 0 && ec.Module.Compiler.Settings.Optimize) {
1978
 
                                var string_type = ec.BuiltinTypes.String;
1979
 
                                if (ec.CurrentType != string_type) {
1980
 
                                        var m = ec.Module.PredefinedMembers.StringEmpty.Get ();
1981
 
                                        if (m != null) {
1982
 
                                                ec.Emit (OpCodes.Ldsfld, m);
1983
 
                                                return;
1984
 
                                        }
1985
 
                                }
1986
 
                        }
1987
 
 
1988
 
                        ec.Emit (OpCodes.Ldstr, Value);
1989
 
                }
1990
 
 
1991
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
1992
 
                {
1993
 
                        // cast to object
1994
 
                        if (type != targetType)
1995
 
                                enc.Encode (type);
1996
 
 
1997
 
                        enc.Encode (Value);
1998
 
                }
1999
 
 
2000
 
                public override bool IsDefaultValue {
2001
 
                        get {
2002
 
                                return Value == null;
2003
 
                        }
2004
 
                }
2005
 
 
2006
 
                public override bool IsNegative {
2007
 
                        get {
2008
 
                                return false;
2009
 
                        }
2010
 
                }
2011
 
 
2012
 
                public override bool IsNull {
2013
 
                        get {
2014
 
                                return IsDefaultValue;
2015
 
                        }
2016
 
                }
2017
 
 
2018
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
2019
 
                {
2020
 
                        return null;
2021
 
                }
2022
 
        }
2023
 
 
2024
 
        //
2025
 
        // Null constant can have its own type, think of `default (Foo)'
2026
 
        //
2027
 
        public class NullConstant : Constant
2028
 
        {
2029
 
                public NullConstant (TypeSpec type, Location loc)
2030
 
                        : base (loc)
2031
 
                {
2032
 
                        eclass = ExprClass.Value;
2033
 
                        this.type = type;
2034
 
                }
2035
 
 
2036
 
                public override Expression CreateExpressionTree (ResolveContext ec)
2037
 
                {
2038
 
                        if (type == InternalType.NullLiteral || type.BuiltinType == BuiltinTypeSpec.Type.Object) {
2039
 
                                // Optimized version, also avoids referencing literal internal type
2040
 
                                Arguments args = new Arguments (1);
2041
 
                                args.Add (new Argument (this));
2042
 
                                return CreateExpressionFactoryCall (ec, "Constant", args);
2043
 
                        }
2044
 
 
2045
 
                        return base.CreateExpressionTree (ec);
2046
 
                }
2047
 
 
2048
 
                public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType)
2049
 
                {
2050
 
                        switch (targetType.BuiltinType) {
2051
 
                        case BuiltinTypeSpec.Type.Object:
2052
 
                                // Type it as string cast
2053
 
                                enc.Encode (rc.Module.Compiler.BuiltinTypes.String);
2054
 
                                goto case BuiltinTypeSpec.Type.String;
2055
 
                        case BuiltinTypeSpec.Type.String:
2056
 
                        case BuiltinTypeSpec.Type.Type:
2057
 
                                enc.Encode (byte.MaxValue);
2058
 
                                return;
2059
 
                        default:
2060
 
                                var ac = targetType as ArrayContainer;
2061
 
                                if (ac != null && ac.Rank == 1 && !ac.Element.IsArray) {
2062
 
                                        enc.Encode (uint.MaxValue);
2063
 
                                        return;
2064
 
                                }
2065
 
 
2066
 
                                break;
2067
 
                        }
2068
 
 
2069
 
                        base.EncodeAttributeValue (rc, enc, targetType);
2070
 
                }
2071
 
 
2072
 
                public override void Emit (EmitContext ec)
2073
 
                {
2074
 
                        ec.EmitNull ();
2075
 
 
2076
 
                        // Only to make verifier happy
2077
 
                        if (type.IsGenericParameter)
2078
 
                                ec.Emit (OpCodes.Unbox_Any, type);
2079
 
                }
2080
 
 
2081
 
                public override string ExprClassName {
2082
 
                        get {
2083
 
                                return GetSignatureForError ();
2084
 
                        }
2085
 
                }
2086
 
 
2087
 
                public override Constant ConvertExplicitly (bool inCheckedContext, TypeSpec targetType)
2088
 
                {
2089
 
                        if (targetType.IsPointer) {
2090
 
                                if (IsLiteral || this is NullPointer)
2091
 
                                        return new NullPointer (targetType, loc);
2092
 
 
2093
 
                                return null;
2094
 
                        }
2095
 
 
2096
 
                        // Exlude internal compiler types
2097
 
                        if (targetType.Kind == MemberKind.InternalCompilerType && targetType.BuiltinType != BuiltinTypeSpec.Type.Dynamic)
2098
 
                                return null;
2099
 
 
2100
 
                        if (!IsLiteral && !Convert.ImplicitStandardConversionExists (this, targetType))
2101
 
                                return null;
2102
 
 
2103
 
                        if (TypeSpec.IsReferenceType (targetType))
2104
 
                                return new NullConstant (targetType, loc);
2105
 
 
2106
 
                        if (targetType.IsNullableType)
2107
 
                                return Nullable.LiftedNull.Create (targetType, loc);
2108
 
 
2109
 
                        return null;
2110
 
                }
2111
 
 
2112
 
                public override Constant ConvertImplicitly (TypeSpec targetType)
2113
 
                {
2114
 
                        return ConvertExplicitly (false, targetType);
2115
 
                }
2116
 
 
2117
 
                public override string GetSignatureForError ()
2118
 
                {
2119
 
                        return "null";
2120
 
                }
2121
 
 
2122
 
                public override object GetValue ()
2123
 
                {
2124
 
                        return null;
2125
 
                }
2126
 
 
2127
 
                public override string GetValueAsLiteral ()
2128
 
                {
2129
 
                        return GetSignatureForError ();
2130
 
                }
2131
 
 
2132
 
                public override long GetValueAsLong ()
2133
 
                {
2134
 
                        throw new NotSupportedException ();
2135
 
                }
2136
 
 
2137
 
                public override bool IsDefaultValue {
2138
 
                        get { return true; }
2139
 
                }
2140
 
 
2141
 
                public override bool IsNegative {
2142
 
                        get { return false; }
2143
 
                }
2144
 
 
2145
 
                public override bool IsNull {
2146
 
                        get { return true; }
2147
 
                }
2148
 
 
2149
 
                public override bool IsZeroInteger {
2150
 
                        get { return true; }
2151
 
                }
2152
 
        }
2153
 
 
2154
 
 
2155
 
        //
2156
 
        // A null constant in a pointer context
2157
 
        //
2158
 
        class NullPointer : NullConstant
2159
 
        {
2160
 
                public NullPointer (TypeSpec type, Location loc)
2161
 
                        : base (type, loc)
2162
 
                {
2163
 
                }
2164
 
 
2165
 
                public override Expression CreateExpressionTree (ResolveContext ec)
2166
 
                {
2167
 
                        Error_PointerInsideExpressionTree (ec);
2168
 
                        return base.CreateExpressionTree (ec);
2169
 
                }
2170
 
 
2171
 
                public override void Emit (EmitContext ec)
2172
 
                {
2173
 
                        //
2174
 
                        // Emits null pointer
2175
 
                        //
2176
 
                        ec.EmitInt (0);
2177
 
                        ec.Emit (OpCodes.Conv_U);
2178
 
                }
2179
 
        }
2180
 
 
2181
 
        /// <summary>
2182
 
        ///   The value is constant, but when emitted has a side effect.  This is
2183
 
        ///   used by BitwiseAnd to ensure that the second expression is invoked
2184
 
        ///   regardless of the value of the left side.  
2185
 
        /// </summary>
2186
 
        public class SideEffectConstant : Constant
2187
 
        {
2188
 
                public readonly Constant value;
2189
 
                Expression side_effect;
2190
 
                
2191
 
                public SideEffectConstant (Constant value, Expression side_effect, Location loc)
2192
 
                        : base (loc)
2193
 
                {
2194
 
                        this.value = value;
2195
 
                        type = value.Type;
2196
 
                        eclass = ExprClass.Value;
2197
 
 
2198
 
                        while (side_effect is SideEffectConstant)
2199
 
                                side_effect = ((SideEffectConstant) side_effect).side_effect;
2200
 
                        this.side_effect = side_effect;
2201
 
                }
2202
 
 
2203
 
                public override bool IsSideEffectFree {
2204
 
                        get {
2205
 
                                return false;
2206
 
                        }
2207
 
                }
2208
 
 
2209
 
                public override object GetValue ()
2210
 
                {
2211
 
                        return value.GetValue ();
2212
 
                }
2213
 
 
2214
 
                public override string GetValueAsLiteral ()
2215
 
                {
2216
 
                        return value.GetValueAsLiteral ();
2217
 
                }
2218
 
 
2219
 
                public override long GetValueAsLong ()
2220
 
                {
2221
 
                        return value.GetValueAsLong ();
2222
 
                }
2223
 
 
2224
 
                public override void Emit (EmitContext ec)
2225
 
                {
2226
 
                        side_effect.EmitSideEffect (ec);
2227
 
                        value.Emit (ec);
2228
 
                }
2229
 
 
2230
 
                public override void EmitSideEffect (EmitContext ec)
2231
 
                {
2232
 
                        side_effect.EmitSideEffect (ec);
2233
 
                        value.EmitSideEffect (ec);
2234
 
                }
2235
 
 
2236
 
                public override bool IsDefaultValue {
2237
 
                        get { return value.IsDefaultValue; }
2238
 
                }
2239
 
 
2240
 
                public override bool IsNegative {
2241
 
                        get { return value.IsNegative; }
2242
 
                }
2243
 
 
2244
 
                public override bool IsZeroInteger {
2245
 
                        get { return value.IsZeroInteger; }
2246
 
                }
2247
 
 
2248
 
                public override Constant ConvertExplicitly (bool in_checked_context, TypeSpec target_type)
2249
 
                {
2250
 
                        Constant new_value = value.ConvertExplicitly (in_checked_context, target_type);
2251
 
                        if (new_value == null)
2252
 
                                return null;
2253
 
 
2254
 
                        var c = new SideEffectConstant (new_value, side_effect, new_value.Location);
2255
 
                        c.type = target_type;
2256
 
                        c.eclass = eclass;
2257
 
                        return c;
2258
 
                }
2259
 
        }
2260
 
}