⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 convert.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 5 页
字号:
								//				// Only allow anonymous method conversions on post ISO_1				//				if (RootContext.Version != LanguageVersion.ISO_1){					MethodGroupExpr mg = expr as MethodGroupExpr;					if (mg != null)						return ImplicitDelegateCreation.Create (							ec, mg, target_type, false, loc);				}			}			if (expr_type == target_type && expr_type != TypeManager.null_type)				return expr;			e = ImplicitNumericConversion (ec, expr, target_type);			if (e != null)				return e;			e = ImplicitReferenceConversion (expr, target_type);			if (e != null)				return e;						if ((target_type == TypeManager.enum_type ||			     target_type.IsSubclassOf (TypeManager.enum_type)) &&			    expr is IntLiteral){				IntLiteral i = (IntLiteral) expr;								if (i.Value == 0)					return new EnumConstant ((Constant) expr, target_type);			}			if (ec.InUnsafe) {				if (expr_type.IsPointer){					if (target_type == TypeManager.void_ptr_type)						return new EmptyCast (expr, target_type);					//					// yep, comparing pointer types cant be done with					// t1 == t2, we have to compare their element types.					//					if (target_type.IsPointer){						if (TypeManager.GetElementType(target_type) == TypeManager.GetElementType(expr_type))							return expr;						//return null;					}				}								if (expr_type == TypeManager.null_type && target_type.IsPointer)					return new EmptyCast (NullPointer.Null, target_type);			}			if (expr_type == TypeManager.anonymous_method_type){				if (!TypeManager.IsDelegateType (target_type)){					Report.Error (1660, loc,						"Cannot convert anonymous method block to type `{0}' because it is not a delegate type",						TypeManager.CSharpName (target_type));					return null;				}				AnonymousMethod am = (AnonymousMethod) expr;				int errors = Report.Errors;				Expression conv = am.Compatible (ec, target_type, false);				if (conv != null)					return conv;								//				// We return something instead of null, to avoid				// the duplicate error, since am.Compatible would have				// reported that already				//				if (errors != Report.Errors)					return new EmptyCast (expr, target_type);			}						return null;		}		/// <summary>		///   Attempts to perform an implicit constant conversion of the IntConstant		///   into a different data type using casts (See Implicit Constant		///   Expression Conversions)		/// </summary>		static public Expression TryImplicitIntConversion (Type target_type, IntConstant ic)		{			int value = ic.Value;			if (target_type == TypeManager.sbyte_type){				if (value >= SByte.MinValue && value <= SByte.MaxValue)					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, ic.Location);			} else if (target_type == TypeManager.short_type){				if (value >= Int16.MinValue && value <= Int16.MaxValue)					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, ic.Location);			} else if (target_type == TypeManager.uint32_type){				if (value >= 0)					return new UIntConstant ((uint) value, ic.Location);			} else if (target_type == TypeManager.uint64_type){				//				// we can optimize this case: a positive int32				// always fits on a uint64.  But we need an opcode				// to do it.				//				if (value >= 0)					return new ULongConstant ((ulong) value, ic.Location);			} else if (target_type == TypeManager.double_type)				return new DoubleConstant ((double) value, ic.Location);			else if (target_type == TypeManager.float_type)				return new FloatConstant ((float) value, ic.Location);						if (value == 0 && ic is IntLiteral && TypeManager.IsEnumType (target_type)){				Type underlying = TypeManager.EnumToUnderlying (target_type);				Constant e = (Constant) ic;								//				// Possibly, we need to create a different 0 literal before passing				// to EnumConstant				//				if (underlying == TypeManager.int64_type)					e = new LongLiteral (0, ic.Location);				else if (underlying == TypeManager.uint64_type)					e = new ULongLiteral (0, ic.Location);				return new EnumConstant (e, target_type);			}			//			// If `target_type' is an interface and the type of `ic' implements the interface			// e.g. target_type is IComparable, IConvertible, IFormattable			//			if (target_type.IsInterface && target_type.IsAssignableFrom (ic.Type))				return new BoxedCast (ic, target_type);			return null;		}		/// <summary>		///   Attempts to implicitly convert `source' into `target_type', using		///   ImplicitConversion.  If there is no implicit conversion, then		///   an error is signaled		/// </summary>		static public Expression ImplicitConversionRequired (EmitContext ec, Expression source,								     Type target_type, Location loc)		{			Expression e;						e = ImplicitConversion (ec, source, target_type, loc);			if (e != null)				return e;			if (source is DoubleLiteral) {				if (target_type == TypeManager.float_type) {					Error_664 (loc, "float", "f");					return null;				}				if (target_type == TypeManager.decimal_type) {					Error_664 (loc, "decimal", "m");					return null;				}			}			source.Error_ValueCannotBeConverted (loc, target_type, false);			return null;		}		static void Error_664 (Location loc, string type, string suffix) {			Report.Error (664, loc,				"Literal of type double cannot be implicitly converted to type `{0}'. Add suffix `{1}' to create a literal of this type",				type, suffix);		}		/// <summary>		///   Performs the explicit numeric conversions		/// </summary>		public static Expression ExplicitNumericConversion (Expression expr, Type target_type)		{			Type expr_type = expr.Type;			Type real_target_type = target_type;			if (expr_type == TypeManager.sbyte_type){				//				// From sbyte to byte, ushort, uint, ulong, char				//				if (real_target_type == TypeManager.byte_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I1_U1);				if (real_target_type == TypeManager.ushort_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I1_U2);				if (real_target_type == TypeManager.uint32_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I1_U4);				if (real_target_type == TypeManager.uint64_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I1_U8);				if (real_target_type == TypeManager.char_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I1_CH);			} else if (expr_type == TypeManager.byte_type){				//				// From byte to sbyte and char				//				if (real_target_type == TypeManager.sbyte_type)					return new ConvCast (expr, target_type, ConvCast.Mode.U1_I1);				if (real_target_type == TypeManager.char_type)					return new ConvCast (expr, target_type, ConvCast.Mode.U1_CH);			} else if (expr_type == TypeManager.short_type){				//				// From short to sbyte, byte, ushort, uint, ulong, char				//				if (real_target_type == TypeManager.sbyte_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I2_I1);				if (real_target_type == TypeManager.byte_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I2_U1);				if (real_target_type == TypeManager.ushort_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I2_U2);				if (real_target_type == TypeManager.uint32_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I2_U4);				if (real_target_type == TypeManager.uint64_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I2_U8);				if (real_target_type == TypeManager.char_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I2_CH);			} else if (expr_type == TypeManager.ushort_type){				//				// From ushort to sbyte, byte, short, char				//				if (real_target_type == TypeManager.sbyte_type)					return new ConvCast (expr, target_type, ConvCast.Mode.U2_I1);				if (real_target_type == TypeManager.byte_type)					return new ConvCast (expr, target_type, ConvCast.Mode.U2_U1);				if (real_target_type == TypeManager.short_type)					return new ConvCast (expr, target_type, ConvCast.Mode.U2_I2);				if (real_target_type == TypeManager.char_type)					return new ConvCast (expr, target_type, ConvCast.Mode.U2_CH);			} else if (expr_type == TypeManager.int32_type){				//				// From int to sbyte, byte, short, ushort, uint, ulong, char				//				if (real_target_type == TypeManager.sbyte_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I4_I1);				if (real_target_type == TypeManager.byte_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I4_U1);				if (real_target_type == TypeManager.short_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I4_I2);				if (real_target_type == TypeManager.ushort_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I4_U2);				if (real_target_type == TypeManager.uint32_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I4_U4);				if (real_target_type == TypeManager.uint64_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I4_U8);				if (real_target_type == TypeManager.char_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I4_CH);			} else if (expr_type == TypeManager.uint32_type){				//				// From uint to sbyte, byte, short, ushort, int, char				//				if (real_target_type == TypeManager.sbyte_type)					return new ConvCast (expr, target_type, ConvCast.Mode.U4_I1);				if (real_target_type == TypeManager.byte_type)					return new ConvCast (expr, target_type, ConvCast.Mode.U4_U1);				if (real_target_type == TypeManager.short_type)					return new ConvCast (expr, target_type, ConvCast.Mode.U4_I2);				if (real_target_type == TypeManager.ushort_type)					return new ConvCast (expr, target_type, ConvCast.Mode.U4_U2);				if (real_target_type == TypeManager.int32_type)					return new ConvCast (expr, target_type, ConvCast.Mode.U4_I4);				if (real_target_type == TypeManager.char_type)					return new ConvCast (expr, target_type, ConvCast.Mode.U4_CH);			} else if (expr_type == TypeManager.int64_type){				//				// From long to sbyte, byte, short, ushort, int, uint, ulong, char				//				if (real_target_type == TypeManager.sbyte_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I8_I1);				if (real_target_type == TypeManager.byte_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I8_U1);				if (real_target_type == TypeManager.short_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I8_I2);				if (real_target_type == TypeManager.ushort_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I8_U2);				if (real_target_type == TypeManager.int32_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I8_I4);				if (real_target_type == TypeManager.uint32_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I8_U4);				if (real_target_type == TypeManager.uint64_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I8_U8);				if (real_target_type == TypeManager.char_type)					return new ConvCast (expr, target_type, ConvCast.Mode.I8_CH);			} else if (expr_type == TypeManager.uint64_type){				//				// From ulong to sbyte, byte, short, ushort, int, uint, long, char				//				if (real_target_type == TypeManager.sbyte_type)					return new ConvCast (expr, target_type, ConvCast.Mode.U8_I1);				if (real_target_type == TypeManager.byte_type)					return new ConvCast (expr, target_type, ConvCast.Mode.U8_U1);				if (real_target_type == TypeManager.short_type)					return new ConvCast (expr, target_type, ConvCast.Mode.U8_I2);				if (real_target_type == TypeManager.ushort_type)					return new ConvCast (expr, target_type, ConvCast.Mode.U8_U2);				if (real_target_type == TypeManager.int32_type)					return new ConvCast (expr, target_type, ConvCast.Mode.U8_I4);				if (real_target_type == TypeManager.uint32_type)					return new ConvCast (expr, target_type, ConvCast.Mode.U8_U4);				if (real_target_type == TypeManager.int64_type)					return new ConvCast (expr, target_type, ConvCast.Mode.U8_I8);				if (real_target_type == TypeManager.char_type)					return new ConvCast (expr, target_type, ConvCast.Mode.U8_CH);			} else if (expr_type == TypeManager.char_type){				//				// From char to sbyte, byte, short				//				if (real_target_type == TypeManager.sbyte_type)					return new ConvCast (expr, target_type, ConvCast.Mode.CH_I1);				if (real_target_type == TypeManager.byte_type)					return new ConvCast (expr, target_type, ConvCast.Mode.CH_U1);				if (real_target_type == TypeManager.short_type)					return new ConvCast (expr, target_type, ConvCast.Mode.CH_I2);			} else if (expr_type == TypeManager.float_type){				//				// From float to sbyte, byte, short,				// ushort, int, uint, long, ulong, char				// or decimal				//				if (real_target_type == TypeManager.sbyte_type)					return new ConvCast (expr, target_type, ConvCast.Mode.R4_I1);				if (real_target_type == TypeManager.byte_type)					return new ConvCast (expr, target_type, ConvCast.Mode.R4_U1);				if (real_target_type == TypeManager.short_type)					return new ConvCast (expr, target_type, ConvCast.Mode.R4_I2);				if (real_target_type == TypeManager.ushort_type)					return new ConvCast (expr, target_type, ConvCast.Mode.R4_U2);				if (real_target_type == TypeManager.int32_type)					return new ConvCast (expr, target_type, ConvCast.Mode.R4_I4);				if (real_target_type == TypeManager.uint32_type)					return new ConvCast (expr, target_type, ConvCast.Mode.R4_U4);				if (real_target_type == TypeManager.int64_type)					return new ConvCast (expr, target_type, ConvCast.Mode.R4_I8);				if (real_target_type == TypeManager.uint64_type)					return new ConvCast (expr, target_type, ConvCast.Mode.R4_U8);				if (real_target_type == TypeManager.char_type)					return new ConvCast (expr, target_type, ConvCast.Mode.R4_CH);				if (real_target_type == TypeManager.decimal_type)					return new CastToDecimal (expr, true);			} else if (expr_type == TypeManager.double_type){				//				// From double to sbyte, byte, short,				// ushort, int, uint, long, ulong,				// char, float or decimal				//				if (real_target_type == TypeManager.sbyte_type)					return new ConvCast (expr, target_type, ConvCast.Mode.R8_I1);				if (real_target_type == TypeManager.byte_type)					return new ConvCast (expr, target_type, ConvCast.Mode.R8_U1);				if (real_target_type == TypeManager.short_type)					return new ConvCast (expr, target_type, ConvCast.Mode.R8_I2);				if (real_target_type == TypeManager.ushort_type)					return new ConvCast (expr, target_type, ConvCast.Mode.R8_U2);				if (real_target_type == TypeManager.int32_type)					return new ConvCast (expr, target_type, ConvCast.Mode.R8_I4);				if (real_target_type == TypeManager.uint32_type)					return new ConvCast (expr, target_type, ConvCast.Mode.R8_U4);				if (real_target_type == TypeManager.int64_type)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -