Beispiel #1
0
        internal SynthesizedAttributeData SynthesizeDecimalConstantAttribute(decimal value)
        {
            var decimalBits = new ConstantValueUtils.DecimalValue(value);
            var systemByte  = GetSpecialType(SpecialType.System_Byte);

            Debug.Assert(!systemByte.HasUseSiteError);

            var systemUnit32 = GetSpecialType(SpecialType.System_UInt32);

            Debug.Assert(!systemUnit32.HasUseSiteError);

            return(SynthesizeAttribute(
                       WellKnownMember.System_Runtime_CompilerServices_DecimalConstantAttribute__ctor,
                       ImmutableArray.Create(
                           new TypedConstant(systemByte, TypedConstantKind.Primitive, decimalBits.Scale),
                           new TypedConstant(systemByte, TypedConstantKind.Primitive, decimalBits.IsNegative ? (byte)128 : (byte)0),
                           new TypedConstant(systemUnit32, TypedConstantKind.Primitive, decimalBits.High),
                           new TypedConstant(systemUnit32, TypedConstantKind.Primitive, decimalBits.Mid),
                           new TypedConstant(systemUnit32, TypedConstantKind.Primitive, decimalBits.Low)
                           )));
        }
Beispiel #2
0
        private BoundExpression MakeDecimalLiteral(CSharpSyntaxNode syntax, ConstantValue constantValue)
        {
            Debug.Assert(constantValue != null);
            Debug.Assert(constantValue.IsDecimal);

            var value = constantValue.DecimalValue;
            var parts = new ConstantValueUtils.DecimalValue(value);
            var scale = parts.Scale;

            var           arguments = new ArrayBuilder <BoundExpression>();
            SpecialMember member;

            // check if we can call a simpler constructor, or use a predefined constant
            if (scale == 0 && int.MinValue <= value && value <= int.MaxValue)
            {
                // If we are building static constructor of System.Decimal, accessing static fields
                // would be bad.
                var curMethod = _factory.CurrentMethod;
                if ((curMethod.MethodKind != MethodKind.SharedConstructor ||
                     curMethod.ContainingType.SpecialType != SpecialType.System_Decimal) &&
                    !_inExpressionLambda)
                {
                    Symbol useField = null;

                    if (value == decimal.Zero)
                    {
                        useField = _compilation.GetSpecialTypeMember(SpecialMember.System_Decimal__Zero);
                    }
                    else if (value == decimal.One)
                    {
                        useField = _compilation.GetSpecialTypeMember(SpecialMember.System_Decimal__One);
                    }
                    else if (value == decimal.MinusOne)
                    {
                        useField = _compilation.GetSpecialTypeMember(SpecialMember.System_Decimal__MinusOne);
                    }

                    if ((object)useField != null &&
                        !useField.HasUseSiteError &&
                        !useField.ContainingType.HasUseSiteError)
                    {
                        var fieldSymbol = (FieldSymbol)useField;
                        return(new BoundFieldAccess(syntax, null, fieldSymbol, constantValue));
                    }
                }

                //new decimal(int);
                member = SpecialMember.System_Decimal__CtorInt32;
                arguments.Add(new BoundLiteral(syntax, ConstantValue.Create((int)value), _compilation.GetSpecialType(SpecialType.System_Int32)));
            }
            else if (scale == 0 && uint.MinValue <= value && value <= uint.MaxValue)
            {
                //new decimal(uint);
                member = SpecialMember.System_Decimal__CtorUInt32;
                arguments.Add(new BoundLiteral(syntax, ConstantValue.Create((uint)value), _compilation.GetSpecialType(SpecialType.System_UInt32)));
            }
            else if (scale == 0 && long.MinValue <= value && value <= long.MaxValue)
            {
                //new decimal(long);
                member = SpecialMember.System_Decimal__CtorInt64;
                arguments.Add(new BoundLiteral(syntax, ConstantValue.Create((long)value), _compilation.GetSpecialType(SpecialType.System_Int64)));
            }
            else if (scale == 0 && ulong.MinValue <= value && value <= ulong.MaxValue)
            {
                //new decimal(ulong);
                member = SpecialMember.System_Decimal__CtorUInt64;
                arguments.Add(new BoundLiteral(syntax, ConstantValue.Create((ulong)value), _compilation.GetSpecialType(SpecialType.System_UInt64)));
            }
            else
            {
                //new decimal(int low, int mid, int high, bool isNegative, byte scale);
                member = SpecialMember.System_Decimal__CtorInt32Int32Int32BooleanByte;
                arguments.Add(new BoundLiteral(syntax, ConstantValue.Create(parts.Low), _compilation.GetSpecialType(SpecialType.System_Int32)));
                arguments.Add(new BoundLiteral(syntax, ConstantValue.Create(parts.Mid), _compilation.GetSpecialType(SpecialType.System_Int32)));
                arguments.Add(new BoundLiteral(syntax, ConstantValue.Create(parts.High), _compilation.GetSpecialType(SpecialType.System_Int32)));
                arguments.Add(new BoundLiteral(syntax, ConstantValue.Create(parts.IsNegative), _compilation.GetSpecialType(SpecialType.System_Boolean)));
                arguments.Add(new BoundLiteral(syntax, ConstantValue.Create(parts.Scale), _compilation.GetSpecialType(SpecialType.System_Byte)));
            }

            var ctor = (MethodSymbol)_compilation.Assembly.GetSpecialTypeMember(member);

            Debug.Assert((object)ctor != null);
            Debug.Assert(ctor.ContainingType.SpecialType == SpecialType.System_Decimal);

            return(new BoundObjectCreationExpression(
                       syntax, ctor, arguments.ToImmutableAndFree(),
                       default(ImmutableArray <string>), default(ImmutableArray <RefKind>), false, default(ImmutableArray <int>),
                       constantValue, null, ctor.ContainingType));
        }