/*************************************************************************************************** * Set the values of the BinOpFullSig from the given BinOpSig. The ExpressionBinder is needed to get * the predefined types. Returns true iff the predef types are found. ***************************************************************************************************/ public BinOpFullSig(ExpressionBinder fnc, BinOpSig bos) { this.pt1 = bos.pt1; this.pt2 = bos.pt2; this.mask = bos.mask; this.cbosSkip = bos.cbosSkip; this.pfn = bos.pfn; this.grfos = bos.grfos; this.fnkind = bos.fnkind; _type1 = pt1 != PredefinedType.PT_UNDEFINEDINDEX ? fnc.GetPredefindType(pt1) : null; _type2 = pt2 != PredefinedType.PT_UNDEFINEDINDEX ? fnc.GetPredefindType(pt2) : null; _grflt = LiftFlags.None; }
private bool bindExplicitConversionToArray(ArrayType arrayDest) { Debug.Assert(_typeSrc != null); Debug.Assert(arrayDest != null); if (_typeSrc is ArrayType arrSrc) { return(bindExplicitConversionFromArrayToArray(arrSrc, arrayDest)); } if (bindExplicitConversionFromIListToArray(arrayDest)) { return(true); } // 13.2.2 // // The explicit reference conversions are: // // * From System.Array and the interfaces it implements, to any array-type. if (_binder.canConvert(_binder.GetPredefindType(PredefinedType.PT_ARRAY), _typeSrc, CONVERTTYPE.NOUDC)) { if (_needsExprDest) { _binder.bindSimpleCast(_exprSrc, _typeDest, out _exprDest, EXPRFLAG.EXF_REFCHECK); } return(true); } return(false); }
private bool bindExplicitConversionToTypeVar() { // 13.2.3 Explicit reference conversions // // For a type-parameter T that is known to be a reference type (25.7), the following // explicit reference conversions exist: // // * From the effective base class C of T to T and from any base class of C to T. // * From any interface-type to T. // * From a type-parameter U to T provided that T depends on U (25.7). Debug.Assert(_typeSrc != null); Debug.Assert(_typeDest != null); // NOTE: for the flags, we have to use EXPRFLAG.EXF_FORCE_UNBOX (not EXPRFLAG.EXF_REFCHECK) even when // we know that the type is a reference type. The verifier expects all code for // type parameters to behave as if the type parameter is a value type. // The jitter should be smart about it.... if (_typeSrc.isInterfaceType() || _binder.canConvert(_typeDest, _typeSrc, CONVERTTYPE.NOUDC)) { if (!_needsExprDest) { return(true); } // There is an explicit, possibly unboxing, conversion from Object or any interface to // a type variable. This will involve a type check and possibly an unbox. // There is an explicit conversion from non-interface X to the type var iff there is an // implicit conversion from the type var to X. if (_typeSrc is TypeParameterType) { // Need to box first before unboxing. Expr exprT; ExprClass exprObj = GetExprFactory().CreateClass(_binder.GetPredefindType(PredefinedType.PT_OBJECT)); _binder.bindSimpleCast(_exprSrc, exprObj, out exprT, EXPRFLAG.EXF_FORCE_BOX); _exprSrc = exprT; } if (_needsExprDest) { _binder.bindSimpleCast(_exprSrc, _exprTypeDest, out _exprDest, EXPRFLAG.EXF_FORCE_UNBOX); } return(true); } return(false); }
/*************************************************************************************************** * Set the values of the UnaOpFullSig from the given UnaOpSig. The ExpressionBinder is needed to get * the predefined type. Returns true iff the predef type is found. ***************************************************************************************************/ public UnaOpFullSig(ExpressionBinder fnc, UnaOpSig uos) { this.pt = uos.pt; this.grfuom = uos.grfuom; this.cuosSkip = uos.cuosSkip; this.pfn = uos.pfn; this.fnkind = uos.fnkind; _type = pt != PredefinedType.PT_UNDEFINEDINDEX ? fnc.GetPredefindType(pt) : null; _grflt = LiftFlags.None; }