/////////////////////////////////////////////////////////////////////////////////

        protected override EXPR VisitSAVE(EXPRBINOP pExpr)
        {
            // Saves should have a LHS that is a CALL to PM_EXPRESSION_PARAMETER
            // and a RHS that is a WRAP of that call.
            Debug.Assert(pExpr.GetOptionalLeftChild() != null);
            Debug.Assert(pExpr.GetOptionalLeftChild().isCALL());
            Debug.Assert(pExpr.GetOptionalLeftChild().asCALL().PredefinedMethod == PREDEFMETH.PM_EXPRESSION_PARAMETER);
            Debug.Assert(pExpr.GetOptionalRightChild() != null);
            Debug.Assert(pExpr.GetOptionalRightChild().isWRAP());

            EXPRCALL call = pExpr.GetOptionalLeftChild().asCALL();
            EXPRTYPEOF TypeOf = call.GetOptionalArguments().asLIST().GetOptionalElement().asTYPEOF();
            Expression parameter = _ListOfParameters.ElementAt(_currentParameterIndex++);
            _DictionaryOfParameters.Add(call, parameter);

            return null;
        }
Beispiel #2
0
 protected virtual EXPR VisitDELEGATESUB(EXPRBINOP pExpr)
 {
     return VisitBINOP(pExpr);
 }
Beispiel #3
0
 protected virtual EXPR VisitSWAP(EXPRBINOP pExpr)
 {
     return VisitBINOP(pExpr);
 }
Beispiel #4
0
 protected virtual EXPR VisitSTRINGNE(EXPRBINOP pExpr)
 {
     return VisitBINOP(pExpr);
 }
Beispiel #5
0
 protected virtual EXPR VisitLOGOR(EXPRBINOP pExpr)
 {
     return VisitBINOP(pExpr);
 }
Beispiel #6
0
 public EXPRBINOP CreateBinop(ExpressionKind exprKind, CType pType, EXPR p1, EXPR p2)
 {
     //Debug.Assert(exprKind.isBinaryOperator());
     EXPRBINOP rval = new EXPRBINOP();
     rval.kind = exprKind;
     rval.type = pType;
     rval.flags = EXPRFLAG.EXF_BINOP;
     rval.SetOptionalLeftChild(p1);
     rval.SetOptionalRightChild(p2);
     rval.isLifted = false;
     rval.SetOptionalUserDefinedCall(null);
     rval.SetUserDefinedCallMethod(null);
     Debug.Assert(rval != null);
     return (rval);
 }
        protected virtual EXPR GenerateUserDefinedBinaryOperator(EXPRBINOP expr)
        {
            Debug.Assert(expr != null);
            Debug.Assert(alwaysRewrite || currentAnonMeth != null);
            PREDEFMETH pdm;

            switch (expr.kind)
            {
                case ExpressionKind.EK_LOGOR: pdm = PREDEFMETH.PM_EXPRESSION_ORELSE_USER_DEFINED; break;
                case ExpressionKind.EK_LOGAND: pdm = PREDEFMETH.PM_EXPRESSION_ANDALSO_USER_DEFINED; break;
                case ExpressionKind.EK_LSHIFT: pdm = PREDEFMETH.PM_EXPRESSION_LEFTSHIFT_USER_DEFINED; break;
                case ExpressionKind.EK_RSHIFT: pdm = PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT_USER_DEFINED; break;
                case ExpressionKind.EK_BITXOR: pdm = PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR_USER_DEFINED; break;
                case ExpressionKind.EK_BITOR: pdm = PREDEFMETH.PM_EXPRESSION_OR_USER_DEFINED; break;
                case ExpressionKind.EK_BITAND: pdm = PREDEFMETH.PM_EXPRESSION_AND_USER_DEFINED; break;
                case ExpressionKind.EK_MOD: pdm = PREDEFMETH.PM_EXPRESSION_MODULO_USER_DEFINED; break;
                case ExpressionKind.EK_DIV: pdm = PREDEFMETH.PM_EXPRESSION_DIVIDE_USER_DEFINED; break;
                case ExpressionKind.EK_STRINGEQ:
                case ExpressionKind.EK_STRINGNE:
                case ExpressionKind.EK_DELEGATEEQ:
                case ExpressionKind.EK_DELEGATENE:
                case ExpressionKind.EK_EQ:
                case ExpressionKind.EK_NE:
                case ExpressionKind.EK_GE:
                case ExpressionKind.EK_GT:
                case ExpressionKind.EK_LE:
                case ExpressionKind.EK_LT:
                    return GenerateUserDefinedComparisonOperator(expr);
                case ExpressionKind.EK_DELEGATESUB:
                case ExpressionKind.EK_SUB:
                    pdm = expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED_USER_DEFINED : PREDEFMETH.PM_EXPRESSION_SUBTRACT_USER_DEFINED;
                    break;
                case ExpressionKind.EK_DELEGATEADD:
                case ExpressionKind.EK_ADD:
                    pdm = expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_ADDCHECKED_USER_DEFINED : PREDEFMETH.PM_EXPRESSION_ADD_USER_DEFINED;
                    break;
                case ExpressionKind.EK_MUL:
                    pdm = expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED_USER_DEFINED : PREDEFMETH.PM_EXPRESSION_MULTIPLY_USER_DEFINED;
                    break;
                default:
                    throw Error.InternalCompilerError();
            }
            EXPR p1 = expr.GetOptionalLeftChild();
            EXPR p2 = expr.GetOptionalRightChild();
            EXPR udcall = expr.GetOptionalUserDefinedCall();
            if (udcall != null)
            {
                Debug.Assert(udcall.kind == ExpressionKind.EK_CALL || udcall.kind == ExpressionKind.EK_USERLOGOP);
                if (udcall.kind == ExpressionKind.EK_CALL)
                {
                    EXPRLIST args = udcall.asCALL().GetOptionalArguments().asLIST();
                    Debug.Assert(args.GetOptionalNextListNode().kind != ExpressionKind.EK_LIST);
                    p1 = args.GetOptionalElement();
                    p2 = args.GetOptionalNextListNode();
                }
                else
                {
                    EXPRLIST args = udcall.asUSERLOGOP().OperatorCall.GetOptionalArguments().asLIST();
                    Debug.Assert(args.GetOptionalNextListNode().kind != ExpressionKind.EK_LIST);
                    p1 = args.GetOptionalElement().asWRAP().GetOptionalExpression();
                    p2 = args.GetOptionalNextListNode();
                }
            }
            p1 = Visit(p1);
            p2 = Visit(p2);
            FixLiftedUserDefinedBinaryOperators(expr, ref p1, ref p2);
            EXPR methodInfo = GetExprFactory().CreateMethodInfo(expr.GetUserDefinedCallMethod());
            EXPR call = GenerateCall(pdm, p1, p2, methodInfo);
            // Delegate add/subtract generates a call to Combine/Remove, which returns System.Delegate,
            // not the operand delegate CType.  We must cast to the delegate CType.
            if (expr.kind == ExpressionKind.EK_DELEGATESUB || expr.kind == ExpressionKind.EK_DELEGATEADD)
            {
                EXPR pTypeOf = CreateTypeOf(expr.type);
                return GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, call, pTypeOf);
            }
            return call;
        }
 protected override EXPR VisitBINOP(EXPRBINOP expr)
 {
     Debug.Assert(expr != null);
     Debug.Assert(alwaysRewrite || currentAnonMeth != null);
     if (expr.GetUserDefinedCallMethod() != null)
     {
         return GenerateUserDefinedBinaryOperator(expr);
     }
     else
     {
         return GenerateBuiltInBinaryOperator(expr);
     }
 }
Beispiel #9
0
 protected virtual EXPR VisitEQUALS(EXPRBINOP pExpr)
 {
     return VisitBINOP(pExpr);
 }
Beispiel #10
0
 protected virtual EXPR VisitLT(EXPRBINOP pExpr)
 {
     return(VisitBINOP(pExpr));
 }
Beispiel #11
0
 protected virtual EXPR VisitDELEGATEADD(EXPRBINOP pExpr)
 {
     return(VisitBINOP(pExpr));
 }
Beispiel #12
0
 protected virtual EXPR VisitSTRINGEQ(EXPRBINOP pExpr)
 {
     return(VisitBINOP(pExpr));
 }
Beispiel #13
0
 protected virtual EXPR VisitSEQUENCE(EXPRBINOP pExpr)
 {
     return(VisitBINOP(pExpr));
 }
Beispiel #14
0
 public EXPRBINOP CreateUserDefinedBinop(ExpressionKind exprKind, CType pType, EXPR p1, EXPR p2, EXPR call, MethPropWithInst pmpwi)
 {
     Debug.Assert(p1 != null);
     Debug.Assert(p2 != null);
     Debug.Assert(call != null);
     EXPRBINOP rval = new EXPRBINOP();
     rval.kind = exprKind;
     rval.type = pType;
     rval.flags = EXPRFLAG.EXF_BINOP;
     rval.SetOptionalLeftChild(p1);
     rval.SetOptionalRightChild(p2);
     // The call may be lifted, but we do not mark the outer binop as lifted.
     rval.isLifted = false;
     rval.SetOptionalUserDefinedCall(call);
     rval.SetUserDefinedCallMethod(pmpwi);
     if (call.HasError())
     {
         rval.SetError();
     }
     Debug.Assert(rval != null);
     return (rval);
 }
Beispiel #15
0
 protected virtual EXPR VisitCOMPARE(EXPRBINOP pExpr)
 {
     return VisitBINOP(pExpr);
 }
        protected void FixLiftedUserDefinedBinaryOperators(EXPRBINOP expr, ref EXPR pp1, ref EXPR pp2)
        {
            // If we have lifted T1 op T2 to T1? op T2?, and we have an expression T1 op T2? or T1? op T2 then
            // we need to ensure that the unlifted actual arguments are promoted to their nullable CType.
            Debug.Assert(expr != null);
            Debug.Assert(pp1 != null);
            Debug.Assert(pp1 != null);
            Debug.Assert(pp2 != null);
            Debug.Assert(pp2 != null);
            MethodSymbol method = expr.GetUserDefinedCallMethod().Meth();
            EXPR orig1 = expr.GetOptionalLeftChild();
            EXPR orig2 = expr.GetOptionalRightChild();
            Debug.Assert(orig1 != null && orig2 != null);
            EXPR new1 = pp1;
            EXPR new2 = pp2;
            CType fptype1 = method.Params.Item(0);
            CType fptype2 = method.Params.Item(1);
            CType aatype1 = orig1.type;
            CType aatype2 = orig2.type;
            // Is the operator even a candidate for lifting?
            if (fptype1.IsNullableType() || fptype2.IsNullableType() ||
                !fptype1.IsAggregateType() || !fptype2.IsAggregateType() ||
                !fptype1.AsAggregateType().getAggregate().IsValueType() ||
                !fptype2.AsAggregateType().getAggregate().IsValueType())
            {
                return;
            }
            CType nubfptype1 = GetSymbolLoader().GetTypeManager().GetNullable(fptype1);
            CType nubfptype2 = GetSymbolLoader().GetTypeManager().GetNullable(fptype2);
            // If we have null op X, or T1 op T2?, or T1 op null, lift first arg to T1?
            if (aatype1.IsNullType() || aatype1 == fptype1 && (aatype2 == nubfptype2 || aatype2.IsNullType()))
            {
                new1 = GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, new1, CreateTypeOf(nubfptype1));
            }

            // If we have X op null, or T1? op T2, or null op T2, lift second arg to T2?
            if (aatype2.IsNullType() || aatype2 == fptype2 && (aatype1 == nubfptype1 || aatype1.IsNullType()))
            {
                new2 = GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, new2, CreateTypeOf(nubfptype2));
            }
            pp1 = new1;
            pp2 = new2;
        }
Beispiel #17
0
 protected virtual EXPR VisitSEQUENCE(EXPRBINOP pExpr)
 {
     return VisitBINOP(pExpr);
 }
        protected virtual EXPR GenerateBuiltInBinaryOperator(EXPRBINOP expr)
        {
            Debug.Assert(expr != null);
            Debug.Assert(alwaysRewrite || currentAnonMeth != null);
            PREDEFMETH pdm;

            switch (expr.kind)
            {
                case ExpressionKind.EK_LSHIFT: pdm = PREDEFMETH.PM_EXPRESSION_LEFTSHIFT; break;
                case ExpressionKind.EK_RSHIFT: pdm = PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT; break;
                case ExpressionKind.EK_BITXOR: pdm = PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR; break;
                case ExpressionKind.EK_BITOR: pdm = PREDEFMETH.PM_EXPRESSION_OR; break;
                case ExpressionKind.EK_BITAND: pdm = PREDEFMETH.PM_EXPRESSION_AND; break;
                case ExpressionKind.EK_LOGAND: pdm = PREDEFMETH.PM_EXPRESSION_ANDALSO; break;
                case ExpressionKind.EK_LOGOR: pdm = PREDEFMETH.PM_EXPRESSION_ORELSE; break;
                case ExpressionKind.EK_STRINGEQ: pdm = PREDEFMETH.PM_EXPRESSION_EQUAL; break;
                case ExpressionKind.EK_EQ: pdm = PREDEFMETH.PM_EXPRESSION_EQUAL; break;
                case ExpressionKind.EK_STRINGNE: pdm = PREDEFMETH.PM_EXPRESSION_NOTEQUAL; break;
                case ExpressionKind.EK_NE: pdm = PREDEFMETH.PM_EXPRESSION_NOTEQUAL; break;
                case ExpressionKind.EK_GE: pdm = PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL; break;
                case ExpressionKind.EK_LE: pdm = PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL; break;
                case ExpressionKind.EK_LT: pdm = PREDEFMETH.PM_EXPRESSION_LESSTHAN; break;
                case ExpressionKind.EK_GT: pdm = PREDEFMETH.PM_EXPRESSION_GREATERTHAN; break;
                case ExpressionKind.EK_MOD: pdm = PREDEFMETH.PM_EXPRESSION_MODULO; break;
                case ExpressionKind.EK_DIV: pdm = PREDEFMETH.PM_EXPRESSION_DIVIDE; break;
                case ExpressionKind.EK_MUL:
                    pdm = expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED : PREDEFMETH.PM_EXPRESSION_MULTIPLY;
                    break;
                case ExpressionKind.EK_SUB:
                    pdm = expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED : PREDEFMETH.PM_EXPRESSION_SUBTRACT;
                    break;
                case ExpressionKind.EK_ADD:
                    pdm = expr.isChecked() ? PREDEFMETH.PM_EXPRESSION_ADDCHECKED : PREDEFMETH.PM_EXPRESSION_ADD;
                    break;

                default:
                    throw Error.InternalCompilerError();
            }
            EXPR origL = expr.GetOptionalLeftChild();
            EXPR origR = expr.GetOptionalRightChild();
            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 = GetSymbolLoader().GetTypeManager().GetNullable(typeL.underlyingEnumType());
                typeL = convertL;
                didEnumConversion = true;
            }
            else if (typeL.IsNullableType() && typeL.StripNubs().isEnumType())
            {
                Debug.Assert(expr.isLifted);
                convertL = GetSymbolLoader().GetTypeManager().GetNullable(typeL.StripNubs().underlyingEnumType());
                typeL = convertL;
                didEnumConversion = true;
            }
            if (typeR.isEnumType())
            {
                Debug.Assert(expr.isLifted);
                convertR = GetSymbolLoader().GetTypeManager().GetNullable(typeR.underlyingEnumType());
                typeR = convertR;
                didEnumConversion = true;
            }
            else if (typeR.IsNullableType() && typeR.StripNubs().isEnumType())
            {
                Debug.Assert(expr.isLifted);
                convertR = GetSymbolLoader().GetTypeManager().GetNullable(typeR.StripNubs().underlyingEnumType());
                typeR = convertR;
                didEnumConversion = true;
            }
            if (typeL.IsNullableType() && typeL.StripNubs() == typeR)
            {
                convertR = typeL;
            }
            if (typeR.IsNullableType() && typeR.StripNubs() == 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;
        }
Beispiel #19
0
 protected virtual EXPR VisitRSHIFT(EXPRBINOP pExpr)
 {
     return VisitBINOP(pExpr);
 }
        protected virtual EXPR GenerateUserDefinedComparisonOperator(EXPRBINOP expr)
        {
            Debug.Assert(expr != null);
            Debug.Assert(alwaysRewrite || currentAnonMeth != null);
            PREDEFMETH pdm;

            switch (expr.kind)
            {
                case ExpressionKind.EK_STRINGEQ: pdm = PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED; break;
                case ExpressionKind.EK_STRINGNE: pdm = PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED; break;
                case ExpressionKind.EK_DELEGATEEQ: pdm = PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED; break;
                case ExpressionKind.EK_DELEGATENE: pdm = PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED; break;
                case ExpressionKind.EK_EQ: pdm = PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED; break;
                case ExpressionKind.EK_NE: pdm = PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED; break;
                case ExpressionKind.EK_LE: pdm = PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL_USER_DEFINED; break;
                case ExpressionKind.EK_LT: pdm = PREDEFMETH.PM_EXPRESSION_LESSTHAN_USER_DEFINED; break;
                case ExpressionKind.EK_GE: pdm = PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL_USER_DEFINED; break;
                case ExpressionKind.EK_GT: pdm = PREDEFMETH.PM_EXPRESSION_GREATERTHAN_USER_DEFINED; break;
                default:
                    throw Error.InternalCompilerError();
            }
            EXPR p1 = expr.GetOptionalLeftChild();
            EXPR p2 = expr.GetOptionalRightChild();
            if (expr.GetOptionalUserDefinedCall() != null)
            {
                EXPRCALL udcall = expr.GetOptionalUserDefinedCall().asCALL();
                EXPRLIST args = udcall.GetOptionalArguments().asLIST();
                Debug.Assert(args.GetOptionalNextListNode().kind != ExpressionKind.EK_LIST);

                p1 = args.GetOptionalElement();
                p2 = args.GetOptionalNextListNode();
            }
            p1 = Visit(p1);
            p2 = Visit(p2);
            FixLiftedUserDefinedBinaryOperators(expr, ref p1, ref p2);
            EXPR lift = GetExprFactory().CreateBoolConstant(false); // We never lift to null in C#.
            EXPR methodInfo = GetExprFactory().CreateMethodInfo(expr.GetUserDefinedCallMethod());
            return GenerateCall(pdm, p1, p2, lift, methodInfo);
        }
Beispiel #21
0
        public EXPRQUESTIONMARK CreateQuestionMark(EXPR pTestExpression, EXPRBINOP pConsequence)
        {
            Debug.Assert(pTestExpression != null);
            Debug.Assert(pConsequence != null);

            CType pType = pConsequence.type;
            if (pType == null)
            {
                Debug.Assert(pConsequence.GetOptionalLeftChild() != null);
                pType = pConsequence.GetOptionalLeftChild().type;
                Debug.Assert(pType != null);
            }
            EXPRQUESTIONMARK pResult = new EXPRQUESTIONMARK();
            pResult.kind = ExpressionKind.EK_QUESTIONMARK;
            pResult.type = pType;
            pResult.flags = 0;
            pResult.SetTestExpression(pTestExpression);
            pResult.SetConsequence(pConsequence);
            Debug.Assert(pResult != null);
            return pResult;
        }