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

📄 expression.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 5 页
字号:
				//				// For this to be used, both arguments have to be reference-types.				// Read the rationale on the spec (14.9.6)				//				if (!(l.IsValueType || r.IsValueType)){					type = TypeManager.bool_type;					if (l == r)						return this;										//					// Also, a standard conversion must exist from either one					//					bool left_to_right =						Convert.ImplicitStandardConversionExists (ec, left, r);					bool right_to_left = !left_to_right &&						Convert.ImplicitStandardConversionExists (ec, right, l);					if (!left_to_right && !right_to_left) {						Error_OperatorCannotBeApplied ();						return null;					}					if (left_to_right && left_operators != null &&					    RootContext.WarningLevel >= 2) {						ArrayList args = new ArrayList (2);						args.Add (new Argument (left, Argument.AType.Expression));						args.Add (new Argument (left, Argument.AType.Expression));						MethodBase method = Invocation.OverloadResolve (							ec, (MethodGroupExpr) left_operators, args, true, Location.Null);						if (method != null)							Warning_UnintendedReferenceComparison (loc, "right", l);					}					if (right_to_left && right_operators != null &&					    RootContext.WarningLevel >= 2) {						ArrayList args = new ArrayList (2);						args.Add (new Argument (right, Argument.AType.Expression));						args.Add (new Argument (right, Argument.AType.Expression));						MethodBase method = Invocation.OverloadResolve (							ec, (MethodGroupExpr) right_operators, args, true, Location.Null);						if (method != null)							Warning_UnintendedReferenceComparison (loc, "left", r);					}					//					// We are going to have to convert to an object to compare					//					if (l != TypeManager.object_type)						left = new EmptyCast (left, TypeManager.object_type);					if (r != TypeManager.object_type)						right = new EmptyCast (right, TypeManager.object_type);					//					// FIXME: CSC here catches errors cs254 and cs252					//					return this;				}				//				// One of them is a valuetype, but the other one is not.				//				if (!l.IsValueType || !r.IsValueType) {					Error_OperatorCannotBeApplied ();					return null;				}			}			// Only perform numeric promotions on:			// +, -, *, /, %, &, |, ^, ==, !=, <, >, <=, >=			//			if (oper == Operator.Addition || oper == Operator.Subtraction) {				if (l.IsSubclassOf (TypeManager.delegate_type)){					if (((right.eclass == ExprClass.MethodGroup) ||					     (r == TypeManager.anonymous_method_type))){						if ((RootContext.Version != LanguageVersion.ISO_1)){							Expression tmp = Convert.ImplicitConversionRequired (ec, right, l, loc);							if (tmp == null)								return null;							right = tmp;							r = right.Type;						}					}										if (r.IsSubclassOf (TypeManager.delegate_type)){						MethodInfo method;						ArrayList args = new ArrayList (2);												args = new ArrayList (2);						args.Add (new Argument (left, Argument.AType.Expression));						args.Add (new Argument (right, Argument.AType.Expression));												if (oper == Operator.Addition)							method = TypeManager.delegate_combine_delegate_delegate;						else							method = TypeManager.delegate_remove_delegate_delegate;												if (l != r) {							Error_OperatorCannotBeApplied ();							return null;						}												return new BinaryDelegate (l, method, args);					}				}								//				// Pointer arithmetic:				//				// T* operator + (T* x, int y);				// T* operator + (T* x, uint y);				// T* operator + (T* x, long y);				// T* operator + (T* x, ulong y);				//				// T* operator + (int y,   T* x);				// T* operator + (uint y,  T *x);				// T* operator + (long y,  T *x);				// T* operator + (ulong y, T *x);				//				// T* operator - (T* x, int y);				// T* operator - (T* x, uint y);				// T* operator - (T* x, long y);				// T* operator - (T* x, ulong y);				//				// long operator - (T* x, T *y)				//				if (l.IsPointer){					if (r.IsPointer && oper == Operator.Subtraction){						if (r == l)							return new PointerArithmetic (								false, left, right, TypeManager.int64_type,								loc).Resolve (ec);					} else {						Expression t = Make32or64 (ec, right);						if (t != null)							return new PointerArithmetic (oper == Operator.Addition, left, t, l, loc).Resolve (ec);					}				} else if (r.IsPointer && oper == Operator.Addition){					Expression t = Make32or64 (ec, left);					if (t != null)						return new PointerArithmetic (true, right, t, r, loc).Resolve (ec);				}			}						//			// Enumeration operators			//			bool lie = TypeManager.IsEnumType (l);			bool rie = TypeManager.IsEnumType (r);			if (lie || rie){				Expression temp;				// U operator - (E e, E f)				if (lie && rie){					if (oper == Operator.Subtraction){						if (l == r){							type = TypeManager.EnumToUnderlying (l);							return this;						}						Error_OperatorCannotBeApplied ();						return null;					}				}									//				// operator + (E e, U x)				// operator - (E e, U x)				//				if (oper == Operator.Addition || oper == Operator.Subtraction){					Type enum_type = lie ? l : r;					Type other_type = lie ? r : l;					Type underlying_type = TypeManager.EnumToUnderlying (enum_type);										if (underlying_type != other_type){						temp = Convert.ImplicitConversion (ec, lie ? right : left, underlying_type, loc);						if (temp != null){							if (lie)								right = temp;							else								left = temp;							type = enum_type;							return this;						}													Error_OperatorCannotBeApplied ();						return null;					}					type = enum_type;					return this;				}								if (!rie){					temp = Convert.ImplicitConversion (ec, right, l, loc);					if (temp != null)						right = temp;					else {						Error_OperatorCannotBeApplied ();						return null;					}				} if (!lie){					temp = Convert.ImplicitConversion (ec, left, r, loc);					if (temp != null){						left = temp;						l = r;					} else {						Error_OperatorCannotBeApplied ();						return null;					}				}				if (oper == Operator.Equality || oper == Operator.Inequality ||				    oper == Operator.LessThanOrEqual || oper == Operator.LessThan ||				    oper == Operator.GreaterThanOrEqual || oper == Operator.GreaterThan){					if (left.Type != right.Type){						Error_OperatorCannotBeApplied ();						return null;					}					type = TypeManager.bool_type;					return this;				}				if (oper == Operator.BitwiseAnd ||				    oper == Operator.BitwiseOr ||				    oper == Operator.ExclusiveOr){					if (left.Type != right.Type){						Error_OperatorCannotBeApplied ();						return null;					}					type = l;					return this;				}				Error_OperatorCannotBeApplied ();				return null;			}						if (oper == Operator.LeftShift || oper == Operator.RightShift)				return CheckShiftArguments (ec);			if (oper == Operator.LogicalOr || oper == Operator.LogicalAnd){				if (l == TypeManager.bool_type && r == TypeManager.bool_type) {					type = TypeManager.bool_type;					return this;				}				if (l != r) {					Error_OperatorCannotBeApplied ();					return null;				}				Expression e = new ConditionalLogicalOperator (					oper == Operator.LogicalAnd, left, right, l, loc);				return e.Resolve (ec);			} 			//			// operator & (bool x, bool y)			// operator | (bool x, bool y)			// operator ^ (bool x, bool y)			//			if (l == TypeManager.bool_type && r == TypeManager.bool_type){				if (oper == Operator.BitwiseAnd ||				    oper == Operator.BitwiseOr ||				    oper == Operator.ExclusiveOr){					type = l;					return this;				}			}						//			// Pointer comparison			//			if (l.IsPointer && r.IsPointer){				if (oper == Operator.LessThan || oper == Operator.LessThanOrEqual ||				    oper == Operator.GreaterThan || oper == Operator.GreaterThanOrEqual){					type = TypeManager.bool_type;					return this;				}			}						//			// This will leave left or right set to null if there is an error			//			bool check_user_conv = is_user_defined (l) && is_user_defined (r);			DoNumericPromotions (ec, l, r, left, right, check_user_conv);			if (left == null || right == null){				Error_OperatorCannotBeApplied (loc, OperName (oper), l, r);				return null;			}			//			// reload our cached types if required			//			l = left.Type;			r = right.Type;						if (oper == Operator.BitwiseAnd ||			    oper == Operator.BitwiseOr ||			    oper == Operator.ExclusiveOr){				if (l == r){					if (((l == TypeManager.int32_type) ||					     (l == TypeManager.uint32_type) ||					     (l == TypeManager.short_type) ||					     (l == TypeManager.ushort_type) ||					     (l == TypeManager.int64_type) ||					     (l == TypeManager.uint64_type))){						type = l;					} else {						Error_OperatorCannotBeApplied ();						return null;					}				} else {					Error_OperatorCannotBeApplied ();					return null;				}			}			if (oper == Operator.Equality ||			    oper == Operator.Inequality ||			    oper == Operator.LessThanOrEqual ||			    oper == Operator.LessThan ||			    oper == Operator.GreaterThanOrEqual ||			    oper == Operator.GreaterThan){				type = TypeManager.bool_type;			}			return this;		}		Constant EnumLiftUp (EmitContext ec, Constant left, Constant right)		{			switch (oper) {				case Operator.BitwiseOr:				case Operator.BitwiseAnd:				case Operator.ExclusiveOr:				case Operator.Equality:				case Operator.Inequality:				case Operator.LessThan:				case Operator.LessThanOrEqual:				case Operator.GreaterThan:				case Operator.GreaterThanOrEqual:					if (left is EnumConstant)						return left;					if (left.IsZeroInteger)						return new EnumConstant (left, right.Type);					break;				case Operator.Addition:				case Operator.Subtraction:					return left;				case Operator.Multiply:				case Operator.Division:				case Operator.Modulus:				case Operator.LeftShift:				case Operator.RightShift:					if (right is EnumConstant || left is EnumConstant)						break;					return left;			}			Error_OperatorCannotBeApplied (loc, Binary.OperName (oper), left.Type, right.Type);			return null;		}		public override Expression DoResolve (EmitContext ec)		{			if ((oper == Operator.Subtraction) && (left is ParenthesizedExpression)) {				left = ((ParenthesizedExpression) left).Expr;				left = left.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.Type);				if (left == null)					return null;				if (left.eclass == ExprClass.Type) {					Report.Error (75, loc, "To cast a negative value, you must enclose the value in parentheses");					return null;				}			} else				left = left.Resolve (ec);			if (left == null)				return null;			Constant lc = left as Constant;			if (lc != null && lc.Type == TypeManager.bool_type && 				((oper == Operator.LogicalAnd && (bool)lc.GetValue () == false) ||				 (oper == Operator.LogicalOr && (bool)lc.GetValue () == true))) {				// TODO: make a sense to resolve unreachable expression as we do for statement				Report.Warning (429, 4, loc, "Unreachable expression code detected");				return left;			}			right = right.Resolve (ec);			if (right == null)				return null;			eclass = ExprClass.Value;			Constant rc = right as Constant;			// The conversion rules are ignored in enum context but why			if (!ec.InEnumContext && lc != null && rc != null && (TypeManager.IsEnumType (left.Type) || TypeManager.IsEnumType (right.Type))) {				left = lc = EnumLiftUp (ec, lc, rc);				if (lc == null)					return null;				right = rc = EnumLiftUp (ec, rc, lc);				if (rc == null)					return null;			}			if (oper == Operator.BitwiseAnd) {				if (rc != null && rc.IsZeroInteger) {					return lc is EnumConstant ?						new EnumConstant (rc, lc.Type):						rc;				}				if (lc != null && lc.IsZeroInteger) {					return rc is EnumConstant ?						new EnumConstant (lc, rc.Type):						lc;				}			}			else if (oper == Operator.BitwiseOr) {				if (lc is EnumConstant &&				    rc != null && rc.IsZeroInteger)					return lc;				if (rc is EnumConstant &&				    lc != null && lc.IsZeroInteger)					return rc;			} else if (oper == Operator.LogicalAnd) {				if (rc != null && rc.IsDefaultValue && rc.Type == TypeManager.bool_type)					return rc;				if (lc != null && lc.IsDefaultValue && lc.Type == TypeManager.bool_type)					return lc;			}			if (rc != null && lc != null){				int prev_e = Report.Errors;				Expression e = ConstantFold.BinaryFold (					ec, oper, lc, rc, loc);				if (e != null || Report.Errors != prev_e)					return e;			}			// Comparison warnings			if (oper == Operator.Equality || oper == Operator.Inequality ||			    oper == Operator.LessThanOrEqual || oper == Operator.LessThan ||			    oper == Operator.GreaterThanOrEqual || oper == Operator.GreaterThan){				if (left.Equals (right)) {					Report.Warning (1718, 3, loc, "Comparison made to same variable; did you mean to compare something else?");				}				CheckUselessComparison (lc, right.Type);				CheckUselessComparison (rc, left.Type);			}			return ResolveOperator (ec);		}		private void CheckUselessComparison (Constant c, Type type)		{			if (c == null || !IsTypeIntegral (type)				|| c is StringConstant				|| c is BoolConstant				|| c is CharConstant				|| c is FloatConstant				|| c is DoubleConstant				|| c is DecimalConstant				)				return;			long value = 0;			if (c is ULongConstant) {				ulong uvalue = ((ULongConstant) c).Value;				if (uvalue > long.MaxValue) {					if (type == TypeManager.byte_type ||					    type == TypeManager.sbyte_type ||					    type == TypeManager.short_type ||					   

⌨️ 快捷键说明

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