public EXPRUSERLOGOP CreateUserLogOp(CType pType, EXPR pCallTF, EXPRCALL pCallOp)
        {
            Debug.Assert(pCallTF != null);
            Debug.Assert(pCallOp != null);
            Debug.Assert(pCallOp.GetOptionalArguments() != null);
            Debug.Assert(pCallOp.GetOptionalArguments().isLIST());
            Debug.Assert(pCallOp.GetOptionalArguments().asLIST().GetOptionalElement() != null);
            EXPRUSERLOGOP rval      = new EXPRUSERLOGOP();
            EXPR          leftChild = pCallOp.GetOptionalArguments().asLIST().GetOptionalElement();

            Debug.Assert(leftChild != null);
            if (leftChild.isWRAP())
            {
                // In the EE case, we don't create WRAPEXPRs.
                leftChild = leftChild.asWRAP().GetOptionalExpression();
                Debug.Assert(leftChild != null);
            }
            rval.kind                  = ExpressionKind.EK_USERLOGOP;
            rval.type                  = pType;
            rval.flags                 = EXPRFLAG.EXF_ASSGOP;
            rval.TrueFalseCall         = pCallTF;
            rval.OperatorCall          = pCallOp;
            rval.FirstOperandToExamine = leftChild;
            Debug.Assert(rval != null);
            return(rval);
        }
        public EXPRUSERLOGOP CreateUserLogOpError(CType pType, EXPR pCallTF, EXPRCALL pCallOp)
        {
            EXPRUSERLOGOP rval = CreateUserLogOp(pType, pCallTF, pCallOp);

            rval.SetError();
            return(rval);
        }
Esempio n. 3
0
        public EXPRCALL CreateCall(EXPRFLAG nFlags, CType pType, EXPR pOptionalArguments, EXPRMEMGRP pMemberGroup, MethWithInst MWI)
        {
            Debug.Assert(0 == (nFlags &
               ~(
                   EXPRFLAG.EXF_NEWOBJCALL | EXPRFLAG.EXF_CONSTRAINED | EXPRFLAG.EXF_BASECALL |
                   EXPRFLAG.EXF_NEWSTRUCTASSG |
                   EXPRFLAG.EXF_IMPLICITSTRUCTASSG | EXPRFLAG.EXF_MASK_ANY
               )
              ));

            EXPRCALL rval = new EXPRCALL();
            rval.kind = ExpressionKind.EK_CALL;
            rval.type = pType;
            rval.flags = nFlags;
            rval.SetOptionalArguments(pOptionalArguments);
            rval.SetMemberGroup(pMemberGroup);
            rval.nubLiftKind = NullableCallLiftKind.NotLifted;
            rval.castOfNonLiftedResultToLiftedType = null;

            rval.mwi = MWI;
            Debug.Assert(rval != null);
            return (rval);
        }
Esempio n. 4
0
        public EXPRCALL BindNew(EXPR pExprSrc)
        {
            Debug.Assert(pExprSrc != null);

            NullableType pNubSourceType = GetSymbolLoader().GetTypeManager().GetNullable(pExprSrc.type);

            AggregateType pSourceType = pNubSourceType.GetAts(GetErrorContext());

            if (pSourceType == null)
            {
                MethWithInst mwi       = new MethWithInst(null, null);
                EXPRMEMGRP   pMemGroup = GetExprFactory().CreateMemGroup(pExprSrc, mwi);
                EXPRCALL     rval      = GetExprFactory().CreateCall(0, pNubSourceType, null, pMemGroup, null);
                rval.SetError();
                return(rval);
            }

            // UNDONE: move this to transform pass
            MethodSymbol meth = GetSymbolLoader().getBSymmgr().methNubCtor;

            if (meth == null)
            {
                meth = GetSymbolLoader().getPredefinedMembers().GetMethod(PREDEFMETH.PM_G_OPTIONAL_CTOR);
                GetSymbolLoader().getBSymmgr().methNubCtor = meth;
            }

            MethWithInst methwithinst = new MethWithInst(meth, pSourceType, BSYMMGR.EmptyTypeArray());
            EXPRMEMGRP   memgroup     = GetExprFactory().CreateMemGroup(null, methwithinst);
            EXPRCALL     pExprRes     = GetExprFactory().CreateCall(EXPRFLAG.EXF_NEWOBJCALL | EXPRFLAG.EXF_CANTBENULL, pNubSourceType, pExprSrc, memgroup, methwithinst);

            if (meth == null)
            {
                pExprRes.SetError();
            }

            return(pExprRes);
        }
Esempio n. 5
0
        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 EXPRCALL CreateCall(EXPRFLAG nFlags, CType pType, EXPR pOptionalArguments, EXPRMEMGRP pMemberGroup, MethWithInst MWI)
        {
            Debug.Assert(0 == (nFlags &
                               ~(
                                   EXPRFLAG.EXF_NEWOBJCALL | EXPRFLAG.EXF_CONSTRAINED | EXPRFLAG.EXF_BASECALL |
                                   EXPRFLAG.EXF_NEWSTRUCTASSG |
                                   EXPRFLAG.EXF_IMPLICITSTRUCTASSG | EXPRFLAG.EXF_MASK_ANY
                                   )
                               ));

            EXPRCALL rval = new EXPRCALL();

            rval.kind  = ExpressionKind.EK_CALL;
            rval.type  = pType;
            rval.flags = nFlags;
            rval.SetOptionalArguments(pOptionalArguments);
            rval.SetMemberGroup(pMemberGroup);
            rval.nubLiftKind = NullableCallLiftKind.NotLifted;
            rval.castOfNonLiftedResultToLiftedType = null;

            rval.mwi = MWI;
            Debug.Assert(rval != null);
            return(rval);
        }
        /////////////////////////////////////////////////////////////////////////////////

        private ExpressionEXPR GenerateUnaryOperator(EXPRCALL pExpr)
        {
            PREDEFMETH pm = pExpr.PredefinedMethod;
            Expression arg = GetExpression(pExpr.GetOptionalArguments());

            switch (pm)
            {
                case PREDEFMETH.PM_EXPRESSION_NOT:
                    return new ExpressionEXPR(Expression.Not(arg));

                case PREDEFMETH.PM_EXPRESSION_NEGATE:
                    return new ExpressionEXPR(Expression.Negate(arg));

                case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED:
                    return new ExpressionEXPR(Expression.NegateChecked(arg));

                default:
                    Debug.Assert(false, "Invalid Predefined Method in GenerateUnaryOperator");
                    throw Error.InternalCompilerError();
            }
        }
        /////////////////////////////////////////////////////////////////////////////////

        private ExpressionEXPR GenerateUserDefinedUnaryOperator(EXPRCALL pExpr)
        {
            PREDEFMETH pm = pExpr.PredefinedMethod;
            EXPRLIST list = pExpr.GetOptionalArguments().asLIST();
            Expression arg = GetExpression(list.GetOptionalElement());
            MethodInfo methodInfo = GetMethodInfoFromExpr(list.GetOptionalNextListNode().asMETHODINFO());

            switch (pm)
            {
                case PREDEFMETH.PM_EXPRESSION_NOT_USER_DEFINED:
                    return new ExpressionEXPR(Expression.Not(arg, methodInfo));

                case PREDEFMETH.PM_EXPRESSION_NEGATE_USER_DEFINED:
                    return new ExpressionEXPR(Expression.Negate(arg, methodInfo));

                case PREDEFMETH.PM_EXPRESSION_UNARYPLUS_USER_DEFINED:
                    return new ExpressionEXPR(Expression.UnaryPlus(arg, methodInfo));

                case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED_USER_DEFINED:
                    return new ExpressionEXPR(Expression.NegateChecked(arg, methodInfo));

                default:
                    Debug.Assert(false, "Invalid Predefined Method in GenerateUserDefinedUnaryOperator");
                    throw Error.InternalCompilerError();
            }
        }
        /////////////////////////////////////////////////////////////////////////////////

        private ExpressionEXPR GenerateBinaryOperator(EXPRCALL pExpr)
        {
            Expression arg1 = GetExpression(pExpr.GetOptionalArguments().asLIST().GetOptionalElement());
            Expression arg2 = GetExpression(pExpr.GetOptionalArguments().asLIST().GetOptionalNextListNode());

            switch (pExpr.PredefinedMethod)
            {
                case PREDEFMETH.PM_EXPRESSION_ADD:
                    return new ExpressionEXPR(Expression.Add(arg1, arg2));
                case PREDEFMETH.PM_EXPRESSION_AND:
                    return new ExpressionEXPR(Expression.And(arg1, arg2));
                case PREDEFMETH.PM_EXPRESSION_DIVIDE:
                    return new ExpressionEXPR(Expression.Divide(arg1, arg2));
                case PREDEFMETH.PM_EXPRESSION_EQUAL:
                    return new ExpressionEXPR(Expression.Equal(arg1, arg2));
                case PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR:
                    return new ExpressionEXPR(Expression.ExclusiveOr(arg1, arg2));
                case PREDEFMETH.PM_EXPRESSION_GREATERTHAN:
                    return new ExpressionEXPR(Expression.GreaterThan(arg1, arg2));
                case PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL:
                    return new ExpressionEXPR(Expression.GreaterThanOrEqual(arg1, arg2));
                case PREDEFMETH.PM_EXPRESSION_LEFTSHIFT:
                    return new ExpressionEXPR(Expression.LeftShift(arg1, arg2));
                case PREDEFMETH.PM_EXPRESSION_LESSTHAN:
                    return new ExpressionEXPR(Expression.LessThan(arg1, arg2));
                case PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL:
                    return new ExpressionEXPR(Expression.LessThanOrEqual(arg1, arg2));
                case PREDEFMETH.PM_EXPRESSION_MODULO:
                    return new ExpressionEXPR(Expression.Modulo(arg1, arg2));
                case PREDEFMETH.PM_EXPRESSION_MULTIPLY:
                    return new ExpressionEXPR(Expression.Multiply(arg1, arg2));
                case PREDEFMETH.PM_EXPRESSION_NOTEQUAL:
                    return new ExpressionEXPR(Expression.NotEqual(arg1, arg2));
                case PREDEFMETH.PM_EXPRESSION_OR:
                    return new ExpressionEXPR(Expression.Or(arg1, arg2));
                case PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT:
                    return new ExpressionEXPR(Expression.RightShift(arg1, arg2));
                case PREDEFMETH.PM_EXPRESSION_SUBTRACT:
                    return new ExpressionEXPR(Expression.Subtract(arg1, arg2));
                case PREDEFMETH.PM_EXPRESSION_ORELSE:
                    return new ExpressionEXPR(Expression.OrElse(arg1, arg2));
                case PREDEFMETH.PM_EXPRESSION_ANDALSO:
                    return new ExpressionEXPR(Expression.AndAlso(arg1, arg2));

                // Checked
                case PREDEFMETH.PM_EXPRESSION_ADDCHECKED:
                    return new ExpressionEXPR(Expression.AddChecked(arg1, arg2));
                case PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED:
                    return new ExpressionEXPR(Expression.MultiplyChecked(arg1, arg2));
                case PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED:
                    return new ExpressionEXPR(Expression.SubtractChecked(arg1, arg2));

                default:
                    Debug.Assert(false, "Invalid Predefined Method in GenerateBinaryOperator");
                    throw Error.InternalCompilerError();
            }
        }
Esempio n. 10
0
        /////////////////////////////////////////////////////////////////////////////////

        private ExpressionEXPR GenerateUserDefinedBinaryOperator(EXPRCALL pExpr)
        {
            EXPRLIST list = pExpr.GetOptionalArguments().asLIST();
            Expression arg1 = GetExpression(list.GetOptionalElement());
            Expression arg2 = GetExpression(list.GetOptionalNextListNode().asLIST().GetOptionalElement());

            list = list.GetOptionalNextListNode().asLIST();
            MethodInfo methodInfo;
            bool bIsLifted = false;
            if (list.GetOptionalNextListNode().isLIST())
            {
                EXPRCONSTANT isLifted = list.GetOptionalNextListNode().asLIST().GetOptionalElement().asCONSTANT();
                bIsLifted = isLifted.getVal().iVal == 1;
                methodInfo = GetMethodInfoFromExpr(list.GetOptionalNextListNode().asLIST().GetOptionalNextListNode().asMETHODINFO());
            }
            else
            {
                methodInfo = GetMethodInfoFromExpr(list.GetOptionalNextListNode().asMETHODINFO());
            }

            switch (pExpr.PredefinedMethod)
            {
                case PREDEFMETH.PM_EXPRESSION_ADD_USER_DEFINED:
                    return new ExpressionEXPR(Expression.Add(arg1, arg2, methodInfo));
                case PREDEFMETH.PM_EXPRESSION_AND_USER_DEFINED:
                    return new ExpressionEXPR(Expression.And(arg1, arg2, methodInfo));
                case PREDEFMETH.PM_EXPRESSION_DIVIDE_USER_DEFINED:
                    return new ExpressionEXPR(Expression.Divide(arg1, arg2, methodInfo));
                case PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED:
                    return new ExpressionEXPR(Expression.Equal(arg1, arg2, bIsLifted, methodInfo));
                case PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR_USER_DEFINED:
                    return new ExpressionEXPR(Expression.ExclusiveOr(arg1, arg2, methodInfo));
                case PREDEFMETH.PM_EXPRESSION_GREATERTHAN_USER_DEFINED:
                    return new ExpressionEXPR(Expression.GreaterThan(arg1, arg2, bIsLifted, methodInfo));
                case PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL_USER_DEFINED:
                    return new ExpressionEXPR(Expression.GreaterThanOrEqual(arg1, arg2, bIsLifted, methodInfo));
                case PREDEFMETH.PM_EXPRESSION_LEFTSHIFT_USER_DEFINED:
                    return new ExpressionEXPR(Expression.LeftShift(arg1, arg2, methodInfo));
                case PREDEFMETH.PM_EXPRESSION_LESSTHAN_USER_DEFINED:
                    return new ExpressionEXPR(Expression.LessThan(arg1, arg2, bIsLifted, methodInfo));
                case PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL_USER_DEFINED:
                    return new ExpressionEXPR(Expression.LessThanOrEqual(arg1, arg2, bIsLifted, methodInfo));
                case PREDEFMETH.PM_EXPRESSION_MODULO_USER_DEFINED:
                    return new ExpressionEXPR(Expression.Modulo(arg1, arg2, methodInfo));
                case PREDEFMETH.PM_EXPRESSION_MULTIPLY_USER_DEFINED:
                    return new ExpressionEXPR(Expression.Multiply(arg1, arg2, methodInfo));
                case PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED:
                    return new ExpressionEXPR(Expression.NotEqual(arg1, arg2, bIsLifted, methodInfo));
                case PREDEFMETH.PM_EXPRESSION_OR_USER_DEFINED:
                    return new ExpressionEXPR(Expression.Or(arg1, arg2, methodInfo));
                case PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT_USER_DEFINED:
                    return new ExpressionEXPR(Expression.RightShift(arg1, arg2, methodInfo));
                case PREDEFMETH.PM_EXPRESSION_SUBTRACT_USER_DEFINED:
                    return new ExpressionEXPR(Expression.Subtract(arg1, arg2, methodInfo));
                case PREDEFMETH.PM_EXPRESSION_ORELSE_USER_DEFINED:
                    return new ExpressionEXPR(Expression.OrElse(arg1, arg2, methodInfo));
                case PREDEFMETH.PM_EXPRESSION_ANDALSO_USER_DEFINED:
                    return new ExpressionEXPR(Expression.AndAlso(arg1, arg2, methodInfo));

                // Checked
                case PREDEFMETH.PM_EXPRESSION_ADDCHECKED_USER_DEFINED:
                    return new ExpressionEXPR(Expression.AddChecked(arg1, arg2, methodInfo));
                case PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED_USER_DEFINED:
                    return new ExpressionEXPR(Expression.MultiplyChecked(arg1, arg2, methodInfo));
                case PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED_USER_DEFINED:
                    return new ExpressionEXPR(Expression.SubtractChecked(arg1, arg2, methodInfo));

                default:
                    Debug.Assert(false, "Invalid Predefined Method in GenerateUserDefinedBinaryOperator");
                    throw Error.InternalCompilerError();
            }
        }
Esempio n. 11
0
 public EXPRUSERLOGOP CreateUserLogOp(CType pType, EXPR pCallTF, EXPRCALL pCallOp)
 {
     Debug.Assert(pCallTF != null);
     Debug.Assert(pCallOp != null);
     Debug.Assert(pCallOp.GetOptionalArguments() != null);
     Debug.Assert(pCallOp.GetOptionalArguments().isLIST());
     Debug.Assert(pCallOp.GetOptionalArguments().asLIST().GetOptionalElement() != null);
     EXPRUSERLOGOP rval = new EXPRUSERLOGOP();
     EXPR leftChild = pCallOp.GetOptionalArguments().asLIST().GetOptionalElement();
     Debug.Assert(leftChild != null);
     if (leftChild.isWRAP())
     {
         // In the EE case, we don't create WRAPEXPRs.
         leftChild = leftChild.asWRAP().GetOptionalExpression();
         Debug.Assert(leftChild != null);
     }
     rval.kind = ExpressionKind.EK_USERLOGOP;
     rval.type = pType;
     rval.flags = EXPRFLAG.EXF_ASSGOP;
     rval.TrueFalseCall = pCallTF;
     rval.OperatorCall = pCallOp;
     rval.FirstOperandToExamine = leftChild;
     Debug.Assert(rval != null);
     return (rval);
 }
Esempio n. 12
0
        /////////////////////////////////////////////////////////////////////////////////

        private ExpressionEXPR GenerateAssignment(EXPRCALL pExpr)
        {
            EXPRLIST list = pExpr.GetOptionalArguments().asLIST();

            return new ExpressionEXPR(Expression.Assign(
                GetExpression(list.GetOptionalElement()),
                GetExpression(list.GetOptionalNextListNode())));
        }
Esempio n. 13
0
 public EXPRUSERLOGOP CreateUserLogOpError(CType pType, EXPR pCallTF, EXPRCALL pCallOp)
 {
     EXPRUSERLOGOP rval = CreateUserLogOp(pType, pCallTF, pCallOp);
     rval.SetError();
     return rval;
 }
Esempio n. 14
0
 protected virtual EXPR VisitCALL(EXPRCALL pExpr)
 {
     return VisitEXPR(pExpr);
 }
Esempio n. 15
0
        /////////////////////////////////////////////////////////////////////////////////

        private ExpressionEXPR GenerateProperty(EXPRCALL pExpr)
        {
            EXPRLIST list = pExpr.asCALL().GetOptionalArguments().asLIST();

            EXPR instance = list.GetOptionalElement();
            EXPRPropertyInfo propinfo = list.GetOptionalNextListNode().isLIST() ?
                list.GetOptionalNextListNode().asLIST().GetOptionalElement().asPropertyInfo() :
                list.GetOptionalNextListNode().asPropertyInfo();
            EXPRARRINIT arguments = list.GetOptionalNextListNode().isLIST() ?
                list.GetOptionalNextListNode().asLIST().GetOptionalNextListNode().asARRINIT() : null;

            PropertyInfo p = GetPropertyInfoFromExpr(propinfo);

            if (p == null)
            {
                Debug.Assert(false, "How did we get a prop that doesn't have a propinfo?");
                throw Error.InternalCompilerError();
            }

            if (arguments == null)
            {
                return new ExpressionEXPR(Expression.Property(GetExpression(instance), p));
            }
            return new ExpressionEXPR(Expression.Property(GetExpression(instance), p, GetArgumentsFromArrayInit(arguments)));
        }
Esempio n. 16
0
        private EXPR BindUserBoolOp(ExpressionKind kind, EXPRCALL pCall)
        {
            RETAILVERIFY(pCall != null);
            RETAILVERIFY(pCall.mwi.Meth() != null);
            RETAILVERIFY(pCall.GetOptionalArguments() != null);
            Debug.Assert(kind == ExpressionKind.EK_LOGAND || kind == ExpressionKind.EK_LOGOR);

            CType typeRet = pCall.type;

            Debug.Assert(pCall.mwi.Meth().Params.size == 2);
            if (!GetTypes().SubstEqualTypes(typeRet, pCall.mwi.Meth().Params.Item(0), typeRet) ||
                !GetTypes().SubstEqualTypes(typeRet, pCall.mwi.Meth().Params.Item(1), typeRet))
            {
                MethWithInst mwi = new MethWithInst(null, null);
                EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(null, mwi);
                EXPRCALL pCallTF = GetExprFactory().CreateCall(0, null, null, pMemGroup, null);
                pCallTF.SetError();
                GetErrorContext().Error(ErrorCode.ERR_BadBoolOp, pCall.mwi);
                return GetExprFactory().CreateUserLogOpError(typeRet, pCallTF, pCall);
            }

            Debug.Assert(pCall.GetOptionalArguments().isLIST());

            EXPR pExpr = pCall.GetOptionalArguments().asLIST().GetOptionalElement();
            EXPR pExprWrap = WrapShortLivedExpression(pExpr);
            pCall.GetOptionalArguments().asLIST().SetOptionalElement(pExprWrap);

            // Reflection load the true and false methods.
            SymbolLoader.RuntimeBinderSymbolTable.PopulateSymbolTableWithName(SpecialNames.CLR_True, null, pExprWrap.type.AssociatedSystemType);
            SymbolLoader.RuntimeBinderSymbolTable.PopulateSymbolTableWithName(SpecialNames.CLR_False, null, pExprWrap.type.AssociatedSystemType);

            EXPR pCallT = bindUDUnop(ExpressionKind.EK_TRUE, pExprWrap);
            EXPR pCallF = bindUDUnop(ExpressionKind.EK_FALSE, pExprWrap);

            if (pCallT == null || pCallF == null)
            {
                EXPR pCallTorF = pCallT != null ? pCallT : pCallF;
                if (pCallTorF == null)
                {
                    MethWithInst mwi = new MethWithInst(null, null);
                    EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(null, mwi);
                    pCallTorF = GetExprFactory().CreateCall(0, null, pExprWrap, pMemGroup, null);
                    pCall.SetError();
                }
                GetErrorContext().Error(ErrorCode.ERR_MustHaveOpTF, typeRet);
                return GetExprFactory().CreateUserLogOpError(typeRet, pCallTorF, pCall);
            }
            pCallT = mustConvert(pCallT, GetReqPDT(PredefinedType.PT_BOOL));
            pCallF = mustConvert(pCallF, GetReqPDT(PredefinedType.PT_BOOL));
            return GetExprFactory().CreateUserLogOp(typeRet, kind == ExpressionKind.EK_LOGAND ? pCallF : pCallT, pCall);
        }
Esempio n. 17
0
        /////////////////////////////////////////////////////////////////////////////////

        private ExpressionEXPR 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 = pExpr.asCALL().GetOptionalArguments().asLIST();
                EXPRLIST list2 = list.GetOptionalNextListNode().asLIST();
                e = GetExpression(list.GetOptionalElement());
                t = list2.GetOptionalElement().asTYPEOF().SourceType.type.AssociatedSystemType;

                if (e.Type.MakeByRefType() == t)
                {
                    // We're trying to convert from a type to its by ref type. Don't do that.
                    return new ExpressionEXPR(e);
                }
                Debug.Assert((pExpr.flags & EXPRFLAG.EXF_UNBOXRUNTIME) == 0);

                MethodInfo m = GetMethodInfoFromExpr(list2.GetOptionalNextListNode().asMETHODINFO());

                if (pm == PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED)
                {
                    return new ExpressionEXPR(Expression.Convert(e, t, m));
                }
                return new ExpressionEXPR(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 = pExpr.asCALL().GetOptionalArguments().asLIST();

                e = GetExpression(list.GetOptionalElement());
                t = list.GetOptionalNextListNode().asTYPEOF().SourceType.type.AssociatedSystemType;

                if (e.Type.MakeByRefType() == t)
                {
                    // We're trying to convert from a type to its by ref type. Don't do that.
                    return new ExpressionEXPR(e);
                }

                if ((pExpr.flags & EXPRFLAG.EXF_UNBOXRUNTIME) != 0)
                {
                    // If we want to unbox this thing, return that instead of the convert.
                    return new ExpressionEXPR(Expression.Unbox(e, t));
                }

                if (pm == PREDEFMETH.PM_EXPRESSION_CONVERT)
                {
                    return new ExpressionEXPR(Expression.Convert(e, t));
                }
                return new ExpressionEXPR(Expression.ConvertChecked(e, t));
            }
        }
Esempio n. 18
0
        /////////////////////////////////////////////////////////////////////////////////

        private ExpressionEXPR GenerateArrayIndex(EXPRCALL pExpr)
        {
            // We have two possibilities here - we're either a single index array, in which 
            // case we'll be PM_EXPRESSION_ARRAYINDEX, or we have multiple dimensions,
            // in which case we are PM_EXPRESSION_ARRAYINDEX2. 
            //
            // Our arguments then, are: object, index or object, indices.
            EXPRLIST list = pExpr.GetOptionalArguments().asLIST();
            Expression obj = GetExpression(list.GetOptionalElement());
            Expression[] indices;

            if (pExpr.PredefinedMethod == PREDEFMETH.PM_EXPRESSION_ARRAYINDEX)
            {
                indices = new Expression[] { GetExpression(list.GetOptionalNextListNode()) };
            }
            else
            {
                Debug.Assert(pExpr.PredefinedMethod == PREDEFMETH.PM_EXPRESSION_ARRAYINDEX2);
                indices = GetArgumentsFromArrayInit(list.GetOptionalNextListNode().asARRINIT());
            }
            return new ExpressionEXPR(Expression.ArrayAccess(obj, indices));
        }
Esempio n. 19
0
        /////////////////////////////////////////////////////////////////////////////////

        private ExpressionEXPR GenerateCall(EXPRCALL pExpr)
        {
            // Our arguments are: object, methodinfo, parameters.
            // The object is either an EXPRWRAP of a CALL, or a CALL that is a PM_CONVERT, whose
            // argument is the WRAP of a CALL. Deal with that first.

            EXPRMETHODINFO methinfo;
            EXPRARRINIT arrinit;

            EXPRLIST list = pExpr.GetOptionalArguments().asLIST();
            if (list.GetOptionalNextListNode().isLIST())
            {
                methinfo = list.GetOptionalNextListNode().asLIST().GetOptionalElement().asMETHODINFO();
                arrinit = list.GetOptionalNextListNode().asLIST().GetOptionalNextListNode().asARRINIT();
            }
            else
            {
                methinfo = list.GetOptionalNextListNode().asMETHODINFO();
                arrinit = null;
            }

            Expression obj = null;
            MethodInfo m = GetMethodInfoFromExpr(methinfo);
            Expression[] arguments = GetArgumentsFromArrayInit(arrinit);

            if (m == null)
            {
                Debug.Assert(false, "How did we get a call that doesn't have a methodinfo?");
                throw Error.InternalCompilerError();
            }

            // The DLR is expecting the instance for a static invocation to be null. If we have
            // an instance method, fetch the object.
            if (!m.IsStatic)
            {
                obj = GetExpression(pExpr.GetOptionalArguments().asLIST().GetOptionalElement());
            }

            return new ExpressionEXPR(Expression.Call(obj, m, arguments));
        }
Esempio n. 20
0
        /////////////////////////////////////////////////////////////////////////////////

        private ExpressionEXPR GenerateLambda(EXPRCALL pExpr)
        {
            // We always call Lambda(body, arrayinit) where the arrayinit 
            // is the initialization of the parameters.
            ExpressionEXPR body = Visit(pExpr.GetOptionalArguments().asLIST().GetOptionalElement()) as ExpressionEXPR;

            Expression e = body.Expression;

            /*
             * // Do we need to do this?
            if (e.Type.IsValueType)
            {
                // If we have a value type, convert it to object so that boxing
                // can happen.

                e = Expression.Convert(body.Expression, typeof(object));
            }
             * */
            return new ExpressionEXPR(e);
        }
Esempio n. 21
0
        /////////////////////////////////////////////////////////////////////////////////

        protected override EXPR VisitCALL(EXPRCALL pExpr)
        {
            if (pExpr.PredefinedMethod != PREDEFMETH.PM_FIRST)
            {
                switch (pExpr.PredefinedMethod)
                {
                    case PREDEFMETH.PM_EXPRESSION_LAMBDA:
                        return GenerateLambda(pExpr);

                    case PREDEFMETH.PM_EXPRESSION_CALL:
                        return GenerateCall(pExpr);

                    case PREDEFMETH.PM_EXPRESSION_ARRAYINDEX:
                    case PREDEFMETH.PM_EXPRESSION_ARRAYINDEX2:
                        return GenerateArrayIndex(pExpr);

                    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(pExpr);

                    case PREDEFMETH.PM_EXPRESSION_PROPERTY:
                        return GenerateProperty(pExpr);

                    case PREDEFMETH.PM_EXPRESSION_FIELD:
                        return GenerateField(pExpr);

                    case PREDEFMETH.PM_EXPRESSION_INVOKE:
                        return GenerateInvoke(pExpr);

                    case PREDEFMETH.PM_EXPRESSION_NEW:
                        return GenerateNew(pExpr);

                    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(pExpr);

                    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(pExpr);

                    case PREDEFMETH.PM_EXPRESSION_NEGATE:
                    case PREDEFMETH.PM_EXPRESSION_NOT:
                    case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED:
                        return GenerateUnaryOperator(pExpr);

                    case PREDEFMETH.PM_EXPRESSION_UNARYPLUS_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_NEGATE_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_NOT_USER_DEFINED:
                    case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED_USER_DEFINED:
                        return GenerateUserDefinedUnaryOperator(pExpr);

                    case PREDEFMETH.PM_EXPRESSION_CONSTANT_OBJECT_TYPE:
                        return GenerateConstantType(pExpr);

                    case PREDEFMETH.PM_EXPRESSION_ASSIGN:
                        return GenerateAssignment(pExpr);

                    default:
                        Debug.Assert(false, "Invalid Predefined Method in VisitCALL");
                        throw Error.InternalCompilerError();
                }
            }
            return pExpr;
        }
Esempio n. 22
0
        protected override EXPR VisitCALL(EXPRCALL expr)
        {
            Debug.Assert(expr != null);
            Debug.Assert(alwaysRewrite || currentAnonMeth != null);

            switch (expr.nubLiftKind)
            {
                default:
                    break;
                case NullableCallLiftKind.NullableIntermediateConversion:
                case NullableCallLiftKind.NullableConversion:
                case NullableCallLiftKind.NullableConversionConstructor:
                    return GenerateConversion(expr.GetOptionalArguments(), expr.type, expr.isChecked());
                case NullableCallLiftKind.NotLiftedIntermediateConversion:
                case NullableCallLiftKind.UserDefinedConversion:
                    return GenerateUserDefinedConversion(expr.GetOptionalArguments(), expr.type, expr.mwi);
            }

            if (expr.mwi.Meth().IsConstructor())
            {
                return GenerateConstructor(expr);
            }

            EXPRMEMGRP memberGroup = expr.GetMemberGroup();
            if (memberGroup.isDelegate())
            {
                return GenerateDelegateInvoke(expr);
            }

            EXPR pObject;
            if (expr.mwi.Meth().isStatic || expr.GetMemberGroup().GetOptionalObject() == null)
            {
                pObject = GetExprFactory().CreateNull();
            }
            else
            {
                pObject = expr.GetMemberGroup().GetOptionalObject();

                // 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.isCAST() && pObject.asCAST().IsBoxingCast())
                {
                    pObject = pObject.asCAST().GetArgument();
                }
                pObject = Visit(pObject);
            }
            EXPR methodInfo = GetExprFactory().CreateMethodInfo(expr.mwi);
            EXPR args = GenerateArgsList(expr.GetOptionalArguments());
            EXPR Params = GenerateParamsArray(args, PredefinedType.PT_EXPRESSION);
            PREDEFMETH pdm = PREDEFMETH.PM_EXPRESSION_CALL;
            Debug.Assert(!expr.mwi.Meth().isVirtual || expr.GetMemberGroup().GetOptionalObject() != null);

            return GenerateCall(pdm, pObject, methodInfo, Params);
        }
Esempio n. 23
0
        protected virtual EXPR GenerateConstructor(EXPRCALL expr)
        {
            Debug.Assert(expr != null);
            Debug.Assert(expr.mwi.Meth().IsConstructor());

            // Realize a call to new DELEGATE(obj, FUNCPTR) as though it actually was
            // (DELEGATE)CreateDelegate(typeof(DELEGATE), obj, GetMethInfoFromHandle(FUNCPTR))

            if (IsDelegateConstructorCall(expr))
            {
                return GenerateDelegateConstructor(expr);
            }
            EXPR constructorInfo = GetExprFactory().CreateMethodInfo(expr.mwi);
            EXPR args = GenerateArgsList(expr.GetOptionalArguments());
            EXPR Params = GenerateParamsArray(args, PredefinedType.PT_EXPRESSION);
            if (expr.type.IsAggregateType() && expr.type.AsAggregateType().getAggregate().IsAnonymousType())
            {
                EXPR members = GenerateMembersArray(expr.type.AsAggregateType(), PredefinedType.PT_METHODINFO);
                return GenerateCall(PREDEFMETH.PM_EXPRESSION_NEW_MEMBERS, constructorInfo, Params, members);
            }
            else
            {
                return GenerateCall(PREDEFMETH.PM_EXPRESSION_NEW, constructorInfo, Params);
            }
        }
Esempio n. 24
0
        /////////////////////////////////////////////////////////////////////////////////

        private ExpressionEXPR GenerateField(EXPRCALL pExpr)
        {
            EXPRLIST list = pExpr.asCALL().GetOptionalArguments().asLIST();
            Type t = list.GetOptionalNextListNode().asFIELDINFO().FieldType().AssociatedSystemType;
            FieldInfo f = list.GetOptionalNextListNode().asFIELDINFO().Field().AssociatedFieldInfo;

            // This is to ensure that for embedded nopia types, we have the
            // appropriate local type from the member itself; this is possible
            // because nopia types are not generic or nested.
            if (!t.GetTypeInfo().IsGenericType && !t.GetTypeInfo().IsNested)
            {
                t = f.DeclaringType;
            }

            // Now find the generic'ed one if we're generic.
            if (t.GetTypeInfo().IsGenericType)
            {
                f = t.GetField(f.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
            }

            return new ExpressionEXPR(Expression.Field(GetExpression(list.GetOptionalElement()), f));
        }
Esempio n. 25
0
 protected virtual EXPR VisitCALL(EXPRCALL pExpr)
 {
     return(VisitEXPR(pExpr));
 }
Esempio n. 26
0
            /***************************************************************************************************
            *   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);
            }
Esempio n. 27
0
        /////////////////////////////////////////////////////////////////////////////////

        private ExpressionEXPR GenerateInvoke(EXPRCALL pExpr)
        {
            EXPRLIST list = pExpr.asCALL().GetOptionalArguments().asLIST();

            return new ExpressionEXPR(Expression.Invoke(
                GetExpression(list.GetOptionalElement()),
                GetArgumentsFromArrayInit(list.GetOptionalNextListNode().asARRINIT())));
        }
Esempio n. 28
0
 protected virtual EXPR GenerateDelegateInvoke(EXPRCALL expr)
 {
     Debug.Assert(expr != null);
     EXPRMEMGRP memberGroup = expr.GetMemberGroup();
     Debug.Assert(memberGroup.isDelegate());
     EXPR oldObject = memberGroup.GetOptionalObject();
     Debug.Assert(oldObject != null);
     EXPR pObject = Visit(oldObject);
     EXPR args = GenerateArgsList(expr.GetOptionalArguments());
     EXPR Params = GenerateParamsArray(args, PredefinedType.PT_EXPRESSION);
     return GenerateCall(PREDEFMETH.PM_EXPRESSION_INVOKE, pObject, Params);
 }
Esempio n. 29
0
        /////////////////////////////////////////////////////////////////////////////////

        private ExpressionEXPR GenerateNew(EXPRCALL pExpr)
        {
            EXPRLIST list = pExpr.asCALL().GetOptionalArguments().asLIST();

            var constructor = GetConstructorInfoFromExpr(list.GetOptionalElement().asMETHODINFO());
            var arguments = GetArgumentsFromArrayInit(list.GetOptionalNextListNode().asARRINIT());
            return new ExpressionEXPR(Expression.New(constructor, arguments));
        }
Esempio n. 30
0
        protected virtual EXPR GenerateDelegateConstructor(EXPRCALL expr)
        {
            // In:
            //
            // new DELEGATE(obj, &FUNC)
            //
            // Out:
            //
            //  Cast(
            //      Call(
            //          null,
            //          (MethodInfo)GetMethodFromHandle(&CreateDelegate),
            //          new Expression[3]{
            //              Constant(typeof(DELEGATE)),
            //              transformed-object,
            //              Constant((MethodInfo)GetMethodFromHandle(&FUNC)}),
            //      typeof(DELEGATE))
            //

            Debug.Assert(expr != null);
            Debug.Assert(expr.mwi.Meth().IsConstructor());
            Debug.Assert(expr.type.isDelegateType());
            Debug.Assert(expr.GetOptionalArguments() != null);
            Debug.Assert(expr.GetOptionalArguments().isLIST());
            EXPRLIST origArgs = expr.GetOptionalArguments().asLIST();
            EXPR target = origArgs.GetOptionalElement();
            Debug.Assert(origArgs.GetOptionalNextListNode().kind == ExpressionKind.EK_FUNCPTR);
            EXPRFUNCPTR funcptr = origArgs.GetOptionalNextListNode().asFUNCPTR();
            MethodSymbol createDelegateMethod = GetPreDefMethod(PREDEFMETH.PM_METHODINFO_CREATEDELEGATE_TYPE_OBJECT);
            AggregateType delegateType = GetSymbolLoader().GetOptPredefTypeErr(PredefinedType.PT_DELEGATE, true);
            MethWithInst mwi = new MethWithInst(createDelegateMethod, delegateType);

            EXPR instance = GenerateConstant(GetExprFactory().CreateMethodInfo(funcptr.mwi));
            EXPR methinfo = GetExprFactory().CreateMethodInfo(mwi);
            EXPR param1 = GenerateConstant(CreateTypeOf(expr.type));
            EXPR param2 = Visit(target);
            EXPR paramsList = GetExprFactory().CreateList(param1, param2);
            EXPR Params = GenerateParamsArray(paramsList, PredefinedType.PT_EXPRESSION);
            EXPR call = GenerateCall(PREDEFMETH.PM_EXPRESSION_CALL, instance, methinfo, Params);
            EXPR pTypeOf = CreateTypeOf(expr.type);
            return GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, call, pTypeOf);
        }
Esempio n. 31
0
        /////////////////////////////////////////////////////////////////////////////////

        private ExpressionEXPR GenerateConstantType(EXPRCALL pExpr)
        {
            EXPRLIST list = pExpr.GetOptionalArguments().asLIST();

            return new ExpressionEXPR(
                Expression.Constant(
                    GetObject(list.GetOptionalElement()),
                    list.GetOptionalNextListNode().asTYPEOF().SourceType.type.AssociatedSystemType));
        }