2005-09-19 Chris Toshok <toshok@ximian.com>
[mono.git] / mcs / mcs / convert.cs
index 77385318a6a31eef2daaa1932fb5a3ba0a1df7ab..8cdda18621b55f881a0429ca79dfd1728edd971e 100644 (file)
@@ -62,7 +62,7 @@ namespace Mono.CSharp {
                                        return null;
 
                                if (expr_type.IsValueType)
-                                       return new BoxedCast (expr);
+                                       return new BoxedCast (expr, target_type);
                                if (expr_type.IsClass || expr_type.IsInterface || expr_type == TypeManager.enum_type){
                                        if (expr_type == TypeManager.anonymous_method_type)
                                                return null;
@@ -72,7 +72,7 @@ namespace Mono.CSharp {
                                return null;
                        } else if (target_type == TypeManager.value_type) {
                                if (expr_type.IsValueType)
-                                       return new BoxedCast (expr);
+                                       return new BoxedCast (expr, target_type);
                                if (expr_type == TypeManager.null_type)
                                        return new NullCast (expr, target_type);
 
@@ -84,7 +84,7 @@ namespace Mono.CSharp {
                                // a boxing conversion
                                //
                                if (expr_type.IsEnum)
-                                       return new BoxedCast (expr);
+                                       return new BoxedCast (expr, target_type);
 
                                return new EmptyCast (expr, target_type);
                        }
@@ -176,8 +176,11 @@ namespace Mono.CSharp {
                // Tests whether an implicit reference conversion exists between expr_type
                // and target_type
                //
-               public static bool ImplicitReferenceConversionExists (Expression expr, Type target_type)
+               static bool ImplicitReferenceConversionExists (Expression expr, Type target_type)
                {
+                       if (target_type.IsValueType)
+                               return false;
+
                        Type expr_type = expr.Type;
 
                        //
@@ -295,7 +298,7 @@ namespace Mono.CSharp {
                                        //
                                        long v = ((LongConstant) expr).Value;
                                        if (v >= 0)
-                                               return new ULongConstant ((ulong) v);
+                                               return new ULongConstant ((ulong) v, expr.Location);
                                } 
                        }
                        
@@ -627,7 +630,7 @@ namespace Mono.CSharp {
                                        if (value >= SByte.MinValue && value <= SByte.MaxValue)
                                                return true;
                                } else if (target_type == TypeManager.byte_type){
-                                       if (Byte.MinValue >= 0 && value <= Byte.MaxValue)
+                                       if (value >= 0 && value <= Byte.MaxValue)
                                                return true;
                                } else if (target_type == TypeManager.short_type){
                                        if (value >= Int16.MinValue && value <= Int16.MaxValue)
@@ -659,7 +662,7 @@ namespace Mono.CSharp {
                                // we just inline it
                                //
                                long v = ((LongConstant) expr).Value;
-                               if (v > 0)
+                               if (v >= 0)
                                        return true;
                        }
                        
@@ -1209,19 +1212,19 @@ namespace Mono.CSharp {
 
                        if (target_type == TypeManager.sbyte_type){
                                if (value >= SByte.MinValue && value <= SByte.MaxValue)
-                                       return new SByteConstant ((sbyte) value);
+                                       return new SByteConstant ((sbyte) value, ic.Location);
                        } else if (target_type == TypeManager.byte_type){
                                if (value >= Byte.MinValue && value <= Byte.MaxValue)
-                                       return new ByteConstant ((byte) value);
+                                       return new ByteConstant ((byte) value, ic.Location);
                        } else if (target_type == TypeManager.short_type){
                                if (value >= Int16.MinValue && value <= Int16.MaxValue)
-                                       return new ShortConstant ((short) value);
+                                       return new ShortConstant ((short) value, ic.Location);
                        } else if (target_type == TypeManager.ushort_type){
                                if (value >= UInt16.MinValue && value <= UInt16.MaxValue)
-                                       return new UShortConstant ((ushort) value);
+                                       return new UShortConstant ((ushort) value, ic.Location);
                        } else if (target_type == TypeManager.uint32_type){
                                if (value >= 0)
-                                       return new UIntConstant ((uint) value);
+                                       return new UIntConstant ((uint) value, ic.Location);
                        } else if (target_type == TypeManager.uint64_type){
                                //
                                // we can optimize this case: a positive int32
@@ -1229,11 +1232,11 @@ namespace Mono.CSharp {
                                // to do it.
                                //
                                if (value >= 0)
-                                       return new ULongConstant ((ulong) value);
+                                       return new ULongConstant ((ulong) value, ic.Location);
                        } else if (target_type == TypeManager.double_type)
-                               return new DoubleConstant ((double) value);
+                               return new DoubleConstant ((double) value, ic.Location);
                        else if (target_type == TypeManager.float_type)
-                               return new FloatConstant ((float) value);
+                               return new FloatConstant ((float) value, ic.Location);
                        
                        if (value == 0 && ic is IntLiteral && TypeManager.IsEnumType (target_type)){
                                Type underlying = TypeManager.EnumToUnderlying (target_type);
@@ -1244,9 +1247,9 @@ namespace Mono.CSharp {
                                // to EnumConstant
                                //
                                if (underlying == TypeManager.int64_type)
-                                       e = new LongLiteral (0);
+                                       e = new LongLiteral (0, ic.Location);
                                else if (underlying == TypeManager.uint64_type)
-                                       e = new ULongLiteral (0);
+                                       e = new ULongLiteral (0, ic.Location);
 
                                return new EnumConstant (e, target_type);
                        }
@@ -1256,7 +1259,7 @@ namespace Mono.CSharp {
                        // e.g. target_type is IComparable, IConvertible, IFormattable
                        //
                        if (target_type.IsInterface && target_type.IsAssignableFrom (ic.Type))
-                               return new BoxedCast (ic);
+                               return new BoxedCast (ic, target_type);
 
                        return null;
                }
@@ -1301,15 +1304,7 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       if (source is Constant){
-                               Constant c = (Constant) source;
-
-                               Expression.Error_ConstantValueCannotBeConverted (loc, c.AsString (), target_type);
-                               return null;
-                       }
-                       
-                       Error_CannotImplicitConversion (loc, source.Type, target_type);
-
+                       source.Error_ValueCannotBeConverted (loc, target_type);
                        return null;
                }
 
@@ -1766,15 +1761,13 @@ namespace Mono.CSharp {
                        Type expr_type = expr.Type;
                        Type original_expr_type = expr_type;
 
+                       Expression ne = ImplicitConversionStandard (ec, expr, target_type, loc);
+
+                       if (ne != null)
+                               return ne;
+
                        if (expr_type.IsSubclassOf (TypeManager.enum_type)){
-                               if (target_type == TypeManager.enum_type ||
-                                   target_type == TypeManager.object_type) {
-                                       if (expr is EnumConstant)
-                                               expr = ((EnumConstant) expr).Child;
-                                       // We really need all these casts here .... :-(
-                                       expr = new BoxedCast (new EmptyCast (expr, expr_type));
-                                       return new EmptyCast (expr, target_type);
-                               } else if ((expr_type == TypeManager.enum_type) && target_type.IsValueType &&
+                               if ((expr_type == TypeManager.enum_type) && target_type.IsValueType &&
                                           target_type.IsSubclassOf (TypeManager.enum_type))
                                        return new UnboxCast (expr, target_type);
 
@@ -1788,11 +1781,6 @@ namespace Mono.CSharp {
                                expr_type = expr.Type;
                        }
 
-                       Expression ne = ImplicitConversionStandard (ec, expr, target_type, loc);
-
-                       if (ne != null)
-                               return ne;
-
                        ne = ExplicitNumericConversion (ec, expr, target_type, loc);
                        if (ne != null)
                                return ne;
@@ -1877,13 +1865,10 @@ namespace Mono.CSharp {
                        if (ne != null)
                                return ne;
 
-                       if (expr is NullLiteral){
-                               Report.Error (37, loc, "Cannot convert null to `{0}' because it is a value type",
-                                             TypeManager.CSharpName (target_type));
-                               return null;
-                       }
-
-                       Error_CannotConvertType (loc, original_expr_type, target_type);
+                       if (expr is Constant)
+                               expr.Error_ValueCannotBeConverted (loc, target_type);
+                       else
+                               Error_CannotConvertType (loc, original_expr_type, target_type);
                        return null;
                }