public static EXPR StripNullableConstructor(EXPR pExpr) { while (IsNullableConstructor(pExpr)) { Debug.Assert(pExpr.isCALL()); pExpr = pExpr.asCALL().GetOptionalArguments(); Debug.Assert(pExpr != null && !pExpr.isLIST()); } return(pExpr); }
// Value public EXPR BindValue(EXPR exprSrc) { Debug.Assert(exprSrc != null && exprSrc.type.IsNullableType()); // For new T?(x), the answer is x. if (CNullable.IsNullableConstructor(exprSrc)) { Debug.Assert(exprSrc.asCALL().GetOptionalArguments() != null && !exprSrc.asCALL().GetOptionalArguments().isLIST()); return(exprSrc.asCALL().GetOptionalArguments()); } CType typeBase = exprSrc.type.AsNullableType().GetUnderlyingType(); AggregateType ats = exprSrc.type.AsNullableType().GetAts(GetErrorContext()); if (ats == null) { EXPRPROP rval = GetExprFactory().CreateProperty(typeBase, exprSrc); rval.SetError(); return(rval); } // UNDONE: move this to transform pass ... PropertySymbol prop = GetSymbolLoader().getBSymmgr().propNubValue; if (prop == null) { prop = GetSymbolLoader().getPredefinedMembers().GetProperty(PREDEFPROP.PP_G_OPTIONAL_VALUE); GetSymbolLoader().getBSymmgr().propNubValue = prop; } PropWithType pwt = new PropWithType(prop, ats); MethWithType mwt = new MethWithType(prop != null ? prop.methGet : null, ats); MethPropWithInst mpwi = new MethPropWithInst(prop, ats); EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(exprSrc, mpwi); EXPRPROP exprRes = GetExprFactory().CreateProperty(typeBase, null, null, pMemGroup, pwt, mwt, null); if (prop == null) { exprRes.SetError(); } return(exprRes); }
public static EXPR StripNullableConstructor(EXPR pExpr) { while (IsNullableConstructor(pExpr)) { Debug.Assert(pExpr.isCALL()); pExpr = pExpr.asCALL().GetOptionalArguments(); Debug.Assert(pExpr != null && !pExpr.isLIST()); } return pExpr; }
// Value public EXPR BindValue(EXPR exprSrc) { Debug.Assert(exprSrc != null && exprSrc.type.IsNullableType()); // For new T?(x), the answer is x. if (CNullable.IsNullableConstructor(exprSrc)) { Debug.Assert(exprSrc.asCALL().GetOptionalArguments() != null && !exprSrc.asCALL().GetOptionalArguments().isLIST()); return exprSrc.asCALL().GetOptionalArguments(); } CType typeBase = exprSrc.type.AsNullableType().GetUnderlyingType(); AggregateType ats = exprSrc.type.AsNullableType().GetAts(GetErrorContext()); if (ats == null) { EXPRPROP rval = GetExprFactory().CreateProperty(typeBase, exprSrc); rval.SetError(); return rval; } PropertySymbol prop = GetSymbolLoader().getBSymmgr().propNubValue; if (prop == null) { prop = GetSymbolLoader().getPredefinedMembers().GetProperty(PREDEFPROP.PP_G_OPTIONAL_VALUE); GetSymbolLoader().getBSymmgr().propNubValue = prop; } PropWithType pwt = new PropWithType(prop, ats); MethWithType mwt = new MethWithType(prop != null ? prop.methGet : null, ats); MethPropWithInst mpwi = new MethPropWithInst(prop, ats); EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(exprSrc, mpwi); EXPRPROP exprRes = GetExprFactory().CreateProperty(typeBase, null, null, pMemGroup, pwt, mwt, null); if (prop == null) { exprRes.SetError(); } return exprRes; }
public static bool IsNullableConstructor(EXPR expr) { Debug.Assert(expr != null); if (!expr.isCALL()) { return false; } EXPRCALL pCall = expr.asCALL(); if (pCall.GetMemberGroup().GetOptionalObject() != null) { return false; } MethodSymbol meth = pCall.mwi.Meth(); if (meth == null) { return false; } return meth.IsNullableConstructor(); }
public static bool IsNullableConstructor(EXPR expr) { Debug.Assert(expr != null); if (!expr.isCALL()) { return(false); } EXPRCALL pCall = expr.asCALL(); if (pCall.GetMemberGroup().GetOptionalObject() != null) { return(false); } MethodSymbol meth = pCall.mwi.Meth(); if (meth == null) { return(false); } return(meth.IsNullableConstructor()); }
protected bool IsDelegateConstructorCall(EXPR pExpr) { Debug.Assert(pExpr != null); if (!pExpr.isCALL()) { return false; } EXPRCALL pCall = pExpr.asCALL(); return pCall.mwi.Meth() != null && pCall.mwi.Meth().IsConstructor() && pCall.type.isDelegateType() && pCall.GetOptionalArguments() != null && pCall.GetOptionalArguments().isLIST() && pCall.GetOptionalArguments().asLIST().GetOptionalNextListNode().kind == ExpressionKind.EK_FUNCPTR; }
/*************************************************************************************************** * Called by BindImplicitConversion when the destination type is Nullable<T>. The following * conversions are handled by this method: * * For S in { object, ValueType, interfaces implemented by underlying type} there is an explicit * unboxing conversion S => T? * System.Enum => T? there is an unboxing conversion if T is an enum type * null => T? implemented as default(T?) * * Implicit T?* => T?+ implemented by either wrapping or calling GetValueOrDefault the * appropriate number of times. * If imp/exp S => T then imp/exp S => T?+ implemented by converting to T then wrapping the * appropriate number of times. * If imp/exp S => T then imp/exp S?+ => T?+ implemented by calling GetValueOrDefault (m-1) times * then calling HasValue, producing a null if it returns false, otherwise calling Value, * converting to T then wrapping the appropriate number of times. * * The 3 rules above can be summarized with the following recursive rules: * * If imp/exp S => T? then imp/exp S? => T? implemented as * qs.HasValue ? (T?)(qs.Value) : default(T?) * If imp/exp S => T then imp/exp S => T? implemented as new T?((T)s) * * This method also handles calling bindUserDefinedConverion. This method does NOT handle * the following conversions: * * Implicit boxing conversion from S? to { object, ValueType, Enum, ifaces implemented by S }. (Handled by BindImplicitConversion.) * If imp/exp S => T then explicit S?+ => T implemented by calling Value the appropriate number * of times. (Handled by BindExplicitConversion.) * * The recursive equivalent is: * * If imp/exp S => T and T is not nullable then explicit S? => T implemented as qs.Value * * Some nullable conversion are NOT standard conversions. In particular, if S => T is implicit * then S? => T is not standard. Similarly if S => T is not implicit then S => T? is not standard. ***************************************************************************************************/ private bool BindNubConversion(NullableType nubDst) { // This code assumes that STANDARD and ISEXPLICIT are never both set. // bindUserDefinedConversion should ensure this! Debug.Assert(0 != (~flags & (CONVERTTYPE.STANDARD | CONVERTTYPE.ISEXPLICIT))); Debug.Assert(exprSrc == null || exprSrc.type == typeSrc); Debug.Assert(!needsExprDest || exprSrc != null); Debug.Assert(typeSrc != nubDst); // BindImplicitConversion should have taken care of this already. AggregateType atsDst = nubDst.GetAts(GetErrorContext()); if (atsDst == null) { return(false); } // Check for the unboxing conversion. This takes precedence over the wrapping conversions. if (GetSymbolLoader().HasBaseConversion(nubDst.GetUnderlyingType(), typeSrc) && !CConversions.FWrappingConv(typeSrc, nubDst)) { // These should be different! Fix the caller if typeSrc is an AggregateType of Nullable. Debug.Assert(atsDst != typeSrc); // typeSrc is a base type of the destination nullable type so there is an explicit // unboxing conversion. if (0 == (flags & CONVERTTYPE.ISEXPLICIT)) { return(false); } if (needsExprDest) { binder.bindSimpleCast(exprSrc, exprTypeDest, out exprDest, EXPRFLAG.EXF_UNBOX); } return(true); } int cnubDst; int cnubSrc; CType typeDstBase = nubDst.StripNubs(out cnubDst); EXPRCLASS exprTypeDstBase = GetExprFactory().MakeClass(typeDstBase); CType typeSrcBase = typeSrc.StripNubs(out cnubSrc); ConversionFunc pfn = (flags & CONVERTTYPE.ISEXPLICIT) != 0 ? (ConversionFunc)binder.BindExplicitConversion : (ConversionFunc)binder.BindImplicitConversion; if (cnubSrc == 0) { Debug.Assert(typeSrc == typeSrcBase); // The null type can be implicitly converted to T? as the default value. if (typeSrc.IsNullType()) { // If we have the constant null, generate it as a default value of T?. If we have // some crazy expression which has been determined to be always null, like (null??null) // keep it in its expression form and transform it in the nullable rewrite pass. if (needsExprDest) { if (exprSrc.isCONSTANT_OK()) { exprDest = GetExprFactory().CreateZeroInit(nubDst); } else { exprDest = GetExprFactory().CreateCast(0x00, typeDest, exprSrc); } } return(true); } EXPR exprTmp = exprSrc; // If there is an implicit/explicit S => T then there is an implicit/explicit S => T? if (typeSrc == typeDstBase || pfn(exprSrc, typeSrc, exprTypeDstBase, nubDst, needsExprDest, out exprTmp, flags | CONVERTTYPE.NOUDC)) { if (needsExprDest) { // UNDONE: This is a premature realization of the nullable conversion as // UNDONE: a constructor. Rather than flagging this, can we simply emit it // UNDONE: as a cast node and have the operator rewrite pass turn it into // UNDONE: a constructor call? EXPRUSERDEFINEDCONVERSION exprUDC = exprTmp.kind == ExpressionKind.EK_USERDEFINEDCONVERSION ? exprTmp.asUSERDEFINEDCONVERSION() : null; if (exprUDC != null) { exprTmp = exprUDC.UserDefinedCall; } // This logic is left over from the days when T?? was legal. However there are error/LAF cases that necessitates the loop. // typeSrc is not nullable so just wrap the required number of times. For legal code (cnubDst <= 0). for (int i = 0; i < cnubDst; i++) { exprTmp = binder.BindNubNew(exprTmp); exprTmp.asCALL().nubLiftKind = NullableCallLiftKind.NullableConversionConstructor; } if (exprUDC != null) { exprUDC.UserDefinedCall = exprTmp; exprUDC.setType((CType)exprTmp.type); exprTmp = exprUDC; } Debug.Assert(exprTmp.type == nubDst); exprDest = exprTmp; } return(true); } // No builtin conversion. Maybe there is a user defined conversion.... return(0 == (flags & CONVERTTYPE.NOUDC) && binder.bindUserDefinedConversion(exprSrc, typeSrc, nubDst, needsExprDest, out exprDest, 0 == (flags & CONVERTTYPE.ISEXPLICIT))); } // Both are Nullable so there is only a conversion if there is a conversion between the base types. // That is, if there is an implicit/explicit S => T then there is an implicit/explicit S?+ => T?+. if (typeSrcBase != typeDstBase && !pfn(null, typeSrcBase, exprTypeDstBase, nubDst, false, out exprDest, flags | CONVERTTYPE.NOUDC)) { // No builtin conversion. Maybe there is a user defined conversion.... return(0 == (flags & CONVERTTYPE.NOUDC) && binder.bindUserDefinedConversion(exprSrc, typeSrc, nubDst, needsExprDest, out exprDest, 0 == (flags & CONVERTTYPE.ISEXPLICIT))); } if (needsExprDest) { MethWithInst mwi = new MethWithInst(null, null); EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(null, mwi); EXPRCALL exprDst = GetExprFactory().CreateCall(0, nubDst, exprSrc, pMemGroup, null); // Here we want to first check whether or not the conversions work on the base types. EXPR arg1 = binder.mustCast(exprSrc, typeSrcBase); EXPRCLASS arg2 = GetExprFactory().MakeClass(typeDstBase); bool convertible; if (0 != (flags & CONVERTTYPE.ISEXPLICIT)) { convertible = binder.BindExplicitConversion(arg1, arg1.type, arg2, typeDstBase, out arg1, flags | CONVERTTYPE.NOUDC); } else { convertible = binder.BindImplicitConversion(arg1, arg1.type, arg2, typeDstBase, out arg1, flags | CONVERTTYPE.NOUDC); } if (!convertible) { VSFAIL("bind(Im|Ex)plicitConversion failed unexpectedly"); return(false); } exprDst.castOfNonLiftedResultToLiftedType = binder.mustCast(arg1, nubDst, 0); exprDst.nubLiftKind = NullableCallLiftKind.NullableConversion; exprDst.pConversions = exprDst.castOfNonLiftedResultToLiftedType; exprDest = exprDst; } return(true); }
private EXPR ReorderArgumentsForNamedAndOptional(EXPR callingObject, EXPR pResult) { EXPR arguments; AggregateType type; MethodOrPropertySymbol methprop; EXPRMEMGRP memgroup; TypeArray typeArgs; if (pResult.isCALL()) { EXPRCALL call = pResult.asCALL(); arguments = call.GetOptionalArguments(); type = call.mwi.Ats; methprop = call.mwi.Meth(); memgroup = call.GetMemberGroup(); typeArgs = call.mwi.TypeArgs; } else { Debug.Assert(pResult.isPROP()); EXPRPROP prop = pResult.asPROP(); arguments = prop.GetOptionalArguments(); type = prop.pwtSlot.Ats; methprop = prop.pwtSlot.Prop(); memgroup = prop.GetMemberGroup(); typeArgs = null; } ArgInfos argInfo = new ArgInfos(); bool b; argInfo.carg = ExpressionBinder.CountArguments(arguments, out b); _binder.FillInArgInfoFromArgList(argInfo, arguments); // We need to substitute type parameters BEFORE getting the most derived one because // we're binding against the base method, and the derived method may change the // generic arguments. TypeArray parameters = SymbolLoader.GetTypeManager().SubstTypeArray(methprop.Params, type, typeArgs); methprop = ExpressionBinder.GroupToArgsBinder.FindMostDerivedMethod(SymbolLoader, methprop, callingObject.type); ExpressionBinder.GroupToArgsBinder.ReOrderArgsForNamedArguments( methprop, parameters, type, memgroup, argInfo, _semanticChecker.GetTypeManager(), _exprFactory, SymbolLoader); { EXPR pList = null; // We reordered, so make a new list of them and set them on the constructor. // Go backwards cause lists are right-flushed. // Also perform the conversions to the right types. for (int i = argInfo.carg - 1; i >= 0; i--) { EXPR pArg = argInfo.prgexpr[i]; // Strip the name-ness away, since we don't need it. pArg = StripNamedArgument(pArg); // Perform the correct conversion. pArg = _binder.tryConvert(pArg, parameters[i]); if (pList == null) { pList = pArg; } else { pList = _exprFactory.CreateList(pArg, pList); } } if (pResult.isCALL()) { pResult.asCALL().SetOptionalArguments(pList); } else { pResult.asPROP().SetOptionalArguments(pList); } } return pResult; }
private void CheckForConditionalMethodError(EXPR pExpr) { Debug.Assert(pExpr.isCALL()); if (pExpr.isCALL()) { // This mimics the behavior of the native CompilerSymbolLoader in GetConditionalSymbols. Override // methods cannot have the conditional attribute, but implicitly acquire it from their slot. EXPRCALL call = pExpr.asCALL(); MethodSymbol method = call.mwi.Meth(); if (method.isOverride) { method = method.swtSlot.Meth(); } object[] conditions = method.AssociatedMemberInfo.GetCustomAttributes(typeof(ConditionalAttribute), false).ToArray(); if (conditions.Length > 0) { throw Error.BindCallToConditionalMethod(method.name); } } }
protected void verifyMethodArgs(EXPR call, CType callingObjectType) { Debug.Assert(call.isCALL() || call.isPROP()); EXPR argsPtr = call.getArgs(); SymWithType swt = call.GetSymWithType(); MethodOrPropertySymbol mp = swt.Sym.AsMethodOrPropertySymbol(); TypeArray pTypeArgs = call.isCALL() ? call.asCALL().mwi.TypeArgs : null; EXPR newArgs; AdjustCallArgumentsForParams(callingObjectType, swt.GetType(), mp, pTypeArgs, argsPtr, out newArgs); call.setArgs(newArgs); }
///////////////////////////////////////////////////////////////////////////////// private Expression GetExpression(EXPR pExpr) { if (pExpr.isWRAP()) { return _DictionaryOfParameters[pExpr.asWRAP().GetOptionalExpression().asCALL()]; } else if (pExpr.isCONSTANT()) { Debug.Assert(pExpr.type.IsNullType()); return null; } else { // We can have a convert node or a call of a user defined conversion. Debug.Assert(pExpr.isCALL()); EXPRCALL call = pExpr.asCALL(); PREDEFMETH pm = call.PredefinedMethod; Debug.Assert(pm == PREDEFMETH.PM_EXPRESSION_CONVERT || pm == PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_NEWARRAYINIT || pm == PREDEFMETH.PM_EXPRESSION_CALL || pm == PREDEFMETH.PM_EXPRESSION_PROPERTY || pm == PREDEFMETH.PM_EXPRESSION_FIELD || pm == PREDEFMETH.PM_EXPRESSION_ARRAYINDEX || pm == PREDEFMETH.PM_EXPRESSION_ARRAYINDEX2 || pm == PREDEFMETH.PM_EXPRESSION_CONSTANT_OBJECT_TYPE || pm == PREDEFMETH.PM_EXPRESSION_NEW || // Binary operators. pm == PREDEFMETH.PM_EXPRESSION_ASSIGN || pm == PREDEFMETH.PM_EXPRESSION_ADD || pm == PREDEFMETH.PM_EXPRESSION_AND || pm == PREDEFMETH.PM_EXPRESSION_DIVIDE || pm == PREDEFMETH.PM_EXPRESSION_EQUAL || pm == PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR || pm == PREDEFMETH.PM_EXPRESSION_GREATERTHAN || pm == PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL || pm == PREDEFMETH.PM_EXPRESSION_LEFTSHIFT || pm == PREDEFMETH.PM_EXPRESSION_LESSTHAN || pm == PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL || pm == PREDEFMETH.PM_EXPRESSION_MODULO || pm == PREDEFMETH.PM_EXPRESSION_MULTIPLY || pm == PREDEFMETH.PM_EXPRESSION_NOTEQUAL || pm == PREDEFMETH.PM_EXPRESSION_OR || pm == PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT || pm == PREDEFMETH.PM_EXPRESSION_SUBTRACT || pm == PREDEFMETH.PM_EXPRESSION_ORELSE || pm == PREDEFMETH.PM_EXPRESSION_ANDALSO || pm == PREDEFMETH.PM_EXPRESSION_ADD_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_AND_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_DIVIDE_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_GREATERTHAN_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_LEFTSHIFT_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_LESSTHAN_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_MODULO_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_MULTIPLY_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_OR_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_SUBTRACT_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_ORELSE_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_ANDALSO_USER_DEFINED || // Checked binary pm == PREDEFMETH.PM_EXPRESSION_ADDCHECKED || pm == PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED || pm == PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED || pm == PREDEFMETH.PM_EXPRESSION_ADDCHECKED_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED_USER_DEFINED || // Unary operators. pm == PREDEFMETH.PM_EXPRESSION_NOT || pm == PREDEFMETH.PM_EXPRESSION_NEGATE || pm == PREDEFMETH.PM_EXPRESSION_NOT_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_NEGATE_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_UNARYPLUS_USER_DEFINED || // Checked unary pm == PREDEFMETH.PM_EXPRESSION_NEGATECHECKED || pm == PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED || pm == PREDEFMETH.PM_EXPRESSION_NEGATECHECKED_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED_USER_DEFINED ); switch (pm) { case PREDEFMETH.PM_EXPRESSION_CALL: return GenerateCall(call).Expression; case PREDEFMETH.PM_EXPRESSION_CONVERT: case PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED: case PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED_USER_DEFINED: return GenerateConvert(call).Expression; case PREDEFMETH.PM_EXPRESSION_NEWARRAYINIT: { EXPRLIST list = call.GetOptionalArguments().asLIST(); return Expression.NewArrayInit( list.GetOptionalElement().asTYPEOF().SourceType.type.AssociatedSystemType, GetArgumentsFromArrayInit(list.GetOptionalNextListNode().asARRINIT())); } case PREDEFMETH.PM_EXPRESSION_ARRAYINDEX: case PREDEFMETH.PM_EXPRESSION_ARRAYINDEX2: return GenerateArrayIndex(call).Expression; case PREDEFMETH.PM_EXPRESSION_NEW: return GenerateNew(call).Expression; case PREDEFMETH.PM_EXPRESSION_PROPERTY: return GenerateProperty(call).Expression; case PREDEFMETH.PM_EXPRESSION_FIELD: return GenerateField(call).Expression; case PREDEFMETH.PM_EXPRESSION_CONSTANT_OBJECT_TYPE: return GenerateConstantType(call).Expression; case PREDEFMETH.PM_EXPRESSION_ASSIGN: return GenerateAssignment(call).Expression; case PREDEFMETH.PM_EXPRESSION_ADD: case PREDEFMETH.PM_EXPRESSION_AND: case PREDEFMETH.PM_EXPRESSION_DIVIDE: case PREDEFMETH.PM_EXPRESSION_EQUAL: case PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR: case PREDEFMETH.PM_EXPRESSION_GREATERTHAN: case PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL: case PREDEFMETH.PM_EXPRESSION_LEFTSHIFT: case PREDEFMETH.PM_EXPRESSION_LESSTHAN: case PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL: case PREDEFMETH.PM_EXPRESSION_MODULO: case PREDEFMETH.PM_EXPRESSION_MULTIPLY: case PREDEFMETH.PM_EXPRESSION_NOTEQUAL: case PREDEFMETH.PM_EXPRESSION_OR: case PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT: case PREDEFMETH.PM_EXPRESSION_SUBTRACT: case PREDEFMETH.PM_EXPRESSION_ORELSE: case PREDEFMETH.PM_EXPRESSION_ANDALSO: // Checked case PREDEFMETH.PM_EXPRESSION_ADDCHECKED: case PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED: case PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED: return GenerateBinaryOperator(call).Expression; case PREDEFMETH.PM_EXPRESSION_ADD_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_AND_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_DIVIDE_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_GREATERTHAN_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_LEFTSHIFT_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_LESSTHAN_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_MODULO_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_MULTIPLY_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_OR_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_SUBTRACT_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_ORELSE_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_ANDALSO_USER_DEFINED: // Checked case PREDEFMETH.PM_EXPRESSION_ADDCHECKED_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED_USER_DEFINED: return GenerateUserDefinedBinaryOperator(call).Expression; case PREDEFMETH.PM_EXPRESSION_NOT: case PREDEFMETH.PM_EXPRESSION_NEGATE: case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED: return GenerateUnaryOperator(call).Expression; case PREDEFMETH.PM_EXPRESSION_NOT_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_NEGATE_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_UNARYPLUS_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED_USER_DEFINED: return GenerateUserDefinedUnaryOperator(call).Expression; default: Debug.Assert(false, "Invalid Predefined Method in GetExpression"); throw Error.InternalCompilerError(); } } }