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) ))); }
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)); }