public override Constant ConvertImplicitly(TypeSpec type)
        {
            //
            // The 0 literal can be converted to an enum value
            //
            if (Value == 0 && type.IsEnum)
            {
                Constant c = ConvertImplicitly(EnumSpec.GetUnderlyingType(type));
                if (c == null)
                {
                    return(null);
                }

                return(new EnumConstant(c, type));
            }

            return(base.ConvertImplicitly(type));
        }
        //
        // The stack contains the pointer and the value of type `type'
        //
        public void EmitStoreFromPtr(TypeSpec type)
        {
            if (type.IsEnum)
            {
                type = EnumSpec.GetUnderlyingType(type);
            }

            switch (type.BuiltinType)
            {
            case BuiltinTypeSpec.Type.Int:
            case BuiltinTypeSpec.Type.UInt:
                ig.Emit(OpCodes.Stind_I4);
                return;

            case BuiltinTypeSpec.Type.Long:
            case BuiltinTypeSpec.Type.ULong:
                ig.Emit(OpCodes.Stind_I8);
                return;

            case BuiltinTypeSpec.Type.Char:
            case BuiltinTypeSpec.Type.Short:
            case BuiltinTypeSpec.Type.UShort:
                ig.Emit(OpCodes.Stind_I2);
                return;

            case BuiltinTypeSpec.Type.Float:
                ig.Emit(OpCodes.Stind_R4);
                return;

            case BuiltinTypeSpec.Type.Double:
                ig.Emit(OpCodes.Stind_R8);
                return;

            case BuiltinTypeSpec.Type.Byte:
            case BuiltinTypeSpec.Type.SByte:
            case BuiltinTypeSpec.Type.Bool:
                ig.Emit(OpCodes.Stind_I1);
                return;

            case BuiltinTypeSpec.Type.IntPtr:
                ig.Emit(OpCodes.Stind_I);
                return;
            }

            switch (type.Kind)
            {
            case MemberKind.Struct:
            case MemberKind.TypeParameter:
                if (IsAnonymousStoreyMutateRequired)
                {
                    type = CurrentAnonymousMethod.Storey.Mutator.Mutate(type);
                }

                ig.Emit(OpCodes.Stobj, type.GetMetaInfo());
                break;

            default:
                ig.Emit(OpCodes.Stind_Ref);
                break;
            }
        }
        //
        // Emits the right opcode to store to an array
        //
        public void EmitArrayStore(ArrayContainer ac)
        {
            if (ac.Rank > 1)
            {
                if (IsAnonymousStoreyMutateRequired)
                {
                    ac = (ArrayContainer)ac.Mutate(CurrentAnonymousMethod.Storey.Mutator);
                }

                ig.Emit(OpCodes.Call, ac.GetSetMethod());
                return;
            }

            var type = ac.Element;

            if (type.Kind == MemberKind.Enum)
            {
                type = EnumSpec.GetUnderlyingType(type);
            }

            switch (type.BuiltinType)
            {
            case BuiltinTypeSpec.Type.Byte:
            case BuiltinTypeSpec.Type.SByte:
            case BuiltinTypeSpec.Type.Bool:
                Emit(OpCodes.Stelem_I1);
                return;

            case BuiltinTypeSpec.Type.Short:
            case BuiltinTypeSpec.Type.UShort:
            case BuiltinTypeSpec.Type.Char:
                Emit(OpCodes.Stelem_I2);
                return;

            case BuiltinTypeSpec.Type.Int:
            case BuiltinTypeSpec.Type.UInt:
                Emit(OpCodes.Stelem_I4);
                return;

            case BuiltinTypeSpec.Type.Long:
            case BuiltinTypeSpec.Type.ULong:
                Emit(OpCodes.Stelem_I8);
                return;

            case BuiltinTypeSpec.Type.Float:
                Emit(OpCodes.Stelem_R4);
                return;

            case BuiltinTypeSpec.Type.Double:
                Emit(OpCodes.Stelem_R8);
                return;
            }

            switch (type.Kind)
            {
            case MemberKind.Struct:
                Emit(OpCodes.Stobj, type);
                break;

            case MemberKind.TypeParameter:
                Emit(OpCodes.Stelem, type);
                break;

            case MemberKind.PointerType:
                Emit(OpCodes.Stelem_I);
                break;

            default:
                Emit(OpCodes.Stelem_Ref);
                break;
            }
        }