private static Expr GenerateConversionWithSource(Expr pTarget, CType pType, bool bChecked) { PREDEFMETH pdm = bChecked ? PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED : PREDEFMETH.PM_EXPRESSION_CONVERT; Expr pTypeOf = CreateTypeOf(pType); return(GenerateCall(pdm, pTarget, pTypeOf)); }
private static PredefinedMethodInfo GetMethInfo(PREDEFMETH method) { Debug.Assert(method >= 0 && method < PREDEFMETH.PM_COUNT); Debug.Assert(s_predefinedMethods[(int)method].method == method); return(s_predefinedMethods[(int)method]); }
private Expression GenerateUserDefinedUnaryOperator(ExprCall pExpr) { PREDEFMETH pm = pExpr.PredefinedMethod; ExprList list = (ExprList)pExpr.OptionalArguments; Expression arg = GetExpression(list.OptionalElement); MethodInfo methodInfo = ((ExprMethodInfo)list.OptionalNextListNode).MethodInfo; switch (pm) { case PREDEFMETH.PM_EXPRESSION_NOT_USER_DEFINED: return(Expression.Not(arg, methodInfo)); case PREDEFMETH.PM_EXPRESSION_NEGATE_USER_DEFINED: return(Expression.Negate(arg, methodInfo)); case PREDEFMETH.PM_EXPRESSION_UNARYPLUS_USER_DEFINED: return(Expression.UnaryPlus(arg, methodInfo)); case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED_USER_DEFINED: return(Expression.NegateChecked(arg, methodInfo)); default: Debug.Fail("Invalid Predefined Method in GenerateUserDefinedUnaryOperator"); throw Error.InternalCompilerError(); } }
private static PREDEFMETH GetPropGetter(PREDEFPROP property) { PREDEFMETH result = GetPropInfo(property).getter; // getters are MethodRequiredEnum.Required Debug.Assert(result >= 0 && result < PREDEFMETH.PM_COUNT); return(result); }
public int[] signature; // Size 8. expand this if a new method has a signature which doesn't fit in the current space public PredefinedMethodInfo(PREDEFMETH method, PredefinedType type, PredefinedName name, MethodCallingConventionEnum callingConvention, ACCESS access, int cTypeVars, int[] signature) { this.method = method; this.type = type; this.name = name; this.callingConvention = callingConvention; this.access = access; this.cTypeVars = cTypeVars; this.signature = signature; }
private MethodSymbol LoadMethod(PREDEFMETH method) { return(LoadMethod( GetMethParent(method), GetMethSignature(method), GetMethTyVars(method), GetMethName(method), GetMethAccess(method), IsMethStatic(method), IsMethVirtual(method))); }
private static MethodSymbol LoadMethod(PREDEFMETH method) { PredefinedMethodInfo info = GetMethInfo(method); return(LoadMethod( GetPredefAgg(info.type), info.signature, info.cTypeVars, NameManager.GetPredefinedName(info.name), info.access, info.callingConvention == MethodCallingConventionEnum.Static, info.callingConvention == MethodCallingConventionEnum.Virtual)); }
private PropertySymbol LoadProperty( PREDEFPROP predefProp, Name propertyName, PREDEFMETH propertyGetter) { Debug.Assert(propertyName != null); Debug.Assert(propertyGetter >= 0 && propertyGetter < PREDEFMETH.PM_COUNT); RuntimeBinderSymbolTable.AddPredefinedPropertyToSymbolTable( GetPredefAgg(GetPropPredefType(predefProp)), propertyName); MethodSymbol getter = GetMethod(propertyGetter); getter.SetMethKind(MethodKindEnum.PropAccessor); PropertySymbol property = getter.getProperty(); Debug.Assert(property != null); return property; }
private ExprCall GenerateCall(PREDEFMETH pdm, Expr arg1, Expr arg2, Expr arg3, Expr arg4) { MethodSymbol method = GetPreDefMethod(pdm); if (method == null) { return(null); } AggregateType expressionType = GetSymbolLoader().GetPredefindType(PredefinedType.PT_EXPRESSION); Expr args = GetExprFactory().CreateList(arg1, arg2, arg3, arg4); MethWithInst mwi = new MethWithInst(method, expressionType); ExprMemberGroup pMemGroup = GetExprFactory().CreateMemGroup(null, mwi); ExprCall call = GetExprFactory().CreateCall(0, mwi.Meth().RetType, args, pMemGroup, mwi); call.PredefinedMethod = pdm; return(call); }
private ExprCall GenerateCall(PREDEFMETH pdm, Expr arg1) { MethodSymbol method = GetPreDefMethod(pdm); // this should be enforced in an earlier pass and the transform pass should not // be handling this error if (method == null) { return(null); } AggregateType expressionType = GetSymbolLoader().GetPredefindType(PredefinedType.PT_EXPRESSION); MethWithInst mwi = new MethWithInst(method, expressionType); ExprMemberGroup pMemGroup = GetExprFactory().CreateMemGroup(null, mwi); ExprCall call = GetExprFactory().CreateCall(0, mwi.Meth().RetType, arg1, pMemGroup, mwi); call.PredefinedMethod = pdm; return(call); }
private Expr GenerateUserDefinedConversion(Expr arg, CType CType, Expr target, MethWithInst method) { // The user-defined explicit conversion from enum? to decimal or decimal? requires // that we convert the enum? to its nullable underlying CType. if (isEnumToDecimalConversion(arg.Type, CType)) { // Special case: If we have enum? to decimal? then we need to emit // a conversion from enum? to its nullable underlying CType first. // This is unfortunate; we ought to reorganize how conversions are // represented in the Expr tree so that this is more transparent. // converting an enum to its underlying CType never fails, so no need to check it. CType underlyingType = arg.Type.StripNubs().underlyingEnumType(); CType nullableType = GetSymbolLoader().GetTypeManager().GetNullable(underlyingType); Expr typeofNubEnum = CreateTypeOf(nullableType); target = GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, target, typeofNubEnum); } // If the methodinfo does not return the target CType AND this is not a lifted conversion // from one value CType to another, then we need to wrap the whole thing in another conversion, // e.g. if we have a user-defined conversion from int to S? and we have (S)myint, then we need to generate // Convert(Convert(myint, typeof(S?), op_implicit), typeof(S)) CType pMethodReturnType = GetSymbolLoader().GetTypeManager().SubstType(method.Meth().RetType, method.GetType(), method.TypeArgs); bool fDontLiftReturnType = (pMethodReturnType == CType || (IsNullableValueType(arg.Type) && IsNullableValueType(CType))); Expr typeofInner = CreateTypeOf(fDontLiftReturnType ? CType : pMethodReturnType); Expr methodInfo = GetExprFactory().CreateMethodInfo(method); PREDEFMETH pdmInner = arg.isChecked() ? PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED_USER_DEFINED : PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED; Expr callUserDefinedConversion = GenerateCall(pdmInner, target, typeofInner, methodInfo); if (fDontLiftReturnType) { return(callUserDefinedConversion); } PREDEFMETH pdmOuter = arg.isChecked() ? PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED : PREDEFMETH.PM_EXPRESSION_CONVERT; Expr typeofOuter = CreateTypeOf(CType); return(GenerateCall(pdmOuter, callUserDefinedConversion, typeofOuter)); }
///////////////////////////////////////////////////////////////////////////////// private Expression GenerateUnaryOperator(ExprCall pExpr) { PREDEFMETH pm = pExpr.PredefinedMethod; Expression arg = GetExpression(pExpr.OptionalArguments); switch (pm) { case PREDEFMETH.PM_EXPRESSION_NOT: return(Expression.Not(arg)); case PREDEFMETH.PM_EXPRESSION_NEGATE: return(Expression.Negate(arg)); case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED: return(Expression.NegateChecked(arg)); default: Debug.Fail("Invalid Predefined Method in GenerateUnaryOperator"); throw Error.InternalCompilerError(); } }
private Expr GenerateUserDefinedComparisonOperator(ExprBinOp expr) { Debug.Assert(expr != null); PREDEFMETH pdm = expr.Kind switch { ExpressionKind.StringEq => PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED, ExpressionKind.StringNotEq => PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED, ExpressionKind.DelegateEq => PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED, ExpressionKind.DelegateNotEq => PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED, ExpressionKind.Eq => PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED, ExpressionKind.NotEq => PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED, ExpressionKind.LessThanOrEqual => PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL_USER_DEFINED, ExpressionKind.LessThan => PREDEFMETH.PM_EXPRESSION_LESSTHAN_USER_DEFINED, ExpressionKind.GreaterThanOrEqual => PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL_USER_DEFINED, ExpressionKind.GreaterThan => PREDEFMETH.PM_EXPRESSION_GREATERTHAN_USER_DEFINED, _ => throw Error.InternalCompilerError(), }; Expr p1 = expr.OptionalLeftChild; Expr p2 = expr.OptionalRightChild; if (expr.OptionalUserDefinedCall != null) { ExprCall udcall = (ExprCall)expr.OptionalUserDefinedCall; ExprList args = (ExprList)udcall.OptionalArguments; Debug.Assert(args.OptionalNextListNode.Kind != ExpressionKind.List); p1 = args.OptionalElement; p2 = args.OptionalNextListNode; } p1 = Visit(p1); p2 = Visit(p2); FixLiftedUserDefinedBinaryOperators(expr, ref p1, ref p2); Expr lift = ExprFactory.CreateBoolConstant(false); // We never lift to null in C#. Expr methodInfo = ExprFactory.CreateMethodInfo(expr.UserDefinedCallMethod); return(GenerateCall(pdm, p1, p2, lift, methodInfo)); }
public static PredefinedMethodInfo GetMethInfo(PREDEFMETH method) { RETAILVERIFY(method > PREDEFMETH.PM_FIRST && method < PREDEFMETH.PM_COUNT); RETAILVERIFY(s_predefinedMethods[(int)method].method == method); return s_predefinedMethods[(int)method]; }
protected MethodSymbol GetPreDefMethod(PREDEFMETH pdm) { return GetSymbolLoader().getPredefinedMembers().GetMethod(pdm); }
protected EXPRCALL GenerateCall(PREDEFMETH pdm, EXPR arg1, EXPR arg2, EXPR arg3, EXPR arg4) { MethodSymbol method = GetPreDefMethod(pdm); if (method == null) return null; AggregateType expressionType = GetSymbolLoader().GetOptPredefTypeErr(PredefinedType.PT_EXPRESSION, true); EXPR args = GetExprFactory().CreateList(arg1, arg2, arg3, arg4); MethWithInst mwi = new MethWithInst(method, expressionType); EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(null, mwi); EXPRCALL call = GetExprFactory().CreateCall(0, mwi.Meth().RetType, args, pMemGroup, mwi); call.PredefinedMethod = pdm; return call; }
//////////////////////////////////////////////////////////////////////////////// // This finds a method and binds it to the args provided. internal EXPRCALL BindPredefMethToArgs(PREDEFMETH predefMethod, EXPR obj, EXPR args, TypeArray clsTypeArgs, TypeArray methTypeArgs) { MethodSymbol methSym = GetSymbolLoader().getPredefinedMembers().GetMethod(predefMethod); if (methSym == null) { MethWithInst mwi = new MethWithInst(null, null); EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(obj, mwi); EXPRCALL rval = GetExprFactory().CreateCall(0, null, args, pMemGroup, null); rval.SetError(); return rval; } AggregateSymbol agg = methSym.getClass(); if (clsTypeArgs == null) { clsTypeArgs = BSYMMGR.EmptyTypeArray(); } AggregateType aggType = GetTypes().GetAggregate(agg, clsTypeArgs); MethPropWithInst mpwiBest = new MethPropWithInst(methSym, aggType, methTypeArgs); EXPRMEMGRP memgroup = GetExprFactory().CreateMemGroup(obj, mpwiBest); EXPRCALL exprRes = BindToMethod(new MethWithInst(mpwiBest), args, memgroup, (MemLookFlags)MemLookFlags.None); return exprRes; }
private static MethodSymbol GetPreDefMethod(PREDEFMETH pdm) => PredefinedMembers.GetMethod(pdm);
private EXPRBINOP CreateBinopForPredefMethodCall(ExpressionKind ek, PREDEFMETH predefMeth, CType RetType, EXPR arg1, EXPR arg2) { MethodSymbol methSym = GetSymbolLoader().getPredefinedMembers().GetMethod(predefMeth); EXPRBINOP binop = GetExprFactory().CreateBinop(ek, RetType, arg1, arg2); // Set the predefined method to call. if (methSym != null) { AggregateSymbol agg = methSym.getClass(); AggregateType callingType = GetTypes().GetAggregate(agg, BSYMMGR.EmptyTypeArray()); binop.predefinedMethodToCall = new MethWithInst(methSym, callingType, null); binop.SetUserDefinedCallMethod(binop.predefinedMethodToCall); } else { // Couldn't find it. binop.SetError(); } return binop; }
private MethodSymbol LoadMethod(PREDEFMETH method) { return LoadMethod( GetMethParent(method), GetMethSignature(method), GetMethTyVars(method), GetMethName(method), GetMethAccess(method), IsMethStatic(method), IsMethVirtual(method)); }
public MethodSymbol GetOptionalMethod(PREDEFMETH method) { return EnsureMethod(method); }
private PropertySymbol LoadProperty( PREDEFPROP predefProp, Name propertyName, PREDEFMETH propertyGetter, PREDEFMETH propertySetter) { Debug.Assert(propertyName != null); Debug.Assert(propertyGetter > PREDEFMETH.PM_FIRST && propertyGetter < PREDEFMETH.PM_COUNT); Debug.Assert(propertySetter > PREDEFMETH.PM_FIRST && propertySetter <= PREDEFMETH.PM_COUNT); MethodSymbol getter = GetOptionalMethod(propertyGetter); MethodSymbol setter = null; if (propertySetter != PREDEFMETH.PM_COUNT) { setter = GetOptionalMethod(propertySetter); } if (getter == null && setter == null) { RuntimeBinderSymbolTable.AddPredefinedPropertyToSymbolTable(GetOptPredefAgg(GetPropPredefType(predefProp)), propertyName); getter = GetOptionalMethod(propertyGetter); if (propertySetter != PREDEFMETH.PM_COUNT) { setter = GetOptionalMethod(propertySetter); } } if (setter != null) { setter.SetMethKind(MethodKindEnum.PropAccessor); } PropertySymbol property = null; if (getter != null) { getter.SetMethKind(MethodKindEnum.PropAccessor); property = getter.getProperty(); // Didn't find it, so load it. if (property == null) { RuntimeBinderSymbolTable.AddPredefinedPropertyToSymbolTable(GetOptPredefAgg(GetPropPredefType(predefProp)), propertyName); } property = getter.getProperty(); Debug.Assert(property != null); if (property.name != propertyName || (propertySetter != PREDEFMETH.PM_COUNT && (setter == null || !setter.isPropertyAccessor() || setter.getProperty() != property)) || property.getBogus()) { property = null; } } return property; }
private Expr GenerateBuiltInBinaryOperator(ExprBinOp expr) { Debug.Assert(expr != null); PREDEFMETH pdm = expr.Kind switch { ExpressionKind.LeftShirt => PREDEFMETH.PM_EXPRESSION_LEFTSHIFT, ExpressionKind.RightShift => PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT, ExpressionKind.BitwiseExclusiveOr => PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR, ExpressionKind.BitwiseOr => PREDEFMETH.PM_EXPRESSION_OR, ExpressionKind.BitwiseAnd => PREDEFMETH.PM_EXPRESSION_AND, ExpressionKind.LogicalAnd => PREDEFMETH.PM_EXPRESSION_ANDALSO, ExpressionKind.LogicalOr => PREDEFMETH.PM_EXPRESSION_ORELSE, ExpressionKind.StringEq => PREDEFMETH.PM_EXPRESSION_EQUAL, ExpressionKind.Eq => PREDEFMETH.PM_EXPRESSION_EQUAL, ExpressionKind.StringNotEq => PREDEFMETH.PM_EXPRESSION_NOTEQUAL, ExpressionKind.NotEq => PREDEFMETH.PM_EXPRESSION_NOTEQUAL, ExpressionKind.GreaterThanOrEqual => PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL, ExpressionKind.LessThanOrEqual => PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL, ExpressionKind.LessThan => PREDEFMETH.PM_EXPRESSION_LESSTHAN, ExpressionKind.GreaterThan => PREDEFMETH.PM_EXPRESSION_GREATERTHAN, ExpressionKind.Modulo => PREDEFMETH.PM_EXPRESSION_MODULO, ExpressionKind.Divide => PREDEFMETH.PM_EXPRESSION_DIVIDE, ExpressionKind.Multiply => expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED : PREDEFMETH.PM_EXPRESSION_MULTIPLY, ExpressionKind.Subtract => expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED : PREDEFMETH.PM_EXPRESSION_SUBTRACT, ExpressionKind.Add => expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_ADDCHECKED : PREDEFMETH.PM_EXPRESSION_ADD, _ => throw Error.InternalCompilerError(), }; Expr origL = expr.OptionalLeftChild; Expr origR = expr.OptionalRightChild; Debug.Assert(origL != null); Debug.Assert(origR != null); CType typeL = origL.Type; CType typeR = origR.Type; Expr newL = Visit(origL); Expr newR = Visit(origR); bool didEnumConversion = false; CType convertL = null; CType convertR = null; if (typeL.IsEnumType) { // We have already inserted casts if not lifted, so we should never see an enum. Debug.Assert(expr.IsLifted); convertL = TypeManager.GetNullable(typeL.UnderlyingEnumType); typeL = convertL; didEnumConversion = true; } else if (typeL is NullableType nubL && nubL.UnderlyingType.IsEnumType) { Debug.Assert(expr.IsLifted); convertL = TypeManager.GetNullable(nubL.UnderlyingType.UnderlyingEnumType); typeL = convertL; didEnumConversion = true; } if (typeR.IsEnumType) { Debug.Assert(expr.IsLifted); convertR = TypeManager.GetNullable(typeR.UnderlyingEnumType); typeR = convertR; didEnumConversion = true; } else if (typeR is NullableType nubR && nubR.UnderlyingType.IsEnumType) { Debug.Assert(expr.IsLifted); convertR = TypeManager.GetNullable(nubR.UnderlyingType.UnderlyingEnumType); typeR = convertR; didEnumConversion = true; } if (typeL is NullableType nubL2 && nubL2.UnderlyingType == typeR) { convertR = typeL; } if (typeR is NullableType nubR2 && nubR2.UnderlyingType == typeL) { convertL = typeR; } if (convertL != null) { newL = GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, newL, CreateTypeOf(convertL)); } if (convertR != null) { newR = GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, newR, CreateTypeOf(convertR)); } Expr call = GenerateCall(pdm, newL, newR); if (didEnumConversion && expr.Type.StripNubs().IsEnumType) { call = GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, call, CreateTypeOf(expr.Type)); } return(call); }
public MethodSymbol GetMethod(PREDEFMETH method) { Debug.Assert(method >= 0 && method < PREDEFMETH.PM_COUNT); return(_methods[(int)method] ?? (_methods[(int)method] = LoadMethod(method))); }
private AggregateSymbol GetMethParent(PREDEFMETH method) { return(GetPredefAgg(GetMethPredefType(method))); }
private Name GetMethName(PREDEFMETH method) { return(GetPredefName(GetMethPredefName(method))); }
public PredefinedPropertyInfo(PREDEFPROP property, PredefinedName name, PREDEFMETH getter) { this.property = property; this.name = name; this.getter = getter; }
private AggregateSymbol GetMethParent(PREDEFMETH method) { return GetOptPredefAgg(GetMethPredefType(method)); }
private static PredefinedType GetMethPredefType(PREDEFMETH method) { return GetMethInfo(method).type; }
public MethodSymbol GetMethod(PREDEFMETH method) { MethodSymbol result = EnsureMethod(method); if (result == null) { ReportError(method); } return result; }
private static bool IsMethVirtual(PREDEFMETH method) { return GetMethInfo(method).callingConvention == MethodCallingConventionEnum.Virtual; }
private MethodSymbol EnsureMethod(PREDEFMETH method) { RETAILVERIFY(method > PREDEFMETH.PM_FIRST && method < PREDEFMETH.PM_COUNT); if (_methods[(int)method] == null) { _methods[(int)method] = LoadMethod(method); } return _methods[(int)method]; }
private static int GetMethTyVars(PREDEFMETH method) { return GetMethInfo(method).cTypeVars; }
private void ReportError(PREDEFMETH method) { ReportError(GetMethPredefType(method), GetMethPredefName(method)); }
private EXPRUNARYOP CreateUnaryOpForPredefMethodCall(ExpressionKind ek, PREDEFMETH predefMeth, CType pRetType, EXPR pArg) { MethodSymbol methSym = GetSymbolLoader().getPredefinedMembers().GetMethod(predefMeth); EXPRUNARYOP pUnaryOp = GetExprFactory().CreateUnaryOp(ek, pRetType, pArg); // Set the predefined method to call. if (methSym != null) { AggregateSymbol pAgg = methSym.getClass(); AggregateType pCallingType = GetTypes().GetAggregate(pAgg, BSYMMGR.EmptyTypeArray()); pUnaryOp.predefinedMethodToCall = new MethWithInst(methSym, pCallingType, null); pUnaryOp.UserDefinedCallMethod = pUnaryOp.predefinedMethodToCall; } else { pUnaryOp.SetError(); } return pUnaryOp; }
private static PredefinedName GetMethPredefName(PREDEFMETH method) { return GetMethInfo(method).name; }
private static PredefinedName GetMethPredefName(PREDEFMETH method) { return(GetMethInfo(method).name); }
private static bool IsMethStatic(PREDEFMETH method) { return GetMethInfo(method).callingConvention == MethodCallingConventionEnum.Static; }
private static PredefinedType GetMethPredefType(PREDEFMETH method) { return(GetMethInfo(method).type); }
private static ACCESS GetMethAccess(PREDEFMETH method) { return GetMethInfo(method).access; }
private static bool IsMethStatic(PREDEFMETH method) { return(GetMethInfo(method).callingConvention == MethodCallingConventionEnum.Static); }
private static int[] GetMethSignature(PREDEFMETH method) { return GetMethInfo(method).signature; }
private static bool IsMethVirtual(PREDEFMETH method) { return(GetMethInfo(method).callingConvention == MethodCallingConventionEnum.Virtual); }
protected override Expr VisitCALL(ExprCall expr) { Debug.Assert(expr != null); switch (expr.NullableCallLiftKind) { default: break; case NullableCallLiftKind.NullableIntermediateConversion: case NullableCallLiftKind.NullableConversion: case NullableCallLiftKind.NullableConversionConstructor: return(GenerateConversion(expr.OptionalArguments, expr.Type, expr.isChecked())); case NullableCallLiftKind.NotLiftedIntermediateConversion: case NullableCallLiftKind.UserDefinedConversion: return(GenerateUserDefinedConversion(expr.OptionalArguments, expr.Type, expr.MethWithInst)); } if (expr.MethWithInst.Meth().IsConstructor()) { return(GenerateConstructor(expr)); } ExprMemberGroup memberGroup = expr.MemberGroup; if (memberGroup.IsDelegate) { return(GenerateDelegateInvoke(expr)); } Expr pObject; if (expr.MethWithInst.Meth().isStatic || expr.MemberGroup.OptionalObject == null) { pObject = GetExprFactory().CreateNull(); } else { pObject = expr.MemberGroup.OptionalObject; // If we have, say, an int? which is the object of a call to ToString // then we do NOT want to generate ((object)i).ToString() because that // will convert a null-valued int? to a null object. Rather what we want // to do is box it to a ValueType and call ValueType.ToString. // // To implement this we say that if the object of the call is an implicit boxing cast // then just generate the object, not the cast. If the cast is explicit in the // source code then it will be an EXPLICITCAST and we will visit it normally. // // It might be better to rewrite the expression tree API so that it // can handle in the general case all implicit boxing conversions. Right now it // requires that all arguments to a call that need to be boxed be explicitly boxed. if (pObject != null && pObject is ExprCast cast && cast.IsBoxingCast) { pObject = cast.Argument; } pObject = Visit(pObject); } Expr methodInfo = GetExprFactory().CreateMethodInfo(expr.MethWithInst); Expr args = GenerateArgsList(expr.OptionalArguments); Expr Params = GenerateParamsArray(args, PredefinedType.PT_EXPRESSION); PREDEFMETH pdm = PREDEFMETH.PM_EXPRESSION_CALL; Debug.Assert(!expr.MethWithInst.Meth().isVirtual || expr.MemberGroup.OptionalObject != null); return(GenerateCall(pdm, pObject, methodInfo, Params)); }
private static ACCESS GetMethAccess(PREDEFMETH method) { return(GetMethInfo(method).access); }
private MethodSymbol GetPreDefMethod(PREDEFMETH pdm) { return(GetSymbolLoader().getPredefinedMembers().GetMethod(pdm)); }
private static int GetMethTyVars(PREDEFMETH method) { return(GetMethInfo(method).cTypeVars); }
protected EXPRCALL GenerateCall(PREDEFMETH pdm, EXPR arg1) { MethodSymbol method = GetPreDefMethod(pdm); // this should be enforced in an earlier pass and the tranform pass should not // be handeling this error if (method == null) return null; AggregateType expressionType = GetSymbolLoader().GetOptPredefTypeErr(PredefinedType.PT_EXPRESSION, true); MethWithInst mwi = new MethWithInst(method, expressionType); EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(null, mwi); EXPRCALL call = GetExprFactory().CreateCall(0, mwi.Meth().RetType, arg1, pMemGroup, mwi); call.PredefinedMethod = pdm; return call; }
private static int[] GetMethSignature(PREDEFMETH method) { return(GetMethInfo(method).signature); }
protected virtual EXPR GenerateBuiltInUnaryOperator(PREDEFMETH pdm, EXPR pOriginalOperator, EXPR pOperator) { EXPR op = Visit(pOriginalOperator); if (pOriginalOperator.type.IsNullableType() && pOriginalOperator.type.StripNubs().isEnumType()) { Debug.Assert(pOperator.kind == ExpressionKind.EK_BITNOT); // The only built-in unary operator defined on nullable enum. CType underlyingType = pOriginalOperator.type.StripNubs().underlyingEnumType(); CType nullableType = GetSymbolLoader().GetTypeManager().GetNullable(underlyingType); op = GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, op, CreateTypeOf(nullableType)); } EXPR call = GenerateCall(pdm, op); if (pOriginalOperator.type.IsNullableType() && pOriginalOperator.type.StripNubs().isEnumType()) { call = GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, call, CreateTypeOf(pOperator.type)); } return call; }
public int[] signature; // Size 8. expand this if a new method has a signature which doesn't fit in the current space public PredefinedMethodInfo(PREDEFMETH method, MethodRequiredEnum required, PredefinedType type, PredefinedName name, MethodCallingConventionEnum callingConvention, ACCESS access, int cTypeVars, int[] signature) { this.method = method; this.type = type; this.name = name; this.callingConvention = callingConvention; this.access = access; this.cTypeVars = cTypeVars; this.signature = signature; }
///////////////////////////////////////////////////////////////////////////////// private Expression GenerateConvert(ExprCall pExpr) { PREDEFMETH pm = pExpr.PredefinedMethod; Expression e; Type t; if (pm == PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED_USER_DEFINED) { // If we have a user defined conversion, then we'll have the object // as the first element, and another list as a second element. This list // contains a TYPEOF as the first element, and the METHODINFO for the call // as the second. ExprList list = (ExprList)pExpr.OptionalArguments; ExprList list2 = (ExprList)list.OptionalNextListNode; e = GetExpression(list.OptionalElement); t = ((ExprTypeOf)list2.OptionalElement).SourceType.AssociatedSystemType; if (e.Type.MakeByRefType() == t) { // We're trying to convert from a type to its by ref type. Don't do that. return(e); } Debug.Assert((pExpr.Flags & EXPRFLAG.EXF_UNBOXRUNTIME) == 0); MethodInfo m = ((ExprMethodInfo)list2.OptionalNextListNode).MethodInfo; if (pm == PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED) { return(Expression.Convert(e, t, m)); } return(Expression.ConvertChecked(e, t, m)); } else { Debug.Assert(pm == PREDEFMETH.PM_EXPRESSION_CONVERT || pm == PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED); // If we have a standard conversion, then we'll have some object as // the first list element (ie a WRAP or a CALL), and then a TYPEOF // as the second list element. ExprList list = (ExprList)pExpr.OptionalArguments; e = GetExpression(list.OptionalElement); t = ((ExprTypeOf)list.OptionalNextListNode).SourceType.AssociatedSystemType; if (e.Type.MakeByRefType() == t) { // We're trying to convert from a type to its by ref type. Don't do that. return(e); } if ((pExpr.Flags & EXPRFLAG.EXF_UNBOXRUNTIME) != 0) { // If we want to unbox this thing, return that instead of the convert. return(Expression.Unbox(e, t)); } if (pm == PREDEFMETH.PM_EXPRESSION_CONVERT) { return(Expression.Convert(e, t)); } return(Expression.ConvertChecked(e, t)); } }
public PredefinedPropertyInfo(PREDEFPROP property, MethodRequiredEnum required, PredefinedName name, PREDEFMETH getter, PREDEFMETH setter) { this.property = property; this.name = name; this.getter = getter; this.setter = setter; }
///////////////////////////////////////////////////////////////////////////////// private Expression GetExpression(Expr pExpr) { if (pExpr is ExprWrap wrap) { return(_DictionaryOfParameters[(ExprCall)wrap.OptionalExpression]); } else if (pExpr is ExprConstant) { Debug.Assert(pExpr.Type is NullType); return(null); } else { // We can have a convert node or a call of a user defined conversion. ExprCall call = (ExprCall)pExpr; Debug.Assert(call != null); 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)); 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)); case PREDEFMETH.PM_EXPRESSION_NEWARRAYINIT: ExprList list = (ExprList)call.OptionalArguments; return (Expression.NewArrayInit( ((ExprTypeOf)list.OptionalElement).SourceType.AssociatedSystemType, GetArgumentsFromArrayInit((ExprArrayInit)list.OptionalNextListNode))); case PREDEFMETH.PM_EXPRESSION_ARRAYINDEX: case PREDEFMETH.PM_EXPRESSION_ARRAYINDEX2: return(GenerateArrayIndex(call)); case PREDEFMETH.PM_EXPRESSION_NEW: return(GenerateNew(call)); case PREDEFMETH.PM_EXPRESSION_PROPERTY: return(GenerateProperty(call)); case PREDEFMETH.PM_EXPRESSION_FIELD: return(GenerateField(call)); case PREDEFMETH.PM_EXPRESSION_CONSTANT_OBJECT_TYPE: return(GenerateConstantType(call)); case PREDEFMETH.PM_EXPRESSION_ASSIGN: return(GenerateAssignment(call)); 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)); 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)); case PREDEFMETH.PM_EXPRESSION_NOT: case PREDEFMETH.PM_EXPRESSION_NEGATE: case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED: return(GenerateUnaryOperator(call)); 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)); default: Debug.Fail("Invalid Predefined Method in GetExpression"); throw Error.InternalCompilerError(); } } }
private Name GetMethName(PREDEFMETH method) { return GetPredefName(GetMethPredefName(method)); }