private bool bindImplicitConversionBetweenSimpleTypes(AggregateType aggTypeSrc) { AggregateSymbol aggSrc = aggTypeSrc.getAggregate(); Debug.Assert(aggSrc.getThisType().isSimpleType()); Debug.Assert(typeDest.isSimpleType()); Debug.Assert(aggSrc.IsPredefined() && typeDest.isPredefined()); PredefinedType ptSrc = aggSrc.GetPredefType(); PredefinedType ptDest = typeDest.getPredefType(); ConvKind convertKind; bool fConstShrinkCast = false; Debug.Assert((int)ptSrc < NUM_SIMPLE_TYPES && (int)ptDest < NUM_SIMPLE_TYPES); // 13.1.7 Implicit constant expression conversions // // An implicit constant expression conversion permits the following conversions: // * A constant-expression (14.16) of type int can be converted to type sbyte, byte, short, // ushort, uint, or ulong, provided the value of the constant-expression is within the range // of the destination type. // * A constant-expression of type long can be converted to type ulong, provided the value of // the constant-expression is not negative. // Note: Don't use GetConst here since the conversion only applies to bona-fide compile time constants. if (exprSrc != null && exprSrc.isCONSTANT_OK() && ((ptSrc == PredefinedType.PT_INT && ptDest != PredefinedType.PT_BOOL && ptDest != PredefinedType.PT_CHAR) || (ptSrc == PredefinedType.PT_LONG && ptDest == PredefinedType.PT_ULONG)) && isConstantInRange(exprSrc.asCONSTANT(), typeDest)) { // Special case (CLR 6.1.6): if integral constant is in range, the conversion is a legal implicit conversion. convertKind = ConvKind.Implicit; fConstShrinkCast = needsExprDest && (GetConvKind(ptSrc, ptDest) != ConvKind.Implicit); } else if (ptSrc == ptDest) { // Special case: precision limiting casts to float or double Debug.Assert(ptSrc == PredefinedType.PT_FLOAT || ptSrc == PredefinedType.PT_DOUBLE); Debug.Assert(0 != (flags & CONVERTTYPE.ISEXPLICIT)); convertKind = ConvKind.Implicit; } else { convertKind = GetConvKind(ptSrc, ptDest); Debug.Assert(convertKind != ConvKind.Identity); // identity conversion should have been handled at first. } if (convertKind != ConvKind.Implicit) { return(false); } // An implicit conversion exists. Do the conversion. if (exprSrc.GetConst() != null) { // Fold the constant cast if possible. ConstCastResult result = binder.bindConstantCast(exprSrc, exprTypeDest, needsExprDest, out exprDest, false); if (result == ConstCastResult.Success) { return(true); // else, don't fold and use a regular cast, below. } // REVIEW: I don't think this can ever be hit. If exprSrc is a constant then // it's either a floating point number (which always succeeds), it's a numeric implicit // conversion (which always succeeds), or it's a constant numeric conversion (which // has already been checked by isConstantInRange, so should always succeed) } if (isUserDefinedConversion(ptSrc, ptDest)) { if (!needsExprDest) { return(true); } // According the language, this is a standard conversion, but it is implemented // through a user-defined conversion. Because it's a standard conversion, we don't // test the NOUDC flag here. return(binder.bindUserDefinedConversion(exprSrc, aggTypeSrc, typeDest, needsExprDest, out exprDest, true)); } if (needsExprDest) { binder.bindSimpleCast(exprSrc, exprTypeDest, out exprDest); } return(true); }
public static bool isNull(this EXPR expr) { return(expr.isCONSTANT_OK() && (expr.type.fundType() == FUNDTYPE.FT_REF) && expr.asCONSTANT().Val.IsNullRef); }
public static bool isZero(this EXPR expr) { return((expr.isCONSTANT_OK()) && (expr.asCONSTANT().IsZero)); }
///////////////////////////////////////////////////////////////////////////////// private object GetObject(EXPR pExpr) { if (pExpr.isCAST()) { return GetObject(pExpr.asCAST().GetArgument()); } else if (pExpr.isTYPEOF()) { return pExpr.asTYPEOF().SourceType.type.AssociatedSystemType; } else if (pExpr.isMETHODINFO()) { return GetMethodInfoFromExpr(pExpr.asMETHODINFO()); } else if (pExpr.isCONSTANT()) { CONSTVAL val = pExpr.asCONSTANT().Val; CType underlyingType = pExpr.type; object objval; if (pExpr.type.IsNullType()) { return null; } if (pExpr.type.isEnumType()) { underlyingType = underlyingType.getAggregate().GetUnderlyingType(); } switch (underlyingType.AssociatedSystemType.GetTypeCode()) { case TypeCode.Boolean: objval = val.boolVal; break; case TypeCode.SByte: objval = val.sbyteVal; break; case TypeCode.Byte: objval = val.byteVal; break; case TypeCode.Int16: objval = val.shortVal; break; case TypeCode.UInt16: objval = val.ushortVal; break; case TypeCode.Int32: objval = val.iVal; break; case TypeCode.UInt32: objval = val.uiVal; break; case TypeCode.Int64: objval = val.longVal; break; case TypeCode.UInt64: objval = val.ulongVal; break; case TypeCode.Single: objval = val.floatVal; break; case TypeCode.Double: objval = val.doubleVal; break; case TypeCode.Decimal: objval = val.decVal; break; case TypeCode.Char: objval = val.cVal; break; case TypeCode.String: objval = val.strVal; break; default: objval = val.objectVal; break; } if (pExpr.type.isEnumType()) { objval = Enum.ToObject(pExpr.type.AssociatedSystemType, objval); } return objval; } else if (pExpr.isZEROINIT()) { if (pExpr.asZEROINIT().OptionalArgument != null) { return GetObject(pExpr.asZEROINIT().OptionalArgument); } return System.Activator.CreateInstance(pExpr.type.AssociatedSystemType); } Debug.Assert(false, "Invalid EXPR in GetObject"); throw Error.InternalCompilerError(); }