///////////////////////////////////////////////////////////////////////////////// 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(); }
protected virtual EXPR GenerateQuestionMarkOperand(EXPR pExpr) { Debug.Assert(pExpr != null); // We must not optimize away compiler-generated reference casts because // the expression tree API insists that the CType of both sides be identical. if (pExpr.isCAST()) { return GenerateConversion(pExpr.asCAST().GetArgument(), pExpr.type, pExpr.isChecked()); } return Visit(pExpr); }
/* Handles enum unary operator (~). */ private EXPR BindEnumUnaOp(ExpressionKind ek, EXPRFLAG flags, EXPR arg) { Debug.Assert(ek == ExpressionKind.EK_BITNOT); Debug.Assert(arg.isCAST()); Debug.Assert(arg.asCAST().GetArgument().type.isEnumType()); PredefinedType ptOp; CType typeEnum = arg.asCAST().GetArgument().type; switch (typeEnum.fundType()) { default: // Promote all smaller types to int. ptOp = PredefinedType.PT_INT; break; case FUNDTYPE.FT_U4: ptOp = PredefinedType.PT_UINT; break; case FUNDTYPE.FT_I8: ptOp = PredefinedType.PT_LONG; break; case FUNDTYPE.FT_U8: ptOp = PredefinedType.PT_ULONG; break; } CType typeOp = GetReqPDT(ptOp); arg = mustCast(arg, typeOp, CONVERTTYPE.NOUDC); EXPR exprRes = BindIntOp(ek, flags, arg, null, ptOp); if (!exprRes.isOK()) { return exprRes; } return mustCastInUncheckedContext(exprRes, typeEnum, CONVERTTYPE.NOUDC); }