Example #1
0
        internal static bool HasImplicitConstantExpressionConversion(BoundExpression source, TypeSymbol destination)
        {
            var constantValue = source.ConstantValue;

            if (constantValue == null)
            {
                return(false);
            }

            // An implicit constant expression conversion permits the following conversions:

            // A constant-expression of type int can be converted to type sbyte, byte, short,
            // ushort, uint, or ulong, provided the value of the constant-expression is within the
            // range of the destination type.
            var specialSource = source.Type.GetSpecialTypeSafe();

            if (specialSource == SpecialType.System_Int32)
            {
                //if the constant value could not be computed, be generous and assume the conversion will work
                int value = constantValue.IsBad ? 0 : constantValue.Int32Value;
                switch (destination.GetSpecialTypeSafe())
                {
                case SpecialType.System_Byte:
                    return(byte.MinValue <= value && value <= byte.MaxValue);

                case SpecialType.System_SByte:
                    return(sbyte.MinValue <= value && value <= sbyte.MaxValue);

                case SpecialType.System_Int16:
                    return(short.MinValue <= value && value <= short.MaxValue);

                case SpecialType.System_UInt32:
                    return(uint.MinValue <= value);

                case SpecialType.System_UInt64:
                    return((int)ulong.MinValue <= value);

                case SpecialType.System_UInt16:
                    return(ushort.MinValue <= value && value <= ushort.MaxValue);

                default:
                    return(false);
                }
            }
            else if (specialSource == SpecialType.System_Int64 && destination.GetSpecialTypeSafe() == SpecialType.System_UInt64 && (constantValue.IsBad || 0 <= constantValue.Int64Value))
            {
                // A constant-expression of type long can be converted to type ulong, provided the
                // value of the constant-expression is not negative.
                return(true);
            }

            return(false);
        }
Example #2
0
        internal static bool HasImplicitVOConstantExpressionConversion(BoundExpression source, TypeSymbol destination)
        {
            var specialSource = source.Type.GetSpecialTypeSafe();

            if (specialSource == SpecialType.System_Double && destination.GetSpecialTypeSafe() == SpecialType.System_Single)
            {
                // TODO (nvk): Check numeric range before accepting conversion!
                return(true);
            }
            else if (specialSource == SpecialType.System_UInt32 && destination.GetSpecialTypeSafe() == SpecialType.System_IntPtr)
            {
                return(true);
            }
            return(false);
        }
Example #3
0
        private static bool AddSpecialTypeKeyword(TypeSymbol symbol, ArrayBuilder <SymbolDescriptionPart> builder)
        {
            var specialType = symbol.GetSpecialTypeSafe();

            switch (specialType)
            {
            case SpecialType.System_Void:
            case SpecialType.System_SByte:
            case SpecialType.System_Int16:
            case SpecialType.System_Int32:
            case SpecialType.System_Int64:
            case SpecialType.System_Byte:
            case SpecialType.System_UInt16:
            case SpecialType.System_UInt32:
            case SpecialType.System_UInt64:
            case SpecialType.System_Single:
            case SpecialType.System_Double:
            case SpecialType.System_Decimal:
            case SpecialType.System_Char:
            case SpecialType.System_Boolean:
            case SpecialType.System_String:
            case SpecialType.System_Object:
                //not calling AddKeyword because someone else is working out the text for us
                builder.Add(new SymbolDescriptionPart
                {
                    Kind = SymbolDescriptionPartKind.Keyword,
                    Text = SemanticFacts.GetLanguageName(specialType),
                });
                return(true);

            default:
                return(false);
            }
        }
Example #4
0
            private static int?TypeToIndex(TypeSymbol type)
            {
                switch (type.GetSpecialTypeSafe())
                {
                case SpecialType.System_String: return(0);

                case SpecialType.System_Int32: return(1);

                default: return(null);
                }
            }
Example #5
0
            private static int TypeToIndex(TypeSymbol type)
            {
                switch (type.GetSpecialTypeSafe())
                {
                    case SpecialType.System_Object: return 0;
                    case SpecialType.System_String: return 1;
                    case SpecialType.System_Boolean: return 2;
                    case SpecialType.System_Char: return 3;
                    case SpecialType.System_SByte: return 4;
                    case SpecialType.System_Int16: return 5;
                    case SpecialType.System_Int32: return 6;
                    case SpecialType.System_Int64: return 7;
                    case SpecialType.System_Byte: return 8;
                    case SpecialType.System_UInt16: return 9;
                    case SpecialType.System_UInt32: return 10;
                    case SpecialType.System_UInt64: return 11;
                    case SpecialType.System_Single: return 12;
                    case SpecialType.System_Double: return 13;
                    case SpecialType.System_Decimal: return 14;

                    case SpecialType.None:
                        if ((object)type != null && type.IsNullableType())
                        {
                            TypeSymbol underlyingType = type.GetNullableUnderlyingType();

                            switch (underlyingType.GetSpecialTypeSafe())
                            {
                                case SpecialType.System_Boolean: return 15;
                                case SpecialType.System_Char: return 16;
                                case SpecialType.System_SByte: return 17;
                                case SpecialType.System_Int16: return 18;
                                case SpecialType.System_Int32: return 19;
                                case SpecialType.System_Int64: return 20;
                                case SpecialType.System_Byte: return 21;
                                case SpecialType.System_UInt16: return 22;
                                case SpecialType.System_UInt32: return 23;
                                case SpecialType.System_UInt64: return 24;
                                case SpecialType.System_Single: return 25;
                                case SpecialType.System_Double: return 26;
                                case SpecialType.System_Decimal: return 27;
                            }
                        }

                        // fall through
                        goto default;

                    default:
                        return -1;
                }
            }
        internal static bool HasImplicitConstantExpressionConversion(BoundExpression source, TypeSymbol destination)
        {
            var constantValue = source.ConstantValue;

            if (constantValue == null)
            {
                return false;
            }

            // An implicit constant expression conversion permits the following conversions:

            // A constant-expression of type int can be converted to type sbyte, byte, short, 
            // ushort, uint, or ulong, provided the value of the constant-expression is within the
            // range of the destination type.
            var specialSource = source.Type.GetSpecialTypeSafe();

            if (specialSource == SpecialType.System_Int32)
            {
                //if the constant value could not be computed, be generous and assume the conversion will work
                int value = constantValue.IsBad ? 0 : constantValue.Int32Value;
                switch (destination.GetSpecialTypeSafe())
                {
                    case SpecialType.System_Byte:
                        return byte.MinValue <= value && value <= byte.MaxValue;
                    case SpecialType.System_SByte:
                        return sbyte.MinValue <= value && value <= sbyte.MaxValue;
                    case SpecialType.System_Int16:
                        return short.MinValue <= value && value <= short.MaxValue;
                    case SpecialType.System_UInt32:
                        return uint.MinValue <= value;
                    case SpecialType.System_UInt64:
                        return (int)ulong.MinValue <= value;
                    case SpecialType.System_UInt16:
                        return ushort.MinValue <= value && value <= ushort.MaxValue;
                    default:
                        return false;
                }
            }
            else if (specialSource == SpecialType.System_Int64 && destination.GetSpecialTypeSafe() == SpecialType.System_UInt64 && (constantValue.IsBad || 0 <= constantValue.Int64Value))
            {
                // A constant-expression of type long can be converted to type ulong, provided the
                // value of the constant-expression is not negative.
                return true;
            }

            return false;
        }
Example #7
0
            private static int TypeToIndex(TypeSymbol type)
            {
                switch (type.GetSpecialTypeSafe())
                {
                case SpecialType.System_Object: return(0);

                case SpecialType.System_String: return(1);

                case SpecialType.System_Boolean: return(2);

                case SpecialType.System_Char: return(3);

                case SpecialType.System_SByte: return(4);

                case SpecialType.System_Int16: return(5);

                case SpecialType.System_Int32: return(6);

                case SpecialType.System_Int64: return(7);

                case SpecialType.System_Byte: return(8);

                case SpecialType.System_UInt16: return(9);

                case SpecialType.System_UInt32: return(10);

                case SpecialType.System_UInt64: return(11);

                case SpecialType.System_Single: return(12);

                case SpecialType.System_Double: return(13);

                case SpecialType.System_Decimal: return(14);

                case SpecialType.None:
                    if ((object)type != null && type.IsNullableType())
                    {
                        TypeSymbol underlyingType = type.GetNullableUnderlyingType();

                        switch (underlyingType.GetSpecialTypeSafe())
                        {
                        case SpecialType.System_Boolean: return(15);

                        case SpecialType.System_Char: return(16);

                        case SpecialType.System_SByte: return(17);

                        case SpecialType.System_Int16: return(18);

                        case SpecialType.System_Int32: return(19);

                        case SpecialType.System_Int64: return(20);

                        case SpecialType.System_Byte: return(21);

                        case SpecialType.System_UInt16: return(22);

                        case SpecialType.System_UInt32: return(23);

                        case SpecialType.System_UInt64: return(24);

                        case SpecialType.System_Single: return(25);

                        case SpecialType.System_Double: return(26);

                        case SpecialType.System_Decimal: return(27);
                        }
                    }

                    // fall through
                    goto default;

                default:
                    return(-1);
                }
            }
        private ConstantValue FoldConstantNumericConversion(
            CSharpSyntaxNode syntax,
            ConstantValue sourceValue,
            TypeSymbol destination,
            DiagnosticBag diagnostics)
        {
            Debug.Assert(sourceValue != null);
            Debug.Assert(!sourceValue.IsBad);

            SpecialType destinationType;
            if ((object)destination != null && destination.IsEnumType())
            {
                var underlyingType = ((NamedTypeSymbol)destination).EnumUnderlyingType;
                Debug.Assert((object)underlyingType != null);
                Debug.Assert(underlyingType.SpecialType != SpecialType.None);
                destinationType = underlyingType.SpecialType;
            }
            else
            {
                destinationType = destination.GetSpecialTypeSafe();
            }

            // In an unchecked context we ignore overflowing conversions on conversions from any
            // integral type, float and double to any integral type. "unchecked" actually does not
            // affect conversions from decimal to any integral type; if those are out of bounds then
            // we always give an error regardless.

            if (sourceValue.IsDecimal)
            {
                if (!CheckConstantBounds(destinationType, sourceValue))
                {
                    // NOTE: Dev10 puts a suffix, "M", on the constant value.
                    Error(diagnostics, ErrorCode.ERR_ConstOutOfRange, syntax, sourceValue.Value + "M", destination);

                    return ConstantValue.Bad;
                }
            }
            else if (destinationType == SpecialType.System_Decimal)
            {
                if (!CheckConstantBounds(destinationType, sourceValue))
                {
                    Error(diagnostics, ErrorCode.ERR_ConstOutOfRange, syntax, sourceValue.Value, destination);

                    return ConstantValue.Bad;
                }
            }
            else if (CheckOverflowAtCompileTime)
            {
                if (!CheckConstantBounds(destinationType, sourceValue))
                {
                    Error(diagnostics, ErrorCode.ERR_ConstOutOfRangeChecked, syntax, sourceValue.Value, destination);

                    return ConstantValue.Bad;
                }
            }

            return ConstantValue.Create(DoUncheckedConversion(destinationType, sourceValue), destinationType);
        }
Example #9
0
        public static string GetErrorReportingName(TypeSymbol type, RefKind refKind = RefKind.None)
        {
            string prefix = "";

            switch (refKind)
            {
            case RefKind.Ref: prefix = "ref "; break;

            case RefKind.Out: prefix = "out "; break;
            }

            switch (type.GetSpecialTypeSafe())
            {
            case SpecialType.System_Void:
            case SpecialType.System_SByte:
            case SpecialType.System_Int16:
            case SpecialType.System_Int32:
            case SpecialType.System_Int64:
            case SpecialType.System_Byte:
            case SpecialType.System_UInt16:
            case SpecialType.System_UInt32:
            case SpecialType.System_UInt64:
            case SpecialType.System_Single:
            case SpecialType.System_Double:
            case SpecialType.System_Decimal:
            case SpecialType.System_Char:
            case SpecialType.System_Boolean:
            case SpecialType.System_String:
            case SpecialType.System_Object:
                return(prefix + SemanticFacts.GetLanguageName(type.SpecialType));

            case SpecialType.None:
                if (type != null && type.IsNullableType() && !ReferenceEquals(type, type.OriginalDefinition))
                {
                    TypeSymbol underlyingType = type.GetNullableUnderlyingType();

                    switch (underlyingType.GetSpecialTypeSafe())
                    {
                    case SpecialType.System_Boolean:
                    case SpecialType.System_SByte:
                    case SpecialType.System_Int16:
                    case SpecialType.System_Int32:
                    case SpecialType.System_Int64:
                    case SpecialType.System_Byte:
                    case SpecialType.System_UInt16:
                    case SpecialType.System_UInt32:
                    case SpecialType.System_UInt64:
                    case SpecialType.System_Single:
                    case SpecialType.System_Double:
                    case SpecialType.System_Decimal:
                    case SpecialType.System_Char:
                        return(prefix + SemanticFacts.GetLanguageName(underlyingType.SpecialType) + "?");
                    }

                    return(prefix + GetErrorReportingName(underlyingType) + "?");
                }

                break;
            }

            var dynamicType = type as DynamicTypeSymbol;

            if (dynamicType != null)
            {
                return(prefix + "dynamic");
            }

            var arrayType = type as ArrayTypeSymbol;

            if (arrayType != null)
            {
                string suffix = "";
                while (true)
                {
                    var elementType = arrayType.ElementType;
                    suffix   += GetSuffix(arrayType.Rank);
                    arrayType = elementType as ArrayTypeSymbol;
                    if (arrayType == null)
                    {
                        return(prefix + GetErrorReportingName(elementType) + suffix);
                    }
                }
            }

            var pointerType = type as PointerTypeSymbol;

            if (pointerType != null)
            {
                return(prefix + GetErrorReportingName(pointerType.BaseType) + "*");
            }

            var namedType = type as NamedTypeSymbol;

            if (namedType != null)
            {
                string result = "";
                if (namedType.ContainingType != null)
                {
                    result = GetErrorReportingName(namedType.ContainingType) + ".";
                }
                else if (namedType.ContainingNamespace != null && !namedType.ContainingNamespace.IsGlobalNamespace)
                {
                    result = namedType.ContainingNamespace.GetFullName() + ".";
                }
                result += type.Name;
                if (namedType.TypeArguments.Count != 0)
                {
                    result += "<";
                    result += namedType.TypeArguments.Select(a => GetErrorReportingName(a)).Comma(",");
                    result += ">";
                }
                return(prefix + result);
            }

            var typeParameter = type as TypeParameterSymbol;

            if (typeParameter != null)
            {
                return(prefix + type.Name);
            }

            Debug.Fail("What case did we miss in type name error reporter?");
            return(prefix + type.GetFullName());
        }
 private static bool AddSpecialTypeKeyword(TypeSymbol symbol, ArrayBuilder<SymbolDescriptionPart> builder)
 {
     var specialType = symbol.GetSpecialTypeSafe();
     switch (specialType)
     {
         case SpecialType.System_Void:
         case SpecialType.System_SByte:
         case SpecialType.System_Int16:
         case SpecialType.System_Int32:
         case SpecialType.System_Int64:
         case SpecialType.System_Byte:
         case SpecialType.System_UInt16:
         case SpecialType.System_UInt32:
         case SpecialType.System_UInt64:
         case SpecialType.System_Single:
         case SpecialType.System_Double:
         case SpecialType.System_Decimal:
         case SpecialType.System_Char:
         case SpecialType.System_Boolean:
         case SpecialType.System_String:
         case SpecialType.System_Object:
             //not calling AddKeyword because someone else is working out the text for us
             builder.Add(new SymbolDescriptionPart
             {
                 Kind = SymbolDescriptionPartKind.Keyword,
                 Text = SemanticFacts.GetLanguageName(specialType),
             });
             return true;
         default:
             return false;
     }
 }
        public static string GetErrorReportingName(TypeSymbol type, RefKind refKind = RefKind.None)
        {
            string prefix = "";
            switch (refKind)
            {
                case RefKind.Ref: prefix = "ref "; break;
                case RefKind.Out: prefix = "out "; break;
            }

            switch (type.GetSpecialTypeSafe())
            {
                case SpecialType.System_Void: 
                case SpecialType.System_SByte:
                case SpecialType.System_Int16:
                case SpecialType.System_Int32:
                case SpecialType.System_Int64:
                case SpecialType.System_Byte: 
                case SpecialType.System_UInt16:
                case SpecialType.System_UInt32:
                case SpecialType.System_UInt64:
                case SpecialType.System_Single:
                case SpecialType.System_Double:
                case SpecialType.System_Decimal:
                case SpecialType.System_Char:
                case SpecialType.System_Boolean:
                case SpecialType.System_String:
                case SpecialType.System_Object:
                    return prefix + SemanticFacts.GetLanguageName(type.SpecialType);

                case SpecialType.None:
                    if (type != null && type.IsNullableType() && !ReferenceEquals(type, type.OriginalDefinition))
                    {
                        TypeSymbol underlyingType = type.GetNullableUnderlyingType();

                        switch (underlyingType.GetSpecialTypeSafe())
                        {
                            case SpecialType.System_Boolean:
                            case SpecialType.System_SByte:
                            case SpecialType.System_Int16:
                            case SpecialType.System_Int32:
                            case SpecialType.System_Int64:
                            case SpecialType.System_Byte:
                            case SpecialType.System_UInt16:
                            case SpecialType.System_UInt32:
                            case SpecialType.System_UInt64:
                            case SpecialType.System_Single:
                            case SpecialType.System_Double:
                            case SpecialType.System_Decimal:
                            case SpecialType.System_Char:
                                return prefix + SemanticFacts.GetLanguageName(underlyingType.SpecialType) + "?";
                        }

                        return prefix + GetErrorReportingName(underlyingType) + "?";
                    }

                    break;
            }

            var dynamicType = type as DynamicTypeSymbol;
            if (dynamicType != null)
            {
                return prefix + "dynamic";
            }

            var arrayType = type as ArrayTypeSymbol;
            if (arrayType != null)
            {
                string suffix = "";
                while (true)
                {
                    var elementType = arrayType.ElementType;
                    suffix += GetSuffix(arrayType.Rank);
                    arrayType = elementType as ArrayTypeSymbol;
                    if (arrayType == null)
                    {
                        return prefix + GetErrorReportingName(elementType) + suffix;
                    }
                }
            }

            var pointerType = type as PointerTypeSymbol;
            if (pointerType != null)
            {
                return prefix + GetErrorReportingName(pointerType.BaseType) + "*";
            }

            var namedType = type as NamedTypeSymbol;
            if (namedType != null)
            {
                string result = "";
                if (namedType.ContainingType != null)
                {
                    result = GetErrorReportingName(namedType.ContainingType) + ".";
                }
                else if (namedType.ContainingNamespace != null && !namedType.ContainingNamespace.IsGlobalNamespace)
                {
                    result = namedType.ContainingNamespace.GetFullName() + ".";
                }
                result += type.Name;
                if (namedType.TypeArguments.Count != 0)
                {
                    result += "<";
                    result += namedType.TypeArguments.Select(a => GetErrorReportingName(a)).Comma(",");
                    result += ">";
                }
                return prefix + result;
            }

            var typeParameter = type as TypeParameterSymbol;
            if (typeParameter != null)
            {
                return prefix + type.Name;
            }

            Debug.Fail("What case did we miss in type name error reporter?");
            return prefix + type.GetFullName();
        }