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

📄 convert.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 5 页
字号:
					return new ConvCast (expr, target_type, ConvCast.Mode.R8_I8);				if (real_target_type == TypeManager.uint64_type)					return new ConvCast (expr, target_type, ConvCast.Mode.R8_U8);				if (real_target_type == TypeManager.char_type)					return new ConvCast (expr, target_type, ConvCast.Mode.R8_CH);				if (real_target_type == TypeManager.float_type)					return new ConvCast (expr, target_type, ConvCast.Mode.R8_R4);				if (real_target_type == TypeManager.decimal_type)					return new CastToDecimal (expr, true);			} else if (expr_type == TypeManager.decimal_type) {				return new CastFromDecimal (expr, target_type).Resolve ();			}			return null;		}		/// <summary>		///  Returns whether an explicit reference conversion can be performed		///  from source_type to target_type		/// </summary>		public static bool ExplicitReferenceConversionExists (Type source_type, Type target_type)		{			bool target_is_value_type = target_type.IsValueType;						if (source_type == target_type)				return true;						//			// From object to any reference type			//			if (source_type == TypeManager.object_type && !target_is_value_type)				return true;								//			// From any class S to any class-type T, provided S is a base class of T			//			if (target_type.IsSubclassOf (source_type))				return true;			//			// From any interface type S to any interface T provided S is not derived from T			//			if (source_type.IsInterface && target_type.IsInterface){				if (!target_type.IsSubclassOf (source_type))					return true;			}			    			//			// From any class type S to any interface T, provided S is not sealed			// and provided S does not implement T.			//			if (target_type.IsInterface && !source_type.IsSealed &&			    !TypeManager.ImplementsInterface (source_type, target_type))				return true;			//			// From any interface-type S to to any class type T, provided T is not			// sealed, or provided T implements S.			//			if (source_type.IsInterface &&			    (!target_type.IsSealed || TypeManager.ImplementsInterface (target_type, source_type)))				return true;									// From an array type S with an element type Se to an array type T with an 			// element type Te provided all the following are true:			//     * S and T differe only in element type, in other words, S and T			//       have the same number of dimensions.			//     * Both Se and Te are reference types			//     * An explicit referenc conversions exist from Se to Te			//			if (source_type.IsArray && target_type.IsArray) {				if (source_type.GetArrayRank () == target_type.GetArrayRank ()) {										Type source_element_type = TypeManager.GetElementType (source_type);					Type target_element_type = TypeManager.GetElementType (target_type);										if (!source_element_type.IsValueType && !target_element_type.IsValueType)						if (ExplicitReferenceConversionExists (source_element_type,										       target_element_type))							return true;				}			}						// From System.Array to any array-type			if (source_type == TypeManager.array_type &&			    target_type.IsArray){				return true;			}			//			// From System delegate to any delegate-type			//			if (source_type == TypeManager.delegate_type &&			    target_type.IsSubclassOf (TypeManager.delegate_type))				return true;			//			// From ICloneable to Array or Delegate types			//			if (source_type == TypeManager.icloneable_type &&			    (target_type == TypeManager.array_type ||			     target_type == TypeManager.delegate_type))				return true;						return false;		}		/// <summary>		///   Implements Explicit Reference conversions		/// </summary>		static Expression ExplicitReferenceConversion (Expression source, Type target_type)		{			Type source_type = source.Type;			bool target_is_value_type = target_type.IsValueType;			//			// From object to any reference type			//			if (source_type == TypeManager.object_type && !target_is_value_type)				return new ClassCast (source, target_type);			//			// Unboxing conversion.			//			if (((source_type == TypeManager.enum_type &&				!(source is EmptyCast)) ||				source_type == TypeManager.value_type) && target_is_value_type)				return new UnboxCast (source, target_type);			//			// From any class S to any class-type T, provided S is a base class of T			//			if (target_type.IsSubclassOf (source_type))				return new ClassCast (source, target_type);			//			// From any interface type S to any interface T provided S is not derived from T			//			if (source_type.IsInterface && target_type.IsInterface){				if (TypeManager.ImplementsInterface (source_type, target_type))					return null;				else					return new ClassCast (source, target_type);			}			    			//			// From any class type S to any interface T, provides S is not sealed			// and provided S does not implement T.			//			if (target_type.IsInterface && !source_type.IsSealed) {				if (TypeManager.ImplementsInterface (source_type, target_type))					return null;				else					return new ClassCast (source, target_type);							}			//			// From any interface-type S to to any class type T, provided T is not			// sealed, or provided T implements S.			//			if (source_type.IsInterface) {				if (!target_type.IsSealed || TypeManager.ImplementsInterface (target_type, source_type)) {					if (target_type.IsClass)						return new ClassCast (source, target_type);					else						return new UnboxCast (source, target_type);				}				return null;			}						// From an array type S with an element type Se to an array type T with an 			// element type Te provided all the following are true:			//     * S and T differe only in element type, in other words, S and T			//       have the same number of dimensions.			//     * Both Se and Te are reference types			//     * An explicit referenc conversions exist from Se to Te			//			if (source_type.IsArray && target_type.IsArray) {				if (source_type.GetArrayRank () == target_type.GetArrayRank ()) {										Type source_element_type = TypeManager.GetElementType (source_type);					Type target_element_type = TypeManager.GetElementType (target_type);										if (!source_element_type.IsValueType && !target_element_type.IsValueType)						if (ExplicitReferenceConversionExists (source_element_type,										       target_element_type))							return new ClassCast (source, target_type);				}			}						// From System.Array to any array-type			if (source_type == TypeManager.array_type &&			    target_type.IsArray) {				return new ClassCast (source, target_type);			}			//			// From System delegate to any delegate-type			//			if (source_type == TypeManager.delegate_type &&			    target_type.IsSubclassOf (TypeManager.delegate_type))				return new ClassCast (source, target_type);			//			// From ICloneable to Array or Delegate types			//			if (source_type == TypeManager.icloneable_type &&			    (target_type == TypeManager.array_type ||			     target_type == TypeManager.delegate_type))				return new ClassCast (source, target_type);						return null;		}				/// <summary>		///   Performs an explicit conversion of the expression `expr' whose		///   type is expr.Type to `target_type'.		/// </summary>		static public Expression ExplicitConversionCore (EmitContext ec, Expression expr,							     Type target_type, Location loc)		{			Type expr_type = expr.Type;			// Explicit conversion includes implicit conversion and it used for enum underlying types too			Expression ne = ImplicitConversionStandard (ec, expr, target_type, loc);			if (ne != null)				return ne;			//			// Unboxing conversions; only object types can be convertible to enum			//			if (expr_type == TypeManager.object_type && target_type.IsValueType || expr_type == TypeManager.enum_type)				return new UnboxCast (expr, target_type);			if (TypeManager.IsEnumType (expr_type)) {				if (expr is EnumConstant)					return ExplicitConversionCore (ec, ((EnumConstant) expr).Child, target_type, loc);				return ExplicitConversionCore (ec, new EmptyCast (expr, TypeManager.EnumToUnderlying (expr_type)), target_type, loc);			}			if (TypeManager.IsEnumType (target_type))				return new EmptyCast (ExplicitConversionCore (ec, expr, TypeManager.EnumToUnderlying (target_type), loc), target_type);			ne = ExplicitNumericConversion (expr, target_type);			if (ne != null)				return ne;			//			// Skip the ExplicitReferenceConversion because we can not convert			// from Null to a ValueType, and ExplicitReference wont check against			// null literal explicitly			//			if (expr_type != TypeManager.null_type){				ne = ExplicitReferenceConversion (expr, target_type);				if (ne != null)					return ne;			}			if (ec.InUnsafe){				ne = ExplicitUnsafe (expr, target_type);				if (ne != null)					return ne;			}			ne = ExplicitUserConversion (ec, expr, target_type, loc);			if (ne != null)				return ne;			return null;		}		public static Expression ExplicitUnsafe (Expression expr, Type target_type)		{			Type expr_type = expr.Type;			if (target_type.IsPointer){				if (expr_type.IsPointer)					return new EmptyCast (expr, target_type);									if (expr_type == TypeManager.sbyte_type ||					expr_type == TypeManager.short_type ||					expr_type == TypeManager.int32_type ||					expr_type == TypeManager.int64_type)					return new OpcodeCast (expr, target_type, OpCodes.Conv_I);				if (expr_type == TypeManager.ushort_type ||					expr_type == TypeManager.uint32_type ||					expr_type == TypeManager.uint64_type ||					expr_type == TypeManager.byte_type)					return new OpcodeCast (expr, target_type, OpCodes.Conv_U);			}			if (expr_type.IsPointer){				if (target_type == TypeManager.sbyte_type)					return new OpcodeCast (expr, target_type, OpCodes.Conv_I1);				else if (target_type == TypeManager.byte_type)					return new OpcodeCast (expr, target_type, OpCodes.Conv_U1);				else if (target_type == TypeManager.short_type)					return new OpcodeCast (expr, target_type, OpCodes.Conv_I2);				else if (target_type == TypeManager.ushort_type)					return new OpcodeCast (expr, target_type, OpCodes.Conv_U2);				else if (target_type == TypeManager.int32_type)					return new OpcodeCast (expr, target_type, OpCodes.Conv_I4);				else if (target_type == TypeManager.uint32_type)					return new OpcodeCast (expr, target_type, OpCodes.Conv_U4);				else if (target_type == TypeManager.uint64_type)					return new OpcodeCast (expr, target_type, OpCodes.Conv_U8);				else if (target_type == TypeManager.int64_type){					return new OpcodeCast (expr, target_type, OpCodes.Conv_I8);				}			}			return null;		}		/// <summary>		///   Same as ExplicitConversion, only it doesn't include user defined conversions		/// </summary>		static public Expression ExplicitConversionStandard (EmitContext ec, Expression expr,								  Type target_type, Location l)		{			Expression ne = ImplicitConversionStandard (ec, expr, target_type, l);			if (ne != null)				return ne;			ne = ExplicitNumericConversion (expr, target_type);			if (ne != null)				return ne;			ne = ExplicitReferenceConversion (expr, target_type);			if (ne != null)				return ne;			if (ec.InUnsafe && expr.Type == TypeManager.void_ptr_type && target_type.IsPointer)				return new EmptyCast (expr, target_type);			expr.Error_ValueCannotBeConverted (l, target_type, true);			return null;		}		/// <summary>		///   Performs an explicit conversion of the expression `expr' whose		///   type is expr.Type to `target_type'.		/// </summary>		static public Expression ExplicitConversion (EmitContext ec, Expression expr,			Type target_type, Location loc)		{			Expression e = ExplicitConversionCore (ec, expr, target_type, loc);			if (e != null)				return e;			expr.Error_ValueCannotBeConverted (loc, target_type, true);			return null;		}	}}

⌨️ 快捷键说明

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