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

📄 ecore.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 5 页
字号:
			StringBuilder sb = new StringBuilder (valid [0]);			for (int i = 1; i < count - 1; i++) {				sb.Append ("', `");				sb.Append (valid [i]);			}			if (count > 1) {				sb.Append ("' or `");				sb.Append (valid [count - 1]);			}			Report.Error (119, loc, 				"Expression denotes a `{0}', where a `{1}' was expected", ExprClassName, sb);		}				public static void UnsafeError (Location loc)		{			Report.Error (214, loc, "Pointers and fixed size buffers may only be used in an unsafe context");		}		//		// Load the object from the pointer.  		//		public static void LoadFromPtr (ILGenerator ig, Type t)		{			if (t == TypeManager.int32_type)				ig.Emit (OpCodes.Ldind_I4);			else if (t == TypeManager.uint32_type)				ig.Emit (OpCodes.Ldind_U4);			else if (t == TypeManager.short_type)				ig.Emit (OpCodes.Ldind_I2);			else if (t == TypeManager.ushort_type)				ig.Emit (OpCodes.Ldind_U2);			else if (t == TypeManager.char_type)				ig.Emit (OpCodes.Ldind_U2);			else if (t == TypeManager.byte_type)				ig.Emit (OpCodes.Ldind_U1);			else if (t == TypeManager.sbyte_type)				ig.Emit (OpCodes.Ldind_I1);			else if (t == TypeManager.uint64_type)				ig.Emit (OpCodes.Ldind_I8);			else if (t == TypeManager.int64_type)				ig.Emit (OpCodes.Ldind_I8);			else if (t == TypeManager.float_type)				ig.Emit (OpCodes.Ldind_R4);			else if (t == TypeManager.double_type)				ig.Emit (OpCodes.Ldind_R8);			else if (t == TypeManager.bool_type)				ig.Emit (OpCodes.Ldind_I1);			else if (t == TypeManager.intptr_type)				ig.Emit (OpCodes.Ldind_I);			else if (TypeManager.IsEnumType (t)) {				if (t == TypeManager.enum_type)					ig.Emit (OpCodes.Ldind_Ref);				else					LoadFromPtr (ig, TypeManager.EnumToUnderlying (t));			} else if (t.IsValueType)				ig.Emit (OpCodes.Ldobj, t);			else if (t.IsPointer)				ig.Emit (OpCodes.Ldind_I);			else 				ig.Emit (OpCodes.Ldind_Ref);		}		//		// The stack contains the pointer and the value of type `type'		//		public static void StoreFromPtr (ILGenerator ig, Type type)		{			if (TypeManager.IsEnumType (type))				type = TypeManager.EnumToUnderlying (type);			if (type == TypeManager.int32_type || type == TypeManager.uint32_type)				ig.Emit (OpCodes.Stind_I4);			else if (type == TypeManager.int64_type || type == TypeManager.uint64_type)				ig.Emit (OpCodes.Stind_I8);			else if (type == TypeManager.char_type || type == TypeManager.short_type ||				 type == TypeManager.ushort_type)				ig.Emit (OpCodes.Stind_I2);			else if (type == TypeManager.float_type)				ig.Emit (OpCodes.Stind_R4);			else if (type == TypeManager.double_type)				ig.Emit (OpCodes.Stind_R8);			else if (type == TypeManager.byte_type || type == TypeManager.sbyte_type ||				 type == TypeManager.bool_type)				ig.Emit (OpCodes.Stind_I1);			else if (type == TypeManager.intptr_type)				ig.Emit (OpCodes.Stind_I);			else if (type.IsValueType)				ig.Emit (OpCodes.Stobj, type);			else				ig.Emit (OpCodes.Stind_Ref);		}				//		// Returns the size of type `t' if known, otherwise, 0		//		public static int GetTypeSize (Type t)		{			t = TypeManager.TypeToCoreType (t);			if (t == TypeManager.int32_type ||			    t == TypeManager.uint32_type ||			    t == TypeManager.float_type)			        return 4;			else if (t == TypeManager.int64_type ||				 t == TypeManager.uint64_type ||				 t == TypeManager.double_type)			        return 8;			else if (t == TypeManager.byte_type ||				 t == TypeManager.sbyte_type ||				 t == TypeManager.bool_type) 				        return 1;			else if (t == TypeManager.short_type ||				 t == TypeManager.char_type ||				 t == TypeManager.ushort_type)				return 2;			else if (t == TypeManager.decimal_type)				return 16;			else				return 0;		}		public static void Error_NegativeArrayIndex (Location loc)		{			Report.Error (248, loc, "Cannot create an array with a negative size");		}		protected void Error_CannotCallAbstractBase (string name)		{			Report.Error (205, loc, "Cannot call an abstract base member `{0}'", name);		}				//		// Converts `source' to an int, uint, long or ulong.		//		public Expression ExpressionToArrayArgument (EmitContext ec, Expression source, Location loc)		{			Expression target;						bool old_checked = ec.CheckState;			ec.CheckState = true;						target = Convert.ImplicitConversion (ec, source, TypeManager.int32_type, loc);			if (target == null){				target = Convert.ImplicitConversion (ec, source, TypeManager.uint32_type, loc);				if (target == null){					target = Convert.ImplicitConversion (ec, source, TypeManager.int64_type, loc);					if (target == null){						target = Convert.ImplicitConversion (ec, source, TypeManager.uint64_type, loc);						if (target == null)							source.Error_ValueCannotBeConverted (loc, TypeManager.int32_type, false);					}				}			} 			ec.CheckState = old_checked;			//			// Only positive constants are allowed at compile time			//			if (target is Constant){				if (target is IntConstant){					if (((IntConstant) target).Value < 0){						Error_NegativeArrayIndex (loc);						return null;					}				}				if (target is LongConstant){					if (((LongConstant) target).Value < 0){						Error_NegativeArrayIndex (loc);						return null;					}				}							}			return target;		}			}	/// <summary>	///   This is just a base class for expressions that can	///   appear on statements (invocations, object creation,	///   assignments, post/pre increment and decrement).  The idea	///   being that they would support an extra Emition interface that	///   does not leave a result on the stack.	/// </summary>	public abstract class ExpressionStatement : Expression {		public virtual ExpressionStatement ResolveStatement (EmitContext ec)		{			Expression e = Resolve (ec);			if (e == null)				return null;			ExpressionStatement es = e as ExpressionStatement;			if (es == null)				Error (201, "Only assignment, call, increment, decrement and new object " +				       "expressions can be used as a statement");			return es;		}		/// <summary>		///   Requests the expression to be emitted in a `statement'		///   context.  This means that no new value is left on the		///   stack after invoking this method (constrasted with		///   Emit that will always leave a value on the stack).		/// </summary>		public abstract void EmitStatement (EmitContext ec);	}	/// <summary>	///   This kind of cast is used to encapsulate the child	///   whose type is child.Type into an expression that is	///   reported to return "return_type".  This is used to encapsulate	///   expressions which have compatible types, but need to be dealt	///   at higher levels with.	///	///   For example, a "byte" expression could be encapsulated in one	///   of these as an "unsigned int".  The type for the expression	///   would be "unsigned int".	///	/// </summary>	public class EmptyCast : Expression {		protected Expression child;		public Expression Child {			get {				return child;			}		}				public EmptyCast (Expression child, Type return_type)		{			eclass = child.eclass;			loc = child.Location;			type = return_type;			this.child = child;		}		public override Expression DoResolve (EmitContext ec)		{			// This should never be invoked, we are born in fully			// initialized state.			return this;		}		public override void Emit (EmitContext ec)		{			child.Emit (ec);		}	}	/// <summary>	/// 	This is a numeric cast to a Decimal	/// </summary>	public class CastToDecimal : EmptyCast {		MethodInfo conversion_operator;		public CastToDecimal (Expression child)			: this (child, false)		{		}		public CastToDecimal (Expression child, bool find_explicit)			: base (child, TypeManager.decimal_type)		{			conversion_operator = GetConversionOperator (find_explicit);			if (conversion_operator == null)				throw new InternalErrorException ("Outer conversion routine is out of sync");		}		// Returns the implicit operator that converts from		// 'child.Type' to System.Decimal.		MethodInfo GetConversionOperator (bool find_explicit)		{			string operator_name = find_explicit ? "op_Explicit" : "op_Implicit";						MemberInfo [] mi = TypeManager.MemberLookup (type, type, type, MemberTypes.Method,				BindingFlags.Static | BindingFlags.Public, operator_name, null);			foreach (MethodInfo oper in mi) {				ParameterData pd = TypeManager.GetParameterData (oper);				if (pd.ParameterType (0) == child.Type && oper.ReturnType == type)					return oper;			}			return null;		}		public override void Emit (EmitContext ec)		{			ILGenerator ig = ec.ig;			child.Emit (ec);			ig.Emit (OpCodes.Call, conversion_operator);		}	}	/// <summary>	/// 	This is an explicit numeric cast from a Decimal	/// </summary>	public class CastFromDecimal : EmptyCast	{		static IDictionary operators;		public CastFromDecimal (Expression child, Type return_type)			: base (child, return_type)		{			if (child.Type != TypeManager.decimal_type)				throw new InternalErrorException (					"The expected type is Decimal, instead it is " + child.Type.FullName);		}		// Returns the explicit operator that converts from an		// express of type System.Decimal to 'type'.		public Expression Resolve ()		{			if (operators == null) {				 MemberInfo[] all_oper = TypeManager.MemberLookup (TypeManager.decimal_type,					TypeManager.decimal_type, TypeManager.decimal_type, MemberTypes.Method,					BindingFlags.Static | BindingFlags.Public, "op_Explicit", null);				operators = new System.Collections.Specialized.HybridDictionary ();				foreach (MethodInfo oper in all_oper) {					ParameterData pd = TypeManager.GetParameterData (oper);					if (pd.ParameterType (0) == TypeManager.decimal_type)						operators.Add (oper.ReturnType, oper);				}			}			return operators.Contains (type) ? this : null;		}		public override void Emit (EmitContext ec)		{			ILGenerator ig = ec.ig;			child.Emit (ec);			ig.Emit (OpCodes.Call, (MethodInfo)operators [type]);		}	}        //	// We need to special case this since an empty cast of	// a NullLiteral is still a Constant	//	public class NullCast : Constant {		public Constant child;						public NullCast (Constant child, Type return_type):			base (Location.Null)		{			eclass = child.eclass;			type = return_type;			this.child = child;		}		override public string AsString ()		{			return "null";		}		public override object GetValue ()		{			return null;		}		public override Expression DoResolve (EmitContext ec)		{			// This should never be invoked, we are born in fully			// initialized state.			return this;		}		public override void Emit (EmitContext ec)		{			child.Emit (ec);		}		public override Constant Increment ()		{			throw new NotSupportedException ();		}		public override bool IsDefaultValue {			get {				throw new NotImplementedException ();			}		}		public override bool IsNegative {			get {				return false;			}		}		public override Constant Reduce (EmitContext ec, Type target_type)		{			if (type == target_type)				return child.Reduce (ec, target_type);			return null;		}	}	/// <summary>	///  This class is used to wrap literals which belong inside Enums	/// </summary>	public class EnumConstant : Constant {		public Constant Child;		public EnumConstant (Constant child, Type enum_type):			base (child.Location)		{			eclass = child.eclass;			this.Child = child;			type = enum_type;		}				public override Expression DoResolve (EmitContext ec)		{			// This should never be invoked, we are born in fully			// initialized state.			return this;		}		public override void Emit (EmitContext ec)		{			Child.Emit (ec);		}		public override string GetSignatureForError()		{			return TypeManager.CSharpName (Type);		}		public override object GetValue ()		{			return Child.GetValue ();		}		public override object GetTypedValue ()		{			// FIXME: runtime is not ready to work with just emited enums			if (!RootContext.StdLib) {				return Child.GetValue ();

⌨️ 快捷键说明

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